forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/fs/quota/dquot.c
....@@ -9,7 +9,7 @@
99 * on the Melbourne quota system as used on BSD derived systems. The internal
1010 * implementation is based on one of the several variants of the LINUX
1111 * inode-subsystem with added complexity of the diskquota system.
12
- *
12
+ *
1313 * Author: Marco van Wieringen <mvw@planets.elm.net>
1414 *
1515 * Fixes: Dmitry Gorodchanin <pgmdsg@ibi.com>, 11 Feb 96
....@@ -51,7 +51,7 @@
5151 * Added journalled quota support, fix lock inversion problems
5252 * Jan Kara, <jack@suse.cz>, 2003,2004
5353 *
54
- * (C) Copyright 1994 - 1997 Marco van Wieringen
54
+ * (C) Copyright 1994 - 1997 Marco van Wieringen
5555 */
5656
5757 #include <linux/errno.h>
....@@ -78,6 +78,8 @@
7878 #include <linux/namei.h>
7979 #include <linux/capability.h>
8080 #include <linux/quotaops.h>
81
+#include <linux/blkdev.h>
82
+#include <linux/sched/mm.h>
8183 #include "../internal.h" /* ugh */
8284
8385 #include <linux/uaccess.h>
....@@ -197,7 +199,7 @@
197199 int qm;
198200
199201 spin_unlock(&dq_list_lock);
200
-
202
+
201203 for (qm = 0; module_names[qm].qm_fmt_id &&
202204 module_names[qm].qm_fmt_id != id; qm++)
203205 ;
....@@ -223,9 +225,9 @@
223225
224226 /*
225227 * Dquot List Management:
226
- * The quota code uses three lists for dquot management: the inuse_list,
227
- * free_dquots, and dquot_hash[] array. A single dquot structure may be
228
- * on all three lists, depending on its current state.
228
+ * The quota code uses four lists for dquot management: the inuse_list,
229
+ * free_dquots, dqi_dirty_list, and dquot_hash[] array. A single dquot
230
+ * structure may be on some of those lists, depending on its current state.
229231 *
230232 * All dquots are placed to the end of inuse_list when first created, and this
231233 * list is used for invalidate operation, which must look at every dquot.
....@@ -235,6 +237,11 @@
235237 * removed from the list as soon as they are used again, and
236238 * dqstats.free_dquots gives the number of dquots on the list. When
237239 * dquot is invalidated it's completely released from memory.
240
+ *
241
+ * Dirty dquots are added to the dqi_dirty_list of quota_info when mark
242
+ * dirtied, and this list is searched when writing dirty dquots back to
243
+ * quota file. Note that some filesystems do dirty dquot tracking on their
244
+ * own (e.g. in a journal) and thus don't use dqi_dirty_list.
238245 *
239246 * Dquots with a specific identity (device, type and id) are placed on
240247 * one of the dquot_hash[] hash chains. The provides an efficient search
....@@ -421,13 +428,16 @@
421428 int dquot_acquire(struct dquot *dquot)
422429 {
423430 int ret = 0, ret2 = 0;
431
+ unsigned int memalloc;
424432 struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
425433
426434 mutex_lock(&dquot->dq_lock);
427
- if (!test_bit(DQ_READ_B, &dquot->dq_flags))
435
+ memalloc = memalloc_nofs_save();
436
+ if (!test_bit(DQ_READ_B, &dquot->dq_flags)) {
428437 ret = dqopt->ops[dquot->dq_id.type]->read_dqblk(dquot);
429
- if (ret < 0)
430
- goto out_iolock;
438
+ if (ret < 0)
439
+ goto out_iolock;
440
+ }
431441 /* Make sure flags update is visible after dquot has been filled */
432442 smp_mb__before_atomic();
433443 set_bit(DQ_READ_B, &dquot->dq_flags);
....@@ -453,6 +463,7 @@
453463 smp_mb__before_atomic();
454464 set_bit(DQ_ACTIVE_B, &dquot->dq_flags);
455465 out_iolock:
466
+ memalloc_nofs_restore(memalloc);
456467 mutex_unlock(&dquot->dq_lock);
457468 return ret;
458469 }
....@@ -464,9 +475,11 @@
464475 int dquot_commit(struct dquot *dquot)
465476 {
466477 int ret = 0;
478
+ unsigned int memalloc;
467479 struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
468480
469481 mutex_lock(&dquot->dq_lock);
482
+ memalloc = memalloc_nofs_save();
470483 if (!clear_dquot_dirty(dquot))
471484 goto out_lock;
472485 /* Inactive dquot can be only if there was error during read/init
....@@ -476,6 +489,7 @@
476489 else
477490 ret = -EIO;
478491 out_lock:
492
+ memalloc_nofs_restore(memalloc);
479493 mutex_unlock(&dquot->dq_lock);
480494 return ret;
481495 }
....@@ -487,9 +501,11 @@
487501 int dquot_release(struct dquot *dquot)
488502 {
489503 int ret = 0, ret2 = 0;
504
+ unsigned int memalloc;
490505 struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
491506
492507 mutex_lock(&dquot->dq_lock);
508
+ memalloc = memalloc_nofs_save();
493509 /* Check whether we are not racing with some other dqget() */
494510 if (dquot_is_busy(dquot))
495511 goto out_dqlock;
....@@ -505,6 +521,7 @@
505521 }
506522 clear_bit(DQ_ACTIVE_B, &dquot->dq_flags);
507523 out_dqlock:
524
+ memalloc_nofs_restore(memalloc);
508525 mutex_unlock(&dquot->dq_lock);
509526 return ret;
510527 }
....@@ -589,7 +606,6 @@
589606 /* Now we have active dquot so we can just increase use count */
590607 atomic_inc(&dquot->dq_count);
591608 spin_unlock(&dq_list_lock);
592
- dqstats_inc(DQST_LOOKUPS);
593609 dqput(old_dquot);
594610 old_dquot = dquot;
595611 /*
....@@ -644,7 +660,6 @@
644660 * use count */
645661 dqgrab(dquot);
646662 spin_unlock(&dq_list_lock);
647
- dqstats_inc(DQST_LOOKUPS);
648663 err = sb->dq_op->write_dquot(dquot);
649664 if (err) {
650665 /*
....@@ -1056,7 +1071,9 @@
10561071 struct list_head *tofree_head)
10571072 {
10581073 struct inode *inode;
1074
+#ifdef CONFIG_QUOTA_DEBUG
10591075 int reserved = 0;
1076
+#endif
10601077
10611078 spin_lock(&sb->s_inode_list_lock);
10621079 list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
....@@ -1068,8 +1085,10 @@
10681085 */
10691086 spin_lock(&dq_data_lock);
10701087 if (!IS_NOQUOTA(inode)) {
1088
+#ifdef CONFIG_QUOTA_DEBUG
10711089 if (unlikely(inode_get_rsv_space(inode) > 0))
10721090 reserved = 1;
1091
+#endif
10731092 remove_inode_dquot_ref(inode, type, tofree_head);
10741093 }
10751094 spin_unlock(&dq_data_lock);
....@@ -1670,7 +1689,7 @@
16701689 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
16711690 if (!dquots[cnt])
16721691 continue;
1673
- if (flags & DQUOT_SPACE_RESERVE) {
1692
+ if (reserve) {
16741693 ret = dquot_add_space(dquots[cnt], 0, number, flags,
16751694 &warn[cnt]);
16761695 } else {
....@@ -1683,13 +1702,11 @@
16831702 if (!dquots[cnt])
16841703 continue;
16851704 spin_lock(&dquots[cnt]->dq_dqb_lock);
1686
- if (flags & DQUOT_SPACE_RESERVE) {
1687
- dquots[cnt]->dq_dqb.dqb_rsvspace -=
1688
- number;
1689
- } else {
1690
- dquots[cnt]->dq_dqb.dqb_curspace -=
1691
- number;
1692
- }
1705
+ if (reserve)
1706
+ dquot_free_reserved_space(dquots[cnt],
1707
+ number);
1708
+ else
1709
+ dquot_decr_space(dquots[cnt], number);
16931710 spin_unlock(&dquots[cnt]->dq_dqb_lock);
16941711 }
16951712 spin_unlock(&inode->i_lock);
....@@ -1740,7 +1757,7 @@
17401757 continue;
17411758 /* Back out changes we already did */
17421759 spin_lock(&dquots[cnt]->dq_dqb_lock);
1743
- dquots[cnt]->dq_dqb.dqb_curinodes--;
1760
+ dquot_decr_inodes(dquots[cnt], 1);
17441761 spin_unlock(&dquots[cnt]->dq_dqb_lock);
17451762 }
17461763 goto warn_put_all;
....@@ -2161,14 +2178,29 @@
21612178 }
21622179 EXPORT_SYMBOL(dquot_file_open);
21632180
2181
+static void vfs_cleanup_quota_inode(struct super_block *sb, int type)
2182
+{
2183
+ struct quota_info *dqopt = sb_dqopt(sb);
2184
+ struct inode *inode = dqopt->files[type];
2185
+
2186
+ if (!inode)
2187
+ return;
2188
+ if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
2189
+ inode_lock(inode);
2190
+ inode->i_flags &= ~S_NOQUOTA;
2191
+ inode_unlock(inode);
2192
+ }
2193
+ dqopt->files[type] = NULL;
2194
+ iput(inode);
2195
+}
2196
+
21642197 /*
21652198 * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
21662199 */
21672200 int dquot_disable(struct super_block *sb, int type, unsigned int flags)
21682201 {
2169
- int cnt, ret = 0;
2202
+ int cnt;
21702203 struct quota_info *dqopt = sb_dqopt(sb);
2171
- struct inode *toputinode[MAXQUOTAS];
21722204
21732205 /* s_umount should be held in exclusive mode */
21742206 if (WARN_ON_ONCE(down_read_trylock(&sb->s_umount)))
....@@ -2190,7 +2222,6 @@
21902222 return 0;
21912223
21922224 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
2193
- toputinode[cnt] = NULL;
21942225 if (type != -1 && cnt != type)
21952226 continue;
21962227 if (!sb_has_quota_loaded(sb, cnt))
....@@ -2210,8 +2241,7 @@
22102241 dqopt->flags &= ~dquot_state_flag(
22112242 DQUOT_SUSPENDED, cnt);
22122243 spin_unlock(&dq_state_lock);
2213
- iput(dqopt->files[cnt]);
2214
- dqopt->files[cnt] = NULL;
2244
+ vfs_cleanup_quota_inode(sb, cnt);
22152245 continue;
22162246 }
22172247 spin_unlock(&dq_state_lock);
....@@ -2233,10 +2263,6 @@
22332263 if (dqopt->ops[cnt]->free_file_info)
22342264 dqopt->ops[cnt]->free_file_info(sb, cnt);
22352265 put_quota_format(dqopt->info[cnt].dqi_format);
2236
-
2237
- toputinode[cnt] = dqopt->files[cnt];
2238
- if (!sb_has_quota_loaded(sb, cnt))
2239
- dqopt->files[cnt] = NULL;
22402266 dqopt->info[cnt].dqi_flags = 0;
22412267 dqopt->info[cnt].dqi_igrace = 0;
22422268 dqopt->info[cnt].dqi_bgrace = 0;
....@@ -2258,32 +2284,22 @@
22582284 * must also discard the blockdev buffers so that we see the
22592285 * changes done by userspace on the next quotaon() */
22602286 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
2261
- /* This can happen when suspending quotas on remount-ro... */
2262
- if (toputinode[cnt] && !sb_has_quota_loaded(sb, cnt)) {
2263
- inode_lock(toputinode[cnt]);
2264
- toputinode[cnt]->i_flags &= ~S_NOQUOTA;
2265
- truncate_inode_pages(&toputinode[cnt]->i_data, 0);
2266
- inode_unlock(toputinode[cnt]);
2267
- mark_inode_dirty_sync(toputinode[cnt]);
2287
+ if (!sb_has_quota_loaded(sb, cnt) && dqopt->files[cnt]) {
2288
+ inode_lock(dqopt->files[cnt]);
2289
+ truncate_inode_pages(&dqopt->files[cnt]->i_data, 0);
2290
+ inode_unlock(dqopt->files[cnt]);
22682291 }
22692292 if (sb->s_bdev)
22702293 invalidate_bdev(sb->s_bdev);
22712294 put_inodes:
2295
+ /* We are done when suspending quotas */
2296
+ if (flags & DQUOT_SUSPENDED)
2297
+ return 0;
2298
+
22722299 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
2273
- if (toputinode[cnt]) {
2274
- /* On remount RO, we keep the inode pointer so that we
2275
- * can reenable quota on the subsequent remount RW. We
2276
- * have to check 'flags' variable and not use sb_has_
2277
- * function because another quotaon / quotaoff could
2278
- * change global state before we got here. We refuse
2279
- * to suspend quotas when there is pending delete on
2280
- * the quota file... */
2281
- if (!(flags & DQUOT_SUSPENDED))
2282
- iput(toputinode[cnt]);
2283
- else if (!toputinode[cnt]->i_nlink)
2284
- ret = -EBUSY;
2285
- }
2286
- return ret;
2300
+ if (!sb_has_quota_loaded(sb, cnt))
2301
+ vfs_cleanup_quota_inode(sb, cnt);
2302
+ return 0;
22872303 }
22882304 EXPORT_SYMBOL(dquot_disable);
22892305
....@@ -2298,28 +2314,52 @@
22982314 * Turn quotas on on a device
22992315 */
23002316
2301
-/*
2302
- * Helper function to turn quotas on when we already have the inode of
2303
- * quota file and no quota information is loaded.
2304
- */
2305
-static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
2317
+static int vfs_setup_quota_inode(struct inode *inode, int type)
2318
+{
2319
+ struct super_block *sb = inode->i_sb;
2320
+ struct quota_info *dqopt = sb_dqopt(sb);
2321
+
2322
+ if (!S_ISREG(inode->i_mode))
2323
+ return -EACCES;
2324
+ if (IS_RDONLY(inode))
2325
+ return -EROFS;
2326
+ if (sb_has_quota_loaded(sb, type))
2327
+ return -EBUSY;
2328
+
2329
+ dqopt->files[type] = igrab(inode);
2330
+ if (!dqopt->files[type])
2331
+ return -EIO;
2332
+ if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
2333
+ /* We don't want quota and atime on quota files (deadlocks
2334
+ * possible) Also nobody should write to the file - we use
2335
+ * special IO operations which ignore the immutable bit. */
2336
+ inode_lock(inode);
2337
+ inode->i_flags |= S_NOQUOTA;
2338
+ inode_unlock(inode);
2339
+ /*
2340
+ * When S_NOQUOTA is set, remove dquot references as no more
2341
+ * references can be added
2342
+ */
2343
+ __dquot_drop(inode);
2344
+ }
2345
+ return 0;
2346
+}
2347
+
2348
+int dquot_load_quota_sb(struct super_block *sb, int type, int format_id,
23062349 unsigned int flags)
23072350 {
23082351 struct quota_format_type *fmt = find_quota_format(format_id);
2309
- struct super_block *sb = inode->i_sb;
23102352 struct quota_info *dqopt = sb_dqopt(sb);
23112353 int error;
23122354
2355
+ /* Just unsuspend quotas? */
2356
+ BUG_ON(flags & DQUOT_SUSPENDED);
2357
+ /* s_umount should be held in exclusive mode */
2358
+ if (WARN_ON_ONCE(down_read_trylock(&sb->s_umount)))
2359
+ up_read(&sb->s_umount);
2360
+
23132361 if (!fmt)
23142362 return -ESRCH;
2315
- if (!S_ISREG(inode->i_mode)) {
2316
- error = -EACCES;
2317
- goto out_fmt;
2318
- }
2319
- if (IS_RDONLY(inode)) {
2320
- error = -EROFS;
2321
- goto out_fmt;
2322
- }
23232363 if (!sb->s_op->quota_write || !sb->s_op->quota_read ||
23242364 (type == PRJQUOTA && sb->dq_op->get_projid == NULL)) {
23252365 error = -EINVAL;
....@@ -2351,27 +2391,9 @@
23512391 invalidate_bdev(sb->s_bdev);
23522392 }
23532393
2354
- if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
2355
- /* We don't want quota and atime on quota files (deadlocks
2356
- * possible) Also nobody should write to the file - we use
2357
- * special IO operations which ignore the immutable bit. */
2358
- inode_lock(inode);
2359
- inode->i_flags |= S_NOQUOTA;
2360
- inode_unlock(inode);
2361
- /*
2362
- * When S_NOQUOTA is set, remove dquot references as no more
2363
- * references can be added
2364
- */
2365
- __dquot_drop(inode);
2366
- }
2367
-
2368
- error = -EIO;
2369
- dqopt->files[type] = igrab(inode);
2370
- if (!dqopt->files[type])
2371
- goto out_file_flags;
23722394 error = -EINVAL;
23732395 if (!fmt->qf_ops->check_quota_file(sb, type))
2374
- goto out_file_init;
2396
+ goto out_fmt;
23752397
23762398 dqopt->ops[type] = fmt->qf_ops;
23772399 dqopt->info[type].dqi_format = fmt;
....@@ -2379,7 +2401,7 @@
23792401 INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
23802402 error = dqopt->ops[type]->read_file_info(sb, type);
23812403 if (error < 0)
2382
- goto out_file_init;
2404
+ goto out_fmt;
23832405 if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) {
23842406 spin_lock(&dq_data_lock);
23852407 dqopt->info[type].dqi_flags |= DQF_SYS_FILE;
....@@ -2394,24 +2416,36 @@
23942416 dquot_disable(sb, type, flags);
23952417
23962418 return error;
2397
-out_file_init:
2398
- dqopt->files[type] = NULL;
2399
- iput(inode);
2400
-out_file_flags:
2401
- inode_lock(inode);
2402
- inode->i_flags &= ~S_NOQUOTA;
2403
- inode_unlock(inode);
24042419 out_fmt:
24052420 put_quota_format(fmt);
24062421
2407
- return error;
2422
+ return error;
24082423 }
2424
+EXPORT_SYMBOL(dquot_load_quota_sb);
2425
+
2426
+/*
2427
+ * More powerful function for turning on quotas on given quota inode allowing
2428
+ * setting of individual quota flags
2429
+ */
2430
+int dquot_load_quota_inode(struct inode *inode, int type, int format_id,
2431
+ unsigned int flags)
2432
+{
2433
+ int err;
2434
+
2435
+ err = vfs_setup_quota_inode(inode, type);
2436
+ if (err < 0)
2437
+ return err;
2438
+ err = dquot_load_quota_sb(inode->i_sb, type, format_id, flags);
2439
+ if (err < 0)
2440
+ vfs_cleanup_quota_inode(inode->i_sb, type);
2441
+ return err;
2442
+}
2443
+EXPORT_SYMBOL(dquot_load_quota_inode);
24092444
24102445 /* Reenable quotas on remount RW */
24112446 int dquot_resume(struct super_block *sb, int type)
24122447 {
24132448 struct quota_info *dqopt = sb_dqopt(sb);
2414
- struct inode *inode;
24152449 int ret = 0, cnt;
24162450 unsigned int flags;
24172451
....@@ -2425,8 +2459,6 @@
24252459 if (!sb_has_quota_suspended(sb, cnt))
24262460 continue;
24272461
2428
- inode = dqopt->files[cnt];
2429
- dqopt->files[cnt] = NULL;
24302462 spin_lock(&dq_state_lock);
24312463 flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED |
24322464 DQUOT_LIMITS_ENABLED,
....@@ -2435,9 +2467,10 @@
24352467 spin_unlock(&dq_state_lock);
24362468
24372469 flags = dquot_generic_flag(flags, cnt);
2438
- ret = vfs_load_quota_inode(inode, cnt,
2439
- dqopt->info[cnt].dqi_fmt_id, flags);
2440
- iput(inode);
2470
+ ret = dquot_load_quota_sb(sb, cnt, dqopt->info[cnt].dqi_fmt_id,
2471
+ flags);
2472
+ if (ret < 0)
2473
+ vfs_cleanup_quota_inode(sb, cnt);
24412474 }
24422475
24432476 return ret;
....@@ -2454,47 +2487,12 @@
24542487 if (path->dentry->d_sb != sb)
24552488 error = -EXDEV;
24562489 else
2457
- error = vfs_load_quota_inode(d_inode(path->dentry), type,
2490
+ error = dquot_load_quota_inode(d_inode(path->dentry), type,
24582491 format_id, DQUOT_USAGE_ENABLED |
24592492 DQUOT_LIMITS_ENABLED);
24602493 return error;
24612494 }
24622495 EXPORT_SYMBOL(dquot_quota_on);
2463
-
2464
-/*
2465
- * More powerful function for turning on quotas allowing setting
2466
- * of individual quota flags
2467
- */
2468
-int dquot_enable(struct inode *inode, int type, int format_id,
2469
- unsigned int flags)
2470
-{
2471
- struct super_block *sb = inode->i_sb;
2472
-
2473
- /* Just unsuspend quotas? */
2474
- BUG_ON(flags & DQUOT_SUSPENDED);
2475
- /* s_umount should be held in exclusive mode */
2476
- if (WARN_ON_ONCE(down_read_trylock(&sb->s_umount)))
2477
- up_read(&sb->s_umount);
2478
-
2479
- if (!flags)
2480
- return 0;
2481
- /* Just updating flags needed? */
2482
- if (sb_has_quota_loaded(sb, type)) {
2483
- if (flags & DQUOT_USAGE_ENABLED &&
2484
- sb_has_quota_usage_enabled(sb, type))
2485
- return -EBUSY;
2486
- if (flags & DQUOT_LIMITS_ENABLED &&
2487
- sb_has_quota_limits_enabled(sb, type))
2488
- return -EBUSY;
2489
- spin_lock(&dq_state_lock);
2490
- sb_dqopt(sb)->flags |= dquot_state_flag(flags, type);
2491
- spin_unlock(&dq_state_lock);
2492
- return 0;
2493
- }
2494
-
2495
- return vfs_load_quota_inode(inode, type, format_id, flags);
2496
-}
2497
-EXPORT_SYMBOL(dquot_enable);
24982496
24992497 /*
25002498 * This function is used when filesystem needs to initialize quotas
....@@ -2506,21 +2504,15 @@
25062504 struct dentry *dentry;
25072505 int error;
25082506
2509
- dentry = lookup_one_len_unlocked(qf_name, sb->s_root, strlen(qf_name));
2507
+ dentry = lookup_positive_unlocked(qf_name, sb->s_root, strlen(qf_name));
25102508 if (IS_ERR(dentry))
25112509 return PTR_ERR(dentry);
25122510
2513
- if (d_really_is_negative(dentry)) {
2514
- error = -ENOENT;
2515
- goto out;
2516
- }
2517
-
25182511 error = security_quota_on(dentry);
25192512 if (!error)
2520
- error = vfs_load_quota_inode(d_inode(dentry), type, format_id,
2513
+ error = dquot_load_quota_inode(d_inode(dentry), type, format_id,
25212514 DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
25222515
2523
-out:
25242516 dput(dentry);
25252517 return error;
25262518 }
....@@ -2542,13 +2534,17 @@
25422534 if (!(flags & qtype_enforce_flag(type)))
25432535 continue;
25442536 /* Can't enforce without accounting */
2545
- if (!sb_has_quota_usage_enabled(sb, type))
2546
- return -EINVAL;
2547
- ret = dquot_enable(dqopt->files[type], type,
2548
- dqopt->info[type].dqi_fmt_id,
2549
- DQUOT_LIMITS_ENABLED);
2550
- if (ret < 0)
2537
+ if (!sb_has_quota_usage_enabled(sb, type)) {
2538
+ ret = -EINVAL;
25512539 goto out_err;
2540
+ }
2541
+ if (sb_has_quota_limits_enabled(sb, type)) {
2542
+ ret = -EBUSY;
2543
+ goto out_err;
2544
+ }
2545
+ spin_lock(&dq_state_lock);
2546
+ dqopt->flags |= dquot_state_flag(DQUOT_LIMITS_ENABLED, type);
2547
+ spin_unlock(&dq_state_lock);
25522548 }
25532549 return 0;
25542550 out_err:
....@@ -2598,10 +2594,12 @@
25982594 out_err:
25992595 /* Backout enforcement disabling we already did */
26002596 for (type--; type >= 0; type--) {
2601
- if (flags & qtype_enforce_flag(type))
2602
- dquot_enable(dqopt->files[type], type,
2603
- dqopt->info[type].dqi_fmt_id,
2604
- DQUOT_LIMITS_ENABLED);
2597
+ if (flags & qtype_enforce_flag(type)) {
2598
+ spin_lock(&dq_state_lock);
2599
+ dqopt->flags |=
2600
+ dquot_state_flag(DQUOT_LIMITS_ENABLED, type);
2601
+ spin_unlock(&dq_state_lock);
2602
+ }
26052603 }
26062604 return ret;
26072605 }
....@@ -2730,7 +2728,7 @@
27302728
27312729 if (check_blim) {
27322730 if (!dm->dqb_bsoftlimit ||
2733
- dm->dqb_curspace + dm->dqb_rsvspace < dm->dqb_bsoftlimit) {
2731
+ dm->dqb_curspace + dm->dqb_rsvspace <= dm->dqb_bsoftlimit) {
27342732 dm->dqb_btime = 0;
27352733 clear_bit(DQ_BLKS_B, &dquot->dq_flags);
27362734 } else if (!(di->d_fieldmask & QC_SPC_TIMER))
....@@ -2739,7 +2737,7 @@
27392737 }
27402738 if (check_ilim) {
27412739 if (!dm->dqb_isoftlimit ||
2742
- dm->dqb_curinodes < dm->dqb_isoftlimit) {
2740
+ dm->dqb_curinodes <= dm->dqb_isoftlimit) {
27432741 dm->dqb_itime = 0;
27442742 clear_bit(DQ_INODES_B, &dquot->dq_flags);
27452743 } else if (!(di->d_fieldmask & QC_INO_TIMER))
....@@ -2782,7 +2780,7 @@
27822780 struct qc_type_state *tstate;
27832781 struct quota_info *dqopt = sb_dqopt(sb);
27842782 int type;
2785
-
2783
+
27862784 memset(state, 0, sizeof(*state));
27872785 for (type = 0; type < MAXQUOTAS; type++) {
27882786 if (!sb_has_quota_active(sb, type))
....@@ -2799,8 +2797,10 @@
27992797 tstate->flags |= QCI_LIMITS_ENFORCED;
28002798 tstate->spc_timelimit = mi->dqi_bgrace;
28012799 tstate->ino_timelimit = mi->dqi_igrace;
2802
- tstate->ino = dqopt->files[type]->i_ino;
2803
- tstate->blocks = dqopt->files[type]->i_blocks;
2800
+ if (dqopt->files[type]) {
2801
+ tstate->ino = dqopt->files[type]->i_ino;
2802
+ tstate->blocks = dqopt->files[type]->i_blocks;
2803
+ }
28042804 tstate->nextents = 1; /* We don't know... */
28052805 spin_unlock(&dq_data_lock);
28062806 }
....@@ -2857,7 +2857,7 @@
28572857 EXPORT_SYMBOL(dquot_quotactl_sysfile_ops);
28582858
28592859 static int do_proc_dqstats(struct ctl_table *table, int write,
2860
- void __user *buffer, size_t *lenp, loff_t *ppos)
2860
+ void *buffer, size_t *lenp, loff_t *ppos)
28612861 {
28622862 unsigned int type = (unsigned long *)table->data - dqstats.stat;
28632863 s64 value = percpu_counter_sum(&dqstats.counter[type]);
....@@ -2987,11 +2987,7 @@
29872987
29882988 /* Find power-of-two hlist_heads which can fit into allocation */
29892989 nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head);
2990
- dq_hash_bits = 0;
2991
- do {
2992
- dq_hash_bits++;
2993
- } while (nr_hash >> dq_hash_bits);
2994
- dq_hash_bits--;
2990
+ dq_hash_bits = ilog2(nr_hash);
29952991
29962992 nr_hash = 1UL << dq_hash_bits;
29972993 dq_hash_mask = nr_hash - 1;