From c0c1cc0e46b36347f11b566f99087dc5e6fc1b89 Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Mon, 7 Mar 2005 21:43:38 +0000 Subject: 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 --- fs/ntfs/attrib.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'fs/ntfs/attrib.c') diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c index 1610f1c..6de5e04 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) { -- cgit v1.1