Преглед на файлове

[tftp] Temporary fix for conveying TFTP block size to callers

pxe_tftp.c assumes that the first seek on its data-transfer interface
represents the block size.  Apart from being an ugly hack, this will
also screw up file size calculation for files smaller than one block.

The proper solution would be to extend the data-transfer interface to
support the reporting of stat()-like data.  This is not going to
happen until the cost of adding interface methods is reduced (a fix I
have planned since June 2008).

In the meantime, abuse the xfer_window() method to return the block
size, since it is not being used for anything else and is vaguely
justifiable.

Astonishingly, having returned the incorrect TFTP blocksize via
PXENV_TFTP_OPEN for almost a year seems not to have affected any of
the test cases run during that time; this bug was found only when
someone tried running the heavily-patched version of pxegrub found in
OpenSolaris.
tags/v0.9.7
Michael Brown преди 15 години
родител
ревизия
1284773363
променени са 2 файла, в които са добавени 23 реда и са изтрити 8 реда
  1. 4
    7
      src/arch/i386/interface/pxe/pxe_tftp.c
  2. 19
    1
      src/net/udp/tftp.c

+ 4
- 7
src/arch/i386/interface/pxe/pxe_tftp.c Целия файл

113
 	/* Calculate new buffer position */
113
 	/* Calculate new buffer position */
114
 	pxe_tftp.offset += len;
114
 	pxe_tftp.offset += len;
115
 
115
 
116
-	/* Mildly ugly hack; assume that the first non-zero seek
117
-	 * indicates the block size.
118
-	 */
119
-	if ( pxe_tftp.blksize == 0 )
120
-		pxe_tftp.blksize = pxe_tftp.offset;
121
-
122
 	/* Record maximum offset as the file size */
116
 	/* Record maximum offset as the file size */
123
 	if ( pxe_tftp.max_offset < pxe_tftp.offset )
117
 	if ( pxe_tftp.max_offset < pxe_tftp.offset )
124
 		pxe_tftp.max_offset = pxe_tftp.offset;
118
 		pxe_tftp.max_offset = pxe_tftp.offset;
265
 
259
 
266
 	/* Wait for OACK to arrive so that we have the block size */
260
 	/* Wait for OACK to arrive so that we have the block size */
267
 	while ( ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) &&
261
 	while ( ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) &&
268
-		( pxe_tftp.blksize == 0 ) ) {
262
+		( pxe_tftp.max_offset == 0 ) ) {
269
 		step();
263
 		step();
270
 	}
264
 	}
265
+	pxe_tftp.blksize = xfer_window ( &pxe_tftp.xfer );
271
 	tftp_open->PacketSize = pxe_tftp.blksize;
266
 	tftp_open->PacketSize = pxe_tftp.blksize;
267
+	DBG ( " blksize=%d", tftp_open->PacketSize );
272
 
268
 
273
 	/* EINPROGRESS is normal; we don't wait for the whole transfer */
269
 	/* EINPROGRESS is normal; we don't wait for the whole transfer */
274
 	if ( rc == -EINPROGRESS )
270
 	if ( rc == -EINPROGRESS )
571
 		step();
567
 		step();
572
 	}
568
 	}
573
 	tftp_get_fsize->FileSize = pxe_tftp.max_offset;
569
 	tftp_get_fsize->FileSize = pxe_tftp.max_offset;
570
+	DBG ( " fsize=%d", tftp_get_fsize->FileSize );
574
 
571
 
575
 	/* EINPROGRESS is normal; we don't wait for the whole transfer */
572
 	/* EINPROGRESS is normal; we don't wait for the whole transfer */
576
 	if ( rc == -EINPROGRESS )
573
 	if ( rc == -EINPROGRESS )

+ 19
- 1
src/net/udp/tftp.c Целия файл

986
 	tftp_done ( tftp, rc );
986
 	tftp_done ( tftp, rc );
987
 }
987
 }
988
 
988
 
989
+/**
990
+ * Check flow control window
991
+ *
992
+ * @v xfer		Data transfer interface
993
+ * @ret len		Length of window
994
+ */
995
+static size_t tftp_xfer_window ( struct xfer_interface *xfer ) {
996
+	struct tftp_request *tftp =
997
+		container_of ( xfer, struct tftp_request, xfer );
998
+
999
+	/* We abuse this data-xfer method to convey the blocksize to
1000
+	 * the caller.  This really should be done using some kind of
1001
+	 * stat() method, but we don't yet have the facility to do
1002
+	 * that.
1003
+	 */
1004
+	return tftp->blksize;
1005
+}
1006
+
989
 /** TFTP data transfer interface operations */
1007
 /** TFTP data transfer interface operations */
990
 static struct xfer_interface_operations tftp_xfer_operations = {
1008
 static struct xfer_interface_operations tftp_xfer_operations = {
991
 	.close		= tftp_xfer_close,
1009
 	.close		= tftp_xfer_close,
992
 	.vredirect	= ignore_xfer_vredirect,
1010
 	.vredirect	= ignore_xfer_vredirect,
993
-	.window		= unlimited_xfer_window,
1011
+	.window		= tftp_xfer_window,
994
 	.alloc_iob	= default_xfer_alloc_iob,
1012
 	.alloc_iob	= default_xfer_alloc_iob,
995
 	.deliver_iob	= xfer_deliver_as_raw,
1013
 	.deliver_iob	= xfer_deliver_as_raw,
996
 	.deliver_raw	= ignore_xfer_deliver_raw,
1014
 	.deliver_raw	= ignore_xfer_deliver_raw,

Loading…
Отказ
Запис