On Mon, 14 Jun 1999, Steve Dodd wrote:
> On Mon, Jun 14, 1999 at 11:56:12AM -0400, Alexander Viro wrote:
>
> > fs driver. And for normal filesystems we can get out pretty easy - a
> > single lock is enough. But here... Arrgh. AFAICS there are recursive
> > dependencies of almost arbitarary depth. Down, not across!
>
> The wonders of NTFS - the inodes are stored in what is for all intents and
> purposes, a normal file. Unnnngh.
>
> > Yup. Looks like we are deep in it.
>
> I've just done some stupid tests - run three processes writing to three files
> in parallel - and I've discovered something else that bites us: the driver
> calls kmalloc(..., GFP_KERNEL), which can (and does) sleep, so there are
> all sorts of odd places where we can sleep without expecting it.
Yup. And from my reading it seems that in many cases it's done for
no good reason.
> > Steve, could you describe the
> > data structures involved (i.e. the layout of fs - no details, just what is
> > there and what depends on what)? I suspect that it will be the fastest way
> > (invitation includes everybody, indeed). OK?
>
> Mmmm. I think it might be easier just to pull the thing apart and make it
> pass buffer_heads around, rather than allocing and copying data willy-nilly.
*probably* yes, but we might want to play with page cache here (definitely
so in 2.3.7).
> But for the record:
> Files can have multiple attributes, or streams, but the $DATA attribute holds
> the normal file contents.
>
> Attributes either have their contents in-inode ('resident') if they are small
> enough, or are non-resident, in which case a 'run-list' is stored in-inode
> instead giving the ranges of blocks (a.k.a clusters) used for the data.
Huh? Is the number of those darlings fixed and what is the size of their
inode?
> Inodes 0 - 0xa are system files; inodes 0xb - 0xf are used for extending
> inode 0 if its run-list (extents list) overflows its inode (usually 1k, 4k
> on older versions of NT).
> The inodes themselves are stored in the $DATA attribute of inode 0 (the system
> file $MFT), sequentially.
> Inode 0 ($MFT) has a $BITMAP attribute which marks
> which inodes are in use and which aren't. Inodes have a 'generation' number
> which gets incremented on disk when they're recycled, so this should make NFS
> less problematical, at least.
> The volume bitmap is stored in the data attribute of inode 5 (system file
> $Bitmap)..
>
> So:
> - the bitmaps need protecting; if we were to pass buffers around presumably
> we can just lock the buffer while we're using the bitmap (what happens to
> this sort of thing when you take the big kernel lock away from the fs
> stuff..?)
it.
> - there shouldn't be a problem with two processes writing back different
> inodes to $MFT, the thing we have to watch out for (and lock) is when we
> have to extend the MFT to make way for more inodes.
Oookay... So:
inode == (several?) blocks. No inode table per se.
inode refers to a bunch of sub-objects. Their allocation data is
stored in inode.
inode #0 refers to the inodes bitmap.
inode #5 refers to the block bitmap.
Right? BTW, how inodes are refered in directories?
Allocating/releasing blocks: should be serialized. Probably that's the
lowest level of locking. BTW, I hope that the size of block bitmap is
constant and allocation data for inode #5 can't be modified, right?
Allocating/releasing inodes: uses the previous one. Needs serialization of
its own. Probably releasing inode may be done without a lock, but that
depends on details of driver. Allocation *definitely* requires locking.
Modifying inode: no special locking, but we may need to allocate blocks.
Ho-hmm...