Lay down some comments related to the previous few revisions of ufs_vnops.c.

This commit is contained in:
dholland 2019-07-01 00:57:06 +00:00
parent f3430e9b6f
commit ea86c8c3a8

View File

@ -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 @@ ufs_readdir(void *v)
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 @@ ufs_readdir(void *v)
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 @@ ufs_readdir(void *v)
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;