diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-03-07 22:43:38 +0100 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-05-05 12:20:49 +0200 |
commit | c0c1cc0e46b36347f11b566f99087dc5e6fc1b89 (patch) | |
tree | 773105bdde7454d10dccc127048a9847f7e01f11 /fs/ntfs/attrib.c | |
parent | NTFS: Add fs/ntfs/attrib.[hc]::ntfs_attr_vcn_to_lcn_nolock() used by the new (diff) | |
download | linux-c0c1cc0e46b36347f11b566f99087dc5e6fc1b89.tar.xz linux-c0c1cc0e46b36347f11b566f99087dc5e6fc1b89.zip |
NTFS: - Fix bug in fs/ntfs/attrib.c::ntfs_find_vcn_nolock() where after
dropping the read lock and taking the write lock we were not checking
whether someone else did not already do the work we wanted to do.
- Rename ntfs_find_vcn_nolock() to ntfs_attr_find_vcn_nolock().
- Tidy up some comments in fs/ntfs/runlist.c.
- Add LCN_ENOMEM and LCN_EIO definitions to fs/ntfs/runlist.h.
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs/ntfs/attrib.c')
-rw-r--r-- | fs/ntfs/attrib.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 1610f1cd2862..6de5e04e97a2 100644 --- a/fs/ntfs/attrib.c +++ b/fs/ntfs/attrib.c @@ -193,19 +193,19 @@ retry_remap: } /** - * ntfs_find_vcn_nolock - find a vcn in the runlist described by an ntfs inode + * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode * @ni: ntfs inode describing the runlist to search * @vcn: vcn to find * @write_locked: true if the runlist is locked for writing * * Find the virtual cluster number @vcn in the runlist described by the ntfs * inode @ni and return the address of the runlist element containing the @vcn. - * The runlist is left locked and the caller has to unlock it. In the error - * case, the runlist is left in the same locking state as on entry. * - * Note if @write_locked is FALSE the lock may be dropped inside the function - * so you cannot rely on the runlist still being the same when this function - * returns. + * If the @vcn is not mapped yet, the attempt is made to map the attribute + * extent containing the @vcn and the vcn to lcn conversion is retried. + * + * If @write_locked is true the caller has locked the runlist for writing and + * if false for reading. * * Note you need to distinguish between the lcn of the returned runlist element * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on @@ -221,13 +221,12 @@ retry_remap: * -ENOMEM - Not enough memory to map runlist. * -EIO - Critical error (runlist/file is corrupt, i/o error, etc). * - * Locking: - The runlist must be unlocked on entry. - * - On failing return, the runlist is unlocked. - * - On successful return, the runlist is locked. If @need_write us - * true, it is locked for writing. Otherwise is is locked for - * reading. + * Locking: - The runlist must be locked on entry and is left locked on return. + * - If @write_locked is FALSE, i.e. the runlist is locked for reading, + * the lock may be dropped inside the function so you cannot rely on + * the runlist still being the same when this function returns. */ -runlist_element *ntfs_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, +runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, const BOOL write_locked) { runlist_element *rl; @@ -268,6 +267,12 @@ retry_remap: if (!write_locked) { up_read(&ni->runlist.lock); down_write(&ni->runlist.lock); + if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) != + LCN_RL_NOT_MAPPED)) { + up_write(&ni->runlist.lock); + down_read(&ni->runlist.lock); + goto retry_remap; + } } err = ntfs_map_runlist_nolock(ni, vcn); if (!write_locked) { |