diff options
Diffstat (limited to 'fs/ntfs/mft.c')
| -rw-r--r-- | fs/ntfs/mft.c | 192 |
1 files changed, 94 insertions, 98 deletions
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c index 0c65cbb8c5c..3014a36a255 100644 --- a/fs/ntfs/mft.c +++ b/fs/ntfs/mft.c @@ -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-2012 Anton Altaparmakov and Tuxera Inc. * Copyright (c) 2002 Richard Russon * * This program/include file is free software; you can redistribute it and/or @@ -21,6 +21,7 @@ */ #include <linux/buffer_head.h> +#include <linux/slab.h> #include <linux/swap.h> #include "attrib.h" @@ -72,7 +73,7 @@ static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni) if (index > end_index || (i_size & ~PAGE_CACHE_MASK) < ofs + vol->mft_record_size) { page = ERR_PTR(-ENOENT); - ntfs_error(vol->sb, "Attemt to read mft record 0x%lx, " + ntfs_error(vol->sb, "Attempt to read mft record 0x%lx, " "which is beyond the end of the mft. " "This is probably a bug in the ntfs " "driver.", ni->mft_no); @@ -93,6 +94,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; @@ -104,8 +106,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. @@ -135,9 +137,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 @@ -160,13 +162,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; @@ -217,7 +219,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 @@ -250,7 +252,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); @@ -261,7 +263,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++) { @@ -274,7 +276,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); @@ -301,7 +303,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); } @@ -312,7 +314,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; @@ -321,7 +323,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; } @@ -330,11 +332,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; } @@ -347,14 +349,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 @@ -383,13 +385,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) { @@ -399,12 +400,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); } @@ -473,7 +474,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); @@ -585,7 +586,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); @@ -650,10 +651,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 @@ -672,8 +670,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; @@ -781,7 +779,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); @@ -859,7 +857,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 @@ -870,7 +868,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 @@ -879,11 +877,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 @@ -893,24 +891,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 @@ -924,7 +922,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; @@ -979,16 +977,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); @@ -997,7 +995,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. */ @@ -1005,13 +1003,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 @@ -1035,7 +1033,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); /* @@ -1043,17 +1041,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; @@ -1072,28 +1070,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); @@ -1105,7 +1103,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 " @@ -1193,7 +1191,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); @@ -1356,7 +1354,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) ntfs_unmap_page(page); /* Allocate a cluster from the DATA_ZONE. */ rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE, - TRUE); + true); if (IS_ERR(rl2)) { up_write(&mftbmp_ni->runlist.lock); ntfs_error(vol->sb, "Failed to allocate a cluster for " @@ -1369,7 +1367,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) ntfs_error(vol->sb, "Failed to merge runlists for mft " "bitmap."); if (ntfs_cluster_free_from_rl(vol, rl2)) { - ntfs_error(vol->sb, "Failed to dealocate " + ntfs_error(vol->sb, "Failed to deallocate " "allocated cluster.%s", es); NVolSetErrors(vol); } @@ -1444,7 +1442,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol) // Note: It will need to be a special mft record and if none of // those are available it gets rather complicated... ntfs_error(vol->sb, "Not enough space in this mft record to " - "accomodate extended mft bitmap attribute " + "accommodate extended mft bitmap attribute " "extent. Cannot handle this yet."); ret = -EOPNOTSUPP; goto undo_alloc; @@ -1726,7 +1724,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); @@ -1782,7 +1780,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) old_last_vcn = rl[1].vcn; do { rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE, - TRUE); + true); if (likely(!IS_ERR(rl2))) break; if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) { @@ -1807,7 +1805,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) ntfs_error(vol->sb, "Failed to merge runlists for mft data " "attribute."); if (ntfs_cluster_free_from_rl(vol, rl2)) { - ntfs_error(vol->sb, "Failed to dealocate clusters " + ntfs_error(vol->sb, "Failed to deallocate clusters " "from the mft data attribute.%s", es); NVolSetErrors(vol); } @@ -1881,12 +1879,12 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol) // and we would then need to update all references to this mft // record appropriately. This is rather complicated... ntfs_error(vol->sb, "Not enough space in this mft record to " - "accomodate extended mft data attribute " + "accommodate extended mft data attribute " "extent. Cannot handle this yet."); 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), @@ -2120,7 +2118,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); @@ -2257,7 +2255,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 " @@ -2359,7 +2357,7 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, const int mode, } #ifdef DEBUG read_lock_irqsave(&mftbmp_ni->size_lock, flags); - ntfs_debug("Status of mftbmp after initialized extention: " + ntfs_debug("Status of mftbmp after initialized extension: " "allocated_size 0x%llx, data_size 0x%llx, " "initialized_size 0x%llx.", (long long)mftbmp_ni->allocated_size, @@ -2456,7 +2454,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)) { @@ -2521,7 +2519,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); @@ -2578,6 +2576,8 @@ mft_rec_already_initialized: flush_dcache_page(page); SetPageUptodate(page); if (base_ni) { + MFT_RECORD *m_tmp; + /* * Setup the base mft record in the extent mft record. This * completes initialization of the allocated extent mft record @@ -2590,11 +2590,11 @@ mft_rec_already_initialized: * attach it to the base inode @base_ni and map, pin, and lock * its, i.e. the allocated, mft record. */ - m = map_extent_mft_record(base_ni, bit, &ni); - if (IS_ERR(m)) { + m_tmp = map_extent_mft_record(base_ni, bit, &ni); + if (IS_ERR(m_tmp)) { ntfs_error(vol->sb, "Failed to map allocated extent " "mft record 0x%llx.", (long long)bit); - err = PTR_ERR(m); + err = PTR_ERR(m_tmp); /* Set the mft record itself not in use. */ m->flags &= cpu_to_le16( ~le16_to_cpu(MFT_RECORD_IN_USE)); @@ -2605,6 +2605,7 @@ mft_rec_already_initialized: ntfs_unmap_page(page); goto undo_mftbmp_alloc; } + BUG_ON(m != m_tmp); /* * Make sure the allocated mft record is written out to disk. * No need to set the inode dirty because the caller is going @@ -2640,11 +2641,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). @@ -2672,7 +2668,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; @@ -2711,7 +2707,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; /* @@ -2798,22 +2794,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; } @@ -2831,7 +2827,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 " @@ -2846,7 +2842,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; @@ -2890,16 +2886,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; } @@ -2914,7 +2910,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; } |
