From 0f0dd62fddcbd0f6830ed8ef3d3426ccc46b9250 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 May 2010 07:16:41 -0400 Subject: quota: kill the vfs_dq_off and vfs_dq_quota_on_remount wrappers Instead of having wrappers in the VFS namespace export the dquot_suspend and dquot_resume helpers directly. Also rename vfs_quota_disable to dquot_disable while we're at it. [Jan Kara: Moved dquot_suspend to quotaops.h and made it inline] Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- include/linux/quotaops.h | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 370abb1e99cb..811529241e33 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -50,6 +50,14 @@ int dquot_alloc_inode(const struct inode *inode); int dquot_claim_space_nodirty(struct inode *inode, qsize_t number); void dquot_free_inode(const struct inode *inode); +int dquot_disable(struct super_block *sb, int type, unsigned int flags); +/* Suspend quotas on remount RO */ +static inline int dquot_suspend(struct super_block *sb, int type) +{ + return dquot_disable(sb, type, DQUOT_SUSPENDED); +} +int dquot_resume(struct super_block *sb, int type); + int dquot_commit(struct dquot *dquot); int dquot_acquire(struct dquot *dquot); int dquot_release(struct dquot *dquot); @@ -67,7 +75,6 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id, int vfs_quota_on_mount(struct super_block *sb, char *qf_name, int format_id, int type); int vfs_quota_off(struct super_block *sb, int type, int remount); -int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags); int vfs_quota_sync(struct super_block *sb, int type, int wait); int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); @@ -78,7 +85,6 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, int __dquot_transfer(struct inode *inode, struct dquot **transfer_to); int dquot_transfer(struct inode *inode, struct iattr *iattr); -int vfs_dq_quota_on_remount(struct super_block *sb); static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type) { @@ -231,11 +237,6 @@ static inline int vfs_dq_off(struct super_block *sb, int remount) return 0; } -static inline int vfs_dq_quota_on_remount(struct super_block *sb) -{ - return 0; -} - static inline int dquot_transfer(struct inode *inode, struct iattr *iattr) { return 0; @@ -262,6 +263,22 @@ static inline int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) return 0; } +static inline int dquot_disable(struct super_block *sb, int type, + unsigned int flags) +{ + return 0; +} + +static inline int dquot_suspend(struct super_block *sb, int type) +{ + return 0; +} + +static inline int dquot_resume(struct super_block *sb, int type) +{ + return 0; +} + #define dquot_file_open generic_file_open #endif /* CONFIG_QUOTA */ -- cgit v1.2.3-58-ga151 From e0ccfd959cd8907bcb66cc2042e0f4fd7fcbff2b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 May 2010 07:16:42 -0400 Subject: quota: move unmount handling into the filesystem Currently the VFS calls into the quotactl interface for unmounting filesystems. This means filesystems with their own quota handling can't easily distinguish between user-space originating quotaoff and an unount. Instead move the responsibily of the unmount handling into the filesystem to be consistent with all other dquot handling. Note that we do call dquot_disable a lot later now, e.g. after a sync_filesystem. But this is fine as the quota code does all its writes via blockdev's mapping and that is synced even later. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ext2/super.c | 2 ++ fs/ext3/super.c | 2 ++ fs/ext4/super.c | 2 ++ fs/jfs/super.c | 2 ++ fs/reiserfs/super.c | 2 ++ fs/super.c | 1 - fs/udf/super.c | 2 ++ fs/ufs/super.c | 2 ++ include/linux/quotaops.h | 15 --------------- 9 files changed, 14 insertions(+), 16 deletions(-) (limited to 'include/linux') diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 318ebc58bb7b..b9b77c3e7ae0 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -119,6 +119,8 @@ static void ext2_put_super (struct super_block * sb) int i; struct ext2_sb_info *sbi = EXT2_SB(sb); + dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); + if (sb->s_dirt) ext2_write_super(sb); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 9d5e582b514a..b2f3715988ba 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -410,6 +410,8 @@ static void ext3_put_super (struct super_block * sb) struct ext3_super_block *es = sbi->s_es; int i, err; + dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); + lock_kernel(); ext3_xattr_put_super(sb); diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 08d31101eb05..808aca3a22f5 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -645,6 +645,8 @@ static void ext4_put_super(struct super_block *sb) struct ext4_super_block *es = sbi->s_es; int i, err; + dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); + flush_workqueue(sbi->dio_unwritten_wq); destroy_workqueue(sbi->dio_unwritten_wq); diff --git a/fs/jfs/super.c b/fs/jfs/super.c index b8a07d4c108e..7d940a3a3d93 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -179,6 +179,8 @@ static void jfs_put_super(struct super_block *sb) jfs_info("In jfs_put_super"); + dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); + lock_kernel(); rc = jfs_umount(sb); diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 5dad5a2707bc..08879af0af0d 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -466,6 +466,8 @@ static void reiserfs_put_super(struct super_block *s) struct reiserfs_transaction_handle th; th.t_trans_id = 0; + dquot_disable(s, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); + reiserfs_write_lock(s); if (s->s_dirt) diff --git a/fs/super.c b/fs/super.c index a38e6e9b6f69..05f62e5d464d 100644 --- a/fs/super.c +++ b/fs/super.c @@ -160,7 +160,6 @@ void deactivate_locked_super(struct super_block *s) { struct file_system_type *fs = s->s_type; if (atomic_dec_and_test(&s->s_active)) { - vfs_dq_off(s, 0); fs->kill_sb(s); put_filesystem(fs); put_super(s); diff --git a/fs/udf/super.c b/fs/udf/super.c index b154c41a7a9a..76a61566f299 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -2102,6 +2102,8 @@ static void udf_put_super(struct super_block *sb) int i; struct udf_sb_info *sbi; + dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); + sbi = UDF_SB(sb); lock_kernel(); diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 495fdc1df7eb..d3977c7128e3 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1227,6 +1227,8 @@ static void ufs_put_super(struct super_block *sb) UFSD("ENTER\n"); + dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); + if (sb->s_dirt) ufs_write_super(sb); diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 811529241e33..cfa2abb1b6d1 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -156,16 +156,6 @@ extern const struct quotactl_ops vfs_quotactl_ops; #define sb_dquot_ops (&dquot_operations) #define sb_quotactl_ops (&vfs_quotactl_ops) -/* Cannot be called inside a transaction */ -static inline int vfs_dq_off(struct super_block *sb, int remount) -{ - int ret = -ENOSYS; - - if (sb->s_qcop && sb->s_qcop->quota_off) - ret = sb->s_qcop->quota_off(sb, -1, remount); - return ret; -} - #else static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type) @@ -232,11 +222,6 @@ static inline void dquot_free_inode(const struct inode *inode) { } -static inline int vfs_dq_off(struct super_block *sb, int remount) -{ - return 0; -} - static inline int dquot_transfer(struct inode *inode, struct iattr *iattr) { return 0; -- cgit v1.2.3-58-ga151 From 307ae18a56e5b706056a2050d52e8cc01b5171c0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 May 2010 07:16:43 -0400 Subject: quota: drop remount argument to ->quota_on and ->quota_off Remount handling has fully moved into the filesystem, so all this is superflous now. Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ext3/super.c | 9 +++------ fs/ext4/super.c | 9 +++------ fs/ocfs2/super.c | 10 ++-------- fs/quota/dquot.c | 8 ++------ fs/quota/quota.c | 4 ++-- fs/reiserfs/super.c | 10 ++++------ include/linux/quota.h | 4 ++-- include/linux/quotaops.h | 4 ++-- 8 files changed, 20 insertions(+), 38 deletions(-) (limited to 'include/linux') diff --git a/fs/ext3/super.c b/fs/ext3/super.c index b2f3715988ba..e52006737b4b 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -750,7 +750,7 @@ static int ext3_release_dquot(struct dquot *dquot); static int ext3_mark_dquot_dirty(struct dquot *dquot); static int ext3_write_info(struct super_block *sb, int type); static int ext3_quota_on(struct super_block *sb, int type, int format_id, - char *path, int remount); + char *path); static int ext3_quota_on_mount(struct super_block *sb, int type); static ssize_t ext3_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off); @@ -1529,7 +1529,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, /* Turn quotas off */ for (i = 0; i < MAXQUOTAS; i++) { if (sb_dqopt(sb)->files[i]) - vfs_quota_off(sb, i, 0); + vfs_quota_off(sb, i); } #endif sb->s_flags = s_flags; /* Restore MS_RDONLY status */ @@ -2870,16 +2870,13 @@ static int ext3_quota_on_mount(struct super_block *sb, int type) * Standard function to be called on quota_on */ static int ext3_quota_on(struct super_block *sb, int type, int format_id, - char *name, int remount) + char *name) { int err; struct path path; if (!test_opt(sb, QUOTA)) return -EINVAL; - /* When remounting, no checks are needed and in fact, name is NULL */ - if (remount) - return vfs_quota_on(sb, type, format_id, name, remount); err = kern_path(name, LOOKUP_FOLLOW, &path); if (err) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 808aca3a22f5..dfe9bf503f85 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1061,7 +1061,7 @@ static int ext4_release_dquot(struct dquot *dquot); static int ext4_mark_dquot_dirty(struct dquot *dquot); static int ext4_write_info(struct super_block *sb, int type); static int ext4_quota_on(struct super_block *sb, int type, int format_id, - char *path, int remount); + char *path); static int ext4_quota_on_mount(struct super_block *sb, int type); static ssize_t ext4_quota_read(struct super_block *sb, int type, char *data, size_t len, loff_t off); @@ -2053,7 +2053,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, /* Turn quotas off */ for (i = 0; i < MAXQUOTAS; i++) { if (sb_dqopt(sb)->files[i]) - vfs_quota_off(sb, i, 0); + vfs_quota_off(sb, i); } #endif sb->s_flags = s_flags; /* Restore MS_RDONLY status */ @@ -3924,16 +3924,13 @@ static int ext4_quota_on_mount(struct super_block *sb, int type) * Standard function to be called on quota_on */ static int ext4_quota_on(struct super_block *sb, int type, int format_id, - char *name, int remount) + char *name) { int err; struct path path; if (!test_opt(sb, QUOTA)) return -EINVAL; - /* When remounting, no checks are needed and in fact, name is NULL */ - if (remount) - return vfs_quota_on(sb, type, format_id, name, remount); err = kern_path(name, LOOKUP_FOLLOW, &path); if (err) diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 0773873d590a..5367d6dee395 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -964,7 +964,7 @@ static void ocfs2_disable_quotas(struct ocfs2_super *osb) /* Handle quota on quotactl */ static int ocfs2_quota_on(struct super_block *sb, int type, int format_id, - char *path, int remount) + char *path) { unsigned int feature[MAXQUOTAS] = { OCFS2_FEATURE_RO_COMPAT_USRQUOTA, OCFS2_FEATURE_RO_COMPAT_GRPQUOTA}; @@ -972,19 +972,13 @@ static int ocfs2_quota_on(struct super_block *sb, int type, int format_id, if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type])) return -EINVAL; - if (remount) - return 0; /* Just ignore it has been handled in - * ocfs2_remount() */ return vfs_quota_enable(sb_dqopt(sb)->files[type], type, format_id, DQUOT_LIMITS_ENABLED); } /* Handle quota off quotactl */ -static int ocfs2_quota_off(struct super_block *sb, int type, int remount) +static int ocfs2_quota_off(struct super_block *sb, int type) { - if (remount) - return 0; /* Ignore now and handle later in - * ocfs2_remount() */ return dquot_disable(sb, type, DQUOT_LIMITS_ENABLED); } diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index cf972283e474..b84422657f6d 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1997,9 +1997,8 @@ put_inodes: } EXPORT_SYMBOL(dquot_disable); -int vfs_quota_off(struct super_block *sb, int type, int remount) +int vfs_quota_off(struct super_block *sb, int type) { - BUG_ON(remount); return dquot_disable(sb, type, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); } @@ -2175,14 +2174,11 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id, } EXPORT_SYMBOL(vfs_quota_on_path); -int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, - int remount) +int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name) { struct path path; int error; - BUG_ON(remount); - error = kern_path(name, LOOKUP_FOLLOW, &path); if (!error) { error = vfs_quota_on_path(sb, type, format_id, &path); diff --git a/fs/quota/quota.c b/fs/quota/quota.c index ce3dfd066f59..b299961e1edb 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c @@ -73,7 +73,7 @@ static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, if (IS_ERR(pathname)) return PTR_ERR(pathname); if (sb->s_qcop->quota_on) - ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0); + ret = sb->s_qcop->quota_on(sb, type, id, pathname); putname(pathname); return ret; } @@ -260,7 +260,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, case Q_QUOTAOFF: if (!sb->s_qcop->quota_off) return -ENOSYS; - return sb->s_qcop->quota_off(sb, type, 0); + return sb->s_qcop->quota_off(sb, type); case Q_GETFMT: return quota_getfmt(sb, type, addr); case Q_GETINFO: diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 08879af0af0d..fa46abd0d958 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -305,7 +305,7 @@ static int finish_unfinished(struct super_block *s) /* Turn quotas off */ for (i = 0; i < MAXQUOTAS; i++) { if (sb_dqopt(s)->files[i]) - vfs_quota_off(s, i, 0); + vfs_quota_off(s, i); } if (ms_active_set) /* Restore the flag back */ @@ -622,7 +622,7 @@ static int reiserfs_acquire_dquot(struct dquot *); static int reiserfs_release_dquot(struct dquot *); static int reiserfs_mark_dquot_dirty(struct dquot *); static int reiserfs_write_info(struct super_block *, int); -static int reiserfs_quota_on(struct super_block *, int, int, char *, int); +static int reiserfs_quota_on(struct super_block *, int, int, char *); static const struct dquot_operations reiserfs_quota_operations = { .write_dquot = reiserfs_write_dquot, @@ -2038,7 +2038,7 @@ static int reiserfs_quota_on_mount(struct super_block *sb, int type) * Standard function to be called on quota_on */ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, - char *name, int remount) + char *name) { int err; struct path path; @@ -2047,9 +2047,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA))) return -EINVAL; - /* No more checks needed? Path and format_id are bogus anyway... */ - if (remount) - return vfs_quota_on(sb, type, format_id, name, 1); + err = kern_path(name, LOOKUP_FOLLOW, &path); if (err) return err; diff --git a/include/linux/quota.h b/include/linux/quota.h index 7126a15467f1..2789d07c37be 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -332,8 +332,8 @@ struct dquot_operations { /* Operations handling requests from userspace */ struct quotactl_ops { - int (*quota_on)(struct super_block *, int, int, char *, int); - int (*quota_off)(struct super_block *, int, int); + int (*quota_on)(struct super_block *, int, int, char *); + int (*quota_off)(struct super_block *, int); int (*quota_sync)(struct super_block *, int, int); int (*get_info)(struct super_block *, int, struct if_dqinfo *); int (*set_info)(struct super_block *, int, struct if_dqinfo *); diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index cfa2abb1b6d1..a6592ddc349f 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -67,14 +67,14 @@ int dquot_mark_dquot_dirty(struct dquot *dquot); int dquot_file_open(struct inode *inode, struct file *file); int vfs_quota_on(struct super_block *sb, int type, int format_id, - char *path, int remount); + char *path); int vfs_quota_enable(struct inode *inode, int type, int format_id, unsigned int flags); int vfs_quota_on_path(struct super_block *sb, int type, int format_id, struct path *path); int vfs_quota_on_mount(struct super_block *sb, char *qf_name, int format_id, int type); -int vfs_quota_off(struct super_block *sb, int type, int remount); +int vfs_quota_off(struct super_block *sb, int type); int vfs_quota_sync(struct super_block *sb, int type, int wait); int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); -- cgit v1.2.3-58-ga151 From 123e9caf1e85008ab7eb5f6cd58c44f9a5d73b2b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 May 2010 07:16:44 -0400 Subject: quota: explicitly set ->dq_op and ->s_qcop Only set the quota operation vectors if the filesystem actually supports quota instead of doing it for all filesystems in alloc_super(). [Jan Kara: Export dquot_operations and vfs_quotactl_ops] Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ext2/super.c | 6 ++++++ fs/jfs/super.c | 4 ++++ fs/quota/dquot.c | 3 ++- fs/super.c | 3 --- fs/udf/super.c | 6 +++++- fs/ufs/super.c | 6 +++++- include/linux/quotaops.h | 9 --------- 7 files changed, 22 insertions(+), 15 deletions(-) (limited to 'include/linux') diff --git a/fs/ext2/super.c b/fs/ext2/super.c index b9b77c3e7ae0..df752b71b869 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -1065,6 +1065,12 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) sb->s_op = &ext2_sops; sb->s_export_op = &ext2_export_ops; sb->s_xattr = ext2_xattr_handlers; + +#ifdef CONFIG_QUOTA + sb->dq_op = &dquot_operations; + sb->s_qcop = &vfs_quotactl_ops; +#endif + root = ext2_iget(sb, EXT2_ROOT_INO); if (IS_ERR(root)) { ret = PTR_ERR(root); diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 7d940a3a3d93..2e7ec5e8cda4 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -481,6 +481,10 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) */ sb->s_op = &jfs_super_operations; sb->s_export_op = &jfs_export_operations; +#ifdef CONFIG_QUOTA + sb->dq_op = &dquot_operations; + sb->s_qcop = &vfs_quotactl_ops; +#endif /* * Initialize direct-mapping inode/address-space diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index b84422657f6d..9ba526e3f719 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -1847,6 +1847,7 @@ const struct dquot_operations dquot_operations = { .alloc_dquot = dquot_alloc, .destroy_dquot = dquot_destroy, }; +EXPORT_SYMBOL(dquot_operations); /* * Generic helper for ->open on filesystems supporting disk quotas. @@ -2491,7 +2492,7 @@ const struct quotactl_ops vfs_quotactl_ops = { .get_dqblk = vfs_get_dqblk, .set_dqblk = vfs_set_dqblk }; - +EXPORT_SYMBOL(vfs_quotactl_ops); static int do_proc_dqstats(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) diff --git a/fs/super.c b/fs/super.c index 05f62e5d464d..af9fd02185aa 100644 --- a/fs/super.c +++ b/fs/super.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include /* for the emergency remount stuff */ @@ -94,8 +93,6 @@ static struct super_block *alloc_super(struct file_system_type *type) init_rwsem(&s->s_dquot.dqptr_sem); init_waitqueue_head(&s->s_wait_unfrozen); s->s_maxbytes = MAX_NON_LFS; - s->dq_op = sb_dquot_ops; - s->s_qcop = sb_quotactl_ops; s->s_op = &default_op; s->s_time_gran = 1000000000; } diff --git a/fs/udf/super.c b/fs/udf/super.c index 76a61566f299..ef9221b7456e 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1948,7 +1948,11 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) /* Fill in the rest of the superblock */ sb->s_op = &udf_sb_ops; sb->s_export_op = &udf_export_ops; - sb->dq_op = NULL; +#ifdef CONFIG_QUOTA + sb->s_qcop = &vfs_quotactl_ops; + sb->dq_op = NULL; /* &dquot_operations */ +#endif + sb->s_dirt = 0; sb->s_magic = UDF_SUPER_MAGIC; sb->s_time_gran = 1000; diff --git a/fs/ufs/super.c b/fs/ufs/super.c index d3977c7128e3..60c989b7012f 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1045,7 +1045,11 @@ magic_found: */ sb->s_op = &ufs_super_ops; sb->s_export_op = &ufs_export_ops; - sb->dq_op = NULL; /***/ +#ifdef CONFIG_QUOTA + sb->s_qcop = &vfs_quotactl_ops; + sb->dq_op = NULL; /* &dquot_operations */ +#endif + sb->s_magic = fs32_to_cpu(sb, usb3->fs_magic); uspi->s_sblkno = fs32_to_cpu(sb, usb1->fs_sblkno); diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index a6592ddc349f..84b8dbf59c03 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -153,9 +153,6 @@ static inline unsigned sb_any_quota_active(struct super_block *sb) extern const struct dquot_operations dquot_operations; extern const struct quotactl_ops vfs_quotactl_ops; -#define sb_dquot_ops (&dquot_operations) -#define sb_quotactl_ops (&vfs_quotactl_ops) - #else static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type) @@ -199,12 +196,6 @@ static inline int sb_any_quota_active(struct super_block *sb) return 0; } -/* - * NO-OP when quota not configured. - */ -#define sb_dquot_ops (NULL) -#define sb_quotactl_ops (NULL) - static inline void dquot_initialize(struct inode *inode) { } -- cgit v1.2.3-58-ga151 From 287a80958cf63fc5c68d5bf6e89a3669dd66234a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 19 May 2010 07:16:45 -0400 Subject: quota: rename default quotactl methods to dquot_ Follow the dquot_* style used elsewhere in dquot.c. [Jan Kara: Fixed up missing conversion of ext2] Signed-off-by: Christoph Hellwig Signed-off-by: Jan Kara --- fs/ext2/super.c | 2 +- fs/ext3/super.c | 20 +++++++-------- fs/ext4/super.c | 20 +++++++-------- fs/jfs/super.c | 2 +- fs/ocfs2/super.c | 18 +++++++------- fs/quota/dquot.c | 64 ++++++++++++++++++++++++------------------------ fs/reiserfs/super.c | 20 +++++++-------- fs/udf/super.c | 2 +- fs/ufs/super.c | 2 +- include/linux/quotaops.h | 22 ++++++++--------- 10 files changed, 86 insertions(+), 86 deletions(-) (limited to 'include/linux') diff --git a/fs/ext2/super.c b/fs/ext2/super.c index df752b71b869..7ff43f4a59cd 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -1068,7 +1068,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) #ifdef CONFIG_QUOTA sb->dq_op = &dquot_operations; - sb->s_qcop = &vfs_quotactl_ops; + sb->s_qcop = &dquot_quotactl_ops; #endif root = ext2_iget(sb, EXT2_ROOT_INO); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index e52006737b4b..6c953bb255e7 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -769,12 +769,12 @@ static const struct dquot_operations ext3_quota_operations = { static const struct quotactl_ops ext3_qctl_operations = { .quota_on = ext3_quota_on, - .quota_off = vfs_quota_off, - .quota_sync = vfs_quota_sync, - .get_info = vfs_get_dqinfo, - .set_info = vfs_set_dqinfo, - .get_dqblk = vfs_get_dqblk, - .set_dqblk = vfs_set_dqblk + .quota_off = dquot_quota_off, + .quota_sync = dquot_quota_sync, + .get_info = dquot_get_dqinfo, + .set_info = dquot_set_dqinfo, + .get_dqblk = dquot_get_dqblk, + .set_dqblk = dquot_set_dqblk }; #endif @@ -1529,7 +1529,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, /* Turn quotas off */ for (i = 0; i < MAXQUOTAS; i++) { if (sb_dqopt(sb)->files[i]) - vfs_quota_off(sb, i); + dquot_quota_off(sb, i); } #endif sb->s_flags = s_flags; /* Restore MS_RDONLY status */ @@ -2862,8 +2862,8 @@ static int ext3_write_info(struct super_block *sb, int type) */ static int ext3_quota_on_mount(struct super_block *sb, int type) { - return vfs_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type], - EXT3_SB(sb)->s_jquota_fmt, type); + return dquot_quota_on_mount(sb, EXT3_SB(sb)->s_qf_names[type], + EXT3_SB(sb)->s_jquota_fmt, type); } /* @@ -2914,7 +2914,7 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id, } } - err = vfs_quota_on_path(sb, type, format_id, &path); + err = dquot_quota_on_path(sb, type, format_id, &path); path_put(&path); return err; } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index dfe9bf503f85..381e5a931265 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1083,12 +1083,12 @@ static const struct dquot_operations ext4_quota_operations = { static const struct quotactl_ops ext4_qctl_operations = { .quota_on = ext4_quota_on, - .quota_off = vfs_quota_off, - .quota_sync = vfs_quota_sync, - .get_info = vfs_get_dqinfo, - .set_info = vfs_set_dqinfo, - .get_dqblk = vfs_get_dqblk, - .set_dqblk = vfs_set_dqblk + .quota_off = dquot_quota_off, + .quota_sync = dquot_quota_sync, + .get_info = dquot_get_dqinfo, + .set_info = dquot_set_dqinfo, + .get_dqblk = dquot_get_dqblk, + .set_dqblk = dquot_set_dqblk }; #endif @@ -2053,7 +2053,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, /* Turn quotas off */ for (i = 0; i < MAXQUOTAS; i++) { if (sb_dqopt(sb)->files[i]) - vfs_quota_off(sb, i); + dquot_quota_off(sb, i); } #endif sb->s_flags = s_flags; /* Restore MS_RDONLY status */ @@ -3916,8 +3916,8 @@ static int ext4_write_info(struct super_block *sb, int type) */ static int ext4_quota_on_mount(struct super_block *sb, int type) { - return vfs_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type], - EXT4_SB(sb)->s_jquota_fmt, type); + return dquot_quota_on_mount(sb, EXT4_SB(sb)->s_qf_names[type], + EXT4_SB(sb)->s_jquota_fmt, type); } /* @@ -3969,7 +3969,7 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, } } - err = vfs_quota_on_path(sb, type, format_id, &path); + err = dquot_quota_on_path(sb, type, format_id, &path); path_put(&path); return err; } diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 2e7ec5e8cda4..b38f96bef829 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -483,7 +483,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) sb->s_export_op = &jfs_export_operations; #ifdef CONFIG_QUOTA sb->dq_op = &dquot_operations; - sb->s_qcop = &vfs_quotactl_ops; + sb->s_qcop = &dquot_quotactl_ops; #endif /* diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 5367d6dee395..0eaa929a4dbf 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c @@ -918,8 +918,8 @@ static int ocfs2_enable_quotas(struct ocfs2_super *osb) status = -ENOENT; goto out_quota_off; } - status = vfs_quota_enable(inode[type], type, QFMT_OCFS2, - DQUOT_USAGE_ENABLED); + status = dquot_enable(inode[type], type, QFMT_OCFS2, + DQUOT_USAGE_ENABLED); if (status < 0) goto out_quota_off; } @@ -972,8 +972,8 @@ static int ocfs2_quota_on(struct super_block *sb, int type, int format_id, if (!OCFS2_HAS_RO_COMPAT_FEATURE(sb, feature[type])) return -EINVAL; - return vfs_quota_enable(sb_dqopt(sb)->files[type], type, - format_id, DQUOT_LIMITS_ENABLED); + return dquot_enable(sb_dqopt(sb)->files[type], type, + format_id, DQUOT_LIMITS_ENABLED); } /* Handle quota off quotactl */ @@ -985,11 +985,11 @@ static int ocfs2_quota_off(struct super_block *sb, int type) static const struct quotactl_ops ocfs2_quotactl_ops = { .quota_on = ocfs2_quota_on, .quota_off = ocfs2_quota_off, - .quota_sync = vfs_quota_sync, - .get_info = vfs_get_dqinfo, - .set_info = vfs_set_dqinfo, - .get_dqblk = vfs_get_dqblk, - .set_dqblk = vfs_set_dqblk, + .quota_sync = dquot_quota_sync, + .get_info = dquot_get_dqinfo, + .set_info = dquot_set_dqinfo, + .get_dqblk = dquot_get_dqblk, + .set_dqblk = dquot_set_dqblk, }; static int ocfs2_fill_super(struct super_block *sb, void *data, int silent) diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 9ba526e3f719..1914a2f6c84c 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -584,7 +584,7 @@ out: } EXPORT_SYMBOL(dquot_scan_active); -int vfs_quota_sync(struct super_block *sb, int type, int wait) +int dquot_quota_sync(struct super_block *sb, int type, int wait) { struct list_head *dirty; struct dquot *dquot; @@ -656,7 +656,7 @@ int vfs_quota_sync(struct super_block *sb, int type, int wait) return 0; } -EXPORT_SYMBOL(vfs_quota_sync); +EXPORT_SYMBOL(dquot_quota_sync); /* Free unused dquots from cache */ static void prune_dqcache(int count) @@ -1998,12 +1998,12 @@ put_inodes: } EXPORT_SYMBOL(dquot_disable); -int vfs_quota_off(struct super_block *sb, int type) +int dquot_quota_off(struct super_block *sb, int type) { return dquot_disable(sb, type, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); } -EXPORT_SYMBOL(vfs_quota_off); +EXPORT_SYMBOL(dquot_quota_off); /* * Turn quotas on on a device @@ -2158,7 +2158,7 @@ int dquot_resume(struct super_block *sb, int type) } EXPORT_SYMBOL(dquot_resume); -int vfs_quota_on_path(struct super_block *sb, int type, int format_id, +int dquot_quota_on_path(struct super_block *sb, int type, int format_id, struct path *path) { int error = security_quota_on(path->dentry); @@ -2173,28 +2173,28 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id, DQUOT_LIMITS_ENABLED); return error; } -EXPORT_SYMBOL(vfs_quota_on_path); +EXPORT_SYMBOL(dquot_quota_on_path); -int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name) +int dquot_quota_on(struct super_block *sb, int type, int format_id, char *name) { struct path path; int error; error = kern_path(name, LOOKUP_FOLLOW, &path); if (!error) { - error = vfs_quota_on_path(sb, type, format_id, &path); + error = dquot_quota_on_path(sb, type, format_id, &path); path_put(&path); } return error; } -EXPORT_SYMBOL(vfs_quota_on); +EXPORT_SYMBOL(dquot_quota_on); /* * More powerful function for turning on quotas allowing setting * of individual quota flags */ -int vfs_quota_enable(struct inode *inode, int type, int format_id, - unsigned int flags) +int dquot_enable(struct inode *inode, int type, int format_id, + unsigned int flags) { int ret = 0; struct super_block *sb = inode->i_sb; @@ -2234,13 +2234,13 @@ out_lock: load_quota: return vfs_load_quota_inode(inode, type, format_id, flags); } -EXPORT_SYMBOL(vfs_quota_enable); +EXPORT_SYMBOL(dquot_enable); /* * This function is used when filesystem needs to initialize quotas * during mount time. */ -int vfs_quota_on_mount(struct super_block *sb, char *qf_name, +int dquot_quota_on_mount(struct super_block *sb, char *qf_name, int format_id, int type) { struct dentry *dentry; @@ -2266,7 +2266,7 @@ out: dput(dentry); return error; } -EXPORT_SYMBOL(vfs_quota_on_mount); +EXPORT_SYMBOL(dquot_quota_on_mount); static inline qsize_t qbtos(qsize_t blocks) { @@ -2301,8 +2301,8 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di) spin_unlock(&dq_data_lock); } -int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, - struct fs_disk_quota *di) +int dquot_get_dqblk(struct super_block *sb, int type, qid_t id, + struct fs_disk_quota *di) { struct dquot *dquot; @@ -2314,7 +2314,7 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, return 0; } -EXPORT_SYMBOL(vfs_get_dqblk); +EXPORT_SYMBOL(dquot_get_dqblk); #define VFS_FS_DQ_MASK \ (FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \ @@ -2413,7 +2413,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) return 0; } -int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, +int dquot_set_dqblk(struct super_block *sb, int type, qid_t id, struct fs_disk_quota *di) { struct dquot *dquot; @@ -2429,10 +2429,10 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, out: return rc; } -EXPORT_SYMBOL(vfs_set_dqblk); +EXPORT_SYMBOL(dquot_set_dqblk); /* Generic routine for getting common part of quota file information */ -int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) +int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) { struct mem_dqinfo *mi; @@ -2451,10 +2451,10 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return 0; } -EXPORT_SYMBOL(vfs_get_dqinfo); +EXPORT_SYMBOL(dquot_get_dqinfo); /* Generic routine for setting common part of quota file information */ -int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) +int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) { struct mem_dqinfo *mi; int err = 0; @@ -2481,18 +2481,18 @@ out: mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); return err; } -EXPORT_SYMBOL(vfs_set_dqinfo); +EXPORT_SYMBOL(dquot_set_dqinfo); -const struct quotactl_ops vfs_quotactl_ops = { - .quota_on = vfs_quota_on, - .quota_off = vfs_quota_off, - .quota_sync = vfs_quota_sync, - .get_info = vfs_get_dqinfo, - .set_info = vfs_set_dqinfo, - .get_dqblk = vfs_get_dqblk, - .set_dqblk = vfs_set_dqblk +const struct quotactl_ops dquot_quotactl_ops = { + .quota_on = dquot_quota_on, + .quota_off = dquot_quota_off, + .quota_sync = dquot_quota_sync, + .get_info = dquot_get_dqinfo, + .set_info = dquot_set_dqinfo, + .get_dqblk = dquot_get_dqblk, + .set_dqblk = dquot_set_dqblk }; -EXPORT_SYMBOL(vfs_quotactl_ops); +EXPORT_SYMBOL(dquot_quotactl_ops); static int do_proc_dqstats(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index fa46abd0d958..f0ab5c94139c 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -305,7 +305,7 @@ static int finish_unfinished(struct super_block *s) /* Turn quotas off */ for (i = 0; i < MAXQUOTAS; i++) { if (sb_dqopt(s)->files[i]) - vfs_quota_off(s, i); + dquot_quota_off(s, i); } if (ms_active_set) /* Restore the flag back */ @@ -636,12 +636,12 @@ static const struct dquot_operations reiserfs_quota_operations = { static const struct quotactl_ops reiserfs_qctl_operations = { .quota_on = reiserfs_quota_on, - .quota_off = vfs_quota_off, - .quota_sync = vfs_quota_sync, - .get_info = vfs_get_dqinfo, - .set_info = vfs_set_dqinfo, - .get_dqblk = vfs_get_dqblk, - .set_dqblk = vfs_set_dqblk, + .quota_off = dquot_quota_off, + .quota_sync = dquot_quota_sync, + .get_info = dquot_get_dqinfo, + .set_info = dquot_set_dqinfo, + .get_dqblk = dquot_get_dqblk, + .set_dqblk = dquot_set_dqblk, }; #endif @@ -2030,8 +2030,8 @@ static int reiserfs_write_info(struct super_block *sb, int type) */ static int reiserfs_quota_on_mount(struct super_block *sb, int type) { - return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type], - REISERFS_SB(sb)->s_jquota_fmt, type); + return dquot_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type], + REISERFS_SB(sb)->s_jquota_fmt, type); } /* @@ -2091,7 +2091,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, if (err) goto out; } - err = vfs_quota_on_path(sb, type, format_id, &path); + err = dquot_quota_on_path(sb, type, format_id, &path); out: path_put(&path); return err; diff --git a/fs/udf/super.c b/fs/udf/super.c index ef9221b7456e..5e03592369d7 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c @@ -1949,7 +1949,7 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent) sb->s_op = &udf_sb_ops; sb->s_export_op = &udf_export_ops; #ifdef CONFIG_QUOTA - sb->s_qcop = &vfs_quotactl_ops; + sb->s_qcop = &dquot_quotactl_ops; sb->dq_op = NULL; /* &dquot_operations */ #endif diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 60c989b7012f..2b08a8dd8ec0 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1046,7 +1046,7 @@ magic_found: sb->s_op = &ufs_super_ops; sb->s_export_op = &ufs_export_ops; #ifdef CONFIG_QUOTA - sb->s_qcop = &vfs_quotactl_ops; + sb->s_qcop = &dquot_quotactl_ops; sb->dq_op = NULL; /* &dquot_operations */ #endif diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index 84b8dbf59c03..0c77cd8d2822 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h @@ -66,21 +66,21 @@ int dquot_mark_dquot_dirty(struct dquot *dquot); int dquot_file_open(struct inode *inode, struct file *file); -int vfs_quota_on(struct super_block *sb, int type, int format_id, +int dquot_quota_on(struct super_block *sb, int type, int format_id, char *path); -int vfs_quota_enable(struct inode *inode, int type, int format_id, +int dquot_enable(struct inode *inode, int type, int format_id, unsigned int flags); -int vfs_quota_on_path(struct super_block *sb, int type, int format_id, +int dquot_quota_on_path(struct super_block *sb, int type, int format_id, struct path *path); -int vfs_quota_on_mount(struct super_block *sb, char *qf_name, +int dquot_quota_on_mount(struct super_block *sb, char *qf_name, int format_id, int type); -int vfs_quota_off(struct super_block *sb, int type); -int vfs_quota_sync(struct super_block *sb, int type, int wait); -int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); -int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); -int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, +int dquot_quota_off(struct super_block *sb, int type); +int dquot_quota_sync(struct super_block *sb, int type, int wait); +int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); +int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii); +int dquot_get_dqblk(struct super_block *sb, int type, qid_t id, struct fs_disk_quota *di); -int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, +int dquot_set_dqblk(struct super_block *sb, int type, qid_t id, struct fs_disk_quota *di); int __dquot_transfer(struct inode *inode, struct dquot **transfer_to); @@ -151,7 +151,7 @@ static inline unsigned sb_any_quota_active(struct super_block *sb) * Operations supported for diskquotas. */ extern const struct dquot_operations dquot_operations; -extern const struct quotactl_ops vfs_quotactl_ops; +extern const struct quotactl_ops dquot_quotactl_ops; #else -- cgit v1.2.3-58-ga151 From f32764bd2bbb6ea003c158b1d276b4dc9f900348 Mon Sep 17 00:00:00 2001 From: Dmitry Monakhov Date: Wed, 26 May 2010 23:21:58 +0200 Subject: quota: Convert quota statistics to generic percpu_counter Generic per-cpu counter has some memory overhead but it is negligible for modern systems and embedded systems compile without quota support. And code reuse is a good thing. This patch should fix complain from preemptive kernels which was introduced by dde9588853b1bde. [Jan Kara: Fixed patch to work on 32-bit archs as well] Reported-by: Rafael J. Wysocki Signed-off-by: Dmitry Monakhov Signed-off-by: Jan Kara --- fs/quota/dquot.c | 46 +++++++++++++--------------------------------- include/linux/quota.h | 16 ++++------------ 2 files changed, 17 insertions(+), 45 deletions(-) (limited to 'include/linux') diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 1ff91314b8a0..531dee651ef7 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c @@ -228,10 +228,6 @@ static struct hlist_head *dquot_hash; struct dqstats dqstats; EXPORT_SYMBOL(dqstats); -#ifdef CONFIG_SMP -struct dqstats *dqstats_pcpu; -EXPORT_SYMBOL(dqstats_pcpu); -#endif static qsize_t inode_get_rsv_space(struct inode *inode); static void __dquot_initialize(struct inode *inode, int type); @@ -676,27 +672,10 @@ static void prune_dqcache(int count) } } -static int dqstats_read(unsigned int type) -{ - int count = 0; -#ifdef CONFIG_SMP - int cpu; - for_each_possible_cpu(cpu) - count += per_cpu_ptr(dqstats_pcpu, cpu)->stat[type]; - /* Statistics reading is racy, but absolute accuracy isn't required */ - if (count < 0) - count = 0; -#else - count = dqstats.stat[type]; -#endif - return count; -} - /* * This is called from kswapd when we think we need some * more memory */ - static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) { if (nr) { @@ -704,7 +683,9 @@ static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) prune_dqcache(nr); spin_unlock(&dq_list_lock); } - return (dqstats_read(DQST_FREE_DQUOTS)/100) * sysctl_vfs_cache_pressure; + return ((unsigned) + percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS]) + /100) * sysctl_vfs_cache_pressure; } static struct shrinker dqcache_shrinker = { @@ -2497,11 +2478,11 @@ EXPORT_SYMBOL(dquot_quotactl_ops); static int do_proc_dqstats(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { -#ifdef CONFIG_SMP - /* Update global table */ unsigned int type = (int *)table->data - dqstats.stat; - dqstats.stat[type] = dqstats_read(type); -#endif + + /* Update global table */ + dqstats.stat[type] = + percpu_counter_sum_positive(&dqstats.counter[type]); return proc_dointvec(table, write, buffer, lenp, ppos); } @@ -2594,7 +2575,7 @@ static ctl_table sys_table[] = { static int __init dquot_init(void) { - int i; + int i, ret; unsigned long nr_hash, order; printk(KERN_NOTICE "VFS: Disk quotas %s\n", __DQUOT_VERSION__); @@ -2612,12 +2593,11 @@ static int __init dquot_init(void) if (!dquot_hash) panic("Cannot create dquot hash table"); -#ifdef CONFIG_SMP - dqstats_pcpu = alloc_percpu(struct dqstats); - if (!dqstats_pcpu) - panic("Cannot create dquot stats table"); -#endif - memset(&dqstats, 0, sizeof(struct dqstats)); + for (i = 0; i < _DQST_DQSTAT_LAST; i++) { + ret = percpu_counter_init(&dqstats.counter[i], 0); + if (ret) + panic("Cannot create dquot stat counters"); + } /* Find power-of-two hlist_heads which can fit into allocation */ nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head); diff --git a/include/linux/quota.h b/include/linux/quota.h index 2789d07c37be..94c1f03b50eb 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -174,8 +174,7 @@ enum { #include #include #include -#include -#include +#include #include #include @@ -254,6 +253,7 @@ enum { struct dqstats { int stat[_DQST_DQSTAT_LAST]; + struct percpu_counter counter[_DQST_DQSTAT_LAST]; }; extern struct dqstats *dqstats_pcpu; @@ -261,20 +261,12 @@ extern struct dqstats dqstats; static inline void dqstats_inc(unsigned int type) { -#ifdef CONFIG_SMP - per_cpu_ptr(dqstats_pcpu, smp_processor_id())->stat[type]++; -#else - dqstats.stat[type]++; -#endif + percpu_counter_inc(&dqstats.counter[type]); } static inline void dqstats_dec(unsigned int type) { -#ifdef CONFIG_SMP - per_cpu_ptr(dqstats_pcpu, smp_processor_id())->stat[type]--; -#else - dqstats.stat[type]--; -#endif + percpu_counter_dec(&dqstats.counter[type]); } #define DQ_MOD_B 0 /* dquot modified since read */ -- cgit v1.2.3-58-ga151