diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-21 10:33:37 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-21 10:33:37 -0500 |
commit | 4843456c5c341eb57f80f9224362a22665d14107 (patch) | |
tree | 5656b405a8b1d2596e8eb748b953ee677a261e3c /fs/ext4 | |
parent | 2b1caf6ed7b888c95a1909d343799672731651a5 (diff) | |
parent | f00c9e44ad1a9660fe8cd3ca15b6cd9497172eab (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6:
quota: Fix deadlock during path resolution
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/super.c | 25 |
1 files changed, 7 insertions, 18 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index cb10a06775e4..48ce561fafac 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1161,7 +1161,7 @@ static int ext4_release_dquot(struct dquot *dquot); | |||
1161 | static int ext4_mark_dquot_dirty(struct dquot *dquot); | 1161 | static int ext4_mark_dquot_dirty(struct dquot *dquot); |
1162 | static int ext4_write_info(struct super_block *sb, int type); | 1162 | static int ext4_write_info(struct super_block *sb, int type); |
1163 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, | 1163 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, |
1164 | char *path); | 1164 | struct path *path); |
1165 | static int ext4_quota_off(struct super_block *sb, int type); | 1165 | static int ext4_quota_off(struct super_block *sb, int type); |
1166 | static int ext4_quota_on_mount(struct super_block *sb, int type); | 1166 | static int ext4_quota_on_mount(struct super_block *sb, int type); |
1167 | static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, | 1167 | static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, |
@@ -4558,27 +4558,20 @@ static int ext4_quota_on_mount(struct super_block *sb, int type) | |||
4558 | * Standard function to be called on quota_on | 4558 | * Standard function to be called on quota_on |
4559 | */ | 4559 | */ |
4560 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, | 4560 | static int ext4_quota_on(struct super_block *sb, int type, int format_id, |
4561 | char *name) | 4561 | struct path *path) |
4562 | { | 4562 | { |
4563 | int err; | 4563 | int err; |
4564 | struct path path; | ||
4565 | 4564 | ||
4566 | if (!test_opt(sb, QUOTA)) | 4565 | if (!test_opt(sb, QUOTA)) |
4567 | return -EINVAL; | 4566 | return -EINVAL; |
4568 | 4567 | ||
4569 | err = kern_path(name, LOOKUP_FOLLOW, &path); | ||
4570 | if (err) | ||
4571 | return err; | ||
4572 | |||
4573 | /* Quotafile not on the same filesystem? */ | 4568 | /* Quotafile not on the same filesystem? */ |
4574 | if (path.mnt->mnt_sb != sb) { | 4569 | if (path->mnt->mnt_sb != sb) |
4575 | path_put(&path); | ||
4576 | return -EXDEV; | 4570 | return -EXDEV; |
4577 | } | ||
4578 | /* Journaling quota? */ | 4571 | /* Journaling quota? */ |
4579 | if (EXT4_SB(sb)->s_qf_names[type]) { | 4572 | if (EXT4_SB(sb)->s_qf_names[type]) { |
4580 | /* Quotafile not in fs root? */ | 4573 | /* Quotafile not in fs root? */ |
4581 | if (path.dentry->d_parent != sb->s_root) | 4574 | if (path->dentry->d_parent != sb->s_root) |
4582 | ext4_msg(sb, KERN_WARNING, | 4575 | ext4_msg(sb, KERN_WARNING, |
4583 | "Quota file not on filesystem root. " | 4576 | "Quota file not on filesystem root. " |
4584 | "Journaled quota will not work"); | 4577 | "Journaled quota will not work"); |
@@ -4589,7 +4582,7 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
4589 | * all updates to the file when we bypass pagecache... | 4582 | * all updates to the file when we bypass pagecache... |
4590 | */ | 4583 | */ |
4591 | if (EXT4_SB(sb)->s_journal && | 4584 | if (EXT4_SB(sb)->s_journal && |
4592 | ext4_should_journal_data(path.dentry->d_inode)) { | 4585 | ext4_should_journal_data(path->dentry->d_inode)) { |
4593 | /* | 4586 | /* |
4594 | * We don't need to lock updates but journal_flush() could | 4587 | * We don't need to lock updates but journal_flush() could |
4595 | * otherwise be livelocked... | 4588 | * otherwise be livelocked... |
@@ -4597,15 +4590,11 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
4597 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 4590 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
4598 | err = jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 4591 | err = jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
4599 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 4592 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); |
4600 | if (err) { | 4593 | if (err) |
4601 | path_put(&path); | ||
4602 | return err; | 4594 | return err; |
4603 | } | ||
4604 | } | 4595 | } |
4605 | 4596 | ||
4606 | err = dquot_quota_on_path(sb, type, format_id, &path); | 4597 | return dquot_quota_on(sb, type, format_id, path); |
4607 | path_put(&path); | ||
4608 | return err; | ||
4609 | } | 4598 | } |
4610 | 4599 | ||
4611 | static int ext4_quota_off(struct super_block *sb, int type) | 4600 | static int ext4_quota_off(struct super_block *sb, int type) |