aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext3/namei.c20
-rw-r--r--fs/ext3/super.c1
-rw-r--r--include/linux/ext3_fs_sb.h1
3 files changed, 13 insertions, 9 deletions
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c
index 81f7348b2de3..7b0e44f7d66f 100644
--- a/fs/ext3/namei.c
+++ b/fs/ext3/namei.c
@@ -1920,7 +1920,7 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode)
1920 struct ext3_iloc iloc; 1920 struct ext3_iloc iloc;
1921 int err = 0, rc; 1921 int err = 0, rc;
1922 1922
1923 lock_super(sb); 1923 mutex_lock(&EXT3_SB(sb)->s_orphan_lock);
1924 if (!list_empty(&EXT3_I(inode)->i_orphan)) 1924 if (!list_empty(&EXT3_I(inode)->i_orphan))
1925 goto out_unlock; 1925 goto out_unlock;
1926 1926
@@ -1929,9 +1929,13 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode)
1929 1929
1930 /* @@@ FIXME: Observation from aviro: 1930 /* @@@ FIXME: Observation from aviro:
1931 * I think I can trigger J_ASSERT in ext3_orphan_add(). We block 1931 * I think I can trigger J_ASSERT in ext3_orphan_add(). We block
1932 * here (on lock_super()), so race with ext3_link() which might bump 1932 * here (on s_orphan_lock), so race with ext3_link() which might bump
1933 * ->i_nlink. For, say it, character device. Not a regular file, 1933 * ->i_nlink. For, say it, character device. Not a regular file,
1934 * not a directory, not a symlink and ->i_nlink > 0. 1934 * not a directory, not a symlink and ->i_nlink > 0.
1935 *
1936 * tytso, 4/25/2009: I'm not sure how that could happen;
1937 * shouldn't the fs core protect us from these sort of
1938 * unlink()/link() races?
1935 */ 1939 */
1936 J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || 1940 J_ASSERT ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
1937 S_ISLNK(inode->i_mode)) || inode->i_nlink == 0); 1941 S_ISLNK(inode->i_mode)) || inode->i_nlink == 0);
@@ -1968,7 +1972,7 @@ int ext3_orphan_add(handle_t *handle, struct inode *inode)
1968 jbd_debug(4, "orphan inode %lu will point to %d\n", 1972 jbd_debug(4, "orphan inode %lu will point to %d\n",
1969 inode->i_ino, NEXT_ORPHAN(inode)); 1973 inode->i_ino, NEXT_ORPHAN(inode));
1970out_unlock: 1974out_unlock:
1971 unlock_super(sb); 1975 mutex_unlock(&EXT3_SB(sb)->s_orphan_lock);
1972 ext3_std_error(inode->i_sb, err); 1976 ext3_std_error(inode->i_sb, err);
1973 return err; 1977 return err;
1974} 1978}
@@ -1986,11 +1990,9 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode)
1986 struct ext3_iloc iloc; 1990 struct ext3_iloc iloc;
1987 int err = 0; 1991 int err = 0;
1988 1992
1989 lock_super(inode->i_sb); 1993 mutex_lock(&EXT3_SB(inode->i_sb)->s_orphan_lock);
1990 if (list_empty(&ei->i_orphan)) { 1994 if (list_empty(&ei->i_orphan))
1991 unlock_super(inode->i_sb); 1995 goto out;
1992 return 0;
1993 }
1994 1996
1995 ino_next = NEXT_ORPHAN(inode); 1997 ino_next = NEXT_ORPHAN(inode);
1996 prev = ei->i_orphan.prev; 1998 prev = ei->i_orphan.prev;
@@ -2040,7 +2042,7 @@ int ext3_orphan_del(handle_t *handle, struct inode *inode)
2040out_err: 2042out_err:
2041 ext3_std_error(inode->i_sb, err); 2043 ext3_std_error(inode->i_sb, err);
2042out: 2044out:
2043 unlock_super(inode->i_sb); 2045 mutex_unlock(&EXT3_SB(inode->i_sb)->s_orphan_lock);
2044 return err; 2046 return err;
2045 2047
2046out_brelse: 2048out_brelse:
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 806b8b780add..97dd3828384c 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -1928,6 +1928,7 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent)
1928 sb->dq_op = &ext3_quota_operations; 1928 sb->dq_op = &ext3_quota_operations;
1929#endif 1929#endif
1930 INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ 1930 INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */
1931 mutex_init(&sbi->s_orphan_lock);
1931 1932
1932 sb->s_root = NULL; 1933 sb->s_root = NULL;
1933 1934
diff --git a/include/linux/ext3_fs_sb.h b/include/linux/ext3_fs_sb.h
index f07f34de2f0e..dd61d83026a0 100644
--- a/include/linux/ext3_fs_sb.h
+++ b/include/linux/ext3_fs_sb.h
@@ -72,6 +72,7 @@ struct ext3_sb_info {
72 struct inode * s_journal_inode; 72 struct inode * s_journal_inode;
73 struct journal_s * s_journal; 73 struct journal_s * s_journal;
74 struct list_head s_orphan; 74 struct list_head s_orphan;
75 struct mutex s_orphan_lock;
75 unsigned long s_commit_interval; 76 unsigned long s_commit_interval;
76 struct block_device *journal_bdev; 77 struct block_device *journal_bdev;
77#ifdef CONFIG_JBD_DEBUG 78#ifdef CONFIG_JBD_DEBUG