diff options
author | Ingo Molnar <mingo@elte.hu> | 2006-07-03 03:25:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-07-03 18:27:08 -0400 |
commit | 59345374742ee6673c2d04b0fa8c888e881b7209 (patch) | |
tree | c58ca74efe0c361086c6ffa70bc7597ec5674c95 /fs/ntfs/inode.c | |
parent | c6573c2904231279de0584787d6214f19a128d0b (diff) |
[PATCH] lockdep: annotate NTFS locking rules
NTFS uses lots of type-opaque objects which acquire their true identity
runtime - so the lock validator needs to be helped in a couple of places to
figure out object types.
Many thanks to Anton Altaparmakov for giving lots of explanations about NTFS
locking rules.
Has no effect on non-lockdep kernels.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/ntfs/inode.c')
-rw-r--r-- | fs/ntfs/inode.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 4c86b7e1d1eb..d313f356e66a 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c | |||
@@ -367,6 +367,12 @@ static void ntfs_destroy_extent_inode(ntfs_inode *ni) | |||
367 | kmem_cache_free(ntfs_inode_cache, ni); | 367 | kmem_cache_free(ntfs_inode_cache, ni); |
368 | } | 368 | } |
369 | 369 | ||
370 | /* | ||
371 | * The attribute runlist lock has separate locking rules from the | ||
372 | * normal runlist lock, so split the two lock-classes: | ||
373 | */ | ||
374 | static struct lock_class_key attr_list_rl_lock_class; | ||
375 | |||
370 | /** | 376 | /** |
371 | * __ntfs_init_inode - initialize ntfs specific part of an inode | 377 | * __ntfs_init_inode - initialize ntfs specific part of an inode |
372 | * @sb: super block of mounted volume | 378 | * @sb: super block of mounted volume |
@@ -394,6 +400,8 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni) | |||
394 | ni->attr_list_size = 0; | 400 | ni->attr_list_size = 0; |
395 | ni->attr_list = NULL; | 401 | ni->attr_list = NULL; |
396 | ntfs_init_runlist(&ni->attr_list_rl); | 402 | ntfs_init_runlist(&ni->attr_list_rl); |
403 | lockdep_set_class(&ni->attr_list_rl.lock, | ||
404 | &attr_list_rl_lock_class); | ||
397 | ni->itype.index.bmp_ino = NULL; | 405 | ni->itype.index.bmp_ino = NULL; |
398 | ni->itype.index.block_size = 0; | 406 | ni->itype.index.block_size = 0; |
399 | ni->itype.index.vcn_size = 0; | 407 | ni->itype.index.vcn_size = 0; |
@@ -405,6 +413,13 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni) | |||
405 | ni->ext.base_ntfs_ino = NULL; | 413 | ni->ext.base_ntfs_ino = NULL; |
406 | } | 414 | } |
407 | 415 | ||
416 | /* | ||
417 | * Extent inodes get MFT-mapped in a nested way, while the base inode | ||
418 | * is still mapped. Teach this nesting to the lock validator by creating | ||
419 | * a separate class for nested inode's mrec_lock's: | ||
420 | */ | ||
421 | static struct lock_class_key extent_inode_mrec_lock_key; | ||
422 | |||
408 | inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, | 423 | inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, |
409 | unsigned long mft_no) | 424 | unsigned long mft_no) |
410 | { | 425 | { |
@@ -413,6 +428,7 @@ inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, | |||
413 | ntfs_debug("Entering."); | 428 | ntfs_debug("Entering."); |
414 | if (likely(ni != NULL)) { | 429 | if (likely(ni != NULL)) { |
415 | __ntfs_init_inode(sb, ni); | 430 | __ntfs_init_inode(sb, ni); |
431 | lockdep_set_class(&ni->mrec_lock, &extent_inode_mrec_lock_key); | ||
416 | ni->mft_no = mft_no; | 432 | ni->mft_no = mft_no; |
417 | ni->type = AT_UNUSED; | 433 | ni->type = AT_UNUSED; |
418 | ni->name = NULL; | 434 | ni->name = NULL; |
@@ -1722,6 +1738,15 @@ err_out: | |||
1722 | return err; | 1738 | return err; |
1723 | } | 1739 | } |
1724 | 1740 | ||
1741 | /* | ||
1742 | * The MFT inode has special locking, so teach the lock validator | ||
1743 | * about this by splitting off the locking rules of the MFT from | ||
1744 | * the locking rules of other inodes. The MFT inode can never be | ||
1745 | * accessed from the VFS side (or even internally), only by the | ||
1746 | * map_mft functions. | ||
1747 | */ | ||
1748 | static struct lock_class_key mft_ni_runlist_lock_key, mft_ni_mrec_lock_key; | ||
1749 | |||
1725 | /** | 1750 | /** |
1726 | * ntfs_read_inode_mount - special read_inode for mount time use only | 1751 | * ntfs_read_inode_mount - special read_inode for mount time use only |
1727 | * @vi: inode to read | 1752 | * @vi: inode to read |
@@ -2148,6 +2173,14 @@ int ntfs_read_inode_mount(struct inode *vi) | |||
2148 | ntfs_attr_put_search_ctx(ctx); | 2173 | ntfs_attr_put_search_ctx(ctx); |
2149 | ntfs_debug("Done."); | 2174 | ntfs_debug("Done."); |
2150 | ntfs_free(m); | 2175 | ntfs_free(m); |
2176 | |||
2177 | /* | ||
2178 | * Split the locking rules of the MFT inode from the | ||
2179 | * locking rules of other inodes: | ||
2180 | */ | ||
2181 | lockdep_set_class(&ni->runlist.lock, &mft_ni_runlist_lock_key); | ||
2182 | lockdep_set_class(&ni->mrec_lock, &mft_ni_mrec_lock_key); | ||
2183 | |||
2151 | return 0; | 2184 | return 0; |
2152 | 2185 | ||
2153 | em_put_err_out: | 2186 | em_put_err_out: |