diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-07 18:19:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-07 18:19:35 -0400 |
commit | ae8ac6b7dbfd67f883050421fd195c153d02f5f3 (patch) | |
tree | 162db451c57aa9be511aeb704f7a4301e3ea2225 | |
parent | 460352c2f18e18accc993a9127a03e903ed8e0ed (diff) | |
parent | 6c83fd5142c68294acb0e857b7bac2ce8a5077f7 (diff) |
Merge branch 'quota_scaling' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull quota scaling updates from Jan Kara:
"This contains changes to make the quota subsystem more scalable.
Reportedly it improves number of files created per second on ext4
filesystem on fast storage by about a factor of 2x"
* 'quota_scaling' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: (28 commits)
quota: Add lock annotations to struct members
quota: Reduce contention on dq_data_lock
fs: Provide __inode_get_bytes()
quota: Inline dquot_[re]claim_reserved_space() into callsite
quota: Inline inode_{incr,decr}_space() into callsites
quota: Inline functions into their callsites
ext4: Disable dirty list tracking of dquots when journalling quotas
quota: Allow disabling tracking of dirty dquots in a list
quota: Remove dq_wait_unused from dquot
quota: Move locking into clear_dquot_dirty()
quota: Do not dirty bad dquots
quota: Fix possible corruption of dqi_flags
quota: Propagate ->quota_read errors from v2_read_file_info()
quota: Fix error codes in v2_read_file_info()
quota: Push dqio_sem down to ->read_file_info()
quota: Push dqio_sem down to ->write_file_info()
quota: Push dqio_sem down to ->get_next_id()
quota: Push dqio_sem down to ->release_dqblk()
quota: Remove locking for writing to the old quota format
quota: Do not acquire dqio_sem for dquot overwrites in v2 format
...
-rw-r--r-- | fs/ext4/super.c | 26 | ||||
-rw-r--r-- | fs/ocfs2/quota_global.c | 36 | ||||
-rw-r--r-- | fs/ocfs2/quota_local.c | 17 | ||||
-rw-r--r-- | fs/quota/dquot.c | 504 | ||||
-rw-r--r-- | fs/quota/quota_tree.c | 10 | ||||
-rw-r--r-- | fs/quota/quota_v1.c | 11 | ||||
-rw-r--r-- | fs/quota/quota_v2.c | 95 | ||||
-rw-r--r-- | fs/stat.c | 2 | ||||
-rw-r--r-- | fs/super.c | 2 | ||||
-rw-r--r-- | include/linux/fs.h | 4 | ||||
-rw-r--r-- | include/linux/quota.h | 31 | ||||
-rw-r--r-- | include/linux/quotaops.h | 5 |
12 files changed, 413 insertions, 330 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index c9e7be58756b..93aece6891f2 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -5215,7 +5215,7 @@ static int ext4_statfs_project(struct super_block *sb, | |||
5215 | dquot = dqget(sb, qid); | 5215 | dquot = dqget(sb, qid); |
5216 | if (IS_ERR(dquot)) | 5216 | if (IS_ERR(dquot)) |
5217 | return PTR_ERR(dquot); | 5217 | return PTR_ERR(dquot); |
5218 | spin_lock(&dq_data_lock); | 5218 | spin_lock(&dquot->dq_dqb_lock); |
5219 | 5219 | ||
5220 | limit = (dquot->dq_dqb.dqb_bsoftlimit ? | 5220 | limit = (dquot->dq_dqb.dqb_bsoftlimit ? |
5221 | dquot->dq_dqb.dqb_bsoftlimit : | 5221 | dquot->dq_dqb.dqb_bsoftlimit : |
@@ -5238,7 +5238,7 @@ static int ext4_statfs_project(struct super_block *sb, | |||
5238 | (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0; | 5238 | (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0; |
5239 | } | 5239 | } |
5240 | 5240 | ||
5241 | spin_unlock(&dq_data_lock); | 5241 | spin_unlock(&dquot->dq_dqb_lock); |
5242 | dqput(dquot); | 5242 | dqput(dquot); |
5243 | return 0; | 5243 | return 0; |
5244 | } | 5244 | } |
@@ -5284,18 +5284,13 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
5284 | return 0; | 5284 | return 0; |
5285 | } | 5285 | } |
5286 | 5286 | ||
5287 | /* Helper function for writing quotas on sync - we need to start transaction | ||
5288 | * before quota file is locked for write. Otherwise the are possible deadlocks: | ||
5289 | * Process 1 Process 2 | ||
5290 | * ext4_create() quota_sync() | ||
5291 | * jbd2_journal_start() write_dquot() | ||
5292 | * dquot_initialize() down(dqio_mutex) | ||
5293 | * down(dqio_mutex) jbd2_journal_start() | ||
5294 | * | ||
5295 | */ | ||
5296 | 5287 | ||
5297 | #ifdef CONFIG_QUOTA | 5288 | #ifdef CONFIG_QUOTA |
5298 | 5289 | ||
5290 | /* | ||
5291 | * Helper functions so that transaction is started before we acquire dqio_sem | ||
5292 | * to keep correct lock ordering of transaction > dqio_sem | ||
5293 | */ | ||
5299 | static inline struct inode *dquot_to_inode(struct dquot *dquot) | 5294 | static inline struct inode *dquot_to_inode(struct dquot *dquot) |
5300 | { | 5295 | { |
5301 | return sb_dqopt(dquot->dq_sb)->files[dquot->dq_id.type]; | 5296 | return sb_dqopt(dquot->dq_sb)->files[dquot->dq_id.type]; |
@@ -5430,6 +5425,13 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
5430 | ext4_msg(sb, KERN_WARNING, | 5425 | ext4_msg(sb, KERN_WARNING, |
5431 | "Quota file not on filesystem root. " | 5426 | "Quota file not on filesystem root. " |
5432 | "Journaled quota will not work"); | 5427 | "Journaled quota will not work"); |
5428 | sb_dqopt(sb)->flags |= DQUOT_NOLIST_DIRTY; | ||
5429 | } else { | ||
5430 | /* | ||
5431 | * Clear the flag just in case mount options changed since | ||
5432 | * last time. | ||
5433 | */ | ||
5434 | sb_dqopt(sb)->flags &= ~DQUOT_NOLIST_DIRTY; | ||
5433 | } | 5435 | } |
5434 | 5436 | ||
5435 | /* | 5437 | /* |
@@ -5526,7 +5528,7 @@ static int ext4_enable_quotas(struct super_block *sb) | |||
5526 | test_opt(sb, PRJQUOTA), | 5528 | test_opt(sb, PRJQUOTA), |
5527 | }; | 5529 | }; |
5528 | 5530 | ||
5529 | sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE; | 5531 | sb_dqopt(sb)->flags |= DQUOT_QUOTA_SYS_FILE | DQUOT_NOLIST_DIRTY; |
5530 | for (type = 0; type < EXT4_MAXQUOTAS; type++) { | 5532 | for (type = 0; type < EXT4_MAXQUOTAS; type++) { |
5531 | if (qf_inums[type]) { | 5533 | if (qf_inums[type]) { |
5532 | err = ext4_quota_enable(sb, type, QFMT_VFS_V1, | 5534 | err = ext4_quota_enable(sb, type, QFMT_VFS_V1, |
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index cec495a921e3..c94b6baaa551 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
@@ -33,7 +33,7 @@ | |||
33 | * Locking of quotas with OCFS2 is rather complex. Here are rules that | 33 | * Locking of quotas with OCFS2 is rather complex. Here are rules that |
34 | * should be obeyed by all the functions: | 34 | * should be obeyed by all the functions: |
35 | * - any write of quota structure (either to local or global file) is protected | 35 | * - any write of quota structure (either to local or global file) is protected |
36 | * by dqio_mutex or dquot->dq_lock. | 36 | * by dqio_sem or dquot->dq_lock. |
37 | * - any modification of global quota file holds inode cluster lock, i_mutex, | 37 | * - any modification of global quota file holds inode cluster lock, i_mutex, |
38 | * and ip_alloc_sem of the global quota file (achieved by | 38 | * and ip_alloc_sem of the global quota file (achieved by |
39 | * ocfs2_lock_global_qf). It also has to hold qinfo_lock. | 39 | * ocfs2_lock_global_qf). It also has to hold qinfo_lock. |
@@ -42,9 +42,9 @@ | |||
42 | * | 42 | * |
43 | * A rough sketch of locking dependencies (lf = local file, gf = global file): | 43 | * A rough sketch of locking dependencies (lf = local file, gf = global file): |
44 | * Normal filesystem operation: | 44 | * Normal filesystem operation: |
45 | * start_trans -> dqio_mutex -> write to lf | 45 | * start_trans -> dqio_sem -> write to lf |
46 | * Syncing of local and global file: | 46 | * Syncing of local and global file: |
47 | * ocfs2_lock_global_qf -> start_trans -> dqio_mutex -> qinfo_lock -> | 47 | * ocfs2_lock_global_qf -> start_trans -> dqio_sem -> qinfo_lock -> |
48 | * write to gf | 48 | * write to gf |
49 | * -> write to lf | 49 | * -> write to lf |
50 | * Acquire dquot for the first time: | 50 | * Acquire dquot for the first time: |
@@ -60,7 +60,7 @@ | |||
60 | * Recovery: | 60 | * Recovery: |
61 | * inode cluster lock of recovered lf | 61 | * inode cluster lock of recovered lf |
62 | * -> read bitmaps -> ip_alloc_sem of lf | 62 | * -> read bitmaps -> ip_alloc_sem of lf |
63 | * -> ocfs2_lock_global_qf -> start_trans -> dqio_mutex -> qinfo_lock -> | 63 | * -> ocfs2_lock_global_qf -> start_trans -> dqio_sem -> qinfo_lock -> |
64 | * write to gf | 64 | * write to gf |
65 | */ | 65 | */ |
66 | 66 | ||
@@ -443,13 +443,17 @@ static int __ocfs2_global_write_info(struct super_block *sb, int type) | |||
443 | int ocfs2_global_write_info(struct super_block *sb, int type) | 443 | int ocfs2_global_write_info(struct super_block *sb, int type) |
444 | { | 444 | { |
445 | int err; | 445 | int err; |
446 | struct ocfs2_mem_dqinfo *info = sb_dqinfo(sb, type)->dqi_priv; | 446 | struct quota_info *dqopt = sb_dqopt(sb); |
447 | struct ocfs2_mem_dqinfo *info = dqopt->info[type].dqi_priv; | ||
447 | 448 | ||
449 | down_write(&dqopt->dqio_sem); | ||
448 | err = ocfs2_qinfo_lock(info, 1); | 450 | err = ocfs2_qinfo_lock(info, 1); |
449 | if (err < 0) | 451 | if (err < 0) |
450 | return err; | 452 | goto out_sem; |
451 | err = __ocfs2_global_write_info(sb, type); | 453 | err = __ocfs2_global_write_info(sb, type); |
452 | ocfs2_qinfo_unlock(info, 1); | 454 | ocfs2_qinfo_unlock(info, 1); |
455 | out_sem: | ||
456 | up_write(&dqopt->dqio_sem); | ||
453 | return err; | 457 | return err; |
454 | } | 458 | } |
455 | 459 | ||
@@ -500,7 +504,7 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing) | |||
500 | /* Update space and inode usage. Get also other information from | 504 | /* Update space and inode usage. Get also other information from |
501 | * global quota file so that we don't overwrite any changes there. | 505 | * global quota file so that we don't overwrite any changes there. |
502 | * We are */ | 506 | * We are */ |
503 | spin_lock(&dq_data_lock); | 507 | spin_lock(&dquot->dq_dqb_lock); |
504 | spacechange = dquot->dq_dqb.dqb_curspace - | 508 | spacechange = dquot->dq_dqb.dqb_curspace - |
505 | OCFS2_DQUOT(dquot)->dq_origspace; | 509 | OCFS2_DQUOT(dquot)->dq_origspace; |
506 | inodechange = dquot->dq_dqb.dqb_curinodes - | 510 | inodechange = dquot->dq_dqb.dqb_curinodes - |
@@ -556,7 +560,7 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing) | |||
556 | __clear_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); | 560 | __clear_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); |
557 | OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace; | 561 | OCFS2_DQUOT(dquot)->dq_origspace = dquot->dq_dqb.dqb_curspace; |
558 | OCFS2_DQUOT(dquot)->dq_originodes = dquot->dq_dqb.dqb_curinodes; | 562 | OCFS2_DQUOT(dquot)->dq_originodes = dquot->dq_dqb.dqb_curinodes; |
559 | spin_unlock(&dq_data_lock); | 563 | spin_unlock(&dquot->dq_dqb_lock); |
560 | err = ocfs2_qinfo_lock(info, freeing); | 564 | err = ocfs2_qinfo_lock(info, freeing); |
561 | if (err < 0) { | 565 | if (err < 0) { |
562 | mlog(ML_ERROR, "Failed to lock quota info, losing quota write" | 566 | mlog(ML_ERROR, "Failed to lock quota info, losing quota write" |
@@ -611,7 +615,7 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type) | |||
611 | mlog_errno(status); | 615 | mlog_errno(status); |
612 | goto out_ilock; | 616 | goto out_ilock; |
613 | } | 617 | } |
614 | mutex_lock(&sb_dqopt(sb)->dqio_mutex); | 618 | down_write(&sb_dqopt(sb)->dqio_sem); |
615 | status = ocfs2_sync_dquot(dquot); | 619 | status = ocfs2_sync_dquot(dquot); |
616 | if (status < 0) | 620 | if (status < 0) |
617 | mlog_errno(status); | 621 | mlog_errno(status); |
@@ -619,7 +623,7 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type) | |||
619 | status = ocfs2_local_write_dquot(dquot); | 623 | status = ocfs2_local_write_dquot(dquot); |
620 | if (status < 0) | 624 | if (status < 0) |
621 | mlog_errno(status); | 625 | mlog_errno(status); |
622 | mutex_unlock(&sb_dqopt(sb)->dqio_mutex); | 626 | up_write(&sb_dqopt(sb)->dqio_sem); |
623 | ocfs2_commit_trans(osb, handle); | 627 | ocfs2_commit_trans(osb, handle); |
624 | out_ilock: | 628 | out_ilock: |
625 | ocfs2_unlock_global_qf(oinfo, 1); | 629 | ocfs2_unlock_global_qf(oinfo, 1); |
@@ -666,9 +670,9 @@ static int ocfs2_write_dquot(struct dquot *dquot) | |||
666 | mlog_errno(status); | 670 | mlog_errno(status); |
667 | goto out; | 671 | goto out; |
668 | } | 672 | } |
669 | mutex_lock(&sb_dqopt(dquot->dq_sb)->dqio_mutex); | 673 | down_write(&sb_dqopt(dquot->dq_sb)->dqio_sem); |
670 | status = ocfs2_local_write_dquot(dquot); | 674 | status = ocfs2_local_write_dquot(dquot); |
671 | mutex_unlock(&sb_dqopt(dquot->dq_sb)->dqio_mutex); | 675 | up_write(&sb_dqopt(dquot->dq_sb)->dqio_sem); |
672 | ocfs2_commit_trans(osb, handle); | 676 | ocfs2_commit_trans(osb, handle); |
673 | out: | 677 | out: |
674 | return status; | 678 | return status; |
@@ -920,10 +924,10 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) | |||
920 | 924 | ||
921 | /* In case user set some limits, sync dquot immediately to global | 925 | /* In case user set some limits, sync dquot immediately to global |
922 | * quota file so that information propagates quicker */ | 926 | * quota file so that information propagates quicker */ |
923 | spin_lock(&dq_data_lock); | 927 | spin_lock(&dquot->dq_dqb_lock); |
924 | if (dquot->dq_flags & mask) | 928 | if (dquot->dq_flags & mask) |
925 | sync = 1; | 929 | sync = 1; |
926 | spin_unlock(&dq_data_lock); | 930 | spin_unlock(&dquot->dq_dqb_lock); |
927 | /* This is a slight hack but we can't afford getting global quota | 931 | /* This is a slight hack but we can't afford getting global quota |
928 | * lock if we already have a transaction started. */ | 932 | * lock if we already have a transaction started. */ |
929 | if (!sync || journal_current_handle()) { | 933 | if (!sync || journal_current_handle()) { |
@@ -939,7 +943,7 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) | |||
939 | mlog_errno(status); | 943 | mlog_errno(status); |
940 | goto out_ilock; | 944 | goto out_ilock; |
941 | } | 945 | } |
942 | mutex_lock(&sb_dqopt(sb)->dqio_mutex); | 946 | down_write(&sb_dqopt(sb)->dqio_sem); |
943 | status = ocfs2_sync_dquot(dquot); | 947 | status = ocfs2_sync_dquot(dquot); |
944 | if (status < 0) { | 948 | if (status < 0) { |
945 | mlog_errno(status); | 949 | mlog_errno(status); |
@@ -948,7 +952,7 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) | |||
948 | /* Now write updated local dquot structure */ | 952 | /* Now write updated local dquot structure */ |
949 | status = ocfs2_local_write_dquot(dquot); | 953 | status = ocfs2_local_write_dquot(dquot); |
950 | out_dlock: | 954 | out_dlock: |
951 | mutex_unlock(&sb_dqopt(sb)->dqio_mutex); | 955 | up_write(&sb_dqopt(sb)->dqio_sem); |
952 | ocfs2_commit_trans(osb, handle); | 956 | ocfs2_commit_trans(osb, handle); |
953 | out_ilock: | 957 | out_ilock: |
954 | ocfs2_unlock_global_qf(oinfo, 1); | 958 | ocfs2_unlock_global_qf(oinfo, 1); |
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c index 32c5a40c1257..aa700fd10610 100644 --- a/fs/ocfs2/quota_local.c +++ b/fs/ocfs2/quota_local.c | |||
@@ -520,8 +520,8 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode, | |||
520 | mlog_errno(status); | 520 | mlog_errno(status); |
521 | goto out_drop_lock; | 521 | goto out_drop_lock; |
522 | } | 522 | } |
523 | mutex_lock(&sb_dqopt(sb)->dqio_mutex); | 523 | down_write(&sb_dqopt(sb)->dqio_sem); |
524 | spin_lock(&dq_data_lock); | 524 | spin_lock(&dquot->dq_dqb_lock); |
525 | /* Add usage from quota entry into quota changes | 525 | /* Add usage from quota entry into quota changes |
526 | * of our node. Auxiliary variables are important | 526 | * of our node. Auxiliary variables are important |
527 | * due to signedness */ | 527 | * due to signedness */ |
@@ -529,7 +529,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode, | |||
529 | inodechange = le64_to_cpu(dqblk->dqb_inodemod); | 529 | inodechange = le64_to_cpu(dqblk->dqb_inodemod); |
530 | dquot->dq_dqb.dqb_curspace += spacechange; | 530 | dquot->dq_dqb.dqb_curspace += spacechange; |
531 | dquot->dq_dqb.dqb_curinodes += inodechange; | 531 | dquot->dq_dqb.dqb_curinodes += inodechange; |
532 | spin_unlock(&dq_data_lock); | 532 | spin_unlock(&dquot->dq_dqb_lock); |
533 | /* We want to drop reference held by the crashed | 533 | /* We want to drop reference held by the crashed |
534 | * node. Since we have our own reference we know | 534 | * node. Since we have our own reference we know |
535 | * global structure actually won't be freed. */ | 535 | * global structure actually won't be freed. */ |
@@ -553,7 +553,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode, | |||
553 | unlock_buffer(qbh); | 553 | unlock_buffer(qbh); |
554 | ocfs2_journal_dirty(handle, qbh); | 554 | ocfs2_journal_dirty(handle, qbh); |
555 | out_commit: | 555 | out_commit: |
556 | mutex_unlock(&sb_dqopt(sb)->dqio_mutex); | 556 | up_write(&sb_dqopt(sb)->dqio_sem); |
557 | ocfs2_commit_trans(OCFS2_SB(sb), handle); | 557 | ocfs2_commit_trans(OCFS2_SB(sb), handle); |
558 | out_drop_lock: | 558 | out_drop_lock: |
559 | ocfs2_unlock_global_qf(oinfo, 1); | 559 | ocfs2_unlock_global_qf(oinfo, 1); |
@@ -691,9 +691,6 @@ static int ocfs2_local_read_info(struct super_block *sb, int type) | |||
691 | struct ocfs2_quota_recovery *rec; | 691 | struct ocfs2_quota_recovery *rec; |
692 | int locked = 0; | 692 | int locked = 0; |
693 | 693 | ||
694 | /* We don't need the lock and we have to acquire quota file locks | ||
695 | * which will later depend on this lock */ | ||
696 | mutex_unlock(&sb_dqopt(sb)->dqio_mutex); | ||
697 | info->dqi_max_spc_limit = 0x7fffffffffffffffLL; | 694 | info->dqi_max_spc_limit = 0x7fffffffffffffffLL; |
698 | info->dqi_max_ino_limit = 0x7fffffffffffffffLL; | 695 | info->dqi_max_ino_limit = 0x7fffffffffffffffLL; |
699 | oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS); | 696 | oinfo = kmalloc(sizeof(struct ocfs2_mem_dqinfo), GFP_NOFS); |
@@ -772,7 +769,6 @@ static int ocfs2_local_read_info(struct super_block *sb, int type) | |||
772 | goto out_err; | 769 | goto out_err; |
773 | } | 770 | } |
774 | 771 | ||
775 | mutex_lock(&sb_dqopt(sb)->dqio_mutex); | ||
776 | return 0; | 772 | return 0; |
777 | out_err: | 773 | out_err: |
778 | if (oinfo) { | 774 | if (oinfo) { |
@@ -786,7 +782,6 @@ out_err: | |||
786 | kfree(oinfo); | 782 | kfree(oinfo); |
787 | } | 783 | } |
788 | brelse(bh); | 784 | brelse(bh); |
789 | mutex_lock(&sb_dqopt(sb)->dqio_mutex); | ||
790 | return -1; | 785 | return -1; |
791 | } | 786 | } |
792 | 787 | ||
@@ -882,12 +877,12 @@ static void olq_set_dquot(struct buffer_head *bh, void *private) | |||
882 | 877 | ||
883 | dqblk->dqb_id = cpu_to_le64(from_kqid(&init_user_ns, | 878 | dqblk->dqb_id = cpu_to_le64(from_kqid(&init_user_ns, |
884 | od->dq_dquot.dq_id)); | 879 | od->dq_dquot.dq_id)); |
885 | spin_lock(&dq_data_lock); | 880 | spin_lock(&od->dq_dquot.dq_dqb_lock); |
886 | dqblk->dqb_spacemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curspace - | 881 | dqblk->dqb_spacemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curspace - |
887 | od->dq_origspace); | 882 | od->dq_origspace); |
888 | dqblk->dqb_inodemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curinodes - | 883 | dqblk->dqb_inodemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curinodes - |
889 | od->dq_originodes); | 884 | od->dq_originodes); |
890 | spin_unlock(&dq_data_lock); | 885 | spin_unlock(&od->dq_dquot.dq_dqb_lock); |
891 | trace_olq_set_dquot( | 886 | trace_olq_set_dquot( |
892 | (unsigned long long)le64_to_cpu(dqblk->dqb_spacemod), | 887 | (unsigned long long)le64_to_cpu(dqblk->dqb_spacemod), |
893 | (unsigned long long)le64_to_cpu(dqblk->dqb_inodemod), | 888 | (unsigned long long)le64_to_cpu(dqblk->dqb_inodemod), |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 566e6ef99f07..8381db9db6d9 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -82,16 +82,19 @@ | |||
82 | #include <linux/uaccess.h> | 82 | #include <linux/uaccess.h> |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * There are three quota SMP locks. dq_list_lock protects all lists with quotas | 85 | * There are five quota SMP locks: |
86 | * and quota formats. | 86 | * * dq_list_lock protects all lists with quotas and quota formats. |
87 | * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and | 87 | * * dquot->dq_dqb_lock protects data from dq_dqb |
88 | * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes. | 88 | * * inode->i_lock protects inode->i_blocks, i_bytes and also guards |
89 | * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly | 89 | * consistency of dquot->dq_dqb with inode->i_blocks, i_bytes so that |
90 | * in inode_add_bytes() and inode_sub_bytes(). dq_state_lock protects | 90 | * dquot_transfer() can stabilize amount it transfers |
91 | * modifications of quota state (on quotaon and quotaoff) and readers who care | 91 | * * dq_data_lock protects mem_dqinfo structures and modifications of dquot |
92 | * about latest values take it as well. | 92 | * pointers in the inode |
93 | * * dq_state_lock protects modifications of quota state (on quotaon and | ||
94 | * quotaoff) and readers who care about latest values take it as well. | ||
93 | * | 95 | * |
94 | * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock, | 96 | * The spinlock ordering is hence: |
97 | * dq_data_lock > dq_list_lock > i_lock > dquot->dq_dqb_lock, | ||
95 | * dq_list_lock > dq_state_lock | 98 | * dq_list_lock > dq_state_lock |
96 | * | 99 | * |
97 | * Note that some things (eg. sb pointer, type, id) doesn't change during | 100 | * Note that some things (eg. sb pointer, type, id) doesn't change during |
@@ -110,17 +113,14 @@ | |||
110 | * sure they cannot race with quotaon which first sets S_NOQUOTA flag and | 113 | * sure they cannot race with quotaon which first sets S_NOQUOTA flag and |
111 | * then drops all pointers to dquots from an inode. | 114 | * then drops all pointers to dquots from an inode. |
112 | * | 115 | * |
113 | * Each dquot has its dq_lock mutex. Locked dquots might not be referenced | 116 | * Each dquot has its dq_lock mutex. Dquot is locked when it is being read to |
114 | * from inodes (dquot_alloc_space() and such don't check the dq_lock). | 117 | * memory (or space for it is being allocated) on the first dqget(), when it is |
115 | * Currently dquot is locked only when it is being read to memory (or space for | 118 | * being written out, and when it is being released on the last dqput(). The |
116 | * it is being allocated) on the first dqget() and when it is being released on | 119 | * allocation and release operations are serialized by the dq_lock and by |
117 | * the last dqput(). The allocation and release oparations are serialized by | 120 | * checking the use count in dquot_release(). |
118 | * the dq_lock and by checking the use count in dquot_release(). Write | ||
119 | * operations on dquots don't hold dq_lock as they copy data under dq_data_lock | ||
120 | * spinlock to internal buffers before writing. | ||
121 | * | 121 | * |
122 | * Lock ordering (including related VFS locks) is the following: | 122 | * Lock ordering (including related VFS locks) is the following: |
123 | * s_umount > i_mutex > journal_lock > dquot->dq_lock > dqio_mutex | 123 | * s_umount > i_mutex > journal_lock > dquot->dq_lock > dqio_sem |
124 | */ | 124 | */ |
125 | 125 | ||
126 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); | 126 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); |
@@ -129,6 +129,8 @@ __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock); | |||
129 | EXPORT_SYMBOL(dq_data_lock); | 129 | EXPORT_SYMBOL(dq_data_lock); |
130 | DEFINE_STATIC_SRCU(dquot_srcu); | 130 | DEFINE_STATIC_SRCU(dquot_srcu); |
131 | 131 | ||
132 | static DECLARE_WAIT_QUEUE_HEAD(dquot_ref_wq); | ||
133 | |||
132 | void __quota_error(struct super_block *sb, const char *func, | 134 | void __quota_error(struct super_block *sb, const char *func, |
133 | const char *fmt, ...) | 135 | const char *fmt, ...) |
134 | { | 136 | { |
@@ -247,6 +249,7 @@ struct dqstats dqstats; | |||
247 | EXPORT_SYMBOL(dqstats); | 249 | EXPORT_SYMBOL(dqstats); |
248 | 250 | ||
249 | static qsize_t inode_get_rsv_space(struct inode *inode); | 251 | static qsize_t inode_get_rsv_space(struct inode *inode); |
252 | static qsize_t __inode_get_rsv_space(struct inode *inode); | ||
250 | static int __dquot_initialize(struct inode *inode, int type); | 253 | static int __dquot_initialize(struct inode *inode, int type); |
251 | 254 | ||
252 | static inline unsigned int | 255 | static inline unsigned int |
@@ -342,6 +345,12 @@ int dquot_mark_dquot_dirty(struct dquot *dquot) | |||
342 | { | 345 | { |
343 | int ret = 1; | 346 | int ret = 1; |
344 | 347 | ||
348 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) | ||
349 | return 0; | ||
350 | |||
351 | if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NOLIST_DIRTY) | ||
352 | return test_and_set_bit(DQ_MOD_B, &dquot->dq_flags); | ||
353 | |||
345 | /* If quota is dirty already, we don't have to acquire dq_list_lock */ | 354 | /* If quota is dirty already, we don't have to acquire dq_list_lock */ |
346 | if (test_bit(DQ_MOD_B, &dquot->dq_flags)) | 355 | if (test_bit(DQ_MOD_B, &dquot->dq_flags)) |
347 | return 1; | 356 | return 1; |
@@ -381,18 +390,26 @@ static inline void dqput_all(struct dquot **dquot) | |||
381 | dqput(dquot[cnt]); | 390 | dqput(dquot[cnt]); |
382 | } | 391 | } |
383 | 392 | ||
384 | /* This function needs dq_list_lock */ | ||
385 | static inline int clear_dquot_dirty(struct dquot *dquot) | 393 | static inline int clear_dquot_dirty(struct dquot *dquot) |
386 | { | 394 | { |
387 | if (!test_and_clear_bit(DQ_MOD_B, &dquot->dq_flags)) | 395 | if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NOLIST_DIRTY) |
396 | return test_and_clear_bit(DQ_MOD_B, &dquot->dq_flags); | ||
397 | |||
398 | spin_lock(&dq_list_lock); | ||
399 | if (!test_and_clear_bit(DQ_MOD_B, &dquot->dq_flags)) { | ||
400 | spin_unlock(&dq_list_lock); | ||
388 | return 0; | 401 | return 0; |
402 | } | ||
389 | list_del_init(&dquot->dq_dirty); | 403 | list_del_init(&dquot->dq_dirty); |
404 | spin_unlock(&dq_list_lock); | ||
390 | return 1; | 405 | return 1; |
391 | } | 406 | } |
392 | 407 | ||
393 | void mark_info_dirty(struct super_block *sb, int type) | 408 | void mark_info_dirty(struct super_block *sb, int type) |
394 | { | 409 | { |
395 | set_bit(DQF_INFO_DIRTY_B, &sb_dqopt(sb)->info[type].dqi_flags); | 410 | spin_lock(&dq_data_lock); |
411 | sb_dqopt(sb)->info[type].dqi_flags |= DQF_INFO_DIRTY; | ||
412 | spin_unlock(&dq_data_lock); | ||
396 | } | 413 | } |
397 | EXPORT_SYMBOL(mark_info_dirty); | 414 | EXPORT_SYMBOL(mark_info_dirty); |
398 | 415 | ||
@@ -406,7 +423,6 @@ int dquot_acquire(struct dquot *dquot) | |||
406 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); | 423 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); |
407 | 424 | ||
408 | mutex_lock(&dquot->dq_lock); | 425 | mutex_lock(&dquot->dq_lock); |
409 | mutex_lock(&dqopt->dqio_mutex); | ||
410 | if (!test_bit(DQ_READ_B, &dquot->dq_flags)) | 426 | if (!test_bit(DQ_READ_B, &dquot->dq_flags)) |
411 | ret = dqopt->ops[dquot->dq_id.type]->read_dqblk(dquot); | 427 | ret = dqopt->ops[dquot->dq_id.type]->read_dqblk(dquot); |
412 | if (ret < 0) | 428 | if (ret < 0) |
@@ -436,7 +452,6 @@ int dquot_acquire(struct dquot *dquot) | |||
436 | smp_mb__before_atomic(); | 452 | smp_mb__before_atomic(); |
437 | set_bit(DQ_ACTIVE_B, &dquot->dq_flags); | 453 | set_bit(DQ_ACTIVE_B, &dquot->dq_flags); |
438 | out_iolock: | 454 | out_iolock: |
439 | mutex_unlock(&dqopt->dqio_mutex); | ||
440 | mutex_unlock(&dquot->dq_lock); | 455 | mutex_unlock(&dquot->dq_lock); |
441 | return ret; | 456 | return ret; |
442 | } | 457 | } |
@@ -450,21 +465,17 @@ int dquot_commit(struct dquot *dquot) | |||
450 | int ret = 0; | 465 | int ret = 0; |
451 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); | 466 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); |
452 | 467 | ||
453 | mutex_lock(&dqopt->dqio_mutex); | 468 | mutex_lock(&dquot->dq_lock); |
454 | spin_lock(&dq_list_lock); | 469 | if (!clear_dquot_dirty(dquot)) |
455 | if (!clear_dquot_dirty(dquot)) { | 470 | goto out_lock; |
456 | spin_unlock(&dq_list_lock); | ||
457 | goto out_sem; | ||
458 | } | ||
459 | spin_unlock(&dq_list_lock); | ||
460 | /* Inactive dquot can be only if there was error during read/init | 471 | /* Inactive dquot can be only if there was error during read/init |
461 | * => we have better not writing it */ | 472 | * => we have better not writing it */ |
462 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) | 473 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) |
463 | ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot); | 474 | ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot); |
464 | else | 475 | else |
465 | ret = -EIO; | 476 | ret = -EIO; |
466 | out_sem: | 477 | out_lock: |
467 | mutex_unlock(&dqopt->dqio_mutex); | 478 | mutex_unlock(&dquot->dq_lock); |
468 | return ret; | 479 | return ret; |
469 | } | 480 | } |
470 | EXPORT_SYMBOL(dquot_commit); | 481 | EXPORT_SYMBOL(dquot_commit); |
@@ -481,7 +492,6 @@ int dquot_release(struct dquot *dquot) | |||
481 | /* Check whether we are not racing with some other dqget() */ | 492 | /* Check whether we are not racing with some other dqget() */ |
482 | if (atomic_read(&dquot->dq_count) > 1) | 493 | if (atomic_read(&dquot->dq_count) > 1) |
483 | goto out_dqlock; | 494 | goto out_dqlock; |
484 | mutex_lock(&dqopt->dqio_mutex); | ||
485 | if (dqopt->ops[dquot->dq_id.type]->release_dqblk) { | 495 | if (dqopt->ops[dquot->dq_id.type]->release_dqblk) { |
486 | ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot); | 496 | ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot); |
487 | /* Write the info */ | 497 | /* Write the info */ |
@@ -493,7 +503,6 @@ int dquot_release(struct dquot *dquot) | |||
493 | ret = ret2; | 503 | ret = ret2; |
494 | } | 504 | } |
495 | clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); | 505 | clear_bit(DQ_ACTIVE_B, &dquot->dq_flags); |
496 | mutex_unlock(&dqopt->dqio_mutex); | ||
497 | out_dqlock: | 506 | out_dqlock: |
498 | mutex_unlock(&dquot->dq_lock); | 507 | mutex_unlock(&dquot->dq_lock); |
499 | return ret; | 508 | return ret; |
@@ -530,22 +539,18 @@ restart: | |||
530 | continue; | 539 | continue; |
531 | /* Wait for dquot users */ | 540 | /* Wait for dquot users */ |
532 | if (atomic_read(&dquot->dq_count)) { | 541 | if (atomic_read(&dquot->dq_count)) { |
533 | DEFINE_WAIT(wait); | ||
534 | |||
535 | dqgrab(dquot); | 542 | dqgrab(dquot); |
536 | prepare_to_wait(&dquot->dq_wait_unused, &wait, | ||
537 | TASK_UNINTERRUPTIBLE); | ||
538 | spin_unlock(&dq_list_lock); | 543 | spin_unlock(&dq_list_lock); |
539 | /* Once dqput() wakes us up, we know it's time to free | 544 | /* |
545 | * Once dqput() wakes us up, we know it's time to free | ||
540 | * the dquot. | 546 | * the dquot. |
541 | * IMPORTANT: we rely on the fact that there is always | 547 | * IMPORTANT: we rely on the fact that there is always |
542 | * at most one process waiting for dquot to free. | 548 | * at most one process waiting for dquot to free. |
543 | * Otherwise dq_count would be > 1 and we would never | 549 | * Otherwise dq_count would be > 1 and we would never |
544 | * wake up. | 550 | * wake up. |
545 | */ | 551 | */ |
546 | if (atomic_read(&dquot->dq_count) > 1) | 552 | wait_event(dquot_ref_wq, |
547 | schedule(); | 553 | atomic_read(&dquot->dq_count) == 1); |
548 | finish_wait(&dquot->dq_wait_unused, &wait); | ||
549 | dqput(dquot); | 554 | dqput(dquot); |
550 | /* At this moment dquot() need not exist (it could be | 555 | /* At this moment dquot() need not exist (it could be |
551 | * reclaimed by prune_dqcache(). Hence we must | 556 | * reclaimed by prune_dqcache(). Hence we must |
@@ -629,11 +634,9 @@ int dquot_writeback_dquots(struct super_block *sb, int type) | |||
629 | while (!list_empty(dirty)) { | 634 | while (!list_empty(dirty)) { |
630 | dquot = list_first_entry(dirty, struct dquot, | 635 | dquot = list_first_entry(dirty, struct dquot, |
631 | dq_dirty); | 636 | dq_dirty); |
632 | /* Dirty and inactive can be only bad dquot... */ | 637 | |
633 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { | 638 | WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)); |
634 | clear_dquot_dirty(dquot); | 639 | |
635 | continue; | ||
636 | } | ||
637 | /* Now we have active dquot from which someone is | 640 | /* Now we have active dquot from which someone is |
638 | * holding reference so we can safely just increase | 641 | * holding reference so we can safely just increase |
639 | * use count */ | 642 | * use count */ |
@@ -759,12 +762,12 @@ we_slept: | |||
759 | /* Releasing dquot during quotaoff phase? */ | 762 | /* Releasing dquot during quotaoff phase? */ |
760 | if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_id.type) && | 763 | if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_id.type) && |
761 | atomic_read(&dquot->dq_count) == 1) | 764 | atomic_read(&dquot->dq_count) == 1) |
762 | wake_up(&dquot->dq_wait_unused); | 765 | wake_up(&dquot_ref_wq); |
763 | spin_unlock(&dq_list_lock); | 766 | spin_unlock(&dq_list_lock); |
764 | return; | 767 | return; |
765 | } | 768 | } |
766 | /* Need to release dquot? */ | 769 | /* Need to release dquot? */ |
767 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) { | 770 | if (dquot_dirty(dquot)) { |
768 | spin_unlock(&dq_list_lock); | 771 | spin_unlock(&dq_list_lock); |
769 | /* Commit dquot before releasing */ | 772 | /* Commit dquot before releasing */ |
770 | ret = dquot->dq_sb->dq_op->write_dquot(dquot); | 773 | ret = dquot->dq_sb->dq_op->write_dquot(dquot); |
@@ -776,14 +779,10 @@ we_slept: | |||
776 | * We clear dirty bit anyway, so that we avoid | 779 | * We clear dirty bit anyway, so that we avoid |
777 | * infinite loop here | 780 | * infinite loop here |
778 | */ | 781 | */ |
779 | spin_lock(&dq_list_lock); | ||
780 | clear_dquot_dirty(dquot); | 782 | clear_dquot_dirty(dquot); |
781 | spin_unlock(&dq_list_lock); | ||
782 | } | 783 | } |
783 | goto we_slept; | 784 | goto we_slept; |
784 | } | 785 | } |
785 | /* Clear flag in case dquot was inactive (something bad happened) */ | ||
786 | clear_dquot_dirty(dquot); | ||
787 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { | 786 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { |
788 | spin_unlock(&dq_list_lock); | 787 | spin_unlock(&dq_list_lock); |
789 | dquot->dq_sb->dq_op->release_dquot(dquot); | 788 | dquot->dq_sb->dq_op->release_dquot(dquot); |
@@ -818,10 +817,10 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) | |||
818 | INIT_LIST_HEAD(&dquot->dq_inuse); | 817 | INIT_LIST_HEAD(&dquot->dq_inuse); |
819 | INIT_HLIST_NODE(&dquot->dq_hash); | 818 | INIT_HLIST_NODE(&dquot->dq_hash); |
820 | INIT_LIST_HEAD(&dquot->dq_dirty); | 819 | INIT_LIST_HEAD(&dquot->dq_dirty); |
821 | init_waitqueue_head(&dquot->dq_wait_unused); | ||
822 | dquot->dq_sb = sb; | 820 | dquot->dq_sb = sb; |
823 | dquot->dq_id = make_kqid_invalid(type); | 821 | dquot->dq_id = make_kqid_invalid(type); |
824 | atomic_set(&dquot->dq_count, 1); | 822 | atomic_set(&dquot->dq_count, 1); |
823 | spin_lock_init(&dquot->dq_dqb_lock); | ||
825 | 824 | ||
826 | return dquot; | 825 | return dquot; |
827 | } | 826 | } |
@@ -1079,42 +1078,6 @@ static void drop_dquot_ref(struct super_block *sb, int type) | |||
1079 | } | 1078 | } |
1080 | } | 1079 | } |
1081 | 1080 | ||
1082 | static inline void dquot_incr_inodes(struct dquot *dquot, qsize_t number) | ||
1083 | { | ||
1084 | dquot->dq_dqb.dqb_curinodes += number; | ||
1085 | } | ||
1086 | |||
1087 | static inline void dquot_incr_space(struct dquot *dquot, qsize_t number) | ||
1088 | { | ||
1089 | dquot->dq_dqb.dqb_curspace += number; | ||
1090 | } | ||
1091 | |||
1092 | static inline void dquot_resv_space(struct dquot *dquot, qsize_t number) | ||
1093 | { | ||
1094 | dquot->dq_dqb.dqb_rsvspace += number; | ||
1095 | } | ||
1096 | |||
1097 | /* | ||
1098 | * Claim reserved quota space | ||
1099 | */ | ||
1100 | static void dquot_claim_reserved_space(struct dquot *dquot, qsize_t number) | ||
1101 | { | ||
1102 | if (dquot->dq_dqb.dqb_rsvspace < number) { | ||
1103 | WARN_ON_ONCE(1); | ||
1104 | number = dquot->dq_dqb.dqb_rsvspace; | ||
1105 | } | ||
1106 | dquot->dq_dqb.dqb_curspace += number; | ||
1107 | dquot->dq_dqb.dqb_rsvspace -= number; | ||
1108 | } | ||
1109 | |||
1110 | static void dquot_reclaim_reserved_space(struct dquot *dquot, qsize_t number) | ||
1111 | { | ||
1112 | if (WARN_ON_ONCE(dquot->dq_dqb.dqb_curspace < number)) | ||
1113 | number = dquot->dq_dqb.dqb_curspace; | ||
1114 | dquot->dq_dqb.dqb_rsvspace += number; | ||
1115 | dquot->dq_dqb.dqb_curspace -= number; | ||
1116 | } | ||
1117 | |||
1118 | static inline | 1081 | static inline |
1119 | void dquot_free_reserved_space(struct dquot *dquot, qsize_t number) | 1082 | void dquot_free_reserved_space(struct dquot *dquot, qsize_t number) |
1120 | { | 1083 | { |
@@ -1278,21 +1241,24 @@ static int ignore_hardlimit(struct dquot *dquot) | |||
1278 | !(info->dqi_flags & DQF_ROOT_SQUASH)); | 1241 | !(info->dqi_flags & DQF_ROOT_SQUASH)); |
1279 | } | 1242 | } |
1280 | 1243 | ||
1281 | /* needs dq_data_lock */ | 1244 | static int dquot_add_inodes(struct dquot *dquot, qsize_t inodes, |
1282 | static int check_idq(struct dquot *dquot, qsize_t inodes, | 1245 | struct dquot_warn *warn) |
1283 | struct dquot_warn *warn) | ||
1284 | { | 1246 | { |
1285 | qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; | 1247 | qsize_t newinodes; |
1248 | int ret = 0; | ||
1286 | 1249 | ||
1250 | spin_lock(&dquot->dq_dqb_lock); | ||
1251 | newinodes = dquot->dq_dqb.dqb_curinodes + inodes; | ||
1287 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_id.type) || | 1252 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_id.type) || |
1288 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1253 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
1289 | return 0; | 1254 | goto add; |
1290 | 1255 | ||
1291 | if (dquot->dq_dqb.dqb_ihardlimit && | 1256 | if (dquot->dq_dqb.dqb_ihardlimit && |
1292 | newinodes > dquot->dq_dqb.dqb_ihardlimit && | 1257 | newinodes > dquot->dq_dqb.dqb_ihardlimit && |
1293 | !ignore_hardlimit(dquot)) { | 1258 | !ignore_hardlimit(dquot)) { |
1294 | prepare_warning(warn, dquot, QUOTA_NL_IHARDWARN); | 1259 | prepare_warning(warn, dquot, QUOTA_NL_IHARDWARN); |
1295 | return -EDQUOT; | 1260 | ret = -EDQUOT; |
1261 | goto out; | ||
1296 | } | 1262 | } |
1297 | 1263 | ||
1298 | if (dquot->dq_dqb.dqb_isoftlimit && | 1264 | if (dquot->dq_dqb.dqb_isoftlimit && |
@@ -1301,7 +1267,8 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, | |||
1301 | ktime_get_real_seconds() >= dquot->dq_dqb.dqb_itime && | 1267 | ktime_get_real_seconds() >= dquot->dq_dqb.dqb_itime && |
1302 | !ignore_hardlimit(dquot)) { | 1268 | !ignore_hardlimit(dquot)) { |
1303 | prepare_warning(warn, dquot, QUOTA_NL_ISOFTLONGWARN); | 1269 | prepare_warning(warn, dquot, QUOTA_NL_ISOFTLONGWARN); |
1304 | return -EDQUOT; | 1270 | ret = -EDQUOT; |
1271 | goto out; | ||
1305 | } | 1272 | } |
1306 | 1273 | ||
1307 | if (dquot->dq_dqb.dqb_isoftlimit && | 1274 | if (dquot->dq_dqb.dqb_isoftlimit && |
@@ -1311,30 +1278,40 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, | |||
1311 | dquot->dq_dqb.dqb_itime = ktime_get_real_seconds() + | 1278 | dquot->dq_dqb.dqb_itime = ktime_get_real_seconds() + |
1312 | sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type].dqi_igrace; | 1279 | sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type].dqi_igrace; |
1313 | } | 1280 | } |
1281 | add: | ||
1282 | dquot->dq_dqb.dqb_curinodes = newinodes; | ||
1314 | 1283 | ||
1315 | return 0; | 1284 | out: |
1285 | spin_unlock(&dquot->dq_dqb_lock); | ||
1286 | return ret; | ||
1316 | } | 1287 | } |
1317 | 1288 | ||
1318 | /* needs dq_data_lock */ | 1289 | static int dquot_add_space(struct dquot *dquot, qsize_t space, |
1319 | static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, | 1290 | qsize_t rsv_space, unsigned int flags, |
1320 | struct dquot_warn *warn) | 1291 | struct dquot_warn *warn) |
1321 | { | 1292 | { |
1322 | qsize_t tspace; | 1293 | qsize_t tspace; |
1323 | struct super_block *sb = dquot->dq_sb; | 1294 | struct super_block *sb = dquot->dq_sb; |
1295 | int ret = 0; | ||
1324 | 1296 | ||
1297 | spin_lock(&dquot->dq_dqb_lock); | ||
1325 | if (!sb_has_quota_limits_enabled(sb, dquot->dq_id.type) || | 1298 | if (!sb_has_quota_limits_enabled(sb, dquot->dq_id.type) || |
1326 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1299 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
1327 | return 0; | 1300 | goto add; |
1328 | 1301 | ||
1329 | tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace | 1302 | tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace |
1330 | + space; | 1303 | + space + rsv_space; |
1304 | |||
1305 | if (flags & DQUOT_SPACE_NOFAIL) | ||
1306 | goto add; | ||
1331 | 1307 | ||
1332 | if (dquot->dq_dqb.dqb_bhardlimit && | 1308 | if (dquot->dq_dqb.dqb_bhardlimit && |
1333 | tspace > dquot->dq_dqb.dqb_bhardlimit && | 1309 | tspace > dquot->dq_dqb.dqb_bhardlimit && |
1334 | !ignore_hardlimit(dquot)) { | 1310 | !ignore_hardlimit(dquot)) { |
1335 | if (!prealloc) | 1311 | if (flags & DQUOT_SPACE_WARN) |
1336 | prepare_warning(warn, dquot, QUOTA_NL_BHARDWARN); | 1312 | prepare_warning(warn, dquot, QUOTA_NL_BHARDWARN); |
1337 | return -EDQUOT; | 1313 | ret = -EDQUOT; |
1314 | goto out; | ||
1338 | } | 1315 | } |
1339 | 1316 | ||
1340 | if (dquot->dq_dqb.dqb_bsoftlimit && | 1317 | if (dquot->dq_dqb.dqb_bsoftlimit && |
@@ -1342,28 +1319,34 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, | |||
1342 | dquot->dq_dqb.dqb_btime && | 1319 | dquot->dq_dqb.dqb_btime && |
1343 | ktime_get_real_seconds() >= dquot->dq_dqb.dqb_btime && | 1320 | ktime_get_real_seconds() >= dquot->dq_dqb.dqb_btime && |
1344 | !ignore_hardlimit(dquot)) { | 1321 | !ignore_hardlimit(dquot)) { |
1345 | if (!prealloc) | 1322 | if (flags & DQUOT_SPACE_WARN) |
1346 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTLONGWARN); | 1323 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTLONGWARN); |
1347 | return -EDQUOT; | 1324 | ret = -EDQUOT; |
1325 | goto out; | ||
1348 | } | 1326 | } |
1349 | 1327 | ||
1350 | if (dquot->dq_dqb.dqb_bsoftlimit && | 1328 | if (dquot->dq_dqb.dqb_bsoftlimit && |
1351 | tspace > dquot->dq_dqb.dqb_bsoftlimit && | 1329 | tspace > dquot->dq_dqb.dqb_bsoftlimit && |
1352 | dquot->dq_dqb.dqb_btime == 0) { | 1330 | dquot->dq_dqb.dqb_btime == 0) { |
1353 | if (!prealloc) { | 1331 | if (flags & DQUOT_SPACE_WARN) { |
1354 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN); | 1332 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN); |
1355 | dquot->dq_dqb.dqb_btime = ktime_get_real_seconds() + | 1333 | dquot->dq_dqb.dqb_btime = ktime_get_real_seconds() + |
1356 | sb_dqopt(sb)->info[dquot->dq_id.type].dqi_bgrace; | 1334 | sb_dqopt(sb)->info[dquot->dq_id.type].dqi_bgrace; |
1357 | } | 1335 | } else { |
1358 | else | ||
1359 | /* | 1336 | /* |
1360 | * We don't allow preallocation to exceed softlimit so exceeding will | 1337 | * We don't allow preallocation to exceed softlimit so exceeding will |
1361 | * be always printed | 1338 | * be always printed |
1362 | */ | 1339 | */ |
1363 | return -EDQUOT; | 1340 | ret = -EDQUOT; |
1341 | goto out; | ||
1342 | } | ||
1364 | } | 1343 | } |
1365 | 1344 | add: | |
1366 | return 0; | 1345 | dquot->dq_dqb.dqb_rsvspace += rsv_space; |
1346 | dquot->dq_dqb.dqb_curspace += space; | ||
1347 | out: | ||
1348 | spin_unlock(&dquot->dq_dqb_lock); | ||
1349 | return ret; | ||
1367 | } | 1350 | } |
1368 | 1351 | ||
1369 | static int info_idq_free(struct dquot *dquot, qsize_t inodes) | 1352 | static int info_idq_free(struct dquot *dquot, qsize_t inodes) |
@@ -1502,8 +1485,15 @@ static int __dquot_initialize(struct inode *inode, int type) | |||
1502 | * did a write before quota was turned on | 1485 | * did a write before quota was turned on |
1503 | */ | 1486 | */ |
1504 | rsv = inode_get_rsv_space(inode); | 1487 | rsv = inode_get_rsv_space(inode); |
1505 | if (unlikely(rsv)) | 1488 | if (unlikely(rsv)) { |
1506 | dquot_resv_space(dquots[cnt], rsv); | 1489 | spin_lock(&inode->i_lock); |
1490 | /* Get reservation again under proper lock */ | ||
1491 | rsv = __inode_get_rsv_space(inode); | ||
1492 | spin_lock(&dquots[cnt]->dq_dqb_lock); | ||
1493 | dquots[cnt]->dq_dqb.dqb_rsvspace += rsv; | ||
1494 | spin_unlock(&dquots[cnt]->dq_dqb_lock); | ||
1495 | spin_unlock(&inode->i_lock); | ||
1496 | } | ||
1507 | } | 1497 | } |
1508 | } | 1498 | } |
1509 | out_lock: | 1499 | out_lock: |
@@ -1598,39 +1588,12 @@ static qsize_t *inode_reserved_space(struct inode * inode) | |||
1598 | return inode->i_sb->dq_op->get_reserved_space(inode); | 1588 | return inode->i_sb->dq_op->get_reserved_space(inode); |
1599 | } | 1589 | } |
1600 | 1590 | ||
1601 | void inode_add_rsv_space(struct inode *inode, qsize_t number) | 1591 | static qsize_t __inode_get_rsv_space(struct inode *inode) |
1602 | { | ||
1603 | spin_lock(&inode->i_lock); | ||
1604 | *inode_reserved_space(inode) += number; | ||
1605 | spin_unlock(&inode->i_lock); | ||
1606 | } | ||
1607 | EXPORT_SYMBOL(inode_add_rsv_space); | ||
1608 | |||
1609 | void inode_claim_rsv_space(struct inode *inode, qsize_t number) | ||
1610 | { | 1592 | { |
1611 | spin_lock(&inode->i_lock); | 1593 | if (!inode->i_sb->dq_op->get_reserved_space) |
1612 | *inode_reserved_space(inode) -= number; | 1594 | return 0; |
1613 | __inode_add_bytes(inode, number); | 1595 | return *inode_reserved_space(inode); |
1614 | spin_unlock(&inode->i_lock); | ||
1615 | } | ||
1616 | EXPORT_SYMBOL(inode_claim_rsv_space); | ||
1617 | |||
1618 | void inode_reclaim_rsv_space(struct inode *inode, qsize_t number) | ||
1619 | { | ||
1620 | spin_lock(&inode->i_lock); | ||
1621 | *inode_reserved_space(inode) += number; | ||
1622 | __inode_sub_bytes(inode, number); | ||
1623 | spin_unlock(&inode->i_lock); | ||
1624 | } | ||
1625 | EXPORT_SYMBOL(inode_reclaim_rsv_space); | ||
1626 | |||
1627 | void inode_sub_rsv_space(struct inode *inode, qsize_t number) | ||
1628 | { | ||
1629 | spin_lock(&inode->i_lock); | ||
1630 | *inode_reserved_space(inode) -= number; | ||
1631 | spin_unlock(&inode->i_lock); | ||
1632 | } | 1596 | } |
1633 | EXPORT_SYMBOL(inode_sub_rsv_space); | ||
1634 | 1597 | ||
1635 | static qsize_t inode_get_rsv_space(struct inode *inode) | 1598 | static qsize_t inode_get_rsv_space(struct inode *inode) |
1636 | { | 1599 | { |
@@ -1639,28 +1602,11 @@ static qsize_t inode_get_rsv_space(struct inode *inode) | |||
1639 | if (!inode->i_sb->dq_op->get_reserved_space) | 1602 | if (!inode->i_sb->dq_op->get_reserved_space) |
1640 | return 0; | 1603 | return 0; |
1641 | spin_lock(&inode->i_lock); | 1604 | spin_lock(&inode->i_lock); |
1642 | ret = *inode_reserved_space(inode); | 1605 | ret = __inode_get_rsv_space(inode); |
1643 | spin_unlock(&inode->i_lock); | 1606 | spin_unlock(&inode->i_lock); |
1644 | return ret; | 1607 | return ret; |
1645 | } | 1608 | } |
1646 | 1609 | ||
1647 | static void inode_incr_space(struct inode *inode, qsize_t number, | ||
1648 | int reserve) | ||
1649 | { | ||
1650 | if (reserve) | ||
1651 | inode_add_rsv_space(inode, number); | ||
1652 | else | ||
1653 | inode_add_bytes(inode, number); | ||
1654 | } | ||
1655 | |||
1656 | static void inode_decr_space(struct inode *inode, qsize_t number, int reserve) | ||
1657 | { | ||
1658 | if (reserve) | ||
1659 | inode_sub_rsv_space(inode, number); | ||
1660 | else | ||
1661 | inode_sub_bytes(inode, number); | ||
1662 | } | ||
1663 | |||
1664 | /* | 1610 | /* |
1665 | * This functions updates i_blocks+i_bytes fields and quota information | 1611 | * This functions updates i_blocks+i_bytes fields and quota information |
1666 | * (together with appropriate checks). | 1612 | * (together with appropriate checks). |
@@ -1682,7 +1628,13 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
1682 | struct dquot **dquots; | 1628 | struct dquot **dquots; |
1683 | 1629 | ||
1684 | if (!dquot_active(inode)) { | 1630 | if (!dquot_active(inode)) { |
1685 | inode_incr_space(inode, number, reserve); | 1631 | if (reserve) { |
1632 | spin_lock(&inode->i_lock); | ||
1633 | *inode_reserved_space(inode) += number; | ||
1634 | spin_unlock(&inode->i_lock); | ||
1635 | } else { | ||
1636 | inode_add_bytes(inode, number); | ||
1637 | } | ||
1686 | goto out; | 1638 | goto out; |
1687 | } | 1639 | } |
1688 | 1640 | ||
@@ -1691,27 +1643,41 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
1691 | 1643 | ||
1692 | dquots = i_dquot(inode); | 1644 | dquots = i_dquot(inode); |
1693 | index = srcu_read_lock(&dquot_srcu); | 1645 | index = srcu_read_lock(&dquot_srcu); |
1694 | spin_lock(&dq_data_lock); | 1646 | spin_lock(&inode->i_lock); |
1695 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1647 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1696 | if (!dquots[cnt]) | 1648 | if (!dquots[cnt]) |
1697 | continue; | 1649 | continue; |
1698 | ret = check_bdq(dquots[cnt], number, | 1650 | if (flags & DQUOT_SPACE_RESERVE) { |
1699 | !(flags & DQUOT_SPACE_WARN), &warn[cnt]); | 1651 | ret = dquot_add_space(dquots[cnt], 0, number, flags, |
1700 | if (ret && !(flags & DQUOT_SPACE_NOFAIL)) { | 1652 | &warn[cnt]); |
1701 | spin_unlock(&dq_data_lock); | 1653 | } else { |
1654 | ret = dquot_add_space(dquots[cnt], number, 0, flags, | ||
1655 | &warn[cnt]); | ||
1656 | } | ||
1657 | if (ret) { | ||
1658 | /* Back out changes we already did */ | ||
1659 | for (cnt--; cnt >= 0; cnt--) { | ||
1660 | if (!dquots[cnt]) | ||
1661 | continue; | ||
1662 | spin_lock(&dquots[cnt]->dq_dqb_lock); | ||
1663 | if (flags & DQUOT_SPACE_RESERVE) { | ||
1664 | dquots[cnt]->dq_dqb.dqb_rsvspace -= | ||
1665 | number; | ||
1666 | } else { | ||
1667 | dquots[cnt]->dq_dqb.dqb_curspace -= | ||
1668 | number; | ||
1669 | } | ||
1670 | spin_unlock(&dquots[cnt]->dq_dqb_lock); | ||
1671 | } | ||
1672 | spin_unlock(&inode->i_lock); | ||
1702 | goto out_flush_warn; | 1673 | goto out_flush_warn; |
1703 | } | 1674 | } |
1704 | } | 1675 | } |
1705 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1676 | if (reserve) |
1706 | if (!dquots[cnt]) | 1677 | *inode_reserved_space(inode) += number; |
1707 | continue; | 1678 | else |
1708 | if (reserve) | 1679 | __inode_add_bytes(inode, number); |
1709 | dquot_resv_space(dquots[cnt], number); | 1680 | spin_unlock(&inode->i_lock); |
1710 | else | ||
1711 | dquot_incr_space(dquots[cnt], number); | ||
1712 | } | ||
1713 | inode_incr_space(inode, number, reserve); | ||
1714 | spin_unlock(&dq_data_lock); | ||
1715 | 1681 | ||
1716 | if (reserve) | 1682 | if (reserve) |
1717 | goto out_flush_warn; | 1683 | goto out_flush_warn; |
@@ -1740,23 +1706,26 @@ int dquot_alloc_inode(struct inode *inode) | |||
1740 | 1706 | ||
1741 | dquots = i_dquot(inode); | 1707 | dquots = i_dquot(inode); |
1742 | index = srcu_read_lock(&dquot_srcu); | 1708 | index = srcu_read_lock(&dquot_srcu); |
1743 | spin_lock(&dq_data_lock); | 1709 | spin_lock(&inode->i_lock); |
1744 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1710 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1745 | if (!dquots[cnt]) | 1711 | if (!dquots[cnt]) |
1746 | continue; | 1712 | continue; |
1747 | ret = check_idq(dquots[cnt], 1, &warn[cnt]); | 1713 | ret = dquot_add_inodes(dquots[cnt], 1, &warn[cnt]); |
1748 | if (ret) | 1714 | if (ret) { |
1715 | for (cnt--; cnt >= 0; cnt--) { | ||
1716 | if (!dquots[cnt]) | ||
1717 | continue; | ||
1718 | /* Back out changes we already did */ | ||
1719 | spin_lock(&dquots[cnt]->dq_dqb_lock); | ||
1720 | dquots[cnt]->dq_dqb.dqb_curinodes--; | ||
1721 | spin_unlock(&dquots[cnt]->dq_dqb_lock); | ||
1722 | } | ||
1749 | goto warn_put_all; | 1723 | goto warn_put_all; |
1750 | } | 1724 | } |
1751 | |||
1752 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
1753 | if (!dquots[cnt]) | ||
1754 | continue; | ||
1755 | dquot_incr_inodes(dquots[cnt], 1); | ||
1756 | } | 1725 | } |
1757 | 1726 | ||
1758 | warn_put_all: | 1727 | warn_put_all: |
1759 | spin_unlock(&dq_data_lock); | 1728 | spin_unlock(&inode->i_lock); |
1760 | if (ret == 0) | 1729 | if (ret == 0) |
1761 | mark_all_dquot_dirty(dquots); | 1730 | mark_all_dquot_dirty(dquots); |
1762 | srcu_read_unlock(&dquot_srcu, index); | 1731 | srcu_read_unlock(&dquot_srcu, index); |
@@ -1774,21 +1743,33 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) | |||
1774 | int cnt, index; | 1743 | int cnt, index; |
1775 | 1744 | ||
1776 | if (!dquot_active(inode)) { | 1745 | if (!dquot_active(inode)) { |
1777 | inode_claim_rsv_space(inode, number); | 1746 | spin_lock(&inode->i_lock); |
1747 | *inode_reserved_space(inode) -= number; | ||
1748 | __inode_add_bytes(inode, number); | ||
1749 | spin_unlock(&inode->i_lock); | ||
1778 | return 0; | 1750 | return 0; |
1779 | } | 1751 | } |
1780 | 1752 | ||
1781 | dquots = i_dquot(inode); | 1753 | dquots = i_dquot(inode); |
1782 | index = srcu_read_lock(&dquot_srcu); | 1754 | index = srcu_read_lock(&dquot_srcu); |
1783 | spin_lock(&dq_data_lock); | 1755 | spin_lock(&inode->i_lock); |
1784 | /* Claim reserved quotas to allocated quotas */ | 1756 | /* Claim reserved quotas to allocated quotas */ |
1785 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1757 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1786 | if (dquots[cnt]) | 1758 | if (dquots[cnt]) { |
1787 | dquot_claim_reserved_space(dquots[cnt], number); | 1759 | struct dquot *dquot = dquots[cnt]; |
1760 | |||
1761 | spin_lock(&dquot->dq_dqb_lock); | ||
1762 | if (WARN_ON_ONCE(dquot->dq_dqb.dqb_rsvspace < number)) | ||
1763 | number = dquot->dq_dqb.dqb_rsvspace; | ||
1764 | dquot->dq_dqb.dqb_curspace += number; | ||
1765 | dquot->dq_dqb.dqb_rsvspace -= number; | ||
1766 | spin_unlock(&dquot->dq_dqb_lock); | ||
1767 | } | ||
1788 | } | 1768 | } |
1789 | /* Update inode bytes */ | 1769 | /* Update inode bytes */ |
1790 | inode_claim_rsv_space(inode, number); | 1770 | *inode_reserved_space(inode) -= number; |
1791 | spin_unlock(&dq_data_lock); | 1771 | __inode_add_bytes(inode, number); |
1772 | spin_unlock(&inode->i_lock); | ||
1792 | mark_all_dquot_dirty(dquots); | 1773 | mark_all_dquot_dirty(dquots); |
1793 | srcu_read_unlock(&dquot_srcu, index); | 1774 | srcu_read_unlock(&dquot_srcu, index); |
1794 | return 0; | 1775 | return 0; |
@@ -1804,21 +1785,33 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) | |||
1804 | int cnt, index; | 1785 | int cnt, index; |
1805 | 1786 | ||
1806 | if (!dquot_active(inode)) { | 1787 | if (!dquot_active(inode)) { |
1807 | inode_reclaim_rsv_space(inode, number); | 1788 | spin_lock(&inode->i_lock); |
1789 | *inode_reserved_space(inode) += number; | ||
1790 | __inode_sub_bytes(inode, number); | ||
1791 | spin_unlock(&inode->i_lock); | ||
1808 | return; | 1792 | return; |
1809 | } | 1793 | } |
1810 | 1794 | ||
1811 | dquots = i_dquot(inode); | 1795 | dquots = i_dquot(inode); |
1812 | index = srcu_read_lock(&dquot_srcu); | 1796 | index = srcu_read_lock(&dquot_srcu); |
1813 | spin_lock(&dq_data_lock); | 1797 | spin_lock(&inode->i_lock); |
1814 | /* Claim reserved quotas to allocated quotas */ | 1798 | /* Claim reserved quotas to allocated quotas */ |
1815 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1799 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1816 | if (dquots[cnt]) | 1800 | if (dquots[cnt]) { |
1817 | dquot_reclaim_reserved_space(dquots[cnt], number); | 1801 | struct dquot *dquot = dquots[cnt]; |
1802 | |||
1803 | spin_lock(&dquot->dq_dqb_lock); | ||
1804 | if (WARN_ON_ONCE(dquot->dq_dqb.dqb_curspace < number)) | ||
1805 | number = dquot->dq_dqb.dqb_curspace; | ||
1806 | dquot->dq_dqb.dqb_rsvspace += number; | ||
1807 | dquot->dq_dqb.dqb_curspace -= number; | ||
1808 | spin_unlock(&dquot->dq_dqb_lock); | ||
1809 | } | ||
1818 | } | 1810 | } |
1819 | /* Update inode bytes */ | 1811 | /* Update inode bytes */ |
1820 | inode_reclaim_rsv_space(inode, number); | 1812 | *inode_reserved_space(inode) += number; |
1821 | spin_unlock(&dq_data_lock); | 1813 | __inode_sub_bytes(inode, number); |
1814 | spin_unlock(&inode->i_lock); | ||
1822 | mark_all_dquot_dirty(dquots); | 1815 | mark_all_dquot_dirty(dquots); |
1823 | srcu_read_unlock(&dquot_srcu, index); | 1816 | srcu_read_unlock(&dquot_srcu, index); |
1824 | return; | 1817 | return; |
@@ -1836,19 +1829,26 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | |||
1836 | int reserve = flags & DQUOT_SPACE_RESERVE, index; | 1829 | int reserve = flags & DQUOT_SPACE_RESERVE, index; |
1837 | 1830 | ||
1838 | if (!dquot_active(inode)) { | 1831 | if (!dquot_active(inode)) { |
1839 | inode_decr_space(inode, number, reserve); | 1832 | if (reserve) { |
1833 | spin_lock(&inode->i_lock); | ||
1834 | *inode_reserved_space(inode) -= number; | ||
1835 | spin_unlock(&inode->i_lock); | ||
1836 | } else { | ||
1837 | inode_sub_bytes(inode, number); | ||
1838 | } | ||
1840 | return; | 1839 | return; |
1841 | } | 1840 | } |
1842 | 1841 | ||
1843 | dquots = i_dquot(inode); | 1842 | dquots = i_dquot(inode); |
1844 | index = srcu_read_lock(&dquot_srcu); | 1843 | index = srcu_read_lock(&dquot_srcu); |
1845 | spin_lock(&dq_data_lock); | 1844 | spin_lock(&inode->i_lock); |
1846 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1845 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1847 | int wtype; | 1846 | int wtype; |
1848 | 1847 | ||
1849 | warn[cnt].w_type = QUOTA_NL_NOWARN; | 1848 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
1850 | if (!dquots[cnt]) | 1849 | if (!dquots[cnt]) |
1851 | continue; | 1850 | continue; |
1851 | spin_lock(&dquots[cnt]->dq_dqb_lock); | ||
1852 | wtype = info_bdq_free(dquots[cnt], number); | 1852 | wtype = info_bdq_free(dquots[cnt], number); |
1853 | if (wtype != QUOTA_NL_NOWARN) | 1853 | if (wtype != QUOTA_NL_NOWARN) |
1854 | prepare_warning(&warn[cnt], dquots[cnt], wtype); | 1854 | prepare_warning(&warn[cnt], dquots[cnt], wtype); |
@@ -1856,9 +1856,13 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | |||
1856 | dquot_free_reserved_space(dquots[cnt], number); | 1856 | dquot_free_reserved_space(dquots[cnt], number); |
1857 | else | 1857 | else |
1858 | dquot_decr_space(dquots[cnt], number); | 1858 | dquot_decr_space(dquots[cnt], number); |
1859 | spin_unlock(&dquots[cnt]->dq_dqb_lock); | ||
1859 | } | 1860 | } |
1860 | inode_decr_space(inode, number, reserve); | 1861 | if (reserve) |
1861 | spin_unlock(&dq_data_lock); | 1862 | *inode_reserved_space(inode) -= number; |
1863 | else | ||
1864 | __inode_sub_bytes(inode, number); | ||
1865 | spin_unlock(&inode->i_lock); | ||
1862 | 1866 | ||
1863 | if (reserve) | 1867 | if (reserve) |
1864 | goto out_unlock; | 1868 | goto out_unlock; |
@@ -1884,19 +1888,21 @@ void dquot_free_inode(struct inode *inode) | |||
1884 | 1888 | ||
1885 | dquots = i_dquot(inode); | 1889 | dquots = i_dquot(inode); |
1886 | index = srcu_read_lock(&dquot_srcu); | 1890 | index = srcu_read_lock(&dquot_srcu); |
1887 | spin_lock(&dq_data_lock); | 1891 | spin_lock(&inode->i_lock); |
1888 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1892 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1889 | int wtype; | 1893 | int wtype; |
1890 | 1894 | ||
1891 | warn[cnt].w_type = QUOTA_NL_NOWARN; | 1895 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
1892 | if (!dquots[cnt]) | 1896 | if (!dquots[cnt]) |
1893 | continue; | 1897 | continue; |
1898 | spin_lock(&dquots[cnt]->dq_dqb_lock); | ||
1894 | wtype = info_idq_free(dquots[cnt], 1); | 1899 | wtype = info_idq_free(dquots[cnt], 1); |
1895 | if (wtype != QUOTA_NL_NOWARN) | 1900 | if (wtype != QUOTA_NL_NOWARN) |
1896 | prepare_warning(&warn[cnt], dquots[cnt], wtype); | 1901 | prepare_warning(&warn[cnt], dquots[cnt], wtype); |
1897 | dquot_decr_inodes(dquots[cnt], 1); | 1902 | dquot_decr_inodes(dquots[cnt], 1); |
1903 | spin_unlock(&dquots[cnt]->dq_dqb_lock); | ||
1898 | } | 1904 | } |
1899 | spin_unlock(&dq_data_lock); | 1905 | spin_unlock(&inode->i_lock); |
1900 | mark_all_dquot_dirty(dquots); | 1906 | mark_all_dquot_dirty(dquots); |
1901 | srcu_read_unlock(&dquot_srcu, index); | 1907 | srcu_read_unlock(&dquot_srcu, index); |
1902 | flush_warnings(warn); | 1908 | flush_warnings(warn); |
@@ -1917,7 +1923,7 @@ EXPORT_SYMBOL(dquot_free_inode); | |||
1917 | */ | 1923 | */ |
1918 | int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | 1924 | int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) |
1919 | { | 1925 | { |
1920 | qsize_t space, cur_space; | 1926 | qsize_t cur_space; |
1921 | qsize_t rsv_space = 0; | 1927 | qsize_t rsv_space = 0; |
1922 | qsize_t inode_usage = 1; | 1928 | qsize_t inode_usage = 1; |
1923 | struct dquot *transfer_from[MAXQUOTAS] = {}; | 1929 | struct dquot *transfer_from[MAXQUOTAS] = {}; |
@@ -1944,14 +1950,18 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1944 | } | 1950 | } |
1945 | 1951 | ||
1946 | spin_lock(&dq_data_lock); | 1952 | spin_lock(&dq_data_lock); |
1953 | spin_lock(&inode->i_lock); | ||
1947 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ | 1954 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ |
1955 | spin_unlock(&inode->i_lock); | ||
1948 | spin_unlock(&dq_data_lock); | 1956 | spin_unlock(&dq_data_lock); |
1949 | return 0; | 1957 | return 0; |
1950 | } | 1958 | } |
1951 | cur_space = inode_get_bytes(inode); | 1959 | cur_space = __inode_get_bytes(inode); |
1952 | rsv_space = inode_get_rsv_space(inode); | 1960 | rsv_space = __inode_get_rsv_space(inode); |
1953 | space = cur_space + rsv_space; | 1961 | /* |
1954 | /* Build the transfer_from list and check the limits */ | 1962 | * Build the transfer_from list, check limits, and update usage in |
1963 | * the target structures. | ||
1964 | */ | ||
1955 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1965 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1956 | /* | 1966 | /* |
1957 | * Skip changes for same uid or gid or for turned off quota-type. | 1967 | * Skip changes for same uid or gid or for turned off quota-type. |
@@ -1963,28 +1973,33 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1963 | continue; | 1973 | continue; |
1964 | is_valid[cnt] = 1; | 1974 | is_valid[cnt] = 1; |
1965 | transfer_from[cnt] = i_dquot(inode)[cnt]; | 1975 | transfer_from[cnt] = i_dquot(inode)[cnt]; |
1966 | ret = check_idq(transfer_to[cnt], inode_usage, &warn_to[cnt]); | 1976 | ret = dquot_add_inodes(transfer_to[cnt], inode_usage, |
1977 | &warn_to[cnt]); | ||
1967 | if (ret) | 1978 | if (ret) |
1968 | goto over_quota; | 1979 | goto over_quota; |
1969 | ret = check_bdq(transfer_to[cnt], space, 0, &warn_to[cnt]); | 1980 | ret = dquot_add_space(transfer_to[cnt], cur_space, rsv_space, 0, |
1970 | if (ret) | 1981 | &warn_to[cnt]); |
1982 | if (ret) { | ||
1983 | dquot_decr_inodes(transfer_to[cnt], inode_usage); | ||
1971 | goto over_quota; | 1984 | goto over_quota; |
1985 | } | ||
1972 | } | 1986 | } |
1973 | 1987 | ||
1974 | /* | 1988 | /* Decrease usage for source structures and update quota pointers */ |
1975 | * Finally perform the needed transfer from transfer_from to transfer_to | ||
1976 | */ | ||
1977 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1989 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1978 | if (!is_valid[cnt]) | 1990 | if (!is_valid[cnt]) |
1979 | continue; | 1991 | continue; |
1980 | /* Due to IO error we might not have transfer_from[] structure */ | 1992 | /* Due to IO error we might not have transfer_from[] structure */ |
1981 | if (transfer_from[cnt]) { | 1993 | if (transfer_from[cnt]) { |
1982 | int wtype; | 1994 | int wtype; |
1995 | |||
1996 | spin_lock(&transfer_from[cnt]->dq_dqb_lock); | ||
1983 | wtype = info_idq_free(transfer_from[cnt], inode_usage); | 1997 | wtype = info_idq_free(transfer_from[cnt], inode_usage); |
1984 | if (wtype != QUOTA_NL_NOWARN) | 1998 | if (wtype != QUOTA_NL_NOWARN) |
1985 | prepare_warning(&warn_from_inodes[cnt], | 1999 | prepare_warning(&warn_from_inodes[cnt], |
1986 | transfer_from[cnt], wtype); | 2000 | transfer_from[cnt], wtype); |
1987 | wtype = info_bdq_free(transfer_from[cnt], space); | 2001 | wtype = info_bdq_free(transfer_from[cnt], |
2002 | cur_space + rsv_space); | ||
1988 | if (wtype != QUOTA_NL_NOWARN) | 2003 | if (wtype != QUOTA_NL_NOWARN) |
1989 | prepare_warning(&warn_from_space[cnt], | 2004 | prepare_warning(&warn_from_space[cnt], |
1990 | transfer_from[cnt], wtype); | 2005 | transfer_from[cnt], wtype); |
@@ -1992,14 +2007,11 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1992 | dquot_decr_space(transfer_from[cnt], cur_space); | 2007 | dquot_decr_space(transfer_from[cnt], cur_space); |
1993 | dquot_free_reserved_space(transfer_from[cnt], | 2008 | dquot_free_reserved_space(transfer_from[cnt], |
1994 | rsv_space); | 2009 | rsv_space); |
2010 | spin_unlock(&transfer_from[cnt]->dq_dqb_lock); | ||
1995 | } | 2011 | } |
1996 | |||
1997 | dquot_incr_inodes(transfer_to[cnt], inode_usage); | ||
1998 | dquot_incr_space(transfer_to[cnt], cur_space); | ||
1999 | dquot_resv_space(transfer_to[cnt], rsv_space); | ||
2000 | |||
2001 | i_dquot(inode)[cnt] = transfer_to[cnt]; | 2012 | i_dquot(inode)[cnt] = transfer_to[cnt]; |
2002 | } | 2013 | } |
2014 | spin_unlock(&inode->i_lock); | ||
2003 | spin_unlock(&dq_data_lock); | 2015 | spin_unlock(&dq_data_lock); |
2004 | 2016 | ||
2005 | mark_all_dquot_dirty(transfer_from); | 2017 | mark_all_dquot_dirty(transfer_from); |
@@ -2013,6 +2025,17 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
2013 | transfer_to[cnt] = transfer_from[cnt]; | 2025 | transfer_to[cnt] = transfer_from[cnt]; |
2014 | return 0; | 2026 | return 0; |
2015 | over_quota: | 2027 | over_quota: |
2028 | /* Back out changes we already did */ | ||
2029 | for (cnt--; cnt >= 0; cnt--) { | ||
2030 | if (!is_valid[cnt]) | ||
2031 | continue; | ||
2032 | spin_lock(&transfer_to[cnt]->dq_dqb_lock); | ||
2033 | dquot_decr_inodes(transfer_to[cnt], inode_usage); | ||
2034 | dquot_decr_space(transfer_to[cnt], cur_space); | ||
2035 | dquot_free_reserved_space(transfer_to[cnt], rsv_space); | ||
2036 | spin_unlock(&transfer_to[cnt]->dq_dqb_lock); | ||
2037 | } | ||
2038 | spin_unlock(&inode->i_lock); | ||
2016 | spin_unlock(&dq_data_lock); | 2039 | spin_unlock(&dq_data_lock); |
2017 | flush_warnings(warn_to); | 2040 | flush_warnings(warn_to); |
2018 | return ret; | 2041 | return ret; |
@@ -2066,29 +2089,21 @@ EXPORT_SYMBOL(dquot_transfer); | |||
2066 | */ | 2089 | */ |
2067 | int dquot_commit_info(struct super_block *sb, int type) | 2090 | int dquot_commit_info(struct super_block *sb, int type) |
2068 | { | 2091 | { |
2069 | int ret; | ||
2070 | struct quota_info *dqopt = sb_dqopt(sb); | 2092 | struct quota_info *dqopt = sb_dqopt(sb); |
2071 | 2093 | ||
2072 | mutex_lock(&dqopt->dqio_mutex); | 2094 | return dqopt->ops[type]->write_file_info(sb, type); |
2073 | ret = dqopt->ops[type]->write_file_info(sb, type); | ||
2074 | mutex_unlock(&dqopt->dqio_mutex); | ||
2075 | return ret; | ||
2076 | } | 2095 | } |
2077 | EXPORT_SYMBOL(dquot_commit_info); | 2096 | EXPORT_SYMBOL(dquot_commit_info); |
2078 | 2097 | ||
2079 | int dquot_get_next_id(struct super_block *sb, struct kqid *qid) | 2098 | int dquot_get_next_id(struct super_block *sb, struct kqid *qid) |
2080 | { | 2099 | { |
2081 | struct quota_info *dqopt = sb_dqopt(sb); | 2100 | struct quota_info *dqopt = sb_dqopt(sb); |
2082 | int err; | ||
2083 | 2101 | ||
2084 | if (!sb_has_quota_active(sb, qid->type)) | 2102 | if (!sb_has_quota_active(sb, qid->type)) |
2085 | return -ESRCH; | 2103 | return -ESRCH; |
2086 | if (!dqopt->ops[qid->type]->get_next_id) | 2104 | if (!dqopt->ops[qid->type]->get_next_id) |
2087 | return -ENOSYS; | 2105 | return -ENOSYS; |
2088 | mutex_lock(&dqopt->dqio_mutex); | 2106 | return dqopt->ops[qid->type]->get_next_id(sb, qid); |
2089 | err = dqopt->ops[qid->type]->get_next_id(sb, qid); | ||
2090 | mutex_unlock(&dqopt->dqio_mutex); | ||
2091 | return err; | ||
2092 | } | 2107 | } |
2093 | EXPORT_SYMBOL(dquot_get_next_id); | 2108 | EXPORT_SYMBOL(dquot_get_next_id); |
2094 | 2109 | ||
@@ -2337,15 +2352,14 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, | |||
2337 | dqopt->info[type].dqi_format = fmt; | 2352 | dqopt->info[type].dqi_format = fmt; |
2338 | dqopt->info[type].dqi_fmt_id = format_id; | 2353 | dqopt->info[type].dqi_fmt_id = format_id; |
2339 | INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); | 2354 | INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); |
2340 | mutex_lock(&dqopt->dqio_mutex); | ||
2341 | error = dqopt->ops[type]->read_file_info(sb, type); | 2355 | error = dqopt->ops[type]->read_file_info(sb, type); |
2342 | if (error < 0) { | 2356 | if (error < 0) |
2343 | mutex_unlock(&dqopt->dqio_mutex); | ||
2344 | goto out_file_init; | 2357 | goto out_file_init; |
2345 | } | 2358 | if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) { |
2346 | if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) | 2359 | spin_lock(&dq_data_lock); |
2347 | dqopt->info[type].dqi_flags |= DQF_SYS_FILE; | 2360 | dqopt->info[type].dqi_flags |= DQF_SYS_FILE; |
2348 | mutex_unlock(&dqopt->dqio_mutex); | 2361 | spin_unlock(&dq_data_lock); |
2362 | } | ||
2349 | spin_lock(&dq_state_lock); | 2363 | spin_lock(&dq_state_lock); |
2350 | dqopt->flags |= dquot_state_flag(flags, type); | 2364 | dqopt->flags |= dquot_state_flag(flags, type); |
2351 | spin_unlock(&dq_state_lock); | 2365 | spin_unlock(&dq_state_lock); |
@@ -2572,7 +2586,7 @@ static void do_get_dqblk(struct dquot *dquot, struct qc_dqblk *di) | |||
2572 | struct mem_dqblk *dm = &dquot->dq_dqb; | 2586 | struct mem_dqblk *dm = &dquot->dq_dqb; |
2573 | 2587 | ||
2574 | memset(di, 0, sizeof(*di)); | 2588 | memset(di, 0, sizeof(*di)); |
2575 | spin_lock(&dq_data_lock); | 2589 | spin_lock(&dquot->dq_dqb_lock); |
2576 | di->d_spc_hardlimit = dm->dqb_bhardlimit; | 2590 | di->d_spc_hardlimit = dm->dqb_bhardlimit; |
2577 | di->d_spc_softlimit = dm->dqb_bsoftlimit; | 2591 | di->d_spc_softlimit = dm->dqb_bsoftlimit; |
2578 | di->d_ino_hardlimit = dm->dqb_ihardlimit; | 2592 | di->d_ino_hardlimit = dm->dqb_ihardlimit; |
@@ -2581,7 +2595,7 @@ static void do_get_dqblk(struct dquot *dquot, struct qc_dqblk *di) | |||
2581 | di->d_ino_count = dm->dqb_curinodes; | 2595 | di->d_ino_count = dm->dqb_curinodes; |
2582 | di->d_spc_timer = dm->dqb_btime; | 2596 | di->d_spc_timer = dm->dqb_btime; |
2583 | di->d_ino_timer = dm->dqb_itime; | 2597 | di->d_ino_timer = dm->dqb_itime; |
2584 | spin_unlock(&dq_data_lock); | 2598 | spin_unlock(&dquot->dq_dqb_lock); |
2585 | } | 2599 | } |
2586 | 2600 | ||
2587 | int dquot_get_dqblk(struct super_block *sb, struct kqid qid, | 2601 | int dquot_get_dqblk(struct super_block *sb, struct kqid qid, |
@@ -2645,7 +2659,7 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di) | |||
2645 | (di->d_ino_hardlimit > dqi->dqi_max_ino_limit))) | 2659 | (di->d_ino_hardlimit > dqi->dqi_max_ino_limit))) |
2646 | return -ERANGE; | 2660 | return -ERANGE; |
2647 | 2661 | ||
2648 | spin_lock(&dq_data_lock); | 2662 | spin_lock(&dquot->dq_dqb_lock); |
2649 | if (di->d_fieldmask & QC_SPACE) { | 2663 | if (di->d_fieldmask & QC_SPACE) { |
2650 | dm->dqb_curspace = di->d_space - dm->dqb_rsvspace; | 2664 | dm->dqb_curspace = di->d_space - dm->dqb_rsvspace; |
2651 | check_blim = 1; | 2665 | check_blim = 1; |
@@ -2711,7 +2725,7 @@ static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di) | |||
2711 | clear_bit(DQ_FAKE_B, &dquot->dq_flags); | 2725 | clear_bit(DQ_FAKE_B, &dquot->dq_flags); |
2712 | else | 2726 | else |
2713 | set_bit(DQ_FAKE_B, &dquot->dq_flags); | 2727 | set_bit(DQ_FAKE_B, &dquot->dq_flags); |
2714 | spin_unlock(&dq_data_lock); | 2728 | spin_unlock(&dquot->dq_dqb_lock); |
2715 | mark_dquot_dirty(dquot); | 2729 | mark_dquot_dirty(dquot); |
2716 | 2730 | ||
2717 | return 0; | 2731 | return 0; |
diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c index 0738972e8d3f..bb3f59bcfcf5 100644 --- a/fs/quota/quota_tree.c +++ b/fs/quota/quota_tree.c | |||
@@ -379,7 +379,7 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | |||
379 | if (!ddquot) | 379 | if (!ddquot) |
380 | return -ENOMEM; | 380 | return -ENOMEM; |
381 | 381 | ||
382 | /* dq_off is guarded by dqio_mutex */ | 382 | /* dq_off is guarded by dqio_sem */ |
383 | if (!dquot->dq_off) { | 383 | if (!dquot->dq_off) { |
384 | ret = dq_insert_tree(info, dquot); | 384 | ret = dq_insert_tree(info, dquot); |
385 | if (ret < 0) { | 385 | if (ret < 0) { |
@@ -389,9 +389,9 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | |||
389 | return ret; | 389 | return ret; |
390 | } | 390 | } |
391 | } | 391 | } |
392 | spin_lock(&dq_data_lock); | 392 | spin_lock(&dquot->dq_dqb_lock); |
393 | info->dqi_ops->mem2disk_dqblk(ddquot, dquot); | 393 | info->dqi_ops->mem2disk_dqblk(ddquot, dquot); |
394 | spin_unlock(&dq_data_lock); | 394 | spin_unlock(&dquot->dq_dqb_lock); |
395 | ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size, | 395 | ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size, |
396 | dquot->dq_off); | 396 | dquot->dq_off); |
397 | if (ret != info->dqi_entry_size) { | 397 | if (ret != info->dqi_entry_size) { |
@@ -649,14 +649,14 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | |||
649 | kfree(ddquot); | 649 | kfree(ddquot); |
650 | goto out; | 650 | goto out; |
651 | } | 651 | } |
652 | spin_lock(&dq_data_lock); | 652 | spin_lock(&dquot->dq_dqb_lock); |
653 | info->dqi_ops->disk2mem_dqblk(dquot, ddquot); | 653 | info->dqi_ops->disk2mem_dqblk(dquot, ddquot); |
654 | if (!dquot->dq_dqb.dqb_bhardlimit && | 654 | if (!dquot->dq_dqb.dqb_bhardlimit && |
655 | !dquot->dq_dqb.dqb_bsoftlimit && | 655 | !dquot->dq_dqb.dqb_bsoftlimit && |
656 | !dquot->dq_dqb.dqb_ihardlimit && | 656 | !dquot->dq_dqb.dqb_ihardlimit && |
657 | !dquot->dq_dqb.dqb_isoftlimit) | 657 | !dquot->dq_dqb.dqb_isoftlimit) |
658 | set_bit(DQ_FAKE_B, &dquot->dq_flags); | 658 | set_bit(DQ_FAKE_B, &dquot->dq_flags); |
659 | spin_unlock(&dq_data_lock); | 659 | spin_unlock(&dquot->dq_dqb_lock); |
660 | kfree(ddquot); | 660 | kfree(ddquot); |
661 | out: | 661 | out: |
662 | dqstats_inc(DQST_READS); | 662 | dqstats_inc(DQST_READS); |
diff --git a/fs/quota/quota_v1.c b/fs/quota/quota_v1.c index 8fe79beced5c..7ac5298aba70 100644 --- a/fs/quota/quota_v1.c +++ b/fs/quota/quota_v1.c | |||
@@ -56,8 +56,9 @@ static int v1_read_dqblk(struct dquot *dquot) | |||
56 | { | 56 | { |
57 | int type = dquot->dq_id.type; | 57 | int type = dquot->dq_id.type; |
58 | struct v1_disk_dqblk dqblk; | 58 | struct v1_disk_dqblk dqblk; |
59 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); | ||
59 | 60 | ||
60 | if (!sb_dqopt(dquot->dq_sb)->files[type]) | 61 | if (!dqopt->files[type]) |
61 | return -EINVAL; | 62 | return -EINVAL; |
62 | 63 | ||
63 | /* Set structure to 0s in case read fails/is after end of file */ | 64 | /* Set structure to 0s in case read fails/is after end of file */ |
@@ -160,6 +161,7 @@ static int v1_read_file_info(struct super_block *sb, int type) | |||
160 | struct v1_disk_dqblk dqblk; | 161 | struct v1_disk_dqblk dqblk; |
161 | int ret; | 162 | int ret; |
162 | 163 | ||
164 | down_read(&dqopt->dqio_sem); | ||
163 | ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, | 165 | ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, |
164 | sizeof(struct v1_disk_dqblk), v1_dqoff(0)); | 166 | sizeof(struct v1_disk_dqblk), v1_dqoff(0)); |
165 | if (ret != sizeof(struct v1_disk_dqblk)) { | 167 | if (ret != sizeof(struct v1_disk_dqblk)) { |
@@ -176,6 +178,7 @@ static int v1_read_file_info(struct super_block *sb, int type) | |||
176 | dqopt->info[type].dqi_bgrace = | 178 | dqopt->info[type].dqi_bgrace = |
177 | dqblk.dqb_btime ? dqblk.dqb_btime : MAX_DQ_TIME; | 179 | dqblk.dqb_btime ? dqblk.dqb_btime : MAX_DQ_TIME; |
178 | out: | 180 | out: |
181 | up_read(&dqopt->dqio_sem); | ||
179 | return ret; | 182 | return ret; |
180 | } | 183 | } |
181 | 184 | ||
@@ -185,7 +188,7 @@ static int v1_write_file_info(struct super_block *sb, int type) | |||
185 | struct v1_disk_dqblk dqblk; | 188 | struct v1_disk_dqblk dqblk; |
186 | int ret; | 189 | int ret; |
187 | 190 | ||
188 | dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY; | 191 | down_write(&dqopt->dqio_sem); |
189 | ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, | 192 | ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, |
190 | sizeof(struct v1_disk_dqblk), v1_dqoff(0)); | 193 | sizeof(struct v1_disk_dqblk), v1_dqoff(0)); |
191 | if (ret != sizeof(struct v1_disk_dqblk)) { | 194 | if (ret != sizeof(struct v1_disk_dqblk)) { |
@@ -193,8 +196,11 @@ static int v1_write_file_info(struct super_block *sb, int type) | |||
193 | ret = -EIO; | 196 | ret = -EIO; |
194 | goto out; | 197 | goto out; |
195 | } | 198 | } |
199 | spin_lock(&dq_data_lock); | ||
200 | dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY; | ||
196 | dqblk.dqb_itime = dqopt->info[type].dqi_igrace; | 201 | dqblk.dqb_itime = dqopt->info[type].dqi_igrace; |
197 | dqblk.dqb_btime = dqopt->info[type].dqi_bgrace; | 202 | dqblk.dqb_btime = dqopt->info[type].dqi_bgrace; |
203 | spin_unlock(&dq_data_lock); | ||
198 | ret = sb->s_op->quota_write(sb, type, (char *)&dqblk, | 204 | ret = sb->s_op->quota_write(sb, type, (char *)&dqblk, |
199 | sizeof(struct v1_disk_dqblk), v1_dqoff(0)); | 205 | sizeof(struct v1_disk_dqblk), v1_dqoff(0)); |
200 | if (ret == sizeof(struct v1_disk_dqblk)) | 206 | if (ret == sizeof(struct v1_disk_dqblk)) |
@@ -202,6 +208,7 @@ static int v1_write_file_info(struct super_block *sb, int type) | |||
202 | else if (ret > 0) | 208 | else if (ret > 0) |
203 | ret = -EIO; | 209 | ret = -EIO; |
204 | out: | 210 | out: |
211 | up_write(&dqopt->dqio_sem); | ||
205 | return ret; | 212 | return ret; |
206 | } | 213 | } |
207 | 214 | ||
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index 2259329616b7..c0187cda2c1e 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c | |||
@@ -65,9 +65,11 @@ static int v2_read_header(struct super_block *sb, int type, | |||
65 | if (size != sizeof(struct v2_disk_dqheader)) { | 65 | if (size != sizeof(struct v2_disk_dqheader)) { |
66 | quota_error(sb, "Failed header read: expected=%zd got=%zd", | 66 | quota_error(sb, "Failed header read: expected=%zd got=%zd", |
67 | sizeof(struct v2_disk_dqheader), size); | 67 | sizeof(struct v2_disk_dqheader), size); |
68 | return 0; | 68 | if (size < 0) |
69 | return size; | ||
70 | return -EIO; | ||
69 | } | 71 | } |
70 | return 1; | 72 | return 0; |
71 | } | 73 | } |
72 | 74 | ||
73 | /* Check whether given file is really vfsv0 quotafile */ | 75 | /* Check whether given file is really vfsv0 quotafile */ |
@@ -77,7 +79,7 @@ static int v2_check_quota_file(struct super_block *sb, int type) | |||
77 | static const uint quota_magics[] = V2_INITQMAGICS; | 79 | static const uint quota_magics[] = V2_INITQMAGICS; |
78 | static const uint quota_versions[] = V2_INITQVERSIONS; | 80 | static const uint quota_versions[] = V2_INITQVERSIONS; |
79 | 81 | ||
80 | if (!v2_read_header(sb, type, &dqhead)) | 82 | if (v2_read_header(sb, type, &dqhead)) |
81 | return 0; | 83 | return 0; |
82 | if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] || | 84 | if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] || |
83 | le32_to_cpu(dqhead.dqh_version) > quota_versions[type]) | 85 | le32_to_cpu(dqhead.dqh_version) > quota_versions[type]) |
@@ -90,28 +92,39 @@ static int v2_read_file_info(struct super_block *sb, int type) | |||
90 | { | 92 | { |
91 | struct v2_disk_dqinfo dinfo; | 93 | struct v2_disk_dqinfo dinfo; |
92 | struct v2_disk_dqheader dqhead; | 94 | struct v2_disk_dqheader dqhead; |
93 | struct mem_dqinfo *info = sb_dqinfo(sb, type); | 95 | struct quota_info *dqopt = sb_dqopt(sb); |
96 | struct mem_dqinfo *info = &dqopt->info[type]; | ||
94 | struct qtree_mem_dqinfo *qinfo; | 97 | struct qtree_mem_dqinfo *qinfo; |
95 | ssize_t size; | 98 | ssize_t size; |
96 | unsigned int version; | 99 | unsigned int version; |
100 | int ret; | ||
97 | 101 | ||
98 | if (!v2_read_header(sb, type, &dqhead)) | 102 | down_read(&dqopt->dqio_sem); |
99 | return -1; | 103 | ret = v2_read_header(sb, type, &dqhead); |
104 | if (ret < 0) | ||
105 | goto out; | ||
100 | version = le32_to_cpu(dqhead.dqh_version); | 106 | version = le32_to_cpu(dqhead.dqh_version); |
101 | if ((info->dqi_fmt_id == QFMT_VFS_V0 && version != 0) || | 107 | if ((info->dqi_fmt_id == QFMT_VFS_V0 && version != 0) || |
102 | (info->dqi_fmt_id == QFMT_VFS_V1 && version != 1)) | 108 | (info->dqi_fmt_id == QFMT_VFS_V1 && version != 1)) { |
103 | return -1; | 109 | ret = -EINVAL; |
110 | goto out; | ||
111 | } | ||
104 | 112 | ||
105 | size = sb->s_op->quota_read(sb, type, (char *)&dinfo, | 113 | size = sb->s_op->quota_read(sb, type, (char *)&dinfo, |
106 | sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); | 114 | sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); |
107 | if (size != sizeof(struct v2_disk_dqinfo)) { | 115 | if (size != sizeof(struct v2_disk_dqinfo)) { |
108 | quota_error(sb, "Can't read info structure"); | 116 | quota_error(sb, "Can't read info structure"); |
109 | return -1; | 117 | if (size < 0) |
118 | ret = size; | ||
119 | else | ||
120 | ret = -EIO; | ||
121 | goto out; | ||
110 | } | 122 | } |
111 | info->dqi_priv = kmalloc(sizeof(struct qtree_mem_dqinfo), GFP_NOFS); | 123 | info->dqi_priv = kmalloc(sizeof(struct qtree_mem_dqinfo), GFP_NOFS); |
112 | if (!info->dqi_priv) | 124 | if (!info->dqi_priv) { |
113 | return -ENOMEM; | 125 | ret = -ENOMEM; |
114 | 126 | goto out; | |
127 | } | ||
115 | qinfo = info->dqi_priv; | 128 | qinfo = info->dqi_priv; |
116 | if (version == 0) { | 129 | if (version == 0) { |
117 | /* limits are stored as unsigned 32-bit data */ | 130 | /* limits are stored as unsigned 32-bit data */ |
@@ -145,17 +158,22 @@ static int v2_read_file_info(struct super_block *sb, int type) | |||
145 | qinfo->dqi_entry_size = sizeof(struct v2r1_disk_dqblk); | 158 | qinfo->dqi_entry_size = sizeof(struct v2r1_disk_dqblk); |
146 | qinfo->dqi_ops = &v2r1_qtree_ops; | 159 | qinfo->dqi_ops = &v2r1_qtree_ops; |
147 | } | 160 | } |
148 | return 0; | 161 | ret = 0; |
162 | out: | ||
163 | up_read(&dqopt->dqio_sem); | ||
164 | return ret; | ||
149 | } | 165 | } |
150 | 166 | ||
151 | /* Write information header to quota file */ | 167 | /* Write information header to quota file */ |
152 | static int v2_write_file_info(struct super_block *sb, int type) | 168 | static int v2_write_file_info(struct super_block *sb, int type) |
153 | { | 169 | { |
154 | struct v2_disk_dqinfo dinfo; | 170 | struct v2_disk_dqinfo dinfo; |
155 | struct mem_dqinfo *info = sb_dqinfo(sb, type); | 171 | struct quota_info *dqopt = sb_dqopt(sb); |
172 | struct mem_dqinfo *info = &dqopt->info[type]; | ||
156 | struct qtree_mem_dqinfo *qinfo = info->dqi_priv; | 173 | struct qtree_mem_dqinfo *qinfo = info->dqi_priv; |
157 | ssize_t size; | 174 | ssize_t size; |
158 | 175 | ||
176 | down_write(&dqopt->dqio_sem); | ||
159 | spin_lock(&dq_data_lock); | 177 | spin_lock(&dq_data_lock); |
160 | info->dqi_flags &= ~DQF_INFO_DIRTY; | 178 | info->dqi_flags &= ~DQF_INFO_DIRTY; |
161 | dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace); | 179 | dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace); |
@@ -168,6 +186,7 @@ static int v2_write_file_info(struct super_block *sb, int type) | |||
168 | dinfo.dqi_free_entry = cpu_to_le32(qinfo->dqi_free_entry); | 186 | dinfo.dqi_free_entry = cpu_to_le32(qinfo->dqi_free_entry); |
169 | size = sb->s_op->quota_write(sb, type, (char *)&dinfo, | 187 | size = sb->s_op->quota_write(sb, type, (char *)&dinfo, |
170 | sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); | 188 | sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); |
189 | up_write(&dqopt->dqio_sem); | ||
171 | if (size != sizeof(struct v2_disk_dqinfo)) { | 190 | if (size != sizeof(struct v2_disk_dqinfo)) { |
172 | quota_error(sb, "Can't write info structure"); | 191 | quota_error(sb, "Can't write info structure"); |
173 | return -1; | 192 | return -1; |
@@ -283,17 +302,51 @@ static int v2r1_is_id(void *dp, struct dquot *dquot) | |||
283 | 302 | ||
284 | static int v2_read_dquot(struct dquot *dquot) | 303 | static int v2_read_dquot(struct dquot *dquot) |
285 | { | 304 | { |
286 | return qtree_read_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot); | 305 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); |
306 | int ret; | ||
307 | |||
308 | down_read(&dqopt->dqio_sem); | ||
309 | ret = qtree_read_dquot( | ||
310 | sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, | ||
311 | dquot); | ||
312 | up_read(&dqopt->dqio_sem); | ||
313 | return ret; | ||
287 | } | 314 | } |
288 | 315 | ||
289 | static int v2_write_dquot(struct dquot *dquot) | 316 | static int v2_write_dquot(struct dquot *dquot) |
290 | { | 317 | { |
291 | return qtree_write_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot); | 318 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); |
319 | int ret; | ||
320 | bool alloc = false; | ||
321 | |||
322 | /* | ||
323 | * If space for dquot is already allocated, we don't need any | ||
324 | * protection as we'll only overwrite the place of dquot. We are | ||
325 | * still protected by concurrent writes of the same dquot by | ||
326 | * dquot->dq_lock. | ||
327 | */ | ||
328 | if (!dquot->dq_off) { | ||
329 | alloc = true; | ||
330 | down_write(&dqopt->dqio_sem); | ||
331 | } | ||
332 | ret = qtree_write_dquot( | ||
333 | sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, | ||
334 | dquot); | ||
335 | if (alloc) | ||
336 | up_write(&dqopt->dqio_sem); | ||
337 | return ret; | ||
292 | } | 338 | } |
293 | 339 | ||
294 | static int v2_release_dquot(struct dquot *dquot) | 340 | static int v2_release_dquot(struct dquot *dquot) |
295 | { | 341 | { |
296 | return qtree_release_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot); | 342 | struct quota_info *dqopt = sb_dqopt(dquot->dq_sb); |
343 | int ret; | ||
344 | |||
345 | down_write(&dqopt->dqio_sem); | ||
346 | ret = qtree_release_dquot(sb_dqinfo(dquot->dq_sb, dquot->dq_id.type)->dqi_priv, dquot); | ||
347 | up_write(&dqopt->dqio_sem); | ||
348 | |||
349 | return ret; | ||
297 | } | 350 | } |
298 | 351 | ||
299 | static int v2_free_file_info(struct super_block *sb, int type) | 352 | static int v2_free_file_info(struct super_block *sb, int type) |
@@ -304,7 +357,13 @@ static int v2_free_file_info(struct super_block *sb, int type) | |||
304 | 357 | ||
305 | static int v2_get_next_id(struct super_block *sb, struct kqid *qid) | 358 | static int v2_get_next_id(struct super_block *sb, struct kqid *qid) |
306 | { | 359 | { |
307 | return qtree_get_next_id(sb_dqinfo(sb, qid->type)->dqi_priv, qid); | 360 | struct quota_info *dqopt = sb_dqopt(sb); |
361 | int ret; | ||
362 | |||
363 | down_read(&dqopt->dqio_sem); | ||
364 | ret = qtree_get_next_id(sb_dqinfo(sb, qid->type)->dqi_priv, qid); | ||
365 | up_read(&dqopt->dqio_sem); | ||
366 | return ret; | ||
308 | } | 367 | } |
309 | 368 | ||
310 | static const struct quota_format_ops v2_format_ops = { | 369 | static const struct quota_format_ops v2_format_ops = { |
@@ -710,7 +710,7 @@ loff_t inode_get_bytes(struct inode *inode) | |||
710 | loff_t ret; | 710 | loff_t ret; |
711 | 711 | ||
712 | spin_lock(&inode->i_lock); | 712 | spin_lock(&inode->i_lock); |
713 | ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; | 713 | ret = __inode_get_bytes(inode); |
714 | spin_unlock(&inode->i_lock); | 714 | spin_unlock(&inode->i_lock); |
715 | return ret; | 715 | return ret; |
716 | } | 716 | } |
diff --git a/fs/super.c b/fs/super.c index 6bc3352adcf3..221cfa1f4e92 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -242,7 +242,7 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags, | |||
242 | atomic_set(&s->s_active, 1); | 242 | atomic_set(&s->s_active, 1); |
243 | mutex_init(&s->s_vfs_rename_mutex); | 243 | mutex_init(&s->s_vfs_rename_mutex); |
244 | lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); | 244 | lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); |
245 | mutex_init(&s->s_dquot.dqio_mutex); | 245 | init_rwsem(&s->s_dquot.dqio_sem); |
246 | s->s_maxbytes = MAX_NON_LFS; | 246 | s->s_maxbytes = MAX_NON_LFS; |
247 | s->s_op = &default_op; | 247 | s->s_op = &default_op; |
248 | s->s_time_gran = 1000000000; | 248 | s->s_time_gran = 1000000000; |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 7d6079dceb39..509434aaf5a4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -3015,6 +3015,10 @@ void __inode_add_bytes(struct inode *inode, loff_t bytes); | |||
3015 | void inode_add_bytes(struct inode *inode, loff_t bytes); | 3015 | void inode_add_bytes(struct inode *inode, loff_t bytes); |
3016 | void __inode_sub_bytes(struct inode *inode, loff_t bytes); | 3016 | void __inode_sub_bytes(struct inode *inode, loff_t bytes); |
3017 | void inode_sub_bytes(struct inode *inode, loff_t bytes); | 3017 | void inode_sub_bytes(struct inode *inode, loff_t bytes); |
3018 | static inline loff_t __inode_get_bytes(struct inode *inode) | ||
3019 | { | ||
3020 | return (((loff_t)inode->i_blocks) << 9) + inode->i_bytes; | ||
3021 | } | ||
3018 | loff_t inode_get_bytes(struct inode *inode); | 3022 | loff_t inode_get_bytes(struct inode *inode); |
3019 | void inode_set_bytes(struct inode *inode, loff_t bytes); | 3023 | void inode_set_bytes(struct inode *inode, loff_t bytes); |
3020 | const char *simple_get_link(struct dentry *, struct inode *, | 3024 | const char *simple_get_link(struct dentry *, struct inode *, |
diff --git a/include/linux/quota.h b/include/linux/quota.h index bfd077ca6ac3..5ac9de4fcd6f 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h | |||
@@ -223,12 +223,12 @@ struct mem_dqinfo { | |||
223 | struct quota_format_type *dqi_format; | 223 | struct quota_format_type *dqi_format; |
224 | int dqi_fmt_id; /* Id of the dqi_format - used when turning | 224 | int dqi_fmt_id; /* Id of the dqi_format - used when turning |
225 | * quotas on after remount RW */ | 225 | * quotas on after remount RW */ |
226 | struct list_head dqi_dirty_list; /* List of dirty dquots */ | 226 | struct list_head dqi_dirty_list; /* List of dirty dquots [dq_list_lock] */ |
227 | unsigned long dqi_flags; | 227 | unsigned long dqi_flags; /* DFQ_ flags [dq_data_lock] */ |
228 | unsigned int dqi_bgrace; | 228 | unsigned int dqi_bgrace; /* Space grace time [dq_data_lock] */ |
229 | unsigned int dqi_igrace; | 229 | unsigned int dqi_igrace; /* Inode grace time [dq_data_lock] */ |
230 | qsize_t dqi_max_spc_limit; | 230 | qsize_t dqi_max_spc_limit; /* Maximum space limit [static] */ |
231 | qsize_t dqi_max_ino_limit; | 231 | qsize_t dqi_max_ino_limit; /* Maximum inode limit [static] */ |
232 | void *dqi_priv; | 232 | void *dqi_priv; |
233 | }; | 233 | }; |
234 | 234 | ||
@@ -293,18 +293,18 @@ static inline void dqstats_dec(unsigned int type) | |||
293 | * clear them when it sees fit. */ | 293 | * clear them when it sees fit. */ |
294 | 294 | ||
295 | struct dquot { | 295 | struct dquot { |
296 | struct hlist_node dq_hash; /* Hash list in memory */ | 296 | struct hlist_node dq_hash; /* Hash list in memory [dq_list_lock] */ |
297 | struct list_head dq_inuse; /* List of all quotas */ | 297 | struct list_head dq_inuse; /* List of all quotas [dq_list_lock] */ |
298 | struct list_head dq_free; /* Free list element */ | 298 | struct list_head dq_free; /* Free list element [dq_list_lock] */ |
299 | struct list_head dq_dirty; /* List of dirty dquots */ | 299 | struct list_head dq_dirty; /* List of dirty dquots [dq_list_lock] */ |
300 | struct mutex dq_lock; /* dquot IO lock */ | 300 | struct mutex dq_lock; /* dquot IO lock */ |
301 | spinlock_t dq_dqb_lock; /* Lock protecting dq_dqb changes */ | ||
301 | atomic_t dq_count; /* Use count */ | 302 | atomic_t dq_count; /* Use count */ |
302 | wait_queue_head_t dq_wait_unused; /* Wait queue for dquot to become unused */ | ||
303 | struct super_block *dq_sb; /* superblock this applies to */ | 303 | struct super_block *dq_sb; /* superblock this applies to */ |
304 | struct kqid dq_id; /* ID this applies to (uid, gid, projid) */ | 304 | struct kqid dq_id; /* ID this applies to (uid, gid, projid) */ |
305 | loff_t dq_off; /* Offset of dquot on disk */ | 305 | loff_t dq_off; /* Offset of dquot on disk [dq_lock, stable once set] */ |
306 | unsigned long dq_flags; /* See DQ_* */ | 306 | unsigned long dq_flags; /* See DQ_* */ |
307 | struct mem_dqblk dq_dqb; /* Diskquota usage */ | 307 | struct mem_dqblk dq_dqb; /* Diskquota usage [dq_dqb_lock] */ |
308 | }; | 308 | }; |
309 | 309 | ||
310 | /* Operations which must be implemented by each quota format */ | 310 | /* Operations which must be implemented by each quota format */ |
@@ -491,6 +491,9 @@ enum { | |||
491 | */ | 491 | */ |
492 | #define DQUOT_NEGATIVE_USAGE (1 << (DQUOT_STATE_LAST + 1)) | 492 | #define DQUOT_NEGATIVE_USAGE (1 << (DQUOT_STATE_LAST + 1)) |
493 | /* Allow negative quota usage */ | 493 | /* Allow negative quota usage */ |
494 | /* Do not track dirty dquots in a list */ | ||
495 | #define DQUOT_NOLIST_DIRTY (1 << (DQUOT_STATE_LAST + 2)) | ||
496 | |||
494 | static inline unsigned int dquot_state_flag(unsigned int flags, int type) | 497 | static inline unsigned int dquot_state_flag(unsigned int flags, int type) |
495 | { | 498 | { |
496 | return flags << type; | 499 | return flags << type; |
@@ -521,7 +524,7 @@ static inline void quota_send_warning(struct kqid qid, dev_t dev, | |||
521 | 524 | ||
522 | struct quota_info { | 525 | struct quota_info { |
523 | unsigned int flags; /* Flags for diskquotas on this device */ | 526 | unsigned int flags; /* Flags for diskquotas on this device */ |
524 | struct mutex dqio_mutex; /* lock device while I/O in progress */ | 527 | struct rw_semaphore dqio_sem; /* Lock quota file while I/O in progress */ |
525 | struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */ | 528 | struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */ |
526 | struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ | 529 | struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ |
527 | const struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */ | 530 | const struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */ |
diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h index dda22f45fc1b..0ce6fc49962e 100644 --- a/include/linux/quotaops.h +++ b/include/linux/quotaops.h | |||
@@ -38,11 +38,6 @@ void __quota_error(struct super_block *sb, const char *func, | |||
38 | /* | 38 | /* |
39 | * declaration of quota_function calls in kernel. | 39 | * declaration of quota_function calls in kernel. |
40 | */ | 40 | */ |
41 | void inode_add_rsv_space(struct inode *inode, qsize_t number); | ||
42 | void inode_claim_rsv_space(struct inode *inode, qsize_t number); | ||
43 | void inode_sub_rsv_space(struct inode *inode, qsize_t number); | ||
44 | void inode_reclaim_rsv_space(struct inode *inode, qsize_t number); | ||
45 | |||
46 | int dquot_initialize(struct inode *inode); | 41 | int dquot_initialize(struct inode *inode); |
47 | bool dquot_initialize_needed(struct inode *inode); | 42 | bool dquot_initialize_needed(struct inode *inode); |
48 | void dquot_drop(struct inode *inode); | 43 | void dquot_drop(struct inode *inode); |