diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-30 12:11:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-30 12:11:11 -0400 |
commit | d28619f1563140526e2f84eae436f39206f40a69 (patch) | |
tree | d93284016a0983c8f27b745a3c50738617e50995 /fs/quota | |
parent | 021fad8b706849c091f6e682bc5df3ce4f9ab4d7 (diff) | |
parent | f32764bd2bbb6ea003c158b1d276b4dc9f900348 (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: Convert quota statistics to generic percpu_counter
ext3 uses rb_node = NULL; to zero rb_root.
quota: Fixup dquot_transfer
reiserfs: Fix resuming of quotas on remount read-write
pohmelfs: Remove dead quota code
ufs: Remove dead quota code
udf: Remove dead quota code
quota: rename default quotactl methods to dquot_
quota: explicitly set ->dq_op and ->s_qcop
quota: drop remount argument to ->quota_on and ->quota_off
quota: move unmount handling into the filesystem
quota: kill the vfs_dq_off and vfs_dq_quota_on_remount wrappers
quota: move remount handling into the filesystem
ocfs2: Fix use after free on remount read-only
Fix up conflicts in fs/ext4/super.c and fs/ufs/file.c
Diffstat (limited to 'fs/quota')
-rw-r--r-- | fs/quota/dquot.c | 190 | ||||
-rw-r--r-- | fs/quota/quota.c | 4 |
2 files changed, 81 insertions, 113 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 1ad8bf076cfc..12c233da1b6b 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -228,10 +228,6 @@ static struct hlist_head *dquot_hash; | |||
228 | 228 | ||
229 | struct dqstats dqstats; | 229 | struct dqstats dqstats; |
230 | EXPORT_SYMBOL(dqstats); | 230 | EXPORT_SYMBOL(dqstats); |
231 | #ifdef CONFIG_SMP | ||
232 | struct dqstats *dqstats_pcpu; | ||
233 | EXPORT_SYMBOL(dqstats_pcpu); | ||
234 | #endif | ||
235 | 231 | ||
236 | static qsize_t inode_get_rsv_space(struct inode *inode); | 232 | static qsize_t inode_get_rsv_space(struct inode *inode); |
237 | static void __dquot_initialize(struct inode *inode, int type); | 233 | static void __dquot_initialize(struct inode *inode, int type); |
@@ -584,7 +580,7 @@ out: | |||
584 | } | 580 | } |
585 | EXPORT_SYMBOL(dquot_scan_active); | 581 | EXPORT_SYMBOL(dquot_scan_active); |
586 | 582 | ||
587 | int vfs_quota_sync(struct super_block *sb, int type, int wait) | 583 | int dquot_quota_sync(struct super_block *sb, int type, int wait) |
588 | { | 584 | { |
589 | struct list_head *dirty; | 585 | struct list_head *dirty; |
590 | struct dquot *dquot; | 586 | struct dquot *dquot; |
@@ -656,7 +652,7 @@ int vfs_quota_sync(struct super_block *sb, int type, int wait) | |||
656 | 652 | ||
657 | return 0; | 653 | return 0; |
658 | } | 654 | } |
659 | EXPORT_SYMBOL(vfs_quota_sync); | 655 | EXPORT_SYMBOL(dquot_quota_sync); |
660 | 656 | ||
661 | /* Free unused dquots from cache */ | 657 | /* Free unused dquots from cache */ |
662 | static void prune_dqcache(int count) | 658 | static void prune_dqcache(int count) |
@@ -676,27 +672,10 @@ static void prune_dqcache(int count) | |||
676 | } | 672 | } |
677 | } | 673 | } |
678 | 674 | ||
679 | static int dqstats_read(unsigned int type) | ||
680 | { | ||
681 | int count = 0; | ||
682 | #ifdef CONFIG_SMP | ||
683 | int cpu; | ||
684 | for_each_possible_cpu(cpu) | ||
685 | count += per_cpu_ptr(dqstats_pcpu, cpu)->stat[type]; | ||
686 | /* Statistics reading is racy, but absolute accuracy isn't required */ | ||
687 | if (count < 0) | ||
688 | count = 0; | ||
689 | #else | ||
690 | count = dqstats.stat[type]; | ||
691 | #endif | ||
692 | return count; | ||
693 | } | ||
694 | |||
695 | /* | 675 | /* |
696 | * This is called from kswapd when we think we need some | 676 | * This is called from kswapd when we think we need some |
697 | * more memory | 677 | * more memory |
698 | */ | 678 | */ |
699 | |||
700 | static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) | 679 | static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) |
701 | { | 680 | { |
702 | if (nr) { | 681 | if (nr) { |
@@ -704,7 +683,9 @@ static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) | |||
704 | prune_dqcache(nr); | 683 | prune_dqcache(nr); |
705 | spin_unlock(&dq_list_lock); | 684 | spin_unlock(&dq_list_lock); |
706 | } | 685 | } |
707 | return (dqstats_read(DQST_FREE_DQUOTS)/100) * sysctl_vfs_cache_pressure; | 686 | return ((unsigned) |
687 | percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS]) | ||
688 | /100) * sysctl_vfs_cache_pressure; | ||
708 | } | 689 | } |
709 | 690 | ||
710 | static struct shrinker dqcache_shrinker = { | 691 | static struct shrinker dqcache_shrinker = { |
@@ -1815,7 +1796,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1815 | if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) | 1796 | if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) |
1816 | transfer_to[USRQUOTA] = dqget(sb, iattr->ia_uid, USRQUOTA); | 1797 | transfer_to[USRQUOTA] = dqget(sb, iattr->ia_uid, USRQUOTA); |
1817 | if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) | 1798 | if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) |
1818 | transfer_to[GRPQUOTA] = dqget(sb, iattr->ia_uid, GRPQUOTA); | 1799 | transfer_to[GRPQUOTA] = dqget(sb, iattr->ia_gid, GRPQUOTA); |
1819 | 1800 | ||
1820 | ret = __dquot_transfer(inode, transfer_to); | 1801 | ret = __dquot_transfer(inode, transfer_to); |
1821 | dqput_all(transfer_to); | 1802 | dqput_all(transfer_to); |
@@ -1850,6 +1831,7 @@ const struct dquot_operations dquot_operations = { | |||
1850 | .alloc_dquot = dquot_alloc, | 1831 | .alloc_dquot = dquot_alloc, |
1851 | .destroy_dquot = dquot_destroy, | 1832 | .destroy_dquot = dquot_destroy, |
1852 | }; | 1833 | }; |
1834 | EXPORT_SYMBOL(dquot_operations); | ||
1853 | 1835 | ||
1854 | /* | 1836 | /* |
1855 | * Generic helper for ->open on filesystems supporting disk quotas. | 1837 | * Generic helper for ->open on filesystems supporting disk quotas. |
@@ -1868,7 +1850,7 @@ EXPORT_SYMBOL(dquot_file_open); | |||
1868 | /* | 1850 | /* |
1869 | * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) | 1851 | * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) |
1870 | */ | 1852 | */ |
1871 | int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) | 1853 | int dquot_disable(struct super_block *sb, int type, unsigned int flags) |
1872 | { | 1854 | { |
1873 | int cnt, ret = 0; | 1855 | int cnt, ret = 0; |
1874 | struct quota_info *dqopt = sb_dqopt(sb); | 1856 | struct quota_info *dqopt = sb_dqopt(sb); |
@@ -1998,14 +1980,15 @@ put_inodes: | |||
1998 | } | 1980 | } |
1999 | return ret; | 1981 | return ret; |
2000 | } | 1982 | } |
2001 | EXPORT_SYMBOL(vfs_quota_disable); | 1983 | EXPORT_SYMBOL(dquot_disable); |
2002 | 1984 | ||
2003 | int vfs_quota_off(struct super_block *sb, int type, int remount) | 1985 | int dquot_quota_off(struct super_block *sb, int type) |
2004 | { | 1986 | { |
2005 | return vfs_quota_disable(sb, type, remount ? DQUOT_SUSPENDED : | 1987 | return dquot_disable(sb, type, |
2006 | (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED)); | 1988 | DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); |
2007 | } | 1989 | } |
2008 | EXPORT_SYMBOL(vfs_quota_off); | 1990 | EXPORT_SYMBOL(dquot_quota_off); |
1991 | |||
2009 | /* | 1992 | /* |
2010 | * Turn quotas on on a device | 1993 | * Turn quotas on on a device |
2011 | */ | 1994 | */ |
@@ -2123,36 +2106,43 @@ out_fmt: | |||
2123 | } | 2106 | } |
2124 | 2107 | ||
2125 | /* Reenable quotas on remount RW */ | 2108 | /* Reenable quotas on remount RW */ |
2126 | static int vfs_quota_on_remount(struct super_block *sb, int type) | 2109 | int dquot_resume(struct super_block *sb, int type) |
2127 | { | 2110 | { |
2128 | struct quota_info *dqopt = sb_dqopt(sb); | 2111 | struct quota_info *dqopt = sb_dqopt(sb); |
2129 | struct inode *inode; | 2112 | struct inode *inode; |
2130 | int ret; | 2113 | int ret = 0, cnt; |
2131 | unsigned int flags; | 2114 | unsigned int flags; |
2132 | 2115 | ||
2133 | mutex_lock(&dqopt->dqonoff_mutex); | 2116 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
2134 | if (!sb_has_quota_suspended(sb, type)) { | 2117 | if (type != -1 && cnt != type) |
2118 | continue; | ||
2119 | |||
2120 | mutex_lock(&dqopt->dqonoff_mutex); | ||
2121 | if (!sb_has_quota_suspended(sb, cnt)) { | ||
2122 | mutex_unlock(&dqopt->dqonoff_mutex); | ||
2123 | continue; | ||
2124 | } | ||
2125 | inode = dqopt->files[cnt]; | ||
2126 | dqopt->files[cnt] = NULL; | ||
2127 | spin_lock(&dq_state_lock); | ||
2128 | flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED | | ||
2129 | DQUOT_LIMITS_ENABLED, | ||
2130 | cnt); | ||
2131 | dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, cnt); | ||
2132 | spin_unlock(&dq_state_lock); | ||
2135 | mutex_unlock(&dqopt->dqonoff_mutex); | 2133 | mutex_unlock(&dqopt->dqonoff_mutex); |
2136 | return 0; | ||
2137 | } | ||
2138 | inode = dqopt->files[type]; | ||
2139 | dqopt->files[type] = NULL; | ||
2140 | spin_lock(&dq_state_lock); | ||
2141 | flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED | | ||
2142 | DQUOT_LIMITS_ENABLED, type); | ||
2143 | dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, type); | ||
2144 | spin_unlock(&dq_state_lock); | ||
2145 | mutex_unlock(&dqopt->dqonoff_mutex); | ||
2146 | 2134 | ||
2147 | flags = dquot_generic_flag(flags, type); | 2135 | flags = dquot_generic_flag(flags, cnt); |
2148 | ret = vfs_load_quota_inode(inode, type, dqopt->info[type].dqi_fmt_id, | 2136 | ret = vfs_load_quota_inode(inode, cnt, |
2149 | flags); | 2137 | dqopt->info[cnt].dqi_fmt_id, flags); |
2150 | iput(inode); | 2138 | iput(inode); |
2139 | } | ||
2151 | 2140 | ||
2152 | return ret; | 2141 | return ret; |
2153 | } | 2142 | } |
2143 | EXPORT_SYMBOL(dquot_resume); | ||
2154 | 2144 | ||
2155 | int vfs_quota_on_path(struct super_block *sb, int type, int format_id, | 2145 | int dquot_quota_on_path(struct super_block *sb, int type, int format_id, |
2156 | struct path *path) | 2146 | struct path *path) |
2157 | { | 2147 | { |
2158 | int error = security_quota_on(path->dentry); | 2148 | int error = security_quota_on(path->dentry); |
@@ -2167,40 +2157,36 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id, | |||
2167 | DQUOT_LIMITS_ENABLED); | 2157 | DQUOT_LIMITS_ENABLED); |
2168 | return error; | 2158 | return error; |
2169 | } | 2159 | } |
2170 | EXPORT_SYMBOL(vfs_quota_on_path); | 2160 | EXPORT_SYMBOL(dquot_quota_on_path); |
2171 | 2161 | ||
2172 | int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, | 2162 | int dquot_quota_on(struct super_block *sb, int type, int format_id, char *name) |
2173 | int remount) | ||
2174 | { | 2163 | { |
2175 | struct path path; | 2164 | struct path path; |
2176 | int error; | 2165 | int error; |
2177 | 2166 | ||
2178 | if (remount) | ||
2179 | return vfs_quota_on_remount(sb, type); | ||
2180 | |||
2181 | error = kern_path(name, LOOKUP_FOLLOW, &path); | 2167 | error = kern_path(name, LOOKUP_FOLLOW, &path); |
2182 | if (!error) { | 2168 | if (!error) { |
2183 | error = vfs_quota_on_path(sb, type, format_id, &path); | 2169 | error = dquot_quota_on_path(sb, type, format_id, &path); |
2184 | path_put(&path); | 2170 | path_put(&path); |
2185 | } | 2171 | } |
2186 | return error; | 2172 | return error; |
2187 | } | 2173 | } |
2188 | EXPORT_SYMBOL(vfs_quota_on); | 2174 | EXPORT_SYMBOL(dquot_quota_on); |
2189 | 2175 | ||
2190 | /* | 2176 | /* |
2191 | * More powerful function for turning on quotas allowing setting | 2177 | * More powerful function for turning on quotas allowing setting |
2192 | * of individual quota flags | 2178 | * of individual quota flags |
2193 | */ | 2179 | */ |
2194 | int vfs_quota_enable(struct inode *inode, int type, int format_id, | 2180 | int dquot_enable(struct inode *inode, int type, int format_id, |
2195 | unsigned int flags) | 2181 | unsigned int flags) |
2196 | { | 2182 | { |
2197 | int ret = 0; | 2183 | int ret = 0; |
2198 | struct super_block *sb = inode->i_sb; | 2184 | struct super_block *sb = inode->i_sb; |
2199 | struct quota_info *dqopt = sb_dqopt(sb); | 2185 | struct quota_info *dqopt = sb_dqopt(sb); |
2200 | 2186 | ||
2201 | /* Just unsuspend quotas? */ | 2187 | /* Just unsuspend quotas? */ |
2202 | if (flags & DQUOT_SUSPENDED) | 2188 | BUG_ON(flags & DQUOT_SUSPENDED); |
2203 | return vfs_quota_on_remount(sb, type); | 2189 | |
2204 | if (!flags) | 2190 | if (!flags) |
2205 | return 0; | 2191 | return 0; |
2206 | /* Just updating flags needed? */ | 2192 | /* Just updating flags needed? */ |
@@ -2232,13 +2218,13 @@ out_lock: | |||
2232 | load_quota: | 2218 | load_quota: |
2233 | return vfs_load_quota_inode(inode, type, format_id, flags); | 2219 | return vfs_load_quota_inode(inode, type, format_id, flags); |
2234 | } | 2220 | } |
2235 | EXPORT_SYMBOL(vfs_quota_enable); | 2221 | EXPORT_SYMBOL(dquot_enable); |
2236 | 2222 | ||
2237 | /* | 2223 | /* |
2238 | * This function is used when filesystem needs to initialize quotas | 2224 | * This function is used when filesystem needs to initialize quotas |
2239 | * during mount time. | 2225 | * during mount time. |
2240 | */ | 2226 | */ |
2241 | int vfs_quota_on_mount(struct super_block *sb, char *qf_name, | 2227 | int dquot_quota_on_mount(struct super_block *sb, char *qf_name, |
2242 | int format_id, int type) | 2228 | int format_id, int type) |
2243 | { | 2229 | { |
2244 | struct dentry *dentry; | 2230 | struct dentry *dentry; |
@@ -2264,24 +2250,7 @@ out: | |||
2264 | dput(dentry); | 2250 | dput(dentry); |
2265 | return error; | 2251 | return error; |
2266 | } | 2252 | } |
2267 | EXPORT_SYMBOL(vfs_quota_on_mount); | 2253 | EXPORT_SYMBOL(dquot_quota_on_mount); |
2268 | |||
2269 | /* Wrapper to turn on quotas when remounting rw */ | ||
2270 | int vfs_dq_quota_on_remount(struct super_block *sb) | ||
2271 | { | ||
2272 | int cnt; | ||
2273 | int ret = 0, err; | ||
2274 | |||
2275 | if (!sb->s_qcop || !sb->s_qcop->quota_on) | ||
2276 | return -ENOSYS; | ||
2277 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
2278 | err = sb->s_qcop->quota_on(sb, cnt, 0, NULL, 1); | ||
2279 | if (err < 0 && !ret) | ||
2280 | ret = err; | ||
2281 | } | ||
2282 | return ret; | ||
2283 | } | ||
2284 | EXPORT_SYMBOL(vfs_dq_quota_on_remount); | ||
2285 | 2254 | ||
2286 | static inline qsize_t qbtos(qsize_t blocks) | 2255 | static inline qsize_t qbtos(qsize_t blocks) |
2287 | { | 2256 | { |
@@ -2316,8 +2285,8 @@ static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2316 | spin_unlock(&dq_data_lock); | 2285 | spin_unlock(&dq_data_lock); |
2317 | } | 2286 | } |
2318 | 2287 | ||
2319 | int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, | 2288 | int dquot_get_dqblk(struct super_block *sb, int type, qid_t id, |
2320 | struct fs_disk_quota *di) | 2289 | struct fs_disk_quota *di) |
2321 | { | 2290 | { |
2322 | struct dquot *dquot; | 2291 | struct dquot *dquot; |
2323 | 2292 | ||
@@ -2329,7 +2298,7 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, | |||
2329 | 2298 | ||
2330 | return 0; | 2299 | return 0; |
2331 | } | 2300 | } |
2332 | EXPORT_SYMBOL(vfs_get_dqblk); | 2301 | EXPORT_SYMBOL(dquot_get_dqblk); |
2333 | 2302 | ||
2334 | #define VFS_FS_DQ_MASK \ | 2303 | #define VFS_FS_DQ_MASK \ |
2335 | (FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \ | 2304 | (FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \ |
@@ -2428,7 +2397,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2428 | return 0; | 2397 | return 0; |
2429 | } | 2398 | } |
2430 | 2399 | ||
2431 | int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, | 2400 | int dquot_set_dqblk(struct super_block *sb, int type, qid_t id, |
2432 | struct fs_disk_quota *di) | 2401 | struct fs_disk_quota *di) |
2433 | { | 2402 | { |
2434 | struct dquot *dquot; | 2403 | struct dquot *dquot; |
@@ -2444,10 +2413,10 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
2444 | out: | 2413 | out: |
2445 | return rc; | 2414 | return rc; |
2446 | } | 2415 | } |
2447 | EXPORT_SYMBOL(vfs_set_dqblk); | 2416 | EXPORT_SYMBOL(dquot_set_dqblk); |
2448 | 2417 | ||
2449 | /* Generic routine for getting common part of quota file information */ | 2418 | /* Generic routine for getting common part of quota file information */ |
2450 | int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | 2419 | int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) |
2451 | { | 2420 | { |
2452 | struct mem_dqinfo *mi; | 2421 | struct mem_dqinfo *mi; |
2453 | 2422 | ||
@@ -2466,10 +2435,10 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
2466 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2435 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
2467 | return 0; | 2436 | return 0; |
2468 | } | 2437 | } |
2469 | EXPORT_SYMBOL(vfs_get_dqinfo); | 2438 | EXPORT_SYMBOL(dquot_get_dqinfo); |
2470 | 2439 | ||
2471 | /* Generic routine for setting common part of quota file information */ | 2440 | /* Generic routine for setting common part of quota file information */ |
2472 | int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | 2441 | int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) |
2473 | { | 2442 | { |
2474 | struct mem_dqinfo *mi; | 2443 | struct mem_dqinfo *mi; |
2475 | int err = 0; | 2444 | int err = 0; |
@@ -2496,27 +2465,27 @@ out: | |||
2496 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2465 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
2497 | return err; | 2466 | return err; |
2498 | } | 2467 | } |
2499 | EXPORT_SYMBOL(vfs_set_dqinfo); | 2468 | EXPORT_SYMBOL(dquot_set_dqinfo); |
2500 | 2469 | ||
2501 | const struct quotactl_ops vfs_quotactl_ops = { | 2470 | const struct quotactl_ops dquot_quotactl_ops = { |
2502 | .quota_on = vfs_quota_on, | 2471 | .quota_on = dquot_quota_on, |
2503 | .quota_off = vfs_quota_off, | 2472 | .quota_off = dquot_quota_off, |
2504 | .quota_sync = vfs_quota_sync, | 2473 | .quota_sync = dquot_quota_sync, |
2505 | .get_info = vfs_get_dqinfo, | 2474 | .get_info = dquot_get_dqinfo, |
2506 | .set_info = vfs_set_dqinfo, | 2475 | .set_info = dquot_set_dqinfo, |
2507 | .get_dqblk = vfs_get_dqblk, | 2476 | .get_dqblk = dquot_get_dqblk, |
2508 | .set_dqblk = vfs_set_dqblk | 2477 | .set_dqblk = dquot_set_dqblk |
2509 | }; | 2478 | }; |
2510 | 2479 | EXPORT_SYMBOL(dquot_quotactl_ops); | |
2511 | 2480 | ||
2512 | static int do_proc_dqstats(struct ctl_table *table, int write, | 2481 | static int do_proc_dqstats(struct ctl_table *table, int write, |
2513 | void __user *buffer, size_t *lenp, loff_t *ppos) | 2482 | void __user *buffer, size_t *lenp, loff_t *ppos) |
2514 | { | 2483 | { |
2515 | #ifdef CONFIG_SMP | ||
2516 | /* Update global table */ | ||
2517 | unsigned int type = (int *)table->data - dqstats.stat; | 2484 | unsigned int type = (int *)table->data - dqstats.stat; |
2518 | dqstats.stat[type] = dqstats_read(type); | 2485 | |
2519 | #endif | 2486 | /* Update global table */ |
2487 | dqstats.stat[type] = | ||
2488 | percpu_counter_sum_positive(&dqstats.counter[type]); | ||
2520 | return proc_dointvec(table, write, buffer, lenp, ppos); | 2489 | return proc_dointvec(table, write, buffer, lenp, ppos); |
2521 | } | 2490 | } |
2522 | 2491 | ||
@@ -2609,7 +2578,7 @@ static ctl_table sys_table[] = { | |||
2609 | 2578 | ||
2610 | static int __init dquot_init(void) | 2579 | static int __init dquot_init(void) |
2611 | { | 2580 | { |
2612 | int i; | 2581 | int i, ret; |
2613 | unsigned long nr_hash, order; | 2582 | unsigned long nr_hash, order; |
2614 | 2583 | ||
2615 | printk(KERN_NOTICE "VFS: Disk quotas %s\n", __DQUOT_VERSION__); | 2584 | printk(KERN_NOTICE "VFS: Disk quotas %s\n", __DQUOT_VERSION__); |
@@ -2627,12 +2596,11 @@ static int __init dquot_init(void) | |||
2627 | if (!dquot_hash) | 2596 | if (!dquot_hash) |
2628 | panic("Cannot create dquot hash table"); | 2597 | panic("Cannot create dquot hash table"); |
2629 | 2598 | ||
2630 | #ifdef CONFIG_SMP | 2599 | for (i = 0; i < _DQST_DQSTAT_LAST; i++) { |
2631 | dqstats_pcpu = alloc_percpu(struct dqstats); | 2600 | ret = percpu_counter_init(&dqstats.counter[i], 0); |
2632 | if (!dqstats_pcpu) | 2601 | if (ret) |
2633 | panic("Cannot create dquot stats table"); | 2602 | panic("Cannot create dquot stat counters"); |
2634 | #endif | 2603 | } |
2635 | memset(&dqstats, 0, sizeof(struct dqstats)); | ||
2636 | 2604 | ||
2637 | /* Find power-of-two hlist_heads which can fit into allocation */ | 2605 | /* Find power-of-two hlist_heads which can fit into allocation */ |
2638 | nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head); | 2606 | nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head); |
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, | |||
73 | if (IS_ERR(pathname)) | 73 | if (IS_ERR(pathname)) |
74 | return PTR_ERR(pathname); | 74 | return PTR_ERR(pathname); |
75 | if (sb->s_qcop->quota_on) | 75 | if (sb->s_qcop->quota_on) |
76 | ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0); | 76 | ret = sb->s_qcop->quota_on(sb, type, id, pathname); |
77 | putname(pathname); | 77 | putname(pathname); |
78 | return ret; | 78 | return ret; |
79 | } | 79 | } |
@@ -260,7 +260,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, | |||
260 | case Q_QUOTAOFF: | 260 | case Q_QUOTAOFF: |
261 | if (!sb->s_qcop->quota_off) | 261 | if (!sb->s_qcop->quota_off) |
262 | return -ENOSYS; | 262 | return -ENOSYS; |
263 | return sb->s_qcop->quota_off(sb, type, 0); | 263 | return sb->s_qcop->quota_off(sb, type); |
264 | case Q_GETFMT: | 264 | case Q_GETFMT: |
265 | return quota_getfmt(sb, type, addr); | 265 | return quota_getfmt(sb, type, addr); |
266 | case Q_GETINFO: | 266 | case Q_GETINFO: |