diff options
author | Theodore Ts'o <tytso@mit.edu> | 2009-04-25 22:54:04 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2009-04-25 22:54:04 -0400 |
commit | 3b9d4ed26680771295d904a6b83e88e620780893 (patch) | |
tree | 905b0e95697839c446c86250cf38dd256f5e846a /fs/ext4/namei.c | |
parent | a63c9eb2ce6f5028da90f282798232c4f398ceb8 (diff) |
ext4: Replace lock/unlock_super() with an explicit lock for the orphan list
Use a separate lock to protect the orphan list, so we can stop
overloading the use of lock_super().
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r-- | fs/ext4/namei.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 22098e1cd085..8018e49a7287 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -1997,7 +1997,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) | |||
1997 | if (!ext4_handle_valid(handle)) | 1997 | if (!ext4_handle_valid(handle)) |
1998 | return 0; | 1998 | return 0; |
1999 | 1999 | ||
2000 | lock_super(sb); | 2000 | mutex_lock(&EXT4_SB(sb)->s_orphan_lock); |
2001 | if (!list_empty(&EXT4_I(inode)->i_orphan)) | 2001 | if (!list_empty(&EXT4_I(inode)->i_orphan)) |
2002 | goto out_unlock; | 2002 | goto out_unlock; |
2003 | 2003 | ||
@@ -2006,9 +2006,13 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) | |||
2006 | 2006 | ||
2007 | /* @@@ FIXME: Observation from aviro: | 2007 | /* @@@ FIXME: Observation from aviro: |
2008 | * I think I can trigger J_ASSERT in ext4_orphan_add(). We block | 2008 | * I think I can trigger J_ASSERT in ext4_orphan_add(). We block |
2009 | * here (on lock_super()), so race with ext4_link() which might bump | 2009 | * here (on s_orphan_lock), so race with ext4_link() which might bump |
2010 | * ->i_nlink. For, say it, character device. Not a regular file, | 2010 | * ->i_nlink. For, say it, character device. Not a regular file, |
2011 | * not a directory, not a symlink and ->i_nlink > 0. | 2011 | * not a directory, not a symlink and ->i_nlink > 0. |
2012 | * | ||
2013 | * tytso, 4/25/2009: I'm not sure how that could happen; | ||
2014 | * shouldn't the fs core protect us from these sort of | ||
2015 | * unlink()/link() races? | ||
2012 | */ | 2016 | */ |
2013 | J_ASSERT((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 2017 | J_ASSERT((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
2014 | S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); | 2018 | S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); |
@@ -2045,7 +2049,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) | |||
2045 | jbd_debug(4, "orphan inode %lu will point to %d\n", | 2049 | jbd_debug(4, "orphan inode %lu will point to %d\n", |
2046 | inode->i_ino, NEXT_ORPHAN(inode)); | 2050 | inode->i_ino, NEXT_ORPHAN(inode)); |
2047 | out_unlock: | 2051 | out_unlock: |
2048 | unlock_super(sb); | 2052 | mutex_unlock(&EXT4_SB(sb)->s_orphan_lock); |
2049 | ext4_std_error(inode->i_sb, err); | 2053 | ext4_std_error(inode->i_sb, err); |
2050 | return err; | 2054 | return err; |
2051 | } | 2055 | } |
@@ -2066,11 +2070,9 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) | |||
2066 | if (!ext4_handle_valid(handle)) | 2070 | if (!ext4_handle_valid(handle)) |
2067 | return 0; | 2071 | return 0; |
2068 | 2072 | ||
2069 | lock_super(inode->i_sb); | 2073 | mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock); |
2070 | if (list_empty(&ei->i_orphan)) { | 2074 | if (list_empty(&ei->i_orphan)) |
2071 | unlock_super(inode->i_sb); | 2075 | goto out; |
2072 | return 0; | ||
2073 | } | ||
2074 | 2076 | ||
2075 | ino_next = NEXT_ORPHAN(inode); | 2077 | ino_next = NEXT_ORPHAN(inode); |
2076 | prev = ei->i_orphan.prev; | 2078 | prev = ei->i_orphan.prev; |
@@ -2120,7 +2122,7 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode) | |||
2120 | out_err: | 2122 | out_err: |
2121 | ext4_std_error(inode->i_sb, err); | 2123 | ext4_std_error(inode->i_sb, err); |
2122 | out: | 2124 | out: |
2123 | unlock_super(inode->i_sb); | 2125 | mutex_unlock(&EXT4_SB(inode->i_sb)->s_orphan_lock); |
2124 | return err; | 2126 | return err; |
2125 | 2127 | ||
2126 | out_brelse: | 2128 | out_brelse: |