aboutsummaryrefslogtreecommitdiffstats
path: root/fs/quota/dquot.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/quota/dquot.c')
-rw-r--r--fs/quota/dquot.c190
1 files changed, 79 insertions, 111 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
229struct dqstats dqstats; 229struct dqstats dqstats;
230EXPORT_SYMBOL(dqstats); 230EXPORT_SYMBOL(dqstats);
231#ifdef CONFIG_SMP
232struct dqstats *dqstats_pcpu;
233EXPORT_SYMBOL(dqstats_pcpu);
234#endif
235 231
236static qsize_t inode_get_rsv_space(struct inode *inode); 232static qsize_t inode_get_rsv_space(struct inode *inode);
237static void __dquot_initialize(struct inode *inode, int type); 233static void __dquot_initialize(struct inode *inode, int type);
@@ -584,7 +580,7 @@ out:
584} 580}
585EXPORT_SYMBOL(dquot_scan_active); 581EXPORT_SYMBOL(dquot_scan_active);
586 582
587int vfs_quota_sync(struct super_block *sb, int type, int wait) 583int 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}
659EXPORT_SYMBOL(vfs_quota_sync); 655EXPORT_SYMBOL(dquot_quota_sync);
660 656
661/* Free unused dquots from cache */ 657/* Free unused dquots from cache */
662static void prune_dqcache(int count) 658static void prune_dqcache(int count)
@@ -676,27 +672,10 @@ static void prune_dqcache(int count)
676 } 672 }
677} 673}
678 674
679static 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
700static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) 679static 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
710static struct shrinker dqcache_shrinker = { 691static 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};
1834EXPORT_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 */
1871int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) 1853int 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}
2001EXPORT_SYMBOL(vfs_quota_disable); 1983EXPORT_SYMBOL(dquot_disable);
2002 1984
2003int vfs_quota_off(struct super_block *sb, int type, int remount) 1985int 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}
2008EXPORT_SYMBOL(vfs_quota_off); 1990EXPORT_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 */
2126static int vfs_quota_on_remount(struct super_block *sb, int type) 2109int 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}
2143EXPORT_SYMBOL(dquot_resume);
2154 2144
2155int vfs_quota_on_path(struct super_block *sb, int type, int format_id, 2145int 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}
2170EXPORT_SYMBOL(vfs_quota_on_path); 2160EXPORT_SYMBOL(dquot_quota_on_path);
2171 2161
2172int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, 2162int 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}
2188EXPORT_SYMBOL(vfs_quota_on); 2174EXPORT_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 */
2194int vfs_quota_enable(struct inode *inode, int type, int format_id, 2180int 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:
2232load_quota: 2218load_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}
2235EXPORT_SYMBOL(vfs_quota_enable); 2221EXPORT_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 */
2241int vfs_quota_on_mount(struct super_block *sb, char *qf_name, 2227int 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}
2267EXPORT_SYMBOL(vfs_quota_on_mount); 2253EXPORT_SYMBOL(dquot_quota_on_mount);
2268
2269/* Wrapper to turn on quotas when remounting rw */
2270int 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}
2284EXPORT_SYMBOL(vfs_dq_quota_on_remount);
2285 2254
2286static inline qsize_t qbtos(qsize_t blocks) 2255static 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
2319int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, 2288int 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}
2332EXPORT_SYMBOL(vfs_get_dqblk); 2301EXPORT_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
2431int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, 2400int 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,
2444out: 2413out:
2445 return rc; 2414 return rc;
2446} 2415}
2447EXPORT_SYMBOL(vfs_set_dqblk); 2416EXPORT_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 */
2450int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) 2419int 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}
2469EXPORT_SYMBOL(vfs_get_dqinfo); 2438EXPORT_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 */
2472int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) 2441int 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}
2499EXPORT_SYMBOL(vfs_set_dqinfo); 2468EXPORT_SYMBOL(dquot_set_dqinfo);
2500 2469
2501const struct quotactl_ops vfs_quotactl_ops = { 2470const 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 2479EXPORT_SYMBOL(dquot_quotactl_ops);
2511 2480
2512static int do_proc_dqstats(struct ctl_table *table, int write, 2481static 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
2610static int __init dquot_init(void) 2579static 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);