Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/ufs Lay down some comments related to the previous f...
details: https://anonhg.NetBSD.org/src/rev/0ed0b4be5c69
branches: trunk
changeset: 461704:0ed0b4be5c69
user: dholland <dholland%NetBSD.org@localhost>
date: Mon Jul 01 00:57:06 2019 +0000
description:
Lay down some comments related to the previous few revisions of ufs_vnops.c.
diffstat:
sys/ufs/ufs/ufs_vnops.c | 79 +++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 74 insertions(+), 5 deletions(-)
diffs (117 lines):
diff -r 2978002d477e -r 0ed0b4be5c69 sys/ufs/ufs/ufs_vnops.c
--- a/sys/ufs/ufs/ufs_vnops.c Sun Jun 30 22:37:11 2019 +0000
+++ b/sys/ufs/ufs/ufs_vnops.c Mon Jul 01 00:57:06 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_vnops.c,v 1.246 2019/02/25 06:00:40 dholland Exp $ */
+/* $NetBSD: ufs_vnops.c,v 1.247 2019/07/01 00:57:06 dholland Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.246 2019/02/25 06:00:40 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.247 2019/07/01 00:57:06 dholland Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -1257,7 +1257,12 @@
KASSERT(VOP_ISLOCKED(vp));
- /* figure out where we want to read */
+ /*
+ * Figure out where the user wants us to read and how much.
+ *
+ * XXX: there should probably be an upper bound on callerbytes
+ * to avoid silliness trying to do large kernel allocations.
+ */
callerbytes = calleruio->uio_resid;
startoffset = calleruio->uio_offset;
endoffset = startoffset + callerbytes;
@@ -1267,7 +1272,39 @@
return EINVAL;
}
- /* round start and end down to block boundaries */
+ /*
+ * Now figure out where to actually start reading. Round the
+ * start down to a block boundary: we need to start at the
+ * beginning of a block in order to read the directory
+ * correctly.
+ *
+ * We also want to always read a whole number of blocks so
+ * that the copying code below doesn't have to worry about
+ * partial entries. (It used to try at one point, and was a
+ * horrible mess.)
+ *
+ * Furthermore, since blocks have to be scanned from the
+ * beginning, if we go partially into another block now we'll
+ * just have to rescan it on the next readdir call, which
+ * doesn't really serve any useful purpose.
+ *
+ * So, round down the end as well. It's ok to underpopulate
+ * the transfer buffer, as long as we send back at least one
+ * dirent so as to avoid giving a bogus EOF indication.
+ *
+ * Note that because dirents are larger than ffs struct
+ * directs, despite the rounding down we may not be able to
+ * send all the entries in the blocks we read and may have to
+ * rescan some of them on the next call anyway. Alternatively
+ * if there's empty space on disk we might have actually been
+ * able to fit the next block in, and so forth. None of this
+ * actually matters that much in practice.
+ *
+ * XXX: what does ffs do if a directory block becomes
+ * completely empty, and what happens if all the blocks we
+ * read are completely empty even though we aren't at EOF? As
+ * of this writing I (dholland) can't remember the details.
+ */
physstart = rounddown2(startoffset, ump->um_dirblksiz);
physend = rounddown2(endoffset, ump->um_dirblksiz);
@@ -1276,10 +1313,42 @@
return EINVAL;
}
+ /*
+ * skipstart is the number of bytes we need to read in
+ * (because we need to start at the beginning of a block) but
+ * not transfer to the user.
+ *
+ * dropend is the number of bytes to ignore at the end of the
+ * user's buffer.
+ */
skipstart = startoffset - physstart;
dropend = endoffset - physend;
- /* how much to actually read */
+ /*
+ * Make a transfer buffer.
+ *
+ * Note: rawbufmax = physend - physstart. Proof:
+ *
+ * physend - physstart = physend - physstart
+ * = physend - physstart + startoffset - startoffset
+ * = physend + (startoffset - physstart) - startoffset
+ * = physend + skipstart - startoffset
+ * = physend + skipstart - startoffset + endoffset - endoffset
+ * = skipstart - startoffset + endoffset - (endoffset - physend)
+ * = skipstart - startoffset + endoffset - dropend
+ * = skipstart - startoffset + (startoffset + callerbytes) - dropend
+ * = skipstart + callerbytes - dropend
+ * = rawbufmax
+ * Qed.
+ *
+ * XXX: this should just use physend - physstart.
+ *
+ * XXX: this should be rewritten to read the directs straight
+ * out of bufferio buffers instead of copying twice. This would
+ * also let us adapt better to the user's buffer size.
+ */
+
+ /* Base buffer space for CALLERBYTES of new data */
rawbufmax = callerbytes + skipstart;
if (rawbufmax < callerbytes)
return EINVAL;
Home |
Main Index |
Thread Index |
Old Index