Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+56 -84
+7 -18
fs/ext3/super.c
··· 754 754 static int ext3_mark_dquot_dirty(struct dquot *dquot); 755 755 static int ext3_write_info(struct super_block *sb, int type); 756 756 static int ext3_quota_on(struct super_block *sb, int type, int format_id, 757 - char *path); 757 + struct path *path); 758 758 static int ext3_quota_on_mount(struct super_block *sb, int type); 759 759 static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data, 760 760 size_t len, loff_t off); ··· 2877 2877 * Standard function to be called on quota_on 2878 2878 */ 2879 2879 static int ext3_quota_on(struct super_block *sb, int type, int format_id, 2880 - char *name) 2880 + struct path *path) 2881 2881 { 2882 2882 int err; 2883 - struct path path; 2884 2883 2885 2884 if (!test_opt(sb, QUOTA)) 2886 2885 return -EINVAL; 2887 2886 2888 - err = kern_path(name, LOOKUP_FOLLOW, &path); 2889 - if (err) 2890 - return err; 2891 - 2892 2887 /* Quotafile not on the same filesystem? */ 2893 - if (path.mnt->mnt_sb != sb) { 2894 - path_put(&path); 2888 + if (path->mnt->mnt_sb != sb) 2895 2889 return -EXDEV; 2896 - } 2897 2890 /* Journaling quota? */ 2898 2891 if (EXT3_SB(sb)->s_qf_names[type]) { 2899 2892 /* Quotafile not of fs root? */ 2900 - if (path.dentry->d_parent != sb->s_root) 2893 + if (path->dentry->d_parent != sb->s_root) 2901 2894 ext3_msg(sb, KERN_WARNING, 2902 2895 "warning: Quota file not on filesystem root. " 2903 2896 "Journaled quota will not work."); ··· 2900 2907 * When we journal data on quota file, we have to flush journal to see 2901 2908 * all updates to the file when we bypass pagecache... 2902 2909 */ 2903 - if (ext3_should_journal_data(path.dentry->d_inode)) { 2910 + if (ext3_should_journal_data(path->dentry->d_inode)) { 2904 2911 /* 2905 2912 * We don't need to lock updates but journal_flush() could 2906 2913 * otherwise be livelocked... ··· 2908 2915 journal_lock_updates(EXT3_SB(sb)->s_journal); 2909 2916 err = journal_flush(EXT3_SB(sb)->s_journal); 2910 2917 journal_unlock_updates(EXT3_SB(sb)->s_journal); 2911 - if (err) { 2912 - path_put(&path); 2918 + if (err) 2913 2919 return err; 2914 - } 2915 2920 } 2916 2921 2917 - err = dquot_quota_on_path(sb, type, format_id, &path); 2918 - path_put(&path); 2919 - return err; 2922 + return dquot_quota_on(sb, type, format_id, path); 2920 2923 } 2921 2924 2922 2925 /* Read data from quotafile - avoid pagecache and such because we cannot afford
+7 -18
fs/ext4/super.c
··· 1161 1161 static int ext4_mark_dquot_dirty(struct dquot *dquot); 1162 1162 static int ext4_write_info(struct super_block *sb, int type); 1163 1163 static int ext4_quota_on(struct super_block *sb, int type, int format_id, 1164 - char *path); 1164 + struct path *path); 1165 1165 static int ext4_quota_off(struct super_block *sb, int type); 1166 1166 static int ext4_quota_on_mount(struct super_block *sb, int type); 1167 1167 static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, ··· 4558 4558 * Standard function to be called on quota_on 4559 4559 */ 4560 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 4563 int err; 4564 - struct path path; 4565 4564 4566 4565 if (!test_opt(sb, QUOTA)) 4567 4566 return -EINVAL; 4568 4567 4569 - err = kern_path(name, LOOKUP_FOLLOW, &path); 4570 - if (err) 4571 - return err; 4572 - 4573 4568 /* Quotafile not on the same filesystem? */ 4574 - if (path.mnt->mnt_sb != sb) { 4575 - path_put(&path); 4569 + if (path->mnt->mnt_sb != sb) 4576 4570 return -EXDEV; 4577 - } 4578 4571 /* Journaling quota? */ 4579 4572 if (EXT4_SB(sb)->s_qf_names[type]) { 4580 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 4575 ext4_msg(sb, KERN_WARNING, 4583 4576 "Quota file not on filesystem root. " 4584 4577 "Journaled quota will not work"); ··· 4582 4589 * all updates to the file when we bypass pagecache... 4583 4590 */ 4584 4591 if (EXT4_SB(sb)->s_journal && 4585 - ext4_should_journal_data(path.dentry->d_inode)) { 4592 + ext4_should_journal_data(path->dentry->d_inode)) { 4586 4593 /* 4587 4594 * We don't need to lock updates but journal_flush() could 4588 4595 * otherwise be livelocked... ··· 4590 4597 jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); 4591 4598 err = jbd2_journal_flush(EXT4_SB(sb)->s_journal); 4592 4599 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 4593 - if (err) { 4594 - path_put(&path); 4600 + if (err) 4595 4601 return err; 4596 - } 4597 4602 } 4598 4603 4599 - err = dquot_quota_on_path(sb, type, format_id, &path); 4600 - path_put(&path); 4601 - return err; 4604 + return dquot_quota_on(sb, type, format_id, path); 4602 4605 } 4603 4606 4604 4607 static int ext4_quota_off(struct super_block *sb, int type)
+2 -3
fs/ocfs2/super.c
··· 993 993 } 994 994 995 995 /* Handle quota on quotactl */ 996 - static int ocfs2_quota_on(struct super_block *sb, int type, int format_id, 997 - char *path) 996 + static int ocfs2_quota_on(struct super_block *sb, int type, int format_id) 998 997 { 999 998 unsigned int feature[MAXQUOTAS] = { OCFS2_FEATURE_RO_COMPAT_USRQUOTA, 1000 999 OCFS2_FEATURE_RO_COMPAT_GRPQUOTA}; ··· 1012 1013 } 1013 1014 1014 1015 static const struct quotactl_ops ocfs2_quotactl_ops = { 1015 - .quota_on = ocfs2_quota_on, 1016 + .quota_on_meta = ocfs2_quota_on, 1016 1017 .quota_off = ocfs2_quota_off, 1017 1018 .quota_sync = dquot_quota_sync, 1018 1019 .get_info = dquot_get_dqinfo,
+2 -16
fs/quota/dquot.c
··· 2189 2189 } 2190 2190 EXPORT_SYMBOL(dquot_resume); 2191 2191 2192 - int dquot_quota_on_path(struct super_block *sb, int type, int format_id, 2193 - struct path *path) 2192 + int dquot_quota_on(struct super_block *sb, int type, int format_id, 2193 + struct path *path) 2194 2194 { 2195 2195 int error = security_quota_on(path->dentry); 2196 2196 if (error) ··· 2202 2202 error = vfs_load_quota_inode(path->dentry->d_inode, type, 2203 2203 format_id, DQUOT_USAGE_ENABLED | 2204 2204 DQUOT_LIMITS_ENABLED); 2205 - return error; 2206 - } 2207 - EXPORT_SYMBOL(dquot_quota_on_path); 2208 - 2209 - int 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 2205 return error; 2220 2206 } 2221 2207 EXPORT_SYMBOL(dquot_quota_on);
+27 -14
fs/quota/quota.c
··· 64 64 } 65 65 66 66 static 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; 70 - int ret = -ENOSYS; 71 - 72 - pathname = getname(addr); 73 - if (IS_ERR(pathname)) 74 - return PTR_ERR(pathname); 75 - if (sb->s_qcop->quota_on) 76 - ret = sb->s_qcop->quota_on(sb, type, id, pathname); 77 - putname(pathname); 78 - return ret; 69 + if (!sb->s_qcop->quota_on && !sb->s_qcop->quota_on_meta) 70 + return -ENOSYS; 71 + if (sb->s_qcop->quota_on_meta) 72 + return sb->s_qcop->quota_on_meta(sb, type, id); 73 + if (IS_ERR(path)) 74 + return PTR_ERR(path); 75 + return sb->s_qcop->quota_on(sb, type, id, path); 79 76 } 80 77 81 78 static int quota_getfmt(struct super_block *sb, int type, void __user *addr) ··· 238 241 239 242 /* Copy parameters and call proper function */ 240 243 static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, 241 - void __user *addr) 244 + void __user *addr, struct path *path) 242 245 { 243 246 int ret; 244 247 ··· 253 256 254 257 switch (cmd) { 255 258 case Q_QUOTAON: 256 - return quota_quotaon(sb, type, cmd, id, addr); 259 + return quota_quotaon(sb, type, cmd, id, path); 257 260 case Q_QUOTAOFF: 258 261 if (!sb->s_qcop->quota_off) 259 262 return -ENOSYS; ··· 332 335 { 333 336 uint cmds, type; 334 337 struct super_block *sb = NULL; 338 + struct path path, *pathp = NULL; 335 339 int ret; 336 340 337 341 cmds = cmd >> SUBCMDSHIFT; ··· 349 351 return -ENODEV; 350 352 } 351 353 354 + /* 355 + * Path for quotaon has to be resolved before grabbing superblock 356 + * because that gets s_umount sem which is also possibly needed by path 357 + * resolution (think about autofs) and thus deadlocks could arise. 358 + */ 359 + if (cmds == Q_QUOTAON) { 360 + ret = user_path_at(AT_FDCWD, addr, LOOKUP_FOLLOW, &path); 361 + if (ret) 362 + pathp = ERR_PTR(ret); 363 + else 364 + pathp = &path; 365 + } 366 + 352 367 sb = quotactl_block(special); 353 368 if (IS_ERR(sb)) 354 369 return PTR_ERR(sb); 355 370 356 - ret = do_quotactl(sb, type, cmds, id, addr); 371 + ret = do_quotactl(sb, type, cmds, id, addr, pathp); 357 372 358 373 drop_super(sb); 374 + if (pathp && !IS_ERR(pathp)) 375 + path_put(pathp); 359 376 return ret; 360 377 }
+6 -11
fs/reiserfs/super.c
··· 632 632 static int reiserfs_release_dquot(struct dquot *); 633 633 static int reiserfs_mark_dquot_dirty(struct dquot *); 634 634 static int reiserfs_write_info(struct super_block *, int); 635 - static int reiserfs_quota_on(struct super_block *, int, int, char *); 635 + static int reiserfs_quota_on(struct super_block *, int, int, struct path *); 636 636 637 637 static const struct dquot_operations reiserfs_quota_operations = { 638 638 .write_dquot = reiserfs_write_dquot, ··· 2048 2048 * Standard function to be called on quota_on 2049 2049 */ 2050 2050 static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, 2051 - char *name) 2051 + struct path *path) 2052 2052 { 2053 2053 int err; 2054 - struct path path; 2055 2054 struct inode *inode; 2056 2055 struct reiserfs_transaction_handle th; 2057 2056 2058 2057 if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA))) 2059 2058 return -EINVAL; 2060 2059 2061 - err = kern_path(name, LOOKUP_FOLLOW, &path); 2062 - if (err) 2063 - return err; 2064 2060 /* Quotafile not on the same filesystem? */ 2065 - if (path.mnt->mnt_sb != sb) { 2061 + if (path->mnt->mnt_sb != sb) { 2066 2062 err = -EXDEV; 2067 2063 goto out; 2068 2064 } 2069 - inode = path.dentry->d_inode; 2065 + inode = path->dentry->d_inode; 2070 2066 /* We must not pack tails for quota files on reiserfs for quota IO to work */ 2071 2067 if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) { 2072 2068 err = reiserfs_unpack(inode, NULL); ··· 2078 2082 /* Journaling quota? */ 2079 2083 if (REISERFS_SB(sb)->s_qf_names[type]) { 2080 2084 /* Quotafile not of fs root? */ 2081 - if (path.dentry->d_parent != sb->s_root) 2085 + if (path->dentry->d_parent != sb->s_root) 2082 2086 reiserfs_warning(sb, "super-6521", 2083 2087 "Quota file not on filesystem root. " 2084 2088 "Journalled quota will not work."); ··· 2097 2101 if (err) 2098 2102 goto out; 2099 2103 } 2100 - err = dquot_quota_on_path(sb, type, format_id, &path); 2104 + err = dquot_quota_on(sb, type, format_id, path); 2101 2105 out: 2102 - path_put(&path); 2103 2106 return err; 2104 2107 } 2105 2108
+4 -1
include/linux/quota.h
··· 322 322 qsize_t *(*get_reserved_space) (struct inode *); 323 323 }; 324 324 325 + struct path; 326 + 325 327 /* Operations handling requests from userspace */ 326 328 struct 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 331 int (*quota_off)(struct super_block *, int); 329 332 int (*quota_sync)(struct super_block *, int, int); 330 333 int (*get_info)(struct super_block *, int, struct if_dqinfo *);
+1 -3
include/linux/quotaops.h
··· 76 76 77 77 int dquot_file_open(struct inode *inode, struct file *file); 78 78 79 - int dquot_quota_on(struct super_block *sb, int type, int format_id, 80 - char *path); 81 79 int dquot_enable(struct inode *inode, int type, int format_id, 82 80 unsigned int flags); 83 - int dquot_quota_on_path(struct super_block *sb, int type, int format_id, 81 + int dquot_quota_on(struct super_block *sb, int type, int format_id, 84 82 struct path *path); 85 83 int dquot_quota_on_mount(struct super_block *sb, char *qf_name, 86 84 int format_id, int type);