It cannot be taken any later. NTFS is a database both in memory and on disk
and in fact the in memory meta data is the on-disk structures (i.e. no
conversion between the two is performed, except in few speed optimization
cases and in cases where meta data is compressed on disk).
Because everything is ogranized in database records, I need to grab the
lock as soon as I intend to access the record (in fact the lock itself is
taken by map_mft_record(READ or WRITE) which returns a locked record, that
is mapped and pinned in memory, to the caller. I can then do all sorts of
things with the record, like search it, parse data from it, etc. When
finished I unmap_mft_record(READ or WRITE) which undoes everything
map_mft_record() did, i.e. unpins the record, unmaps it and releases the lock.
All transactions with the on disk storage are done via the page cache and
read_cache_page() using a special readpage() and a special async io
completion handler.
Because of the abstraction of access layers it is undesirable to operate on
the same locks in different layers, hence the top most layer is the one
locking and unlocking the records. The lower layers don't even know the
locks exist. Also pushing the lock deep into the layers is not actually
possible as it would probably need to be taken in reac_cache_page() (the
only place where the code knows if the page is present in memory or not and
a disk access is required) which is a VFS/MM function and hence that is not
an option.
Further, I may need to allocate memory in order to store decompressed
metadata for example but I won't know if I need to do that until I have
already locked the record and accessed it to determine if the metadata is
compressed or not.
So basically I can only obtain sufficient info for deciding what lock I
need after I have already accessed parts of the record, but to access it I
need to have locked it. Chicken and egg situation... So the locks are
always semaphores and are taken in the top layer.
A combi lock would allow spinning in the case where it turns out the code
paths will not hit disk or sleep in kmalloc, etc and sleeping in the
disk/kmalloc hit case.
(Yes I know atomic kmalloc exists but I actually need vmalloc in some cases
depending how much memory I need to handle the metadata...)
Best regards,
Anton
-- "I've not lost my mind. It's backed up on tape somewhere." - Unknown-- Anton Altaparmakov <aia21 at cam.ac.uk> (replace at with @) Linux NTFS Maintainer / WWW: http://linux-ntfs.sf.net/ ICQ: 8561279 / WWW: http://www-stu.christs.cam.ac.uk/~aia21/- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/