ceph: use separate class for ceph sockets' sk_lock
[safe/jmp/linux-2.6] / fs / ntfs / mft.c
index 66ef6e2..1caa0ef 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
  *
- * Copyright (c) 2001-2005 Anton Altaparmakov
+ * Copyright (c) 2001-2006 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -49,7 +49,8 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
        ntfs_volume *vol = ni->vol;
        struct inode *mft_vi = vol->mft_ino;
        struct page *page;
-       unsigned long index, ofs, end_index;
+       unsigned long index, end_index;
+       unsigned ofs;
 
        BUG_ON(ni->page);
        /*
@@ -58,7 +59,8 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
         * overflowing the unsigned long, but I don't think we would ever get
         * here if the volume was that big...
         */
-       index = ni->mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT;
+       index = (u64)ni->mft_no << vol->mft_record_size_bits >>
+                       PAGE_CACHE_SHIFT;
        ofs = (ni->mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK;
 
        i_size = i_size_read(mft_vi);
@@ -91,6 +93,7 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)
                                "Run chkdsk.", ni->mft_no);
                ntfs_unmap_page(page);
                page = ERR_PTR(-EIO);
+               NVolSetErrors(vol);
        }
 err_out:
        ni->page = NULL;
@@ -102,8 +105,8 @@ err_out:
  * map_mft_record - map, pin and lock an mft record
  * @ni:                ntfs inode whose MFT record to map
  *
- * First, take the mrec_lock semaphore. We might now be sleeping, while waiting
- * for the semaphore if it was already locked by someone else.
+ * First, take the mrec_lock mutex.  We might now be sleeping, while waiting
+ * for the mutex if it was already locked by someone else.
  *
  * The page of the record is mapped using map_mft_record_page() before being
  * returned to the caller.
@@ -133,9 +136,9 @@ err_out:
  * So that code will end up having to own the mrec_lock of all mft
  * records/inodes present in the page before I/O can proceed. In that case we
  * wouldn't need to bother with PG_locked and PG_uptodate as nobody will be
- * accessing anything without owning the mrec_lock semaphore. But we do need
- * to use them because of the read_cache_page() invocation and the code becomes
- * so much simpler this way that it is well worth it.
+ * accessing anything without owning the mrec_lock mutex.  But we do need to
+ * use them because of the read_cache_page() invocation and the code becomes so
+ * much simpler this way that it is well worth it.
  *
  * 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
@@ -158,13 +161,13 @@ MFT_RECORD *map_mft_record(ntfs_inode *ni)
        atomic_inc(&ni->count);
 
        /* Serialize access to this mft record. */
-       down(&ni->mrec_lock);
+       mutex_lock(&ni->mrec_lock);
 
        m = map_mft_record_page(ni);
        if (likely(!IS_ERR(m)))
                return m;
 
-       up(&ni->mrec_lock);
+       mutex_unlock(&ni->mrec_lock);
        atomic_dec(&ni->count);
        ntfs_error(ni->vol->sb, "Failed with error code %lu.", -PTR_ERR(m));
        return m;
@@ -215,7 +218,7 @@ void unmap_mft_record(ntfs_inode *ni)
        ntfs_debug("Entering for mft_no 0x%lx.", ni->mft_no);
 
        unmap_mft_record_page(ni);
-       up(&ni->mrec_lock);
+       mutex_unlock(&ni->mrec_lock);
        atomic_dec(&ni->count);
        /*
         * If pure ntfs_inode, i.e. no vfs inode attached, we leave it to
@@ -248,7 +251,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
        int i;
        unsigned long mft_no = MREF(mref);
        u16 seq_no = MSEQNO(mref);
-       BOOL destroy_ni = FALSE;
+       bool destroy_ni = false;
 
        ntfs_debug("Mapping extent mft record 0x%lx (base mft record 0x%lx).",
                        mft_no, base_ni->mft_no);
@@ -259,7 +262,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
         * in which case just return it. If not found, add it to the base
         * inode before returning it.
         */
-       down(&base_ni->extent_lock);
+       mutex_lock(&base_ni->extent_lock);
        if (base_ni->nr_extents > 0) {
                extent_nis = base_ni->ext.extent_ntfs_inos;
                for (i = 0; i < base_ni->nr_extents; i++) {
@@ -272,7 +275,7 @@ MFT_RECORD *map_extent_mft_record(ntfs_inode *base_ni, MFT_REF mref,
                }
        }
        if (likely(ni != NULL)) {
-               up(&base_ni->extent_lock);
+               mutex_unlock(&base_ni->extent_lock);
                atomic_dec(&base_ni->count);
                /* We found the record; just have to map and return it. */
                m = map_mft_record(ni);
@@ -299,7 +302,7 @@ map_err_out:
        /* Record wasn't there. Get a new ntfs inode and initialize it. */
        ni = ntfs_new_extent_inode(base_ni->vol->sb, mft_no);
        if (unlikely(!ni)) {
-               up(&base_ni->extent_lock);
+               mutex_unlock(&base_ni->extent_lock);
                atomic_dec(&base_ni->count);
                return ERR_PTR(-ENOMEM);
        }
@@ -310,7 +313,7 @@ map_err_out:
        /* Now map the record. */
        m = map_mft_record(ni);
        if (IS_ERR(m)) {
-               up(&base_ni->extent_lock);
+               mutex_unlock(&base_ni->extent_lock);
                atomic_dec(&base_ni->count);
                ntfs_clear_extent_inode(ni);
                goto map_err_out;
@@ -319,7 +322,7 @@ map_err_out:
        if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) {
                ntfs_error(base_ni->vol->sb, "Found stale extent mft "
                                "reference! Corrupt filesystem. Run chkdsk.");
-               destroy_ni = TRUE;
+               destroy_ni = true;
                m = ERR_PTR(-EIO);
                goto unm_err_out;
        }
@@ -328,11 +331,11 @@ map_err_out:
                ntfs_inode **tmp;
                int new_size = (base_ni->nr_extents + 4) * sizeof(ntfs_inode *);
 
-               tmp = (ntfs_inode **)kmalloc(new_size, GFP_NOFS);
+               tmp = kmalloc(new_size, GFP_NOFS);
                if (unlikely(!tmp)) {
                        ntfs_error(base_ni->vol->sb, "Failed to allocate "
                                        "internal buffer.");
-                       destroy_ni = TRUE;
+                       destroy_ni = true;
                        m = ERR_PTR(-ENOMEM);
                        goto unm_err_out;
                }
@@ -345,14 +348,14 @@ map_err_out:
                base_ni->ext.extent_ntfs_inos = tmp;
        }
        base_ni->ext.extent_ntfs_inos[base_ni->nr_extents++] = ni;
-       up(&base_ni->extent_lock);
+       mutex_unlock(&base_ni->extent_lock);
        atomic_dec(&base_ni->count);
        ntfs_debug("Done 2.");
        *ntfs_ino = ni;
        return m;
 unm_err_out:
        unmap_mft_record(ni);
-       up(&base_ni->extent_lock);
+       mutex_unlock(&base_ni->extent_lock);
        atomic_dec(&base_ni->count);
        /*
         * If the extent inode was not attached to the base inode we need to
@@ -381,13 +384,12 @@ unm_err_out:
  * it is dirty in the inode meta data rather than the data page cache of the
  * inode, and thus there are no data pages that need writing out.  Therefore, a
  * full mark_inode_dirty() is overkill.  A mark_inode_dirty_sync(), on the
- * other hand, is not sufficient, because I_DIRTY_DATASYNC needs to be set to
- * ensure ->write_inode is called from generic_osync_inode() and this needs to
- * happen or the file data would not necessarily hit the device synchronously,
- * even though the vfs inode has the O_SYNC flag set.  Also, I_DIRTY_DATASYNC
- * simply "feels" better than just I_DIRTY_SYNC, since the file data has not
- * actually hit the block device yet, which is not what I_DIRTY_SYNC on its own
- * would suggest.
+ * other hand, is not sufficient, because ->write_inode needs to be called even
+ * in case of fdatasync. This needs to happen or the file data would not
+ * necessarily hit the device synchronously, even though the vfs inode has the
+ * O_SYNC flag set.  Also, I_DIRTY_DATASYNC simply "feels" better than just
+ * I_DIRTY_SYNC, since the file data has not actually hit the block device yet,
+ * which is not what I_DIRTY_SYNC on its own would suggest.
  */
 void __mark_mft_record_dirty(ntfs_inode *ni)
 {
@@ -397,12 +399,12 @@ void __mark_mft_record_dirty(ntfs_inode *ni)
        BUG_ON(NInoAttr(ni));
        mark_ntfs_record_dirty(ni->page, ni->page_ofs);
        /* Determine the base vfs inode and mark it dirty, too. */
-       down(&ni->extent_lock);
+       mutex_lock(&ni->extent_lock);
        if (likely(ni->nr_extents >= 0))
                base_ni = ni;
        else
                base_ni = ni->ext.base_ntfs_ino;
-       up(&ni->extent_lock);
+       mutex_unlock(&ni->extent_lock);
        __mark_inode_dirty(VFS_I(base_ni), I_DIRTY_SYNC | I_DIRTY_DATASYNC);
 }
 
@@ -471,7 +473,7 @@ int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no,
        runlist_element *rl;
        unsigned int block_start, block_end, m_start, m_end, page_ofs;
        int i_bhs, nr_bhs, err = 0;
-       unsigned char blocksize_bits = vol->mftmirr_ino->i_blkbits;
+       unsigned char blocksize_bits = vol->sb->s_blocksize_bits;
 
        ntfs_debug("Entering for inode 0x%lx.", mft_no);
        BUG_ON(!max_bhs);
@@ -511,7 +513,6 @@ int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no,
                } while (bh);
                tail->b_this_page = head;
                attach_page_buffers(page, head);
-               BUG_ON(!page_has_buffers(page));
        }
        bh = head = page_buffers(page);
        BUG_ON(!bh);
@@ -533,6 +534,7 @@ int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no,
                        LCN lcn;
                        unsigned int vcn_ofs;
 
+                       bh->b_bdev = vol->sb->s_bdev;
                        /* Obtain the vcn and offset of the current block. */
                        vcn = ((VCN)mft_no << vol->mft_record_size_bits) +
                                        (block_start - m_start);
@@ -583,7 +585,7 @@ int ntfs_sync_mft_mirror(ntfs_volume *vol, const unsigned long mft_no,
                for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) {
                        struct buffer_head *tbh = bhs[i_bhs];
 
-                       if (unlikely(test_set_buffer_locked(tbh)))
+                       if (!trylock_buffer(tbh))
                                BUG();
                        BUG_ON(!buffer_uptodate(tbh));
                        clear_buffer_dirty(tbh);
@@ -648,10 +650,7 @@ err_out:
  * fs/ntfs/aops.c::mark_ntfs_record_dirty().
  *
  * On success, clean the mft record and return 0.  On error, leave the mft
- * record dirty and return -errno.  The caller should call make_bad_inode() on
- * the base inode to ensure no more access happens to this inode.  We do not do
- * it here as the caller may want to finish writing other extent mft records
- * first to minimize on-disk metadata inconsistencies.
+ * record dirty and return -errno.
  *
  * NOTE:  We always perform synchronous i/o and ignore the @sync parameter.
  * However, if the mft record has a counterpart in the mft mirror and @sync is
@@ -670,8 +669,8 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync)
 {
        ntfs_volume *vol = ni->vol;
        struct page *page = ni->page;
-       unsigned char blocksize_bits = vol->mft_ino->i_blkbits;
-       unsigned int blocksize = 1 << blocksize_bits;
+       unsigned int blocksize = vol->sb->s_blocksize;
+       unsigned char blocksize_bits = vol->sb->s_blocksize_bits;
        int max_bhs = vol->mft_record_size / blocksize;
        struct buffer_head *bhs[max_bhs];
        struct buffer_head *bh, *head;
@@ -691,7 +690,6 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync)
         */
        if (!NInoTestClearDirty(ni))
                goto done;
-       BUG_ON(!page_has_buffers(page));
        bh = head = page_buffers(page);
        BUG_ON(!bh);
        rl = NULL;
@@ -725,6 +723,7 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync)
                        LCN lcn;
                        unsigned int vcn_ofs;
 
+                       bh->b_bdev = vol->sb->s_bdev;
                        /* Obtain the vcn and offset of the current block. */
                        vcn = ((VCN)ni->mft_no << vol->mft_record_size_bits) +
                                        (block_start - m_start);
@@ -779,7 +778,7 @@ int write_mft_record_nolock(ntfs_inode *ni, MFT_RECORD *m, int sync)
        for (i_bhs = 0; i_bhs < nr_bhs; i_bhs++) {
                struct buffer_head *tbh = bhs[i_bhs];
 
-               if (unlikely(test_set_buffer_locked(tbh)))
+               if (!trylock_buffer(tbh))
                        BUG();
                BUG_ON(!buffer_uptodate(tbh));
                clear_buffer_dirty(tbh);
@@ -857,7 +856,7 @@ err_out:
  * caller is responsible for unlocking the ntfs inode and unpinning the base
  * vfs inode.
  *
- * Return TRUE if the mft record may be written out and FALSE if not.
+ * Return 'true' if the mft record may be written out and 'false' if not.
  *
  * The caller has locked the page and cleared the uptodate flag on it which
  * means that we can safely write out any dirty mft records that do not have
@@ -868,7 +867,7 @@ err_out:
  * Here is a description of the tests we perform:
  *
  * If the inode is found in icache we know the mft record must be a base mft
- * record.  If it is dirty, we do not write it and return FALSE as the vfs
+ * record.  If it is dirty, we do not write it and return 'false' as the vfs
  * inode write paths will result in the access times being updated which would
  * cause the base mft record to be redirtied and written out again.  (We know
  * the access time update will modify the base mft record because Windows
@@ -877,11 +876,11 @@ err_out:
  *
  * If the inode is in icache and not dirty, we attempt to lock the mft record
  * and if we find the lock was already taken, it is not safe to write the mft
- * record and we return FALSE.
+ * record and we return 'false'.
  *
  * If we manage to obtain the lock we have exclusive access to the mft record,
  * which also allows us safe writeout of the mft record.  We then set
- * @locked_ni to the locked ntfs inode and return TRUE.
+ * @locked_ni to the locked ntfs inode and return 'true'.
  *
  * Note we cannot just lock the mft record and sleep while waiting for the lock
  * because this would deadlock due to lock reversal (normally the mft record is
@@ -891,24 +890,24 @@ err_out:
  * If the inode is not in icache we need to perform further checks.
  *
  * If the mft record is not a FILE record or it is a base mft record, we can
- * safely write it and return TRUE.
+ * safely write it and return 'true'.
  *
  * We now know the mft record is an extent mft record.  We check if the inode
  * corresponding to its base mft record is in icache and obtain a reference to
- * it if it is.  If it is not, we can safely write it and return TRUE.
+ * it if it is.  If it is not, we can safely write it and return 'true'.
  *
  * We now have the base inode for the extent mft record.  We check if it has an
  * ntfs inode for the extent mft record attached and if not it is safe to write
- * the extent mft record and we return TRUE.
+ * the extent mft record and we return 'true'.
  *
  * The ntfs inode for the extent mft record is attached to the base inode so we
  * attempt to lock the extent mft record and if we find the lock was already
- * taken, it is not safe to write the extent mft record and we return FALSE.
+ * taken, it is not safe to write the extent mft record and we return 'false'.
  *
  * If we manage to obtain the lock we have exclusive access to the extent mft
  * record, which also allows us safe writeout of the extent mft record.  We
  * set the ntfs inode of the extent mft record clean and then set @locked_ni to
- * the now locked ntfs inode and return TRUE.
+ * the now locked ntfs inode and return 'true'.
  *
  * Note, the reason for actually writing dirty mft records here and not just
  * relying on the vfs inode dirty code paths is that we can have mft records
@@ -922,7 +921,7 @@ err_out:
  * appear if the mft record is reused for a new inode before it got written
  * out.
  */
-BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
+bool ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
                const MFT_RECORD *m, ntfs_inode **locked_ni)
 {
        struct super_block *sb = vol->sb;
@@ -948,20 +947,23 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
        na.name_len = 0;
        na.type = AT_UNUSED;
        /*
-        * For inode 0, i.e. $MFT itself, we cannot use ilookup5() from here or
-        * we deadlock because the inode is already locked by the kernel
-        * (fs/fs-writeback.c::__sync_single_inode()) and ilookup5() waits
-        * until the inode is unlocked before returning it and it never gets
-        * unlocked because ntfs_should_write_mft_record() never returns.  )-:
-        * Fortunately, we have inode 0 pinned in icache for the duration of
-        * the mount so we can access it directly.
+        * Optimize inode 0, i.e. $MFT itself, since we have it in memory and
+        * we get here for it rather often.
         */
        if (!mft_no) {
                /* Balance the below iput(). */
                vi = igrab(mft_vi);
                BUG_ON(vi != mft_vi);
-       } else
-               vi = ilookup5(sb, mft_no, (test_t)ntfs_test_inode, &na);
+       } else {
+               /*
+                * Have to use ilookup5_nowait() since ilookup5() waits for the
+                * inode lock which causes ntfs to deadlock when a concurrent
+                * inode write via the inode dirty code paths and the page
+                * dirty code path of the inode dirty code path when writing
+                * $MFT occurs.
+                */
+               vi = ilookup5_nowait(sb, mft_no, (test_t)ntfs_test_inode, &na);
+       }
        if (vi) {
                ntfs_debug("Base inode 0x%lx is in icache.", mft_no);
                /* The inode is in icache. */
@@ -974,16 +976,16 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
                                        mft_no);
                        atomic_dec(&ni->count);
                        iput(vi);
-                       return FALSE;
+                       return false;
                }
                ntfs_debug("Inode 0x%lx is not dirty.", mft_no);
                /* The inode is not dirty, try to take the mft record lock. */
-               if (unlikely(down_trylock(&ni->mrec_lock))) {
+               if (unlikely(!mutex_trylock(&ni->mrec_lock))) {
                        ntfs_debug("Mft record 0x%lx is already locked, do "
                                        "not write it.", mft_no);
                        atomic_dec(&ni->count);
                        iput(vi);
-                       return FALSE;
+                       return false;
                }
                ntfs_debug("Managed to lock mft record 0x%lx, write it.",
                                mft_no);
@@ -992,7 +994,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
                 * return the locked ntfs inode.
                 */
                *locked_ni = ni;
-               return TRUE;
+               return true;
        }
        ntfs_debug("Inode 0x%lx is not in icache.", mft_no);
        /* The inode is not in icache. */
@@ -1000,13 +1002,13 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
        if (!ntfs_is_mft_record(m->magic)) {
                ntfs_debug("Mft record 0x%lx is not a FILE record, write it.",
                                mft_no);
-               return TRUE;
+               return true;
        }
        /* Write the mft record if it is a base inode. */
        if (!m->base_mft_record) {
                ntfs_debug("Mft record 0x%lx is a base record, write it.",
                                mft_no);
-               return TRUE;
+               return true;
        }
        /*
         * This is an extent mft record.  Check if the inode corresponding to
@@ -1016,7 +1018,13 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
        na.mft_no = MREF_LE(m->base_mft_record);
        ntfs_debug("Mft record 0x%lx is an extent record.  Looking for base "
                        "inode 0x%lx in icache.", mft_no, na.mft_no);
-       vi = ilookup5(sb, na.mft_no, (test_t)ntfs_test_inode, &na);
+       if (!na.mft_no) {
+               /* Balance the below iput(). */
+               vi = igrab(mft_vi);
+               BUG_ON(vi != mft_vi);
+       } else
+               vi = ilookup5_nowait(sb, na.mft_no, (test_t)ntfs_test_inode,
+                               &na);
        if (!vi) {
                /*
                 * The base inode is not in icache, write this extent mft
@@ -1024,7 +1032,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
                 */
                ntfs_debug("Base inode 0x%lx is not in icache, write the "
                                "extent record.", na.mft_no);
-               return TRUE;
+               return true;
        }
        ntfs_debug("Base inode 0x%lx is in icache.", na.mft_no);
        /*
@@ -1032,17 +1040,17 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
         * corresponding to this extent mft record attached.
         */
        ni = NTFS_I(vi);
-       down(&ni->extent_lock);
+       mutex_lock(&ni->extent_lock);
        if (ni->nr_extents <= 0) {
                /*
                 * The base inode has no attached extent inodes, write this
                 * extent mft record.
                 */
-               up(&ni->extent_lock);
+               mutex_unlock(&ni->extent_lock);
                iput(vi);
                ntfs_debug("Base inode 0x%lx has no attached extent inodes, "
                                "write the extent record.", na.mft_no);
-               return TRUE;
+               return true;
        }
        /* Iterate over the attached extent inodes. */
        extent_nis = ni->ext.extent_ntfs_inos;
@@ -1061,28 +1069,28 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
         * extent mft record.
         */
        if (!eni) {
-               up(&ni->extent_lock);
+               mutex_unlock(&ni->extent_lock);
                iput(vi);
                ntfs_debug("Extent inode 0x%lx is not attached to its base "
                                "inode 0x%lx, write the extent record.",
                                mft_no, na.mft_no);
-               return TRUE;
+               return true;
        }
        ntfs_debug("Extent inode 0x%lx is attached to its base inode 0x%lx.",
                        mft_no, na.mft_no);
        /* Take a reference to the extent ntfs inode. */
        atomic_inc(&eni->count);
-       up(&ni->extent_lock);
+       mutex_unlock(&ni->extent_lock);
        /*
         * Found the extent inode coresponding to this extent mft record.
         * Try to take the mft record lock.
         */
-       if (unlikely(down_trylock(&eni->mrec_lock))) {
+       if (unlikely(!mutex_trylock(&eni->mrec_lock))) {
                atomic_dec(&eni->count);
                iput(vi);
                ntfs_debug("Extent mft record 0x%lx is already locked, do "
                                "not write it.", mft_no);
-               return FALSE;
+               return false;
        }
        ntfs_debug("Managed to lock extent mft record 0x%lx, write it.",
                        mft_no);
@@ -1094,7 +1102,7 @@ BOOL ntfs_may_write_mft_record(ntfs_volume *vol, const unsigned long mft_no,
         * the locked extent ntfs inode.
         */
        *locked_ni = eni;
-       return TRUE;
+       return true;
 }
 
 static const char *es = "  Leaving inconsistent metadata.  Unmount and run "
@@ -1182,7 +1190,7 @@ static int ntfs_mft_bitmap_find_and_alloc_free_rec_nolock(ntfs_volume *vol,
                if (size) {
                        page = ntfs_map_page(mftbmp_mapping,
                                        ofs >> PAGE_CACHE_SHIFT);
-                       if (unlikely(IS_ERR(page))) {
+                       if (IS_ERR(page)) {
                                ntfs_error(vol->sb, "Failed to read mft "
                                                "bitmap, aborting.");
                                return PTR_ERR(page);
@@ -1297,8 +1305,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
        read_lock_irqsave(&mftbmp_ni->size_lock, flags);
        ll = mftbmp_ni->allocated_size;
        read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
-       rl = ntfs_find_vcn_nolock(mftbmp_ni,
-                       (ll - 1) >> vol->cluster_size_bits, TRUE);
+       rl = ntfs_attr_find_vcn_nolock(mftbmp_ni,
+                       (ll - 1) >> vol->cluster_size_bits, NULL);
        if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
                up_write(&mftbmp_ni->runlist.lock);
                ntfs_error(vol->sb, "Failed to determine last allocated "
@@ -1344,7 +1352,8 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
                up_write(&vol->lcnbmp_lock);
                ntfs_unmap_page(page);
                /* Allocate a cluster from the DATA_ZONE. */
-               rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE);
+               rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE,
+                               true);
                if (IS_ERR(rl2)) {
                        up_write(&mftbmp_ni->runlist.lock);
                        ntfs_error(vol->sb, "Failed to allocate a cluster for "
@@ -1407,7 +1416,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
        BUG_ON(ll < rl2->vcn);
        BUG_ON(ll >= rl2->vcn + rl2->length);
        /* Get the size for the new mapping pairs array for this extent. */
-       mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll);
+       mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1);
        if (unlikely(mp_size <= 0)) {
                ntfs_error(vol->sb, "Get size for mapping pairs failed for "
                                "mft bitmap attribute extent.");
@@ -1441,7 +1450,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
        /* Generate the mapping pairs array directly into the attr record. */
        ret = ntfs_mapping_pairs_build(vol, (u8*)a +
                        le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
-                       mp_size, rl2, ll, NULL);
+                       mp_size, rl2, ll, -1, NULL);
        if (unlikely(ret)) {
                ntfs_error(vol->sb, "Failed to build mapping pairs array for "
                                "mft bitmap attribute.");
@@ -1529,7 +1538,7 @@ undo_alloc:
                                a->data.non_resident.mapping_pairs_offset),
                                old_alen - le16_to_cpu(
                                a->data.non_resident.mapping_pairs_offset),
-                               rl2, ll, NULL)) {
+                               rl2, ll, -1, NULL)) {
                        ntfs_error(vol->sb, "Failed to restore mapping pairs "
                                        "array.%s", es);
                        NVolSetErrors(vol);
@@ -1714,7 +1723,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
        ATTR_RECORD *a = NULL;
        int ret, mp_size;
        u32 old_alen = 0;
-       BOOL mp_rebuilt = FALSE;
+       bool mp_rebuilt = false;
 
        ntfs_debug("Extending mft data allocation.");
        mft_ni = NTFS_I(vol->mft_ino);
@@ -1727,8 +1736,8 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
        read_lock_irqsave(&mft_ni->size_lock, flags);
        ll = mft_ni->allocated_size;
        read_unlock_irqrestore(&mft_ni->size_lock, flags);
-       rl = ntfs_find_vcn_nolock(mft_ni, (ll - 1) >> vol->cluster_size_bits,
-                       TRUE);
+       rl = ntfs_attr_find_vcn_nolock(mft_ni,
+                       (ll - 1) >> vol->cluster_size_bits, NULL);
        if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {
                up_write(&mft_ni->runlist.lock);
                ntfs_error(vol->sb, "Failed to determine last allocated "
@@ -1769,7 +1778,8 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
                        nr > min_nr ? "default" : "minimal", (long long)nr);
        old_last_vcn = rl[1].vcn;
        do {
-               rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE);
+               rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE,
+                               true);
                if (likely(!IS_ERR(rl2)))
                        break;
                if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) {
@@ -1838,7 +1848,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
        BUG_ON(ll < rl2->vcn);
        BUG_ON(ll >= rl2->vcn + rl2->length);
        /* Get the size for the new mapping pairs array for this extent. */
-       mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll);
+       mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1);
        if (unlikely(mp_size <= 0)) {
                ntfs_error(vol->sb, "Get size for mapping pairs failed for "
                                "mft data attribute extent.");
@@ -1873,11 +1883,11 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
                ret = -EOPNOTSUPP;
                goto undo_alloc;
        }
-       mp_rebuilt = TRUE;
+       mp_rebuilt = true;
        /* Generate the mapping pairs array directly into the attr record. */
        ret = ntfs_mapping_pairs_build(vol, (u8*)a +
                        le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
-                       mp_size, rl2, ll, NULL);
+                       mp_size, rl2, ll, -1, NULL);
        if (unlikely(ret)) {
                ntfs_error(vol->sb, "Failed to build mapping pairs array of "
                                "mft data attribute.");
@@ -1941,25 +1951,26 @@ restore_undo_alloc:
                NVolSetErrors(vol);
                return ret;
        }
-       a = ctx->attr;
-       a->data.non_resident.highest_vcn = cpu_to_sle64(old_last_vcn - 1);
+       ctx->attr->data.non_resident.highest_vcn =
+                       cpu_to_sle64(old_last_vcn - 1);
 undo_alloc:
-       if (ntfs_cluster_free(vol->mft_ino, old_last_vcn, -1) < 0) {
+       if (ntfs_cluster_free(mft_ni, old_last_vcn, -1, ctx) < 0) {
                ntfs_error(vol->sb, "Failed to free clusters from mft data "
                                "attribute.%s", es);
                NVolSetErrors(vol);
        }
+       a = ctx->attr;
        if (ntfs_rl_truncate_nolock(vol, &mft_ni->runlist, old_last_vcn)) {
                ntfs_error(vol->sb, "Failed to truncate mft data attribute "
                                "runlist.%s", es);
                NVolSetErrors(vol);
        }
-       if (mp_rebuilt) {
+       if (mp_rebuilt && !IS_ERR(ctx->mrec)) {
                if (ntfs_mapping_pairs_build(vol, (u8*)a + le16_to_cpu(
                                a->data.non_resident.mapping_pairs_offset),
                                old_alen - le16_to_cpu(
                                a->data.non_resident.mapping_pairs_offset),
-                               rl2, ll, NULL)) {
+                               rl2, ll, -1, NULL)) {
                        ntfs_error(vol->sb, "Failed to restore mapping pairs "
                                        "array.%s", es);
                        NVolSetErrors(vol);
@@ -1971,6 +1982,10 @@ undo_alloc:
                }
                flush_dcache_mft_record_page(ctx->ntfs_ino);
                mark_mft_record_dirty(ctx->ntfs_ino);
+       } else if (IS_ERR(ctx->mrec)) {
+               ntfs_error(vol->sb, "Failed to restore attribute search "
+                               "context.%s", es);
+               NVolSetErrors(vol);
        }
        if (ctx)
                ntfs_attr_put_search_ctx(ctx);
@@ -2102,7 +2117,7 @@ static int ntfs_mft_record_format(const ntfs_volume *vol, const s64 mft_no)
        }
        /* Read, map, and pin the page containing the mft record. */
        page = ntfs_map_page(mft_vi->i_mapping, index);
-       if (unlikely(IS_ERR(page))) {
+       if (IS_ERR(page)) {
                ntfs_error(vol->sb, "Failed to map page containing mft record "
                                "to format 0x%llx.", (long long)mft_no);
                return PTR_ERR(page);
@@ -2239,7 +2254,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode,
        unsigned int ofs;
        int err;
        le16 seq_no, usn;
-       BOOL record_formatted = FALSE;
+       bool record_formatted = false;
 
        if (base_ni) {
                ntfs_debug("Entering (allocating an extent mft record for "
@@ -2438,7 +2453,7 @@ have_alloc_rec:
                mft_ni->initialized_size = new_initialized_size;
        }
        write_unlock_irqrestore(&mft_ni->size_lock, flags);
-       record_formatted = TRUE;
+       record_formatted = true;
        /* Update the mft data attribute record to reflect the new sizes. */
        m = map_mft_record(mft_ni);
        if (IS_ERR(m)) {
@@ -2503,7 +2518,7 @@ mft_rec_already_initialized:
        ofs = (bit << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK;
        /* Read, map, and pin the page containing the mft record. */
        page = ntfs_map_page(vol->mft_ino->i_mapping, index);
-       if (unlikely(IS_ERR(page))) {
+       if (IS_ERR(page)) {
                ntfs_error(vol->sb, "Failed to map page containing allocated "
                                "mft record 0x%llx.", (long long)bit);
                err = PTR_ERR(page);
@@ -2622,11 +2637,6 @@ mft_rec_already_initialized:
                }
                vi->i_ino = bit;
                /*
-                * This is the optimal IO size (for stat), not the fs block
-                * size.
-                */
-               vi->i_blksize = PAGE_CACHE_SIZE;
-               /*
                 * This is for checking whether an inode has changed w.r.t. a
                 * file so that the file can be updated if necessary (compare
                 * with f_version).
@@ -2654,7 +2664,7 @@ mft_rec_already_initialized:
                        ni->name_len = 4;
 
                        ni->itype.index.block_size = 4096;
-                       ni->itype.index.block_size_bits = generic_ffs(4096) - 1;
+                       ni->itype.index.block_size_bits = ntfs_ffs(4096) - 1;
                        ni->itype.index.collation_rule = COLLATION_FILE_NAME;
                        if (vol->cluster_size <= ni->itype.index.block_size) {
                                ni->itype.index.vcn_size = vol->cluster_size;
@@ -2693,7 +2703,7 @@ mft_rec_already_initialized:
                 * have its page mapped and it is very easy to do.
                 */
                atomic_inc(&ni->count);
-               down(&ni->mrec_lock);
+               mutex_lock(&ni->mrec_lock);
                ni->page = page;
                ni->page_ofs = ofs;
                /*
@@ -2780,22 +2790,22 @@ int ntfs_extent_mft_record_free(ntfs_inode *ni, MFT_RECORD *m)
        BUG_ON(NInoAttr(ni));
        BUG_ON(ni->nr_extents != -1);
 
-       down(&ni->extent_lock);
+       mutex_lock(&ni->extent_lock);
        base_ni = ni->ext.base_ntfs_ino;
-       up(&ni->extent_lock);
+       mutex_unlock(&ni->extent_lock);
 
        BUG_ON(base_ni->nr_extents <= 0);
 
        ntfs_debug("Entering for extent inode 0x%lx, base inode 0x%lx.\n",
                        mft_no, base_ni->mft_no);
 
-       down(&base_ni->extent_lock);
+       mutex_lock(&base_ni->extent_lock);
 
        /* Make sure we are holding the only reference to the extent inode. */
        if (atomic_read(&ni->count) > 2) {
                ntfs_error(vol->sb, "Tried to free busy extent inode 0x%lx, "
                                "not freeing.", base_ni->mft_no);
-               up(&base_ni->extent_lock);
+               mutex_unlock(&base_ni->extent_lock);
                return -EBUSY;
        }
 
@@ -2813,7 +2823,7 @@ int ntfs_extent_mft_record_free(ntfs_inode *ni, MFT_RECORD *m)
                break;
        }
 
-       up(&base_ni->extent_lock);
+       mutex_unlock(&base_ni->extent_lock);
 
        if (unlikely(err)) {
                ntfs_error(vol->sb, "Extent inode 0x%lx is not attached to "
@@ -2828,7 +2838,7 @@ int ntfs_extent_mft_record_free(ntfs_inode *ni, MFT_RECORD *m)
         */
 
        /* Mark the mft record as not in use. */
-       m->flags &= const_cpu_to_le16(~const_le16_to_cpu(MFT_RECORD_IN_USE));
+       m->flags &= ~MFT_RECORD_IN_USE;
 
        /* Increment the sequence number, skipping zero, if it is not zero. */
        old_seq_no = m->sequence_number;
@@ -2872,16 +2882,16 @@ rollback_error:
        return 0;
 rollback:
        /* Rollback what we did... */
-       down(&base_ni->extent_lock);
+       mutex_lock(&base_ni->extent_lock);
        extent_nis = base_ni->ext.extent_ntfs_inos;
        if (!(base_ni->nr_extents & 3)) {
                int new_size = (base_ni->nr_extents + 4) * sizeof(ntfs_inode*);
 
-               extent_nis = (ntfs_inode**)kmalloc(new_size, GFP_NOFS);
+               extent_nis = kmalloc(new_size, GFP_NOFS);
                if (unlikely(!extent_nis)) {
                        ntfs_error(vol->sb, "Failed to allocate internal "
                                        "buffer during rollback.%s", es);
-                       up(&base_ni->extent_lock);
+                       mutex_unlock(&base_ni->extent_lock);
                        NVolSetErrors(vol);
                        goto rollback_error;
                }
@@ -2896,7 +2906,7 @@ rollback:
        m->flags |= MFT_RECORD_IN_USE;
        m->sequence_number = old_seq_no;
        extent_nis[base_ni->nr_extents++] = ni;
-       up(&base_ni->extent_lock);
+       mutex_unlock(&base_ni->extent_lock);
        mark_mft_record_dirty(ni);
        return err;
 }