aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext3/super.c25
-rw-r--r--fs/ext4/super.c25
-rw-r--r--fs/ocfs2/super.c5
-rw-r--r--fs/quota/dquot.c18
-rw-r--r--fs/quota/quota.c41
-rw-r--r--fs/reiserfs/super.c17
-rw-r--r--include/linux/quota.h5
-rw-r--r--include/linux/quotaops.h4
8 files changed, 56 insertions, 84 deletions
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index b7d0554631e4..0e0d391626be 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -755,7 +755,7 @@ static int ext3_release_dquot(struct dquot *dquot);
755static int ext3_mark_dquot_dirty(struct dquot *dquot); 755static int ext3_mark_dquot_dirty(struct dquot *dquot);
756static int ext3_write_info(struct super_block *sb, int type); 756static int ext3_write_info(struct super_block *sb, int type);
757static int ext3_quota_on(struct super_block *sb, int type, int format_id, 757static int ext3_quota_on(struct super_block *sb, int type, int format_id,
758 char *path); 758 struct path *path);
759static int ext3_quota_on_mount(struct super_block *sb, int type); 759static int ext3_quota_on_mount(struct super_block *sb, int type);
760static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data, 760static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data,
761 size_t len, loff_t off); 761 size_t len, loff_t off);
@@ -2885,27 +2885,20 @@ static int ext3_quota_on_mount(struct super_block *sb, int type)
2885 * Standard function to be called on quota_on 2885 * Standard function to be called on quota_on
2886 */ 2886 */
2887static int ext3_quota_on(struct super_block *sb, int type, int format_id, 2887static int ext3_quota_on(struct super_block *sb, int type, int format_id,
2888 char *name) 2888 struct path *path)
2889{ 2889{
2890 int err; 2890 int err;
2891 struct path path;
2892 2891
2893 if (!test_opt(sb, QUOTA)) 2892 if (!test_opt(sb, QUOTA))
2894 return -EINVAL; 2893 return -EINVAL;
2895 2894
2896 err = kern_path(name, LOOKUP_FOLLOW, &path);
2897 if (err)
2898 return err;
2899
2900 /* Quotafile not on the same filesystem? */ 2895 /* Quotafile not on the same filesystem? */
2901 if (path.mnt->mnt_sb != sb) { 2896 if (path->mnt->mnt_sb != sb)
2902 path_put(&path);
2903 return -EXDEV; 2897 return -EXDEV;
2904 }
2905 /* Journaling quota? */ 2898 /* Journaling quota? */
2906 if (EXT3_SB(sb)->s_qf_names[type]) { 2899 if (EXT3_SB(sb)->s_qf_names[type]) {
2907 /* Quotafile not of fs root? */ 2900 /* Quotafile not of fs root? */
2908 if (path.dentry->d_parent != sb->s_root) 2901 if (path->dentry->d_parent != sb->s_root)
2909 ext3_msg(sb, KERN_WARNING, 2902 ext3_msg(sb, KERN_WARNING,
2910 "warning: Quota file not on filesystem root. " 2903 "warning: Quota file not on filesystem root. "
2911 "Journaled quota will not work."); 2904 "Journaled quota will not work.");
@@ -2915,7 +2908,7 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id,
2915 * When we journal data on quota file, we have to flush journal to see 2908 * When we journal data on quota file, we have to flush journal to see
2916 * all updates to the file when we bypass pagecache... 2909 * all updates to the file when we bypass pagecache...
2917 */ 2910 */
2918 if (ext3_should_journal_data(path.dentry->d_inode)) { 2911 if (ext3_should_journal_data(path->dentry->d_inode)) {
2919 /* 2912 /*
2920 * We don't need to lock updates but journal_flush() could 2913 * We don't need to lock updates but journal_flush() could
2921 * otherwise be livelocked... 2914 * otherwise be livelocked...
@@ -2923,15 +2916,11 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id,
2923 journal_lock_updates(EXT3_SB(sb)->s_journal); 2916 journal_lock_updates(EXT3_SB(sb)->s_journal);
2924 err = journal_flush(EXT3_SB(sb)->s_journal); 2917 err = journal_flush(EXT3_SB(sb)->s_journal);
2925 journal_unlock_updates(EXT3_SB(sb)->s_journal); 2918 journal_unlock_updates(EXT3_SB(sb)->s_journal);
2926 if (err) { 2919 if (err)
2927 path_put(&path);
2928 return err; 2920 return err;
2929 }
2930 } 2921 }
2931 2922
2932 err = dquot_quota_on_path(sb, type, format_id, &path); 2923 return dquot_quota_on(sb, type, format_id, path);
2933 path_put(&path);
2934 return err;
2935} 2924}
2936 2925
2937/* Read data from quotafile - avoid pagecache and such because we cannot afford 2926/* Read data from quotafile - avoid pagecache and such because we cannot afford
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 29c80f6d8b27..0f10ccd6bfc0 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -1162,7 +1162,7 @@ static int ext4_release_dquot(struct dquot *dquot);
1162static int ext4_mark_dquot_dirty(struct dquot *dquot); 1162static int ext4_mark_dquot_dirty(struct dquot *dquot);
1163static int ext4_write_info(struct super_block *sb, int type); 1163static int ext4_write_info(struct super_block *sb, int type);
1164static int ext4_quota_on(struct super_block *sb, int type, int format_id, 1164static int ext4_quota_on(struct super_block *sb, int type, int format_id,
1165 char *path); 1165 struct path *path);
1166static int ext4_quota_off(struct super_block *sb, int type); 1166static int ext4_quota_off(struct super_block *sb, int type);
1167static int ext4_quota_on_mount(struct super_block *sb, int type); 1167static int ext4_quota_on_mount(struct super_block *sb, int type);
1168static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, 1168static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data,
@@ -4566,27 +4566,20 @@ static int ext4_quota_on_mount(struct super_block *sb, int type)
4566 * Standard function to be called on quota_on 4566 * Standard function to be called on quota_on
4567 */ 4567 */
4568static int ext4_quota_on(struct super_block *sb, int type, int format_id, 4568static int ext4_quota_on(struct super_block *sb, int type, int format_id,
4569 char *name) 4569 struct path *path)
4570{ 4570{
4571 int err; 4571 int err;
4572 struct path path;
4573 4572
4574 if (!test_opt(sb, QUOTA)) 4573 if (!test_opt(sb, QUOTA))
4575 return -EINVAL; 4574 return -EINVAL;
4576 4575
4577 err = kern_path(name, LOOKUP_FOLLOW, &path);
4578 if (err)
4579 return err;
4580
4581 /* Quotafile not on the same filesystem? */ 4576 /* Quotafile not on the same filesystem? */
4582 if (path.mnt->mnt_sb != sb) { 4577 if (path->mnt->mnt_sb != sb)
4583 path_put(&path);
4584 return -EXDEV; 4578 return -EXDEV;
4585 }
4586 /* Journaling quota? */ 4579 /* Journaling quota? */
4587 if (EXT4_SB(sb)->s_qf_names[type]) { 4580 if (EXT4_SB(sb)->s_qf_names[type]) {
4588 /* Quotafile not in fs root? */ 4581 /* Quotafile not in fs root? */
4589 if (path.dentry->d_parent != sb->s_root) 4582 if (path->dentry->d_parent != sb->s_root)
4590 ext4_msg(sb, KERN_WARNING, 4583 ext4_msg(sb, KERN_WARNING,
4591 "Quota file not on filesystem root. " 4584 "Quota file not on filesystem root. "
4592 "Journaled quota will not work"); 4585 "Journaled quota will not work");
@@ -4597,7 +4590,7 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
4597 * all updates to the file when we bypass pagecache... 4590 * all updates to the file when we bypass pagecache...
4598 */ 4591 */
4599 if (EXT4_SB(sb)->s_journal && 4592 if (EXT4_SB(sb)->s_journal &&
4600 ext4_should_journal_data(path.dentry->d_inode)) { 4593 ext4_should_journal_data(path->dentry->d_inode)) {
4601 /* 4594 /*
4602 * We don't need to lock updates but journal_flush() could 4595 * We don't need to lock updates but journal_flush() could
4603 * otherwise be livelocked... 4596 * otherwise be livelocked...
@@ -4605,15 +4598,11 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
4605 jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); 4598 jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal);
4606 err = jbd2_journal_flush(EXT4_SB(sb)->s_journal); 4599 err = jbd2_journal_flush(EXT4_SB(sb)->s_journal);
4607 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 4600 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
4608 if (err) { 4601 if (err)
4609 path_put(&path);
4610 return err; 4602 return err;
4611 }
4612 } 4603 }
4613 4604
4614 err = dquot_quota_on_path(sb, type, format_id, &path); 4605 return dquot_quota_on(sb, type, format_id, path);
4615 path_put(&path);
4616 return err;
4617} 4606}
4618 4607
4619static int ext4_quota_off(struct super_block *sb, int type) 4608static int ext4_quota_off(struct super_block *sb, int type)
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 17ff46fa8a10..31c3ffd2f8d0 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -993,8 +993,7 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb)
993} 993}
994 994
995/* Handle quota on quotactl */ 995/* Handle quota on quotactl */
996static int ocfs2_quota_on(struct super_block *sb, int type, int format_id, 996static int ocfs2_quota_on(struct super_block *sb, int type, int format_id)
997 char *path)
998{ 997{
999 unsigned int feature[MAXQUOTAS] = { OCFS2_FEATURE_RO_COMPAT_USRQUOTA, 998 unsigned int feature[MAXQUOTAS] = { OCFS2_FEATURE_RO_COMPAT_USRQUOTA,
1000 OCFS2_FEATURE_RO_COMPAT_GRPQUOTA}; 999 OCFS2_FEATURE_RO_COMPAT_GRPQUOTA};
@@ -1013,7 +1012,7 @@ static int ocfs2_quota_off(struct super_block *sb, int type)
1013} 1012}
1014 1013
1015static const struct quotactl_ops ocfs2_quotactl_ops = { 1014static const struct quotactl_ops ocfs2_quotactl_ops = {
1016 .quota_on = ocfs2_quota_on, 1015 .quota_on_meta = ocfs2_quota_on,
1017 .quota_off = ocfs2_quota_off, 1016 .quota_off = ocfs2_quota_off,
1018 .quota_sync = dquot_quota_sync, 1017 .quota_sync = dquot_quota_sync,
1019 .get_info = dquot_get_dqinfo, 1018 .get_info = dquot_get_dqinfo,
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 84becd3e4772..a2a622e079f0 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2189,8 +2189,8 @@ int dquot_resume(struct super_block *sb, int type)
2189} 2189}
2190EXPORT_SYMBOL(dquot_resume); 2190EXPORT_SYMBOL(dquot_resume);
2191 2191
2192int dquot_quota_on_path(struct super_block *sb, int type, int format_id, 2192int dquot_quota_on(struct super_block *sb, int type, int format_id,
2193 struct path *path) 2193 struct path *path)
2194{ 2194{
2195 int error = security_quota_on(path->dentry); 2195 int error = security_quota_on(path->dentry);
2196 if (error) 2196 if (error)
@@ -2204,20 +2204,6 @@ int dquot_quota_on_path(struct super_block *sb, int type, int format_id,
2204 DQUOT_LIMITS_ENABLED); 2204 DQUOT_LIMITS_ENABLED);
2205 return error; 2205 return error;
2206} 2206}
2207EXPORT_SYMBOL(dquot_quota_on_path);
2208
2209int dquot_quota_on(struct super_block *sb, int type, int format_id, char *name)
2210{
2211 struct path path;
2212 int error;
2213
2214 error = kern_path(name, LOOKUP_FOLLOW, &path);
2215 if (!error) {
2216 error = dquot_quota_on_path(sb, type, format_id, &path);
2217 path_put(&path);
2218 }
2219 return error;
2220}
2221EXPORT_SYMBOL(dquot_quota_on); 2207EXPORT_SYMBOL(dquot_quota_on);
2222 2208
2223/* 2209/*
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index b299961e1edb..b34bdb25490c 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -64,18 +64,15 @@ static int quota_sync_all(int type)
64} 64}
65 65
66static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, 66static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id,
67 void __user *addr) 67 struct path *path)
68{ 68{
69 char *pathname; 69 if (!sb->s_qcop->quota_on && !sb->s_qcop->quota_on_meta)
70 int ret = -ENOSYS; 70 return -ENOSYS;
71 71 if (sb->s_qcop->quota_on_meta)
72 pathname = getname(addr); 72 return sb->s_qcop->quota_on_meta(sb, type, id);
73 if (IS_ERR(pathname)) 73 if (IS_ERR(path))
74 return PTR_ERR(pathname); 74 return PTR_ERR(path);
75 if (sb->s_qcop->quota_on) 75 return sb->s_qcop->quota_on(sb, type, id, path);
76 ret = sb->s_qcop->quota_on(sb, type, id, pathname);
77 putname(pathname);
78 return ret;
79} 76}
80 77
81static int quota_getfmt(struct super_block *sb, int type, void __user *addr) 78static int quota_getfmt(struct super_block *sb, int type, void __user *addr)
@@ -241,7 +238,7 @@ static int quota_getxquota(struct super_block *sb, int type, qid_t id,
241 238
242/* Copy parameters and call proper function */ 239/* Copy parameters and call proper function */
243static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, 240static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
244 void __user *addr) 241 void __user *addr, struct path *path)
245{ 242{
246 int ret; 243 int ret;
247 244
@@ -256,7 +253,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
256 253
257 switch (cmd) { 254 switch (cmd) {
258 case Q_QUOTAON: 255 case Q_QUOTAON:
259 return quota_quotaon(sb, type, cmd, id, addr); 256 return quota_quotaon(sb, type, cmd, id, path);
260 case Q_QUOTAOFF: 257 case Q_QUOTAOFF:
261 if (!sb->s_qcop->quota_off) 258 if (!sb->s_qcop->quota_off)
262 return -ENOSYS; 259 return -ENOSYS;
@@ -335,6 +332,7 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
335{ 332{
336 uint cmds, type; 333 uint cmds, type;
337 struct super_block *sb = NULL; 334 struct super_block *sb = NULL;
335 struct path path, *pathp = NULL;
338 int ret; 336 int ret;
339 337
340 cmds = cmd >> SUBCMDSHIFT; 338 cmds = cmd >> SUBCMDSHIFT;
@@ -351,12 +349,27 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
351 return -ENODEV; 349 return -ENODEV;
352 } 350 }
353 351
352 /*
353 * Path for quotaon has to be resolved before grabbing superblock
354 * because that gets s_umount sem which is also possibly needed by path
355 * resolution (think about autofs) and thus deadlocks could arise.
356 */
357 if (cmds == Q_QUOTAON) {
358 ret = user_path_at(AT_FDCWD, addr, LOOKUP_FOLLOW, &path);
359 if (ret)
360 pathp = ERR_PTR(ret);
361 else
362 pathp = &path;
363 }
364
354 sb = quotactl_block(special); 365 sb = quotactl_block(special);
355 if (IS_ERR(sb)) 366 if (IS_ERR(sb))
356 return PTR_ERR(sb); 367 return PTR_ERR(sb);
357 368
358 ret = do_quotactl(sb, type, cmds, id, addr); 369 ret = do_quotactl(sb, type, cmds, id, addr, pathp);
359 370
360 drop_super(sb); 371 drop_super(sb);
372 if (pathp && !IS_ERR(pathp))
373 path_put(pathp);
361 return ret; 374 return ret;
362} 375}
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 2575682a9ead..0aab04f46827 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -632,7 +632,7 @@ static int reiserfs_acquire_dquot(struct dquot *);
632static int reiserfs_release_dquot(struct dquot *); 632static int reiserfs_release_dquot(struct dquot *);
633static int reiserfs_mark_dquot_dirty(struct dquot *); 633static int reiserfs_mark_dquot_dirty(struct dquot *);
634static int reiserfs_write_info(struct super_block *, int); 634static int reiserfs_write_info(struct super_block *, int);
635static int reiserfs_quota_on(struct super_block *, int, int, char *); 635static int reiserfs_quota_on(struct super_block *, int, int, struct path *);
636 636
637static const struct dquot_operations reiserfs_quota_operations = { 637static const struct dquot_operations reiserfs_quota_operations = {
638 .write_dquot = reiserfs_write_dquot, 638 .write_dquot = reiserfs_write_dquot,
@@ -2048,25 +2048,21 @@ static int reiserfs_quota_on_mount(struct super_block *sb, int type)
2048 * Standard function to be called on quota_on 2048 * Standard function to be called on quota_on
2049 */ 2049 */
2050static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, 2050static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
2051 char *name) 2051 struct path *path)
2052{ 2052{
2053 int err; 2053 int err;
2054 struct path path;
2055 struct inode *inode; 2054 struct inode *inode;
2056 struct reiserfs_transaction_handle th; 2055 struct reiserfs_transaction_handle th;
2057 2056
2058 if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA))) 2057 if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA)))
2059 return -EINVAL; 2058 return -EINVAL;
2060 2059
2061 err = kern_path(name, LOOKUP_FOLLOW, &path);
2062 if (err)
2063 return err;
2064 /* Quotafile not on the same filesystem? */ 2060 /* Quotafile not on the same filesystem? */
2065 if (path.mnt->mnt_sb != sb) { 2061 if (path->mnt->mnt_sb != sb) {
2066 err = -EXDEV; 2062 err = -EXDEV;
2067 goto out; 2063 goto out;
2068 } 2064 }
2069 inode = path.dentry->d_inode; 2065 inode = path->dentry->d_inode;
2070 /* We must not pack tails for quota files on reiserfs for quota IO to work */ 2066 /* We must not pack tails for quota files on reiserfs for quota IO to work */
2071 if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) { 2067 if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) {
2072 err = reiserfs_unpack(inode, NULL); 2068 err = reiserfs_unpack(inode, NULL);
@@ -2082,7 +2078,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
2082 /* Journaling quota? */ 2078 /* Journaling quota? */
2083 if (REISERFS_SB(sb)->s_qf_names[type]) { 2079 if (REISERFS_SB(sb)->s_qf_names[type]) {
2084 /* Quotafile not of fs root? */ 2080 /* Quotafile not of fs root? */
2085 if (path.dentry->d_parent != sb->s_root) 2081 if (path->dentry->d_parent != sb->s_root)
2086 reiserfs_warning(sb, "super-6521", 2082 reiserfs_warning(sb, "super-6521",
2087 "Quota file not on filesystem root. " 2083 "Quota file not on filesystem root. "
2088 "Journalled quota will not work."); 2084 "Journalled quota will not work.");
@@ -2101,9 +2097,8 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
2101 if (err) 2097 if (err)
2102 goto out; 2098 goto out;
2103 } 2099 }
2104 err = dquot_quota_on_path(sb, type, format_id, &path); 2100 err = dquot_quota_on(sb, type, format_id, path);
2105out: 2101out:
2106 path_put(&path);
2107 return err; 2102 return err;
2108} 2103}
2109 2104
diff --git a/include/linux/quota.h b/include/linux/quota.h
index 94c1f03b50eb..9a85412e0db6 100644
--- a/include/linux/quota.h
+++ b/include/linux/quota.h
@@ -322,9 +322,12 @@ struct dquot_operations {
322 qsize_t *(*get_reserved_space) (struct inode *); 322 qsize_t *(*get_reserved_space) (struct inode *);
323}; 323};
324 324
325struct path;
326
325/* Operations handling requests from userspace */ 327/* Operations handling requests from userspace */
326struct quotactl_ops { 328struct quotactl_ops {
327 int (*quota_on)(struct super_block *, int, int, char *); 329 int (*quota_on)(struct super_block *, int, int, struct path *);
330 int (*quota_on_meta)(struct super_block *, int, int);
328 int (*quota_off)(struct super_block *, int); 331 int (*quota_off)(struct super_block *, int);
329 int (*quota_sync)(struct super_block *, int, int); 332 int (*quota_sync)(struct super_block *, int, int);
330 int (*get_info)(struct super_block *, int, struct if_dqinfo *); 333 int (*get_info)(struct super_block *, int, struct if_dqinfo *);
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
index 223b14cd129c..eb354f6f26b3 100644
--- a/include/linux/quotaops.h
+++ b/include/linux/quotaops.h
@@ -76,11 +76,9 @@ int dquot_mark_dquot_dirty(struct dquot *dquot);
76 76
77int dquot_file_open(struct inode *inode, struct file *file); 77int dquot_file_open(struct inode *inode, struct file *file);
78 78
79int dquot_quota_on(struct super_block *sb, int type, int format_id,
80 char *path);
81int dquot_enable(struct inode *inode, int type, int format_id, 79int dquot_enable(struct inode *inode, int type, int format_id,
82 unsigned int flags); 80 unsigned int flags);
83int dquot_quota_on_path(struct super_block *sb, int type, int format_id, 81int dquot_quota_on(struct super_block *sb, int type, int format_id,
84 struct path *path); 82 struct path *path);
85int dquot_quota_on_mount(struct super_block *sb, char *qf_name, 83int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
86 int format_id, int type); 84 int format_id, int type);