X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=fs%2Fntfs%2Finode.c;h=2d3de9c89818033a0c96f1a9f43afeb84132a285;hb=97d41e90fe61399b99d74820cb7f2d6e0fbac91d;hp=4c86b7e1d1eb435addf5822d6fd67132b580604a;hpb=be9bf30c73184e0f1e4e0a50fb193d2a551bf75e;p=~andy%2Flinux diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 4c86b7e1d1e..2d3de9c8981 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -137,7 +137,7 @@ static int ntfs_init_locked_inode(struct inode *vi, ntfs_attr *na) BUG_ON(!na->name); i = na->name_len * sizeof(ntfschar); - ni->name = (ntfschar*)kmalloc(i + sizeof(ntfschar), GFP_ATOMIC); + ni->name = kmalloc(i + sizeof(ntfschar), GFP_ATOMIC); if (!ni->name) return -ENOMEM; memcpy(ni->name, na->name, i); @@ -367,6 +367,12 @@ static void ntfs_destroy_extent_inode(ntfs_inode *ni) kmem_cache_free(ntfs_inode_cache, ni); } +/* + * The attribute runlist lock has separate locking rules from the + * normal runlist lock, so split the two lock-classes: + */ +static struct lock_class_key attr_list_rl_lock_class; + /** * __ntfs_init_inode - initialize ntfs specific part of an inode * @sb: super block of mounted volume @@ -394,6 +400,8 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni) ni->attr_list_size = 0; ni->attr_list = NULL; ntfs_init_runlist(&ni->attr_list_rl); + lockdep_set_class(&ni->attr_list_rl.lock, + &attr_list_rl_lock_class); ni->itype.index.bmp_ino = NULL; ni->itype.index.block_size = 0; ni->itype.index.vcn_size = 0; @@ -405,6 +413,13 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni) ni->ext.base_ntfs_ino = NULL; } +/* + * Extent inodes get MFT-mapped in a nested way, while the base inode + * is still mapped. Teach this nesting to the lock validator by creating + * a separate class for nested inode's mrec_lock's: + */ +static struct lock_class_key extent_inode_mrec_lock_key; + inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, unsigned long mft_no) { @@ -413,6 +428,7 @@ inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, ntfs_debug("Entering."); if (likely(ni != NULL)) { __ntfs_init_inode(sb, ni); + lockdep_set_class(&ni->mrec_lock, &extent_inode_mrec_lock_key); ni->mft_no = mft_no; ni->type = AT_UNUSED; ni->name = NULL; @@ -540,8 +556,6 @@ static int ntfs_read_locked_inode(struct inode *vi) /* Setup the generic vfs inode parts now. */ - /* 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). @@ -1218,7 +1232,6 @@ static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi) base_ni = NTFS_I(base_vi); /* Just mirror the values from the base inode. */ - vi->i_blksize = base_vi->i_blksize; vi->i_version = base_vi->i_version; vi->i_uid = base_vi->i_uid; vi->i_gid = base_vi->i_gid; @@ -1488,7 +1501,6 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi) ni = NTFS_I(vi); base_ni = NTFS_I(base_vi); /* Just mirror the values from the base inode. */ - vi->i_blksize = base_vi->i_blksize; vi->i_version = base_vi->i_version; vi->i_uid = base_vi->i_uid; vi->i_gid = base_vi->i_gid; @@ -1722,6 +1734,15 @@ err_out: return err; } +/* + * The MFT inode has special locking, so teach the lock validator + * about this by splitting off the locking rules of the MFT from + * the locking rules of other inodes. The MFT inode can never be + * accessed from the VFS side (or even internally), only by the + * map_mft functions. + */ +static struct lock_class_key mft_ni_runlist_lock_key, mft_ni_mrec_lock_key; + /** * ntfs_read_inode_mount - special read_inode for mount time use only * @vi: inode to read @@ -2148,6 +2169,14 @@ int ntfs_read_inode_mount(struct inode *vi) ntfs_attr_put_search_ctx(ctx); ntfs_debug("Done."); ntfs_free(m); + + /* + * Split the locking rules of the MFT inode from the + * locking rules of other inodes: + */ + lockdep_set_class(&ni->runlist.lock, &mft_ni_runlist_lock_key); + lockdep_set_class(&ni->mrec_lock, &mft_ni_mrec_lock_key); + return 0; em_put_err_out: @@ -2272,7 +2301,7 @@ void ntfs_clear_big_inode(struct inode *vi) } #ifdef NTFS_RW if (NInoDirty(ni)) { - BOOL was_bad = (is_bad_inode(vi)); + bool was_bad = (is_bad_inode(vi)); /* Committing the inode also commits all extent inodes. */ ntfs_commit_inode(vi); @@ -2986,7 +3015,7 @@ int ntfs_write_inode(struct inode *vi, int sync) MFT_RECORD *m; STANDARD_INFORMATION *si; int err = 0; - BOOL modified = FALSE; + bool modified = false; ntfs_debug("Entering for %sinode 0x%lx.", NInoAttr(ni) ? "attr " : "", vi->i_ino); @@ -3028,7 +3057,7 @@ int ntfs_write_inode(struct inode *vi, int sync) sle64_to_cpu(si->last_data_change_time), (long long)sle64_to_cpu(nt)); si->last_data_change_time = nt; - modified = TRUE; + modified = true; } nt = utc2ntfs(vi->i_ctime); if (si->last_mft_change_time != nt) { @@ -3037,7 +3066,7 @@ int ntfs_write_inode(struct inode *vi, int sync) sle64_to_cpu(si->last_mft_change_time), (long long)sle64_to_cpu(nt)); si->last_mft_change_time = nt; - modified = TRUE; + modified = true; } nt = utc2ntfs(vi->i_atime); if (si->last_access_time != nt) { @@ -3046,7 +3075,7 @@ int ntfs_write_inode(struct inode *vi, int sync) (long long)sle64_to_cpu(si->last_access_time), (long long)sle64_to_cpu(nt)); si->last_access_time = nt; - modified = TRUE; + modified = true; } /* * If we just modified the standard information attribute we need to