]> git.hungrycats.org Git - linux/commitdiff
NTFS: Add fs/ntfs/mft.c::try_map_mft_record() which fails with -EALREADY if
authorAnton Altaparmakov <aia21@cantab.net>
Mon, 11 Oct 2004 14:51:24 +0000 (15:51 +0100)
committerAnton Altaparmakov <aia21@cantab.net>
Mon, 11 Oct 2004 14:51:24 +0000 (15:51 +0100)
      the mft record is already locked and otherwise behaves the same way
      as fs/ntfs/mft.c::map_mft_record().

Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
fs/ntfs/ChangeLog
fs/ntfs/mft.c
fs/ntfs/mft.h

index 91b23be8c7dbcef02862a64a9bdbc0f68ff060bc..c3ff4343a74b786c63b2711e55469c996d4b2d62 100644 (file)
@@ -70,6 +70,9 @@ ToDo/Notes:
          mft record dirty as well as the page itself.
        - Fix compiler warnings on x86-64 in fs/ntfs/dir.c.  (Randy Dunlap,
          slightly modified by me)
+       - Add fs/ntfs/mft.c::try_map_mft_record() which fails with -EALREADY if
+         the mft record is already locked and otherwise behaves the same way
+         as fs/ntfs/mft.c::map_mft_record().
 
 2.1.20 - Fix two stupid bugs introduced in 2.1.18 release.
 
index c74ae7d72c3faca764e82993faf90f8f6a16db07..01e44140ac39244d6af8cef352bda893bd4439a6 100644 (file)
@@ -114,6 +114,57 @@ err_out:
        return (void*)page;
 }
 
+/**
+ * try_map_mft_record - attempt to map, pin and lock an mft record
+ * @ni:                ntfs inode whose MFT record to map
+ *
+ * First, attempt to take the mrec_lock semaphore.  If the semaphore is already
+ * taken by someone else, return the error code -EALREADY.  Otherwise continue
+ * as described below.
+ *
+ * The page of the record is mapped using map_mft_record_page() before being
+ * returned to the caller.
+ *
+ * This in turn uses ntfs_map_page() to get the page containing the wanted mft
+ * record (it in turn calls read_cache_page() which reads it in from disk if
+ * necessary, increments the use count on the page so that it cannot disappear
+ * under us and returns a reference to the page cache page).
+ *
+ * The mft record is now ours and we return a pointer to it.  You need to check
+ * the returned pointer with IS_ERR() and if that is true, PTR_ERR() will return
+ * the error code.
+ *
+ * For further details see the description of map_mft_record() below.
+ */
+MFT_RECORD *try_map_mft_record(ntfs_inode *ni)
+{
+       MFT_RECORD *m;
+
+       ntfs_debug("Entering for mft_no 0x%lx.", ni->mft_no);
+
+       /* Make sure the ntfs inode doesn't go away. */
+       atomic_inc(&ni->count);
+
+       /*
+        * Serialize access to this mft record.  If someone else is already
+        * holding the lock, abort instead of waiting for the lock.
+        */
+       if (unlikely(down_trylock(&ni->mrec_lock))) {
+               ntfs_debug("Mft record is already locked, aborting.");
+               atomic_dec(&ni->count);
+               return ERR_PTR(-EALREADY);
+       }
+
+       m = map_mft_record_page(ni);
+       if (likely(!IS_ERR(m)))
+               return m;
+
+       up(&ni->mrec_lock);
+       atomic_dec(&ni->count);
+       ntfs_error(ni->vol->sb, "Failed with error code %lu.", -PTR_ERR(m));
+       return m;
+}
+
 /**
  * map_mft_record - map, pin and lock an mft record
  * @ni:                ntfs inode whose MFT record to map
index 924f87abff8b93f54088d721e90adc511ee44e3a..fddc92e21d90094489e4f703fdf1405beb58f4c7 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "inode.h"
 
+extern MFT_RECORD *try_map_mft_record(ntfs_inode *ni);
 extern MFT_RECORD *map_mft_record(ntfs_inode *ni);
 extern void unmap_mft_record(ntfs_inode *ni);