diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-05-31 06:07:15 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2010-05-31 06:07:15 -0400 |
commit | e37c83c06c2690157a989df40dc99a6b61c9ea15 (patch) | |
tree | 024dfb8b2c9abeec9ca7cb0c0136c276d9aacc91 /fs/quota | |
parent | ce1f7d30766f6549db6fa0b9e595e0d26a5b7d9a (diff) | |
parent | 67a3e12b05e055c0415c556a315a3d3eb637e29e (diff) |
Merge commit 'v2.6.35-rc1' into for-2.6.36
Diffstat (limited to 'fs/quota')
-rw-r--r-- | fs/quota/Kconfig | 8 | ||||
-rw-r--r-- | fs/quota/dquot.c | 436 | ||||
-rw-r--r-- | fs/quota/netlink.c | 1 | ||||
-rw-r--r-- | fs/quota/quota.c | 99 | ||||
-rw-r--r-- | fs/quota/quota_tree.c | 50 | ||||
-rw-r--r-- | fs/quota/quota_tree.h | 6 | ||||
-rw-r--r-- | fs/quota/quota_v1.c | 4 | ||||
-rw-r--r-- | fs/quota/quota_v2.c | 6 |
8 files changed, 344 insertions, 266 deletions
diff --git a/fs/quota/Kconfig b/fs/quota/Kconfig index dad7fb247ddc..3e21b1e2ad3a 100644 --- a/fs/quota/Kconfig +++ b/fs/quota/Kconfig | |||
@@ -33,6 +33,14 @@ config PRINT_QUOTA_WARNING | |||
33 | Note that this behavior is currently deprecated and may go away in | 33 | Note that this behavior is currently deprecated and may go away in |
34 | future. Please use notification via netlink socket instead. | 34 | future. Please use notification via netlink socket instead. |
35 | 35 | ||
36 | config QUOTA_DEBUG | ||
37 | bool "Additional quota sanity checks" | ||
38 | depends on QUOTA | ||
39 | default n | ||
40 | help | ||
41 | If you say Y here, quota subsystem will perform some additional | ||
42 | sanity checks of quota internal structures. If unsure, say N. | ||
43 | |||
36 | # Generic support for tree structured quota files. Selected when needed. | 44 | # Generic support for tree structured quota files. Selected when needed. |
37 | config QUOTA_TREE | 45 | config QUOTA_TREE |
38 | tristate | 46 | tristate |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index e0b870f4749f..12c233da1b6b 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -80,11 +80,9 @@ | |||
80 | 80 | ||
81 | #include <asm/uaccess.h> | 81 | #include <asm/uaccess.h> |
82 | 82 | ||
83 | #define __DQUOT_PARANOIA | ||
84 | |||
85 | /* | 83 | /* |
86 | * There are three quota SMP locks. dq_list_lock protects all lists with quotas | 84 | * There are three quota SMP locks. dq_list_lock protects all lists with quotas |
87 | * and quota formats, dqstats structure containing statistics about the lists | 85 | * and quota formats. |
88 | * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and | 86 | * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and |
89 | * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes. | 87 | * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes. |
90 | * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly | 88 | * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly |
@@ -134,7 +132,9 @@ static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_state_lock); | |||
134 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock); | 132 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock); |
135 | EXPORT_SYMBOL(dq_data_lock); | 133 | EXPORT_SYMBOL(dq_data_lock); |
136 | 134 | ||
135 | #if defined(CONFIG_QUOTA_DEBUG) || defined(CONFIG_PRINT_QUOTA_WARNING) | ||
137 | static char *quotatypes[] = INITQFNAMES; | 136 | static char *quotatypes[] = INITQFNAMES; |
137 | #endif | ||
138 | static struct quota_format_type *quota_formats; /* List of registered formats */ | 138 | static struct quota_format_type *quota_formats; /* List of registered formats */ |
139 | static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES; | 139 | static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES; |
140 | 140 | ||
@@ -275,7 +275,7 @@ static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, | |||
275 | static inline void put_dquot_last(struct dquot *dquot) | 275 | static inline void put_dquot_last(struct dquot *dquot) |
276 | { | 276 | { |
277 | list_add_tail(&dquot->dq_free, &free_dquots); | 277 | list_add_tail(&dquot->dq_free, &free_dquots); |
278 | dqstats.free_dquots++; | 278 | dqstats_inc(DQST_FREE_DQUOTS); |
279 | } | 279 | } |
280 | 280 | ||
281 | static inline void remove_free_dquot(struct dquot *dquot) | 281 | static inline void remove_free_dquot(struct dquot *dquot) |
@@ -283,7 +283,7 @@ static inline void remove_free_dquot(struct dquot *dquot) | |||
283 | if (list_empty(&dquot->dq_free)) | 283 | if (list_empty(&dquot->dq_free)) |
284 | return; | 284 | return; |
285 | list_del_init(&dquot->dq_free); | 285 | list_del_init(&dquot->dq_free); |
286 | dqstats.free_dquots--; | 286 | dqstats_dec(DQST_FREE_DQUOTS); |
287 | } | 287 | } |
288 | 288 | ||
289 | static inline void put_inuse(struct dquot *dquot) | 289 | static inline void put_inuse(struct dquot *dquot) |
@@ -291,12 +291,12 @@ static inline void put_inuse(struct dquot *dquot) | |||
291 | /* We add to the back of inuse list so we don't have to restart | 291 | /* We add to the back of inuse list so we don't have to restart |
292 | * when traversing this list and we block */ | 292 | * when traversing this list and we block */ |
293 | list_add_tail(&dquot->dq_inuse, &inuse_list); | 293 | list_add_tail(&dquot->dq_inuse, &inuse_list); |
294 | dqstats.allocated_dquots++; | 294 | dqstats_inc(DQST_ALLOC_DQUOTS); |
295 | } | 295 | } |
296 | 296 | ||
297 | static inline void remove_inuse(struct dquot *dquot) | 297 | static inline void remove_inuse(struct dquot *dquot) |
298 | { | 298 | { |
299 | dqstats.allocated_dquots--; | 299 | dqstats_dec(DQST_ALLOC_DQUOTS); |
300 | list_del(&dquot->dq_inuse); | 300 | list_del(&dquot->dq_inuse); |
301 | } | 301 | } |
302 | /* | 302 | /* |
@@ -319,14 +319,23 @@ static inline int mark_dquot_dirty(struct dquot *dquot) | |||
319 | return dquot->dq_sb->dq_op->mark_dirty(dquot); | 319 | return dquot->dq_sb->dq_op->mark_dirty(dquot); |
320 | } | 320 | } |
321 | 321 | ||
322 | /* Mark dquot dirty in atomic manner, and return it's old dirty flag state */ | ||
322 | int dquot_mark_dquot_dirty(struct dquot *dquot) | 323 | int dquot_mark_dquot_dirty(struct dquot *dquot) |
323 | { | 324 | { |
325 | int ret = 1; | ||
326 | |||
327 | /* If quota is dirty already, we don't have to acquire dq_list_lock */ | ||
328 | if (test_bit(DQ_MOD_B, &dquot->dq_flags)) | ||
329 | return 1; | ||
330 | |||
324 | spin_lock(&dq_list_lock); | 331 | spin_lock(&dq_list_lock); |
325 | if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags)) | 332 | if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags)) { |
326 | list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)-> | 333 | list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)-> |
327 | info[dquot->dq_type].dqi_dirty_list); | 334 | info[dquot->dq_type].dqi_dirty_list); |
335 | ret = 0; | ||
336 | } | ||
328 | spin_unlock(&dq_list_lock); | 337 | spin_unlock(&dq_list_lock); |
329 | return 0; | 338 | return ret; |
330 | } | 339 | } |
331 | EXPORT_SYMBOL(dquot_mark_dquot_dirty); | 340 | EXPORT_SYMBOL(dquot_mark_dquot_dirty); |
332 | 341 | ||
@@ -552,8 +561,8 @@ int dquot_scan_active(struct super_block *sb, | |||
552 | continue; | 561 | continue; |
553 | /* Now we have active dquot so we can just increase use count */ | 562 | /* Now we have active dquot so we can just increase use count */ |
554 | atomic_inc(&dquot->dq_count); | 563 | atomic_inc(&dquot->dq_count); |
555 | dqstats.lookups++; | ||
556 | spin_unlock(&dq_list_lock); | 564 | spin_unlock(&dq_list_lock); |
565 | dqstats_inc(DQST_LOOKUPS); | ||
557 | dqput(old_dquot); | 566 | dqput(old_dquot); |
558 | old_dquot = dquot; | 567 | old_dquot = dquot; |
559 | ret = fn(dquot, priv); | 568 | ret = fn(dquot, priv); |
@@ -571,7 +580,7 @@ out: | |||
571 | } | 580 | } |
572 | EXPORT_SYMBOL(dquot_scan_active); | 581 | EXPORT_SYMBOL(dquot_scan_active); |
573 | 582 | ||
574 | int vfs_quota_sync(struct super_block *sb, int type, int wait) | 583 | int dquot_quota_sync(struct super_block *sb, int type, int wait) |
575 | { | 584 | { |
576 | struct list_head *dirty; | 585 | struct list_head *dirty; |
577 | struct dquot *dquot; | 586 | struct dquot *dquot; |
@@ -598,8 +607,8 @@ int vfs_quota_sync(struct super_block *sb, int type, int wait) | |||
598 | * holding reference so we can safely just increase | 607 | * holding reference so we can safely just increase |
599 | * use count */ | 608 | * use count */ |
600 | atomic_inc(&dquot->dq_count); | 609 | atomic_inc(&dquot->dq_count); |
601 | dqstats.lookups++; | ||
602 | spin_unlock(&dq_list_lock); | 610 | spin_unlock(&dq_list_lock); |
611 | dqstats_inc(DQST_LOOKUPS); | ||
603 | sb->dq_op->write_dquot(dquot); | 612 | sb->dq_op->write_dquot(dquot); |
604 | dqput(dquot); | 613 | dqput(dquot); |
605 | spin_lock(&dq_list_lock); | 614 | spin_lock(&dq_list_lock); |
@@ -611,9 +620,7 @@ int vfs_quota_sync(struct super_block *sb, int type, int wait) | |||
611 | if ((cnt == type || type == -1) && sb_has_quota_active(sb, cnt) | 620 | if ((cnt == type || type == -1) && sb_has_quota_active(sb, cnt) |
612 | && info_dirty(&dqopt->info[cnt])) | 621 | && info_dirty(&dqopt->info[cnt])) |
613 | sb->dq_op->write_info(sb, cnt); | 622 | sb->dq_op->write_info(sb, cnt); |
614 | spin_lock(&dq_list_lock); | 623 | dqstats_inc(DQST_SYNCS); |
615 | dqstats.syncs++; | ||
616 | spin_unlock(&dq_list_lock); | ||
617 | mutex_unlock(&dqopt->dqonoff_mutex); | 624 | mutex_unlock(&dqopt->dqonoff_mutex); |
618 | 625 | ||
619 | if (!wait || (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE)) | 626 | if (!wait || (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE)) |
@@ -645,7 +652,7 @@ int vfs_quota_sync(struct super_block *sb, int type, int wait) | |||
645 | 652 | ||
646 | return 0; | 653 | return 0; |
647 | } | 654 | } |
648 | EXPORT_SYMBOL(vfs_quota_sync); | 655 | EXPORT_SYMBOL(dquot_quota_sync); |
649 | 656 | ||
650 | /* Free unused dquots from cache */ | 657 | /* Free unused dquots from cache */ |
651 | static void prune_dqcache(int count) | 658 | static void prune_dqcache(int count) |
@@ -669,7 +676,6 @@ static void prune_dqcache(int count) | |||
669 | * This is called from kswapd when we think we need some | 676 | * This is called from kswapd when we think we need some |
670 | * more memory | 677 | * more memory |
671 | */ | 678 | */ |
672 | |||
673 | static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) | 679 | static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) |
674 | { | 680 | { |
675 | if (nr) { | 681 | if (nr) { |
@@ -677,7 +683,9 @@ static int shrink_dqcache_memory(int nr, gfp_t gfp_mask) | |||
677 | prune_dqcache(nr); | 683 | prune_dqcache(nr); |
678 | spin_unlock(&dq_list_lock); | 684 | spin_unlock(&dq_list_lock); |
679 | } | 685 | } |
680 | return (dqstats.free_dquots / 100) * sysctl_vfs_cache_pressure; | 686 | return ((unsigned) |
687 | percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS]) | ||
688 | /100) * sysctl_vfs_cache_pressure; | ||
681 | } | 689 | } |
682 | 690 | ||
683 | static struct shrinker dqcache_shrinker = { | 691 | static struct shrinker dqcache_shrinker = { |
@@ -695,7 +703,7 @@ void dqput(struct dquot *dquot) | |||
695 | 703 | ||
696 | if (!dquot) | 704 | if (!dquot) |
697 | return; | 705 | return; |
698 | #ifdef __DQUOT_PARANOIA | 706 | #ifdef CONFIG_QUOTA_DEBUG |
699 | if (!atomic_read(&dquot->dq_count)) { | 707 | if (!atomic_read(&dquot->dq_count)) { |
700 | printk("VFS: dqput: trying to free free dquot\n"); | 708 | printk("VFS: dqput: trying to free free dquot\n"); |
701 | printk("VFS: device %s, dquot of %s %d\n", | 709 | printk("VFS: device %s, dquot of %s %d\n", |
@@ -705,10 +713,7 @@ void dqput(struct dquot *dquot) | |||
705 | BUG(); | 713 | BUG(); |
706 | } | 714 | } |
707 | #endif | 715 | #endif |
708 | 716 | dqstats_inc(DQST_DROPS); | |
709 | spin_lock(&dq_list_lock); | ||
710 | dqstats.drops++; | ||
711 | spin_unlock(&dq_list_lock); | ||
712 | we_slept: | 717 | we_slept: |
713 | spin_lock(&dq_list_lock); | 718 | spin_lock(&dq_list_lock); |
714 | if (atomic_read(&dquot->dq_count) > 1) { | 719 | if (atomic_read(&dquot->dq_count) > 1) { |
@@ -748,7 +753,7 @@ we_slept: | |||
748 | goto we_slept; | 753 | goto we_slept; |
749 | } | 754 | } |
750 | atomic_dec(&dquot->dq_count); | 755 | atomic_dec(&dquot->dq_count); |
751 | #ifdef __DQUOT_PARANOIA | 756 | #ifdef CONFIG_QUOTA_DEBUG |
752 | /* sanity check */ | 757 | /* sanity check */ |
753 | BUG_ON(!list_empty(&dquot->dq_free)); | 758 | BUG_ON(!list_empty(&dquot->dq_free)); |
754 | #endif | 759 | #endif |
@@ -825,15 +830,15 @@ we_slept: | |||
825 | put_inuse(dquot); | 830 | put_inuse(dquot); |
826 | /* hash it first so it can be found */ | 831 | /* hash it first so it can be found */ |
827 | insert_dquot_hash(dquot); | 832 | insert_dquot_hash(dquot); |
828 | dqstats.lookups++; | ||
829 | spin_unlock(&dq_list_lock); | 833 | spin_unlock(&dq_list_lock); |
834 | dqstats_inc(DQST_LOOKUPS); | ||
830 | } else { | 835 | } else { |
831 | if (!atomic_read(&dquot->dq_count)) | 836 | if (!atomic_read(&dquot->dq_count)) |
832 | remove_free_dquot(dquot); | 837 | remove_free_dquot(dquot); |
833 | atomic_inc(&dquot->dq_count); | 838 | atomic_inc(&dquot->dq_count); |
834 | dqstats.cache_hits++; | ||
835 | dqstats.lookups++; | ||
836 | spin_unlock(&dq_list_lock); | 839 | spin_unlock(&dq_list_lock); |
840 | dqstats_inc(DQST_CACHE_HITS); | ||
841 | dqstats_inc(DQST_LOOKUPS); | ||
837 | } | 842 | } |
838 | /* Wait for dq_lock - after this we know that either dquot_release() is | 843 | /* Wait for dq_lock - after this we know that either dquot_release() is |
839 | * already finished or it will be canceled due to dq_count > 1 test */ | 844 | * already finished or it will be canceled due to dq_count > 1 test */ |
@@ -845,7 +850,7 @@ we_slept: | |||
845 | dquot = NULL; | 850 | dquot = NULL; |
846 | goto out; | 851 | goto out; |
847 | } | 852 | } |
848 | #ifdef __DQUOT_PARANOIA | 853 | #ifdef CONFIG_QUOTA_DEBUG |
849 | BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */ | 854 | BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */ |
850 | #endif | 855 | #endif |
851 | out: | 856 | out: |
@@ -874,14 +879,18 @@ static int dqinit_needed(struct inode *inode, int type) | |||
874 | static void add_dquot_ref(struct super_block *sb, int type) | 879 | static void add_dquot_ref(struct super_block *sb, int type) |
875 | { | 880 | { |
876 | struct inode *inode, *old_inode = NULL; | 881 | struct inode *inode, *old_inode = NULL; |
882 | #ifdef CONFIG_QUOTA_DEBUG | ||
877 | int reserved = 0; | 883 | int reserved = 0; |
884 | #endif | ||
878 | 885 | ||
879 | spin_lock(&inode_lock); | 886 | spin_lock(&inode_lock); |
880 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { | 887 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { |
881 | if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW)) | 888 | if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE|I_NEW)) |
882 | continue; | 889 | continue; |
890 | #ifdef CONFIG_QUOTA_DEBUG | ||
883 | if (unlikely(inode_get_rsv_space(inode) > 0)) | 891 | if (unlikely(inode_get_rsv_space(inode) > 0)) |
884 | reserved = 1; | 892 | reserved = 1; |
893 | #endif | ||
885 | if (!atomic_read(&inode->i_writecount)) | 894 | if (!atomic_read(&inode->i_writecount)) |
886 | continue; | 895 | continue; |
887 | if (!dqinit_needed(inode, type)) | 896 | if (!dqinit_needed(inode, type)) |
@@ -903,11 +912,13 @@ static void add_dquot_ref(struct super_block *sb, int type) | |||
903 | spin_unlock(&inode_lock); | 912 | spin_unlock(&inode_lock); |
904 | iput(old_inode); | 913 | iput(old_inode); |
905 | 914 | ||
915 | #ifdef CONFIG_QUOTA_DEBUG | ||
906 | if (reserved) { | 916 | if (reserved) { |
907 | printk(KERN_WARNING "VFS (%s): Writes happened before quota" | 917 | printk(KERN_WARNING "VFS (%s): Writes happened before quota" |
908 | " was turned on thus quota information is probably " | 918 | " was turned on thus quota information is probably " |
909 | "inconsistent. Please run quotacheck(8).\n", sb->s_id); | 919 | "inconsistent. Please run quotacheck(8).\n", sb->s_id); |
910 | } | 920 | } |
921 | #endif | ||
911 | } | 922 | } |
912 | 923 | ||
913 | /* | 924 | /* |
@@ -934,7 +945,7 @@ static int remove_inode_dquot_ref(struct inode *inode, int type, | |||
934 | inode->i_dquot[type] = NULL; | 945 | inode->i_dquot[type] = NULL; |
935 | if (dquot) { | 946 | if (dquot) { |
936 | if (dqput_blocks(dquot)) { | 947 | if (dqput_blocks(dquot)) { |
937 | #ifdef __DQUOT_PARANOIA | 948 | #ifdef CONFIG_QUOTA_DEBUG |
938 | if (atomic_read(&dquot->dq_count) != 1) | 949 | if (atomic_read(&dquot->dq_count) != 1) |
939 | printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count)); | 950 | printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count)); |
940 | #endif | 951 | #endif |
@@ -1484,11 +1495,13 @@ static void inode_decr_space(struct inode *inode, qsize_t number, int reserve) | |||
1484 | /* | 1495 | /* |
1485 | * This operation can block, but only after everything is updated | 1496 | * This operation can block, but only after everything is updated |
1486 | */ | 1497 | */ |
1487 | int __dquot_alloc_space(struct inode *inode, qsize_t number, | 1498 | int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) |
1488 | int warn, int reserve) | ||
1489 | { | 1499 | { |
1490 | int cnt, ret = 0; | 1500 | int cnt, ret = 0; |
1491 | char warntype[MAXQUOTAS]; | 1501 | char warntype[MAXQUOTAS]; |
1502 | int warn = flags & DQUOT_SPACE_WARN; | ||
1503 | int reserve = flags & DQUOT_SPACE_RESERVE; | ||
1504 | int nofail = flags & DQUOT_SPACE_NOFAIL; | ||
1492 | 1505 | ||
1493 | /* | 1506 | /* |
1494 | * First test before acquiring mutex - solves deadlocks when we | 1507 | * First test before acquiring mutex - solves deadlocks when we |
@@ -1509,7 +1522,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, | |||
1509 | continue; | 1522 | continue; |
1510 | ret = check_bdq(inode->i_dquot[cnt], number, !warn, | 1523 | ret = check_bdq(inode->i_dquot[cnt], number, !warn, |
1511 | warntype+cnt); | 1524 | warntype+cnt); |
1512 | if (ret) { | 1525 | if (ret && !nofail) { |
1513 | spin_unlock(&dq_data_lock); | 1526 | spin_unlock(&dq_data_lock); |
1514 | goto out_flush_warn; | 1527 | goto out_flush_warn; |
1515 | } | 1528 | } |
@@ -1608,10 +1621,11 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty); | |||
1608 | /* | 1621 | /* |
1609 | * This operation can block, but only after everything is updated | 1622 | * This operation can block, but only after everything is updated |
1610 | */ | 1623 | */ |
1611 | void __dquot_free_space(struct inode *inode, qsize_t number, int reserve) | 1624 | void __dquot_free_space(struct inode *inode, qsize_t number, int flags) |
1612 | { | 1625 | { |
1613 | unsigned int cnt; | 1626 | unsigned int cnt; |
1614 | char warntype[MAXQUOTAS]; | 1627 | char warntype[MAXQUOTAS]; |
1628 | int reserve = flags & DQUOT_SPACE_RESERVE; | ||
1615 | 1629 | ||
1616 | /* First test before acquiring mutex - solves deadlocks when we | 1630 | /* First test before acquiring mutex - solves deadlocks when we |
1617 | * re-enter the quota code and are already holding the mutex */ | 1631 | * re-enter the quota code and are already holding the mutex */ |
@@ -1673,16 +1687,19 @@ EXPORT_SYMBOL(dquot_free_inode); | |||
1673 | 1687 | ||
1674 | /* | 1688 | /* |
1675 | * Transfer the number of inode and blocks from one diskquota to an other. | 1689 | * Transfer the number of inode and blocks from one diskquota to an other. |
1690 | * On success, dquot references in transfer_to are consumed and references | ||
1691 | * to original dquots that need to be released are placed there. On failure, | ||
1692 | * references are kept untouched. | ||
1676 | * | 1693 | * |
1677 | * This operation can block, but only after everything is updated | 1694 | * This operation can block, but only after everything is updated |
1678 | * A transaction must be started when entering this function. | 1695 | * A transaction must be started when entering this function. |
1696 | * | ||
1679 | */ | 1697 | */ |
1680 | static int __dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask) | 1698 | int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) |
1681 | { | 1699 | { |
1682 | qsize_t space, cur_space; | 1700 | qsize_t space, cur_space; |
1683 | qsize_t rsv_space = 0; | 1701 | qsize_t rsv_space = 0; |
1684 | struct dquot *transfer_from[MAXQUOTAS]; | 1702 | struct dquot *transfer_from[MAXQUOTAS] = {}; |
1685 | struct dquot *transfer_to[MAXQUOTAS]; | ||
1686 | int cnt, ret = 0; | 1703 | int cnt, ret = 0; |
1687 | char warntype_to[MAXQUOTAS]; | 1704 | char warntype_to[MAXQUOTAS]; |
1688 | char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS]; | 1705 | char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS]; |
@@ -1692,19 +1709,12 @@ static int __dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask | |||
1692 | if (IS_NOQUOTA(inode)) | 1709 | if (IS_NOQUOTA(inode)) |
1693 | return 0; | 1710 | return 0; |
1694 | /* Initialize the arrays */ | 1711 | /* Initialize the arrays */ |
1695 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1712 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1696 | transfer_from[cnt] = NULL; | ||
1697 | transfer_to[cnt] = NULL; | ||
1698 | warntype_to[cnt] = QUOTA_NL_NOWARN; | 1713 | warntype_to[cnt] = QUOTA_NL_NOWARN; |
1699 | } | ||
1700 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
1701 | if (mask & (1 << cnt)) | ||
1702 | transfer_to[cnt] = dqget(inode->i_sb, chid[cnt], cnt); | ||
1703 | } | ||
1704 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1714 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1705 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ | 1715 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ |
1706 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1716 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1707 | goto put_all; | 1717 | return 0; |
1708 | } | 1718 | } |
1709 | spin_lock(&dq_data_lock); | 1719 | spin_lock(&dq_data_lock); |
1710 | cur_space = inode_get_bytes(inode); | 1720 | cur_space = inode_get_bytes(inode); |
@@ -1756,47 +1766,41 @@ static int __dquot_transfer(struct inode *inode, qid_t *chid, unsigned long mask | |||
1756 | 1766 | ||
1757 | mark_all_dquot_dirty(transfer_from); | 1767 | mark_all_dquot_dirty(transfer_from); |
1758 | mark_all_dquot_dirty(transfer_to); | 1768 | mark_all_dquot_dirty(transfer_to); |
1759 | /* The reference we got is transferred to the inode */ | 1769 | /* Pass back references to put */ |
1760 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1770 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1761 | transfer_to[cnt] = NULL; | 1771 | transfer_to[cnt] = transfer_from[cnt]; |
1762 | warn_put_all: | 1772 | warn: |
1763 | flush_warnings(transfer_to, warntype_to); | 1773 | flush_warnings(transfer_to, warntype_to); |
1764 | flush_warnings(transfer_from, warntype_from_inodes); | 1774 | flush_warnings(transfer_from, warntype_from_inodes); |
1765 | flush_warnings(transfer_from, warntype_from_space); | 1775 | flush_warnings(transfer_from, warntype_from_space); |
1766 | put_all: | ||
1767 | dqput_all(transfer_from); | ||
1768 | dqput_all(transfer_to); | ||
1769 | return ret; | 1776 | return ret; |
1770 | over_quota: | 1777 | over_quota: |
1771 | spin_unlock(&dq_data_lock); | 1778 | spin_unlock(&dq_data_lock); |
1772 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1779 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1773 | /* Clear dquot pointers we don't want to dqput() */ | 1780 | goto warn; |
1774 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | ||
1775 | transfer_from[cnt] = NULL; | ||
1776 | goto warn_put_all; | ||
1777 | } | 1781 | } |
1782 | EXPORT_SYMBOL(__dquot_transfer); | ||
1778 | 1783 | ||
1779 | /* Wrapper for transferring ownership of an inode for uid/gid only | 1784 | /* Wrapper for transferring ownership of an inode for uid/gid only |
1780 | * Called from FSXXX_setattr() | 1785 | * Called from FSXXX_setattr() |
1781 | */ | 1786 | */ |
1782 | int dquot_transfer(struct inode *inode, struct iattr *iattr) | 1787 | int dquot_transfer(struct inode *inode, struct iattr *iattr) |
1783 | { | 1788 | { |
1784 | qid_t chid[MAXQUOTAS]; | 1789 | struct dquot *transfer_to[MAXQUOTAS] = {}; |
1785 | unsigned long mask = 0; | 1790 | struct super_block *sb = inode->i_sb; |
1791 | int ret; | ||
1786 | 1792 | ||
1787 | if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) { | 1793 | if (!sb_any_quota_active(sb) || IS_NOQUOTA(inode)) |
1788 | mask |= 1 << USRQUOTA; | 1794 | return 0; |
1789 | chid[USRQUOTA] = iattr->ia_uid; | 1795 | |
1790 | } | 1796 | if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) |
1791 | if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) { | 1797 | transfer_to[USRQUOTA] = dqget(sb, iattr->ia_uid, USRQUOTA); |
1792 | mask |= 1 << GRPQUOTA; | 1798 | if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid) |
1793 | chid[GRPQUOTA] = iattr->ia_gid; | 1799 | transfer_to[GRPQUOTA] = dqget(sb, iattr->ia_gid, GRPQUOTA); |
1794 | } | 1800 | |
1795 | if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) { | 1801 | ret = __dquot_transfer(inode, transfer_to); |
1796 | dquot_initialize(inode); | 1802 | dqput_all(transfer_to); |
1797 | return __dquot_transfer(inode, chid, mask); | 1803 | return ret; |
1798 | } | ||
1799 | return 0; | ||
1800 | } | 1804 | } |
1801 | EXPORT_SYMBOL(dquot_transfer); | 1805 | EXPORT_SYMBOL(dquot_transfer); |
1802 | 1806 | ||
@@ -1827,6 +1831,7 @@ const struct dquot_operations dquot_operations = { | |||
1827 | .alloc_dquot = dquot_alloc, | 1831 | .alloc_dquot = dquot_alloc, |
1828 | .destroy_dquot = dquot_destroy, | 1832 | .destroy_dquot = dquot_destroy, |
1829 | }; | 1833 | }; |
1834 | EXPORT_SYMBOL(dquot_operations); | ||
1830 | 1835 | ||
1831 | /* | 1836 | /* |
1832 | * Generic helper for ->open on filesystems supporting disk quotas. | 1837 | * Generic helper for ->open on filesystems supporting disk quotas. |
@@ -1845,7 +1850,7 @@ EXPORT_SYMBOL(dquot_file_open); | |||
1845 | /* | 1850 | /* |
1846 | * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) | 1851 | * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) |
1847 | */ | 1852 | */ |
1848 | int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) | 1853 | int dquot_disable(struct super_block *sb, int type, unsigned int flags) |
1849 | { | 1854 | { |
1850 | int cnt, ret = 0; | 1855 | int cnt, ret = 0; |
1851 | struct quota_info *dqopt = sb_dqopt(sb); | 1856 | struct quota_info *dqopt = sb_dqopt(sb); |
@@ -1975,14 +1980,15 @@ put_inodes: | |||
1975 | } | 1980 | } |
1976 | return ret; | 1981 | return ret; |
1977 | } | 1982 | } |
1978 | EXPORT_SYMBOL(vfs_quota_disable); | 1983 | EXPORT_SYMBOL(dquot_disable); |
1979 | 1984 | ||
1980 | int vfs_quota_off(struct super_block *sb, int type, int remount) | 1985 | int dquot_quota_off(struct super_block *sb, int type) |
1981 | { | 1986 | { |
1982 | return vfs_quota_disable(sb, type, remount ? DQUOT_SUSPENDED : | 1987 | return dquot_disable(sb, type, |
1983 | (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED)); | 1988 | DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); |
1984 | } | 1989 | } |
1985 | EXPORT_SYMBOL(vfs_quota_off); | 1990 | EXPORT_SYMBOL(dquot_quota_off); |
1991 | |||
1986 | /* | 1992 | /* |
1987 | * Turn quotas on on a device | 1993 | * Turn quotas on on a device |
1988 | */ | 1994 | */ |
@@ -2100,36 +2106,43 @@ out_fmt: | |||
2100 | } | 2106 | } |
2101 | 2107 | ||
2102 | /* Reenable quotas on remount RW */ | 2108 | /* Reenable quotas on remount RW */ |
2103 | static int vfs_quota_on_remount(struct super_block *sb, int type) | 2109 | int dquot_resume(struct super_block *sb, int type) |
2104 | { | 2110 | { |
2105 | struct quota_info *dqopt = sb_dqopt(sb); | 2111 | struct quota_info *dqopt = sb_dqopt(sb); |
2106 | struct inode *inode; | 2112 | struct inode *inode; |
2107 | int ret; | 2113 | int ret = 0, cnt; |
2108 | unsigned int flags; | 2114 | unsigned int flags; |
2109 | 2115 | ||
2110 | mutex_lock(&dqopt->dqonoff_mutex); | 2116 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
2111 | if (!sb_has_quota_suspended(sb, type)) { | 2117 | if (type != -1 && cnt != type) |
2118 | continue; | ||
2119 | |||
2120 | mutex_lock(&dqopt->dqonoff_mutex); | ||
2121 | if (!sb_has_quota_suspended(sb, cnt)) { | ||
2122 | mutex_unlock(&dqopt->dqonoff_mutex); | ||
2123 | continue; | ||
2124 | } | ||
2125 | inode = dqopt->files[cnt]; | ||
2126 | dqopt->files[cnt] = NULL; | ||
2127 | spin_lock(&dq_state_lock); | ||
2128 | flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED | | ||
2129 | DQUOT_LIMITS_ENABLED, | ||
2130 | cnt); | ||
2131 | dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, cnt); | ||
2132 | spin_unlock(&dq_state_lock); | ||
2112 | mutex_unlock(&dqopt->dqonoff_mutex); | 2133 | mutex_unlock(&dqopt->dqonoff_mutex); |
2113 | return 0; | ||
2114 | } | ||
2115 | inode = dqopt->files[type]; | ||
2116 | dqopt->files[type] = NULL; | ||
2117 | spin_lock(&dq_state_lock); | ||
2118 | flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED | | ||
2119 | DQUOT_LIMITS_ENABLED, type); | ||
2120 | dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, type); | ||
2121 | spin_unlock(&dq_state_lock); | ||
2122 | mutex_unlock(&dqopt->dqonoff_mutex); | ||
2123 | 2134 | ||
2124 | flags = dquot_generic_flag(flags, type); | 2135 | flags = dquot_generic_flag(flags, cnt); |
2125 | ret = vfs_load_quota_inode(inode, type, dqopt->info[type].dqi_fmt_id, | 2136 | ret = vfs_load_quota_inode(inode, cnt, |
2126 | flags); | 2137 | dqopt->info[cnt].dqi_fmt_id, flags); |
2127 | iput(inode); | 2138 | iput(inode); |
2139 | } | ||
2128 | 2140 | ||
2129 | return ret; | 2141 | return ret; |
2130 | } | 2142 | } |
2143 | EXPORT_SYMBOL(dquot_resume); | ||
2131 | 2144 | ||
2132 | int vfs_quota_on_path(struct super_block *sb, int type, int format_id, | 2145 | int dquot_quota_on_path(struct super_block *sb, int type, int format_id, |
2133 | struct path *path) | 2146 | struct path *path) |
2134 | { | 2147 | { |
2135 | int error = security_quota_on(path->dentry); | 2148 | int error = security_quota_on(path->dentry); |
@@ -2144,40 +2157,36 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id, | |||
2144 | DQUOT_LIMITS_ENABLED); | 2157 | DQUOT_LIMITS_ENABLED); |
2145 | return error; | 2158 | return error; |
2146 | } | 2159 | } |
2147 | EXPORT_SYMBOL(vfs_quota_on_path); | 2160 | EXPORT_SYMBOL(dquot_quota_on_path); |
2148 | 2161 | ||
2149 | int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, | 2162 | int dquot_quota_on(struct super_block *sb, int type, int format_id, char *name) |
2150 | int remount) | ||
2151 | { | 2163 | { |
2152 | struct path path; | 2164 | struct path path; |
2153 | int error; | 2165 | int error; |
2154 | 2166 | ||
2155 | if (remount) | ||
2156 | return vfs_quota_on_remount(sb, type); | ||
2157 | |||
2158 | error = kern_path(name, LOOKUP_FOLLOW, &path); | 2167 | error = kern_path(name, LOOKUP_FOLLOW, &path); |
2159 | if (!error) { | 2168 | if (!error) { |
2160 | error = vfs_quota_on_path(sb, type, format_id, &path); | 2169 | error = dquot_quota_on_path(sb, type, format_id, &path); |
2161 | path_put(&path); | 2170 | path_put(&path); |
2162 | } | 2171 | } |
2163 | return error; | 2172 | return error; |
2164 | } | 2173 | } |
2165 | EXPORT_SYMBOL(vfs_quota_on); | 2174 | EXPORT_SYMBOL(dquot_quota_on); |
2166 | 2175 | ||
2167 | /* | 2176 | /* |
2168 | * More powerful function for turning on quotas allowing setting | 2177 | * More powerful function for turning on quotas allowing setting |
2169 | * of individual quota flags | 2178 | * of individual quota flags |
2170 | */ | 2179 | */ |
2171 | int vfs_quota_enable(struct inode *inode, int type, int format_id, | 2180 | int dquot_enable(struct inode *inode, int type, int format_id, |
2172 | unsigned int flags) | 2181 | unsigned int flags) |
2173 | { | 2182 | { |
2174 | int ret = 0; | 2183 | int ret = 0; |
2175 | struct super_block *sb = inode->i_sb; | 2184 | struct super_block *sb = inode->i_sb; |
2176 | struct quota_info *dqopt = sb_dqopt(sb); | 2185 | struct quota_info *dqopt = sb_dqopt(sb); |
2177 | 2186 | ||
2178 | /* Just unsuspend quotas? */ | 2187 | /* Just unsuspend quotas? */ |
2179 | if (flags & DQUOT_SUSPENDED) | 2188 | BUG_ON(flags & DQUOT_SUSPENDED); |
2180 | return vfs_quota_on_remount(sb, type); | 2189 | |
2181 | if (!flags) | 2190 | if (!flags) |
2182 | return 0; | 2191 | return 0; |
2183 | /* Just updating flags needed? */ | 2192 | /* Just updating flags needed? */ |
@@ -2209,13 +2218,13 @@ out_lock: | |||
2209 | load_quota: | 2218 | load_quota: |
2210 | return vfs_load_quota_inode(inode, type, format_id, flags); | 2219 | return vfs_load_quota_inode(inode, type, format_id, flags); |
2211 | } | 2220 | } |
2212 | EXPORT_SYMBOL(vfs_quota_enable); | 2221 | EXPORT_SYMBOL(dquot_enable); |
2213 | 2222 | ||
2214 | /* | 2223 | /* |
2215 | * This function is used when filesystem needs to initialize quotas | 2224 | * This function is used when filesystem needs to initialize quotas |
2216 | * during mount time. | 2225 | * during mount time. |
2217 | */ | 2226 | */ |
2218 | int vfs_quota_on_mount(struct super_block *sb, char *qf_name, | 2227 | int dquot_quota_on_mount(struct super_block *sb, char *qf_name, |
2219 | int format_id, int type) | 2228 | int format_id, int type) |
2220 | { | 2229 | { |
2221 | struct dentry *dentry; | 2230 | struct dentry *dentry; |
@@ -2241,24 +2250,7 @@ out: | |||
2241 | dput(dentry); | 2250 | dput(dentry); |
2242 | return error; | 2251 | return error; |
2243 | } | 2252 | } |
2244 | EXPORT_SYMBOL(vfs_quota_on_mount); | 2253 | EXPORT_SYMBOL(dquot_quota_on_mount); |
2245 | |||
2246 | /* Wrapper to turn on quotas when remounting rw */ | ||
2247 | int vfs_dq_quota_on_remount(struct super_block *sb) | ||
2248 | { | ||
2249 | int cnt; | ||
2250 | int ret = 0, err; | ||
2251 | |||
2252 | if (!sb->s_qcop || !sb->s_qcop->quota_on) | ||
2253 | return -ENOSYS; | ||
2254 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
2255 | err = sb->s_qcop->quota_on(sb, cnt, 0, NULL, 1); | ||
2256 | if (err < 0 && !ret) | ||
2257 | ret = err; | ||
2258 | } | ||
2259 | return ret; | ||
2260 | } | ||
2261 | EXPORT_SYMBOL(vfs_dq_quota_on_remount); | ||
2262 | 2254 | ||
2263 | static inline qsize_t qbtos(qsize_t blocks) | 2255 | static inline qsize_t qbtos(qsize_t blocks) |
2264 | { | 2256 | { |
@@ -2271,25 +2263,30 @@ static inline qsize_t stoqb(qsize_t space) | |||
2271 | } | 2263 | } |
2272 | 2264 | ||
2273 | /* Generic routine for getting common part of quota structure */ | 2265 | /* Generic routine for getting common part of quota structure */ |
2274 | static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di) | 2266 | static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di) |
2275 | { | 2267 | { |
2276 | struct mem_dqblk *dm = &dquot->dq_dqb; | 2268 | struct mem_dqblk *dm = &dquot->dq_dqb; |
2277 | 2269 | ||
2270 | memset(di, 0, sizeof(*di)); | ||
2271 | di->d_version = FS_DQUOT_VERSION; | ||
2272 | di->d_flags = dquot->dq_type == USRQUOTA ? | ||
2273 | XFS_USER_QUOTA : XFS_GROUP_QUOTA; | ||
2274 | di->d_id = dquot->dq_id; | ||
2275 | |||
2278 | spin_lock(&dq_data_lock); | 2276 | spin_lock(&dq_data_lock); |
2279 | di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit); | 2277 | di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit); |
2280 | di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit); | 2278 | di->d_blk_softlimit = stoqb(dm->dqb_bsoftlimit); |
2281 | di->dqb_curspace = dm->dqb_curspace + dm->dqb_rsvspace; | 2279 | di->d_ino_hardlimit = dm->dqb_ihardlimit; |
2282 | di->dqb_ihardlimit = dm->dqb_ihardlimit; | 2280 | di->d_ino_softlimit = dm->dqb_isoftlimit; |
2283 | di->dqb_isoftlimit = dm->dqb_isoftlimit; | 2281 | di->d_bcount = dm->dqb_curspace + dm->dqb_rsvspace; |
2284 | di->dqb_curinodes = dm->dqb_curinodes; | 2282 | di->d_icount = dm->dqb_curinodes; |
2285 | di->dqb_btime = dm->dqb_btime; | 2283 | di->d_btimer = dm->dqb_btime; |
2286 | di->dqb_itime = dm->dqb_itime; | 2284 | di->d_itimer = dm->dqb_itime; |
2287 | di->dqb_valid = QIF_ALL; | ||
2288 | spin_unlock(&dq_data_lock); | 2285 | spin_unlock(&dq_data_lock); |
2289 | } | 2286 | } |
2290 | 2287 | ||
2291 | int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, | 2288 | int dquot_get_dqblk(struct super_block *sb, int type, qid_t id, |
2292 | struct if_dqblk *di) | 2289 | struct fs_disk_quota *di) |
2293 | { | 2290 | { |
2294 | struct dquot *dquot; | 2291 | struct dquot *dquot; |
2295 | 2292 | ||
@@ -2301,55 +2298,74 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, | |||
2301 | 2298 | ||
2302 | return 0; | 2299 | return 0; |
2303 | } | 2300 | } |
2304 | EXPORT_SYMBOL(vfs_get_dqblk); | 2301 | EXPORT_SYMBOL(dquot_get_dqblk); |
2302 | |||
2303 | #define VFS_FS_DQ_MASK \ | ||
2304 | (FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \ | ||
2305 | FS_DQ_ICOUNT | FS_DQ_ISOFT | FS_DQ_IHARD | \ | ||
2306 | FS_DQ_BTIMER | FS_DQ_ITIMER) | ||
2305 | 2307 | ||
2306 | /* Generic routine for setting common part of quota structure */ | 2308 | /* Generic routine for setting common part of quota structure */ |
2307 | static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | 2309 | static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) |
2308 | { | 2310 | { |
2309 | struct mem_dqblk *dm = &dquot->dq_dqb; | 2311 | struct mem_dqblk *dm = &dquot->dq_dqb; |
2310 | int check_blim = 0, check_ilim = 0; | 2312 | int check_blim = 0, check_ilim = 0; |
2311 | struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; | 2313 | struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; |
2312 | 2314 | ||
2313 | if ((di->dqb_valid & QIF_BLIMITS && | 2315 | if (di->d_fieldmask & ~VFS_FS_DQ_MASK) |
2314 | (di->dqb_bhardlimit > dqi->dqi_maxblimit || | 2316 | return -EINVAL; |
2315 | di->dqb_bsoftlimit > dqi->dqi_maxblimit)) || | 2317 | |
2316 | (di->dqb_valid & QIF_ILIMITS && | 2318 | if (((di->d_fieldmask & FS_DQ_BSOFT) && |
2317 | (di->dqb_ihardlimit > dqi->dqi_maxilimit || | 2319 | (di->d_blk_softlimit > dqi->dqi_maxblimit)) || |
2318 | di->dqb_isoftlimit > dqi->dqi_maxilimit))) | 2320 | ((di->d_fieldmask & FS_DQ_BHARD) && |
2321 | (di->d_blk_hardlimit > dqi->dqi_maxblimit)) || | ||
2322 | ((di->d_fieldmask & FS_DQ_ISOFT) && | ||
2323 | (di->d_ino_softlimit > dqi->dqi_maxilimit)) || | ||
2324 | ((di->d_fieldmask & FS_DQ_IHARD) && | ||
2325 | (di->d_ino_hardlimit > dqi->dqi_maxilimit))) | ||
2319 | return -ERANGE; | 2326 | return -ERANGE; |
2320 | 2327 | ||
2321 | spin_lock(&dq_data_lock); | 2328 | spin_lock(&dq_data_lock); |
2322 | if (di->dqb_valid & QIF_SPACE) { | 2329 | if (di->d_fieldmask & FS_DQ_BCOUNT) { |
2323 | dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace; | 2330 | dm->dqb_curspace = di->d_bcount - dm->dqb_rsvspace; |
2324 | check_blim = 1; | 2331 | check_blim = 1; |
2325 | __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); | 2332 | set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); |
2326 | } | 2333 | } |
2327 | if (di->dqb_valid & QIF_BLIMITS) { | 2334 | |
2328 | dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); | 2335 | if (di->d_fieldmask & FS_DQ_BSOFT) |
2329 | dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); | 2336 | dm->dqb_bsoftlimit = qbtos(di->d_blk_softlimit); |
2337 | if (di->d_fieldmask & FS_DQ_BHARD) | ||
2338 | dm->dqb_bhardlimit = qbtos(di->d_blk_hardlimit); | ||
2339 | if (di->d_fieldmask & (FS_DQ_BSOFT | FS_DQ_BHARD)) { | ||
2330 | check_blim = 1; | 2340 | check_blim = 1; |
2331 | __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); | 2341 | set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); |
2332 | } | 2342 | } |
2333 | if (di->dqb_valid & QIF_INODES) { | 2343 | |
2334 | dm->dqb_curinodes = di->dqb_curinodes; | 2344 | if (di->d_fieldmask & FS_DQ_ICOUNT) { |
2345 | dm->dqb_curinodes = di->d_icount; | ||
2335 | check_ilim = 1; | 2346 | check_ilim = 1; |
2336 | __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); | 2347 | set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); |
2337 | } | 2348 | } |
2338 | if (di->dqb_valid & QIF_ILIMITS) { | 2349 | |
2339 | dm->dqb_isoftlimit = di->dqb_isoftlimit; | 2350 | if (di->d_fieldmask & FS_DQ_ISOFT) |
2340 | dm->dqb_ihardlimit = di->dqb_ihardlimit; | 2351 | dm->dqb_isoftlimit = di->d_ino_softlimit; |
2352 | if (di->d_fieldmask & FS_DQ_IHARD) | ||
2353 | dm->dqb_ihardlimit = di->d_ino_hardlimit; | ||
2354 | if (di->d_fieldmask & (FS_DQ_ISOFT | FS_DQ_IHARD)) { | ||
2341 | check_ilim = 1; | 2355 | check_ilim = 1; |
2342 | __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); | 2356 | set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); |
2343 | } | 2357 | } |
2344 | if (di->dqb_valid & QIF_BTIME) { | 2358 | |
2345 | dm->dqb_btime = di->dqb_btime; | 2359 | if (di->d_fieldmask & FS_DQ_BTIMER) { |
2360 | dm->dqb_btime = di->d_btimer; | ||
2346 | check_blim = 1; | 2361 | check_blim = 1; |
2347 | __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); | 2362 | set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); |
2348 | } | 2363 | } |
2349 | if (di->dqb_valid & QIF_ITIME) { | 2364 | |
2350 | dm->dqb_itime = di->dqb_itime; | 2365 | if (di->d_fieldmask & FS_DQ_ITIMER) { |
2366 | dm->dqb_itime = di->d_itimer; | ||
2351 | check_ilim = 1; | 2367 | check_ilim = 1; |
2352 | __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); | 2368 | set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); |
2353 | } | 2369 | } |
2354 | 2370 | ||
2355 | if (check_blim) { | 2371 | if (check_blim) { |
@@ -2357,7 +2373,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
2357 | dm->dqb_curspace < dm->dqb_bsoftlimit) { | 2373 | dm->dqb_curspace < dm->dqb_bsoftlimit) { |
2358 | dm->dqb_btime = 0; | 2374 | dm->dqb_btime = 0; |
2359 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); | 2375 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
2360 | } else if (!(di->dqb_valid & QIF_BTIME)) | 2376 | } else if (!(di->d_fieldmask & FS_DQ_BTIMER)) |
2361 | /* Set grace only if user hasn't provided his own... */ | 2377 | /* Set grace only if user hasn't provided his own... */ |
2362 | dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; | 2378 | dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; |
2363 | } | 2379 | } |
@@ -2366,7 +2382,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
2366 | dm->dqb_curinodes < dm->dqb_isoftlimit) { | 2382 | dm->dqb_curinodes < dm->dqb_isoftlimit) { |
2367 | dm->dqb_itime = 0; | 2383 | dm->dqb_itime = 0; |
2368 | clear_bit(DQ_INODES_B, &dquot->dq_flags); | 2384 | clear_bit(DQ_INODES_B, &dquot->dq_flags); |
2369 | } else if (!(di->dqb_valid & QIF_ITIME)) | 2385 | } else if (!(di->d_fieldmask & FS_DQ_ITIMER)) |
2370 | /* Set grace only if user hasn't provided his own... */ | 2386 | /* Set grace only if user hasn't provided his own... */ |
2371 | dm->dqb_itime = get_seconds() + dqi->dqi_igrace; | 2387 | dm->dqb_itime = get_seconds() + dqi->dqi_igrace; |
2372 | } | 2388 | } |
@@ -2381,8 +2397,8 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
2381 | return 0; | 2397 | return 0; |
2382 | } | 2398 | } |
2383 | 2399 | ||
2384 | int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, | 2400 | int dquot_set_dqblk(struct super_block *sb, int type, qid_t id, |
2385 | struct if_dqblk *di) | 2401 | struct fs_disk_quota *di) |
2386 | { | 2402 | { |
2387 | struct dquot *dquot; | 2403 | struct dquot *dquot; |
2388 | int rc; | 2404 | int rc; |
@@ -2397,10 +2413,10 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, | |||
2397 | out: | 2413 | out: |
2398 | return rc; | 2414 | return rc; |
2399 | } | 2415 | } |
2400 | EXPORT_SYMBOL(vfs_set_dqblk); | 2416 | EXPORT_SYMBOL(dquot_set_dqblk); |
2401 | 2417 | ||
2402 | /* Generic routine for getting common part of quota file information */ | 2418 | /* Generic routine for getting common part of quota file information */ |
2403 | int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | 2419 | int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) |
2404 | { | 2420 | { |
2405 | struct mem_dqinfo *mi; | 2421 | struct mem_dqinfo *mi; |
2406 | 2422 | ||
@@ -2419,10 +2435,10 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
2419 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2435 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
2420 | return 0; | 2436 | return 0; |
2421 | } | 2437 | } |
2422 | EXPORT_SYMBOL(vfs_get_dqinfo); | 2438 | EXPORT_SYMBOL(dquot_get_dqinfo); |
2423 | 2439 | ||
2424 | /* Generic routine for setting common part of quota file information */ | 2440 | /* Generic routine for setting common part of quota file information */ |
2425 | int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | 2441 | int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) |
2426 | { | 2442 | { |
2427 | struct mem_dqinfo *mi; | 2443 | struct mem_dqinfo *mi; |
2428 | int err = 0; | 2444 | int err = 0; |
@@ -2449,74 +2465,86 @@ out: | |||
2449 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2465 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
2450 | return err; | 2466 | return err; |
2451 | } | 2467 | } |
2452 | EXPORT_SYMBOL(vfs_set_dqinfo); | 2468 | EXPORT_SYMBOL(dquot_set_dqinfo); |
2453 | 2469 | ||
2454 | const struct quotactl_ops vfs_quotactl_ops = { | 2470 | const struct quotactl_ops dquot_quotactl_ops = { |
2455 | .quota_on = vfs_quota_on, | 2471 | .quota_on = dquot_quota_on, |
2456 | .quota_off = vfs_quota_off, | 2472 | .quota_off = dquot_quota_off, |
2457 | .quota_sync = vfs_quota_sync, | 2473 | .quota_sync = dquot_quota_sync, |
2458 | .get_info = vfs_get_dqinfo, | 2474 | .get_info = dquot_get_dqinfo, |
2459 | .set_info = vfs_set_dqinfo, | 2475 | .set_info = dquot_set_dqinfo, |
2460 | .get_dqblk = vfs_get_dqblk, | 2476 | .get_dqblk = dquot_get_dqblk, |
2461 | .set_dqblk = vfs_set_dqblk | 2477 | .set_dqblk = dquot_set_dqblk |
2462 | }; | 2478 | }; |
2479 | EXPORT_SYMBOL(dquot_quotactl_ops); | ||
2480 | |||
2481 | static int do_proc_dqstats(struct ctl_table *table, int write, | ||
2482 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2483 | { | ||
2484 | unsigned int type = (int *)table->data - dqstats.stat; | ||
2485 | |||
2486 | /* Update global table */ | ||
2487 | dqstats.stat[type] = | ||
2488 | percpu_counter_sum_positive(&dqstats.counter[type]); | ||
2489 | return proc_dointvec(table, write, buffer, lenp, ppos); | ||
2490 | } | ||
2463 | 2491 | ||
2464 | static ctl_table fs_dqstats_table[] = { | 2492 | static ctl_table fs_dqstats_table[] = { |
2465 | { | 2493 | { |
2466 | .procname = "lookups", | 2494 | .procname = "lookups", |
2467 | .data = &dqstats.lookups, | 2495 | .data = &dqstats.stat[DQST_LOOKUPS], |
2468 | .maxlen = sizeof(int), | 2496 | .maxlen = sizeof(int), |
2469 | .mode = 0444, | 2497 | .mode = 0444, |
2470 | .proc_handler = proc_dointvec, | 2498 | .proc_handler = do_proc_dqstats, |
2471 | }, | 2499 | }, |
2472 | { | 2500 | { |
2473 | .procname = "drops", | 2501 | .procname = "drops", |
2474 | .data = &dqstats.drops, | 2502 | .data = &dqstats.stat[DQST_DROPS], |
2475 | .maxlen = sizeof(int), | 2503 | .maxlen = sizeof(int), |
2476 | .mode = 0444, | 2504 | .mode = 0444, |
2477 | .proc_handler = proc_dointvec, | 2505 | .proc_handler = do_proc_dqstats, |
2478 | }, | 2506 | }, |
2479 | { | 2507 | { |
2480 | .procname = "reads", | 2508 | .procname = "reads", |
2481 | .data = &dqstats.reads, | 2509 | .data = &dqstats.stat[DQST_READS], |
2482 | .maxlen = sizeof(int), | 2510 | .maxlen = sizeof(int), |
2483 | .mode = 0444, | 2511 | .mode = 0444, |
2484 | .proc_handler = proc_dointvec, | 2512 | .proc_handler = do_proc_dqstats, |
2485 | }, | 2513 | }, |
2486 | { | 2514 | { |
2487 | .procname = "writes", | 2515 | .procname = "writes", |
2488 | .data = &dqstats.writes, | 2516 | .data = &dqstats.stat[DQST_WRITES], |
2489 | .maxlen = sizeof(int), | 2517 | .maxlen = sizeof(int), |
2490 | .mode = 0444, | 2518 | .mode = 0444, |
2491 | .proc_handler = proc_dointvec, | 2519 | .proc_handler = do_proc_dqstats, |
2492 | }, | 2520 | }, |
2493 | { | 2521 | { |
2494 | .procname = "cache_hits", | 2522 | .procname = "cache_hits", |
2495 | .data = &dqstats.cache_hits, | 2523 | .data = &dqstats.stat[DQST_CACHE_HITS], |
2496 | .maxlen = sizeof(int), | 2524 | .maxlen = sizeof(int), |
2497 | .mode = 0444, | 2525 | .mode = 0444, |
2498 | .proc_handler = proc_dointvec, | 2526 | .proc_handler = do_proc_dqstats, |
2499 | }, | 2527 | }, |
2500 | { | 2528 | { |
2501 | .procname = "allocated_dquots", | 2529 | .procname = "allocated_dquots", |
2502 | .data = &dqstats.allocated_dquots, | 2530 | .data = &dqstats.stat[DQST_ALLOC_DQUOTS], |
2503 | .maxlen = sizeof(int), | 2531 | .maxlen = sizeof(int), |
2504 | .mode = 0444, | 2532 | .mode = 0444, |
2505 | .proc_handler = proc_dointvec, | 2533 | .proc_handler = do_proc_dqstats, |
2506 | }, | 2534 | }, |
2507 | { | 2535 | { |
2508 | .procname = "free_dquots", | 2536 | .procname = "free_dquots", |
2509 | .data = &dqstats.free_dquots, | 2537 | .data = &dqstats.stat[DQST_FREE_DQUOTS], |
2510 | .maxlen = sizeof(int), | 2538 | .maxlen = sizeof(int), |
2511 | .mode = 0444, | 2539 | .mode = 0444, |
2512 | .proc_handler = proc_dointvec, | 2540 | .proc_handler = do_proc_dqstats, |
2513 | }, | 2541 | }, |
2514 | { | 2542 | { |
2515 | .procname = "syncs", | 2543 | .procname = "syncs", |
2516 | .data = &dqstats.syncs, | 2544 | .data = &dqstats.stat[DQST_SYNCS], |
2517 | .maxlen = sizeof(int), | 2545 | .maxlen = sizeof(int), |
2518 | .mode = 0444, | 2546 | .mode = 0444, |
2519 | .proc_handler = proc_dointvec, | 2547 | .proc_handler = do_proc_dqstats, |
2520 | }, | 2548 | }, |
2521 | #ifdef CONFIG_PRINT_QUOTA_WARNING | 2549 | #ifdef CONFIG_PRINT_QUOTA_WARNING |
2522 | { | 2550 | { |
@@ -2550,7 +2578,7 @@ static ctl_table sys_table[] = { | |||
2550 | 2578 | ||
2551 | static int __init dquot_init(void) | 2579 | static int __init dquot_init(void) |
2552 | { | 2580 | { |
2553 | int i; | 2581 | int i, ret; |
2554 | unsigned long nr_hash, order; | 2582 | unsigned long nr_hash, order; |
2555 | 2583 | ||
2556 | printk(KERN_NOTICE "VFS: Disk quotas %s\n", __DQUOT_VERSION__); | 2584 | printk(KERN_NOTICE "VFS: Disk quotas %s\n", __DQUOT_VERSION__); |
@@ -2568,6 +2596,12 @@ static int __init dquot_init(void) | |||
2568 | if (!dquot_hash) | 2596 | if (!dquot_hash) |
2569 | panic("Cannot create dquot hash table"); | 2597 | panic("Cannot create dquot hash table"); |
2570 | 2598 | ||
2599 | for (i = 0; i < _DQST_DQSTAT_LAST; i++) { | ||
2600 | ret = percpu_counter_init(&dqstats.counter[i], 0); | ||
2601 | if (ret) | ||
2602 | panic("Cannot create dquot stat counters"); | ||
2603 | } | ||
2604 | |||
2571 | /* Find power-of-two hlist_heads which can fit into allocation */ | 2605 | /* Find power-of-two hlist_heads which can fit into allocation */ |
2572 | nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head); | 2606 | nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head); |
2573 | dq_hash_bits = 0; | 2607 | dq_hash_bits = 0; |
diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c index 2663ed90fb03..d67908b407d9 100644 --- a/fs/quota/netlink.c +++ b/fs/quota/netlink.c | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
6 | #include <linux/quotaops.h> | 6 | #include <linux/quotaops.h> |
7 | #include <linux/sched.h> | 7 | #include <linux/sched.h> |
8 | #include <linux/slab.h> | ||
8 | #include <net/netlink.h> | 9 | #include <net/netlink.h> |
9 | #include <net/genetlink.h> | 10 | #include <net/genetlink.h> |
10 | 11 | ||
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 95388f9b7356..b299961e1edb 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
@@ -45,36 +45,22 @@ static int check_quotactl_permission(struct super_block *sb, int type, int cmd, | |||
45 | return security_quotactl(cmd, type, id, sb); | 45 | return security_quotactl(cmd, type, id, sb); |
46 | } | 46 | } |
47 | 47 | ||
48 | static void quota_sync_one(struct super_block *sb, void *arg) | ||
49 | { | ||
50 | if (sb->s_qcop && sb->s_qcop->quota_sync) | ||
51 | sb->s_qcop->quota_sync(sb, *(int *)arg, 1); | ||
52 | } | ||
53 | |||
48 | static int quota_sync_all(int type) | 54 | static int quota_sync_all(int type) |
49 | { | 55 | { |
50 | struct super_block *sb; | ||
51 | int ret; | 56 | int ret; |
52 | 57 | ||
53 | if (type >= MAXQUOTAS) | 58 | if (type >= MAXQUOTAS) |
54 | return -EINVAL; | 59 | return -EINVAL; |
55 | ret = security_quotactl(Q_SYNC, type, 0, NULL); | 60 | ret = security_quotactl(Q_SYNC, type, 0, NULL); |
56 | if (ret) | 61 | if (!ret) |
57 | return ret; | 62 | iterate_supers(quota_sync_one, &type); |
58 | 63 | return ret; | |
59 | spin_lock(&sb_lock); | ||
60 | restart: | ||
61 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
62 | if (!sb->s_qcop || !sb->s_qcop->quota_sync) | ||
63 | continue; | ||
64 | |||
65 | sb->s_count++; | ||
66 | spin_unlock(&sb_lock); | ||
67 | down_read(&sb->s_umount); | ||
68 | if (sb->s_root) | ||
69 | sb->s_qcop->quota_sync(sb, type, 1); | ||
70 | up_read(&sb->s_umount); | ||
71 | spin_lock(&sb_lock); | ||
72 | if (__put_super_and_need_restart(sb)) | ||
73 | goto restart; | ||
74 | } | ||
75 | spin_unlock(&sb_lock); | ||
76 | |||
77 | return 0; | ||
78 | } | 64 | } |
79 | 65 | ||
80 | static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, | 66 | static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, |
@@ -87,7 +73,7 @@ static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id, | |||
87 | if (IS_ERR(pathname)) | 73 | if (IS_ERR(pathname)) |
88 | return PTR_ERR(pathname); | 74 | return PTR_ERR(pathname); |
89 | if (sb->s_qcop->quota_on) | 75 | if (sb->s_qcop->quota_on) |
90 | ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0); | 76 | ret = sb->s_qcop->quota_on(sb, type, id, pathname); |
91 | putname(pathname); | 77 | putname(pathname); |
92 | return ret; | 78 | return ret; |
93 | } | 79 | } |
@@ -113,8 +99,6 @@ static int quota_getinfo(struct super_block *sb, int type, void __user *addr) | |||
113 | struct if_dqinfo info; | 99 | struct if_dqinfo info; |
114 | int ret; | 100 | int ret; |
115 | 101 | ||
116 | if (!sb_has_quota_active(sb, type)) | ||
117 | return -ESRCH; | ||
118 | if (!sb->s_qcop->get_info) | 102 | if (!sb->s_qcop->get_info) |
119 | return -ENOSYS; | 103 | return -ENOSYS; |
120 | ret = sb->s_qcop->get_info(sb, type, &info); | 104 | ret = sb->s_qcop->get_info(sb, type, &info); |
@@ -129,43 +113,80 @@ static int quota_setinfo(struct super_block *sb, int type, void __user *addr) | |||
129 | 113 | ||
130 | if (copy_from_user(&info, addr, sizeof(info))) | 114 | if (copy_from_user(&info, addr, sizeof(info))) |
131 | return -EFAULT; | 115 | return -EFAULT; |
132 | if (!sb_has_quota_active(sb, type)) | ||
133 | return -ESRCH; | ||
134 | if (!sb->s_qcop->set_info) | 116 | if (!sb->s_qcop->set_info) |
135 | return -ENOSYS; | 117 | return -ENOSYS; |
136 | return sb->s_qcop->set_info(sb, type, &info); | 118 | return sb->s_qcop->set_info(sb, type, &info); |
137 | } | 119 | } |
138 | 120 | ||
121 | static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src) | ||
122 | { | ||
123 | dst->dqb_bhardlimit = src->d_blk_hardlimit; | ||
124 | dst->dqb_bsoftlimit = src->d_blk_softlimit; | ||
125 | dst->dqb_curspace = src->d_bcount; | ||
126 | dst->dqb_ihardlimit = src->d_ino_hardlimit; | ||
127 | dst->dqb_isoftlimit = src->d_ino_softlimit; | ||
128 | dst->dqb_curinodes = src->d_icount; | ||
129 | dst->dqb_btime = src->d_btimer; | ||
130 | dst->dqb_itime = src->d_itimer; | ||
131 | dst->dqb_valid = QIF_ALL; | ||
132 | } | ||
133 | |||
139 | static int quota_getquota(struct super_block *sb, int type, qid_t id, | 134 | static int quota_getquota(struct super_block *sb, int type, qid_t id, |
140 | void __user *addr) | 135 | void __user *addr) |
141 | { | 136 | { |
137 | struct fs_disk_quota fdq; | ||
142 | struct if_dqblk idq; | 138 | struct if_dqblk idq; |
143 | int ret; | 139 | int ret; |
144 | 140 | ||
145 | if (!sb_has_quota_active(sb, type)) | ||
146 | return -ESRCH; | ||
147 | if (!sb->s_qcop->get_dqblk) | 141 | if (!sb->s_qcop->get_dqblk) |
148 | return -ENOSYS; | 142 | return -ENOSYS; |
149 | ret = sb->s_qcop->get_dqblk(sb, type, id, &idq); | 143 | ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq); |
150 | if (ret) | 144 | if (ret) |
151 | return ret; | 145 | return ret; |
146 | copy_to_if_dqblk(&idq, &fdq); | ||
152 | if (copy_to_user(addr, &idq, sizeof(idq))) | 147 | if (copy_to_user(addr, &idq, sizeof(idq))) |
153 | return -EFAULT; | 148 | return -EFAULT; |
154 | return 0; | 149 | return 0; |
155 | } | 150 | } |
156 | 151 | ||
152 | static void copy_from_if_dqblk(struct fs_disk_quota *dst, struct if_dqblk *src) | ||
153 | { | ||
154 | dst->d_blk_hardlimit = src->dqb_bhardlimit; | ||
155 | dst->d_blk_softlimit = src->dqb_bsoftlimit; | ||
156 | dst->d_bcount = src->dqb_curspace; | ||
157 | dst->d_ino_hardlimit = src->dqb_ihardlimit; | ||
158 | dst->d_ino_softlimit = src->dqb_isoftlimit; | ||
159 | dst->d_icount = src->dqb_curinodes; | ||
160 | dst->d_btimer = src->dqb_btime; | ||
161 | dst->d_itimer = src->dqb_itime; | ||
162 | |||
163 | dst->d_fieldmask = 0; | ||
164 | if (src->dqb_valid & QIF_BLIMITS) | ||
165 | dst->d_fieldmask |= FS_DQ_BSOFT | FS_DQ_BHARD; | ||
166 | if (src->dqb_valid & QIF_SPACE) | ||
167 | dst->d_fieldmask |= FS_DQ_BCOUNT; | ||
168 | if (src->dqb_valid & QIF_ILIMITS) | ||
169 | dst->d_fieldmask |= FS_DQ_ISOFT | FS_DQ_IHARD; | ||
170 | if (src->dqb_valid & QIF_INODES) | ||
171 | dst->d_fieldmask |= FS_DQ_ICOUNT; | ||
172 | if (src->dqb_valid & QIF_BTIME) | ||
173 | dst->d_fieldmask |= FS_DQ_BTIMER; | ||
174 | if (src->dqb_valid & QIF_ITIME) | ||
175 | dst->d_fieldmask |= FS_DQ_ITIMER; | ||
176 | } | ||
177 | |||
157 | static int quota_setquota(struct super_block *sb, int type, qid_t id, | 178 | static int quota_setquota(struct super_block *sb, int type, qid_t id, |
158 | void __user *addr) | 179 | void __user *addr) |
159 | { | 180 | { |
181 | struct fs_disk_quota fdq; | ||
160 | struct if_dqblk idq; | 182 | struct if_dqblk idq; |
161 | 183 | ||
162 | if (copy_from_user(&idq, addr, sizeof(idq))) | 184 | if (copy_from_user(&idq, addr, sizeof(idq))) |
163 | return -EFAULT; | 185 | return -EFAULT; |
164 | if (!sb_has_quota_active(sb, type)) | ||
165 | return -ESRCH; | ||
166 | if (!sb->s_qcop->set_dqblk) | 186 | if (!sb->s_qcop->set_dqblk) |
167 | return -ENOSYS; | 187 | return -ENOSYS; |
168 | return sb->s_qcop->set_dqblk(sb, type, id, &idq); | 188 | copy_from_if_dqblk(&fdq, &idq); |
189 | return sb->s_qcop->set_dqblk(sb, type, id, &fdq); | ||
169 | } | 190 | } |
170 | 191 | ||
171 | static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr) | 192 | static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr) |
@@ -199,9 +220,9 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id, | |||
199 | 220 | ||
200 | if (copy_from_user(&fdq, addr, sizeof(fdq))) | 221 | if (copy_from_user(&fdq, addr, sizeof(fdq))) |
201 | return -EFAULT; | 222 | return -EFAULT; |
202 | if (!sb->s_qcop->set_xquota) | 223 | if (!sb->s_qcop->set_dqblk) |
203 | return -ENOSYS; | 224 | return -ENOSYS; |
204 | return sb->s_qcop->set_xquota(sb, type, id, &fdq); | 225 | return sb->s_qcop->set_dqblk(sb, type, id, &fdq); |
205 | } | 226 | } |
206 | 227 | ||
207 | static int quota_getxquota(struct super_block *sb, int type, qid_t id, | 228 | static int quota_getxquota(struct super_block *sb, int type, qid_t id, |
@@ -210,9 +231,9 @@ static int quota_getxquota(struct super_block *sb, int type, qid_t id, | |||
210 | struct fs_disk_quota fdq; | 231 | struct fs_disk_quota fdq; |
211 | int ret; | 232 | int ret; |
212 | 233 | ||
213 | if (!sb->s_qcop->get_xquota) | 234 | if (!sb->s_qcop->get_dqblk) |
214 | return -ENOSYS; | 235 | return -ENOSYS; |
215 | ret = sb->s_qcop->get_xquota(sb, type, id, &fdq); | 236 | ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq); |
216 | if (!ret && copy_to_user(addr, &fdq, sizeof(fdq))) | 237 | if (!ret && copy_to_user(addr, &fdq, sizeof(fdq))) |
217 | return -EFAULT; | 238 | return -EFAULT; |
218 | return ret; | 239 | return ret; |
@@ -239,7 +260,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, | |||
239 | case Q_QUOTAOFF: | 260 | case Q_QUOTAOFF: |
240 | if (!sb->s_qcop->quota_off) | 261 | if (!sb->s_qcop->quota_off) |
241 | return -ENOSYS; | 262 | return -ENOSYS; |
242 | return sb->s_qcop->quota_off(sb, type, 0); | 263 | return sb->s_qcop->quota_off(sb, type); |
243 | case Q_GETFMT: | 264 | case Q_GETFMT: |
244 | return quota_getfmt(sb, type, addr); | 265 | return quota_getfmt(sb, type, addr); |
245 | case Q_GETINFO: | 266 | case Q_GETINFO: |
diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c index f81f4bcfb178..24f03407eeb5 100644 --- a/fs/quota/quota_tree.c +++ b/fs/quota/quota_tree.c | |||
@@ -60,9 +60,17 @@ static ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) | |||
60 | static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) | 60 | static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) |
61 | { | 61 | { |
62 | struct super_block *sb = info->dqi_sb; | 62 | struct super_block *sb = info->dqi_sb; |
63 | ssize_t ret; | ||
63 | 64 | ||
64 | return sb->s_op->quota_write(sb, info->dqi_type, buf, | 65 | ret = sb->s_op->quota_write(sb, info->dqi_type, buf, |
65 | info->dqi_usable_bs, blk << info->dqi_blocksize_bits); | 66 | info->dqi_usable_bs, blk << info->dqi_blocksize_bits); |
67 | if (ret != info->dqi_usable_bs) { | ||
68 | q_warn(KERN_WARNING "VFS: dquota write failed on " | ||
69 | "dev %s\n", sb->s_id); | ||
70 | if (ret >= 0) | ||
71 | ret = -EIO; | ||
72 | } | ||
73 | return ret; | ||
66 | } | 74 | } |
67 | 75 | ||
68 | /* Remove empty block from list and return it */ | 76 | /* Remove empty block from list and return it */ |
@@ -152,7 +160,7 @@ static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, | |||
152 | dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); | 160 | dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); |
153 | /* No matter whether write succeeds block is out of list */ | 161 | /* No matter whether write succeeds block is out of list */ |
154 | if (write_blk(info, blk, buf) < 0) | 162 | if (write_blk(info, blk, buf) < 0) |
155 | printk(KERN_ERR | 163 | q_warn(KERN_ERR |
156 | "VFS: Can't write block (%u) with free entries.\n", | 164 | "VFS: Can't write block (%u) with free entries.\n", |
157 | blk); | 165 | blk); |
158 | return 0; | 166 | return 0; |
@@ -244,7 +252,7 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, | |||
244 | if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) { | 252 | if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) { |
245 | *err = remove_free_dqentry(info, buf, blk); | 253 | *err = remove_free_dqentry(info, buf, blk); |
246 | if (*err < 0) { | 254 | if (*err < 0) { |
247 | printk(KERN_ERR "VFS: find_free_dqentry(): Can't " | 255 | q_warn(KERN_ERR "VFS: find_free_dqentry(): Can't " |
248 | "remove block (%u) from entry free list.\n", | 256 | "remove block (%u) from entry free list.\n", |
249 | blk); | 257 | blk); |
250 | goto out_buf; | 258 | goto out_buf; |
@@ -268,7 +276,7 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, | |||
268 | #endif | 276 | #endif |
269 | *err = write_blk(info, blk, buf); | 277 | *err = write_blk(info, blk, buf); |
270 | if (*err < 0) { | 278 | if (*err < 0) { |
271 | printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota " | 279 | q_warn(KERN_ERR "VFS: find_free_dqentry(): Can't write quota " |
272 | "data block %u.\n", blk); | 280 | "data block %u.\n", blk); |
273 | goto out_buf; | 281 | goto out_buf; |
274 | } | 282 | } |
@@ -303,7 +311,7 @@ static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, | |||
303 | } else { | 311 | } else { |
304 | ret = read_blk(info, *treeblk, buf); | 312 | ret = read_blk(info, *treeblk, buf); |
305 | if (ret < 0) { | 313 | if (ret < 0) { |
306 | printk(KERN_ERR "VFS: Can't read tree quota block " | 314 | q_warn(KERN_ERR "VFS: Can't read tree quota block " |
307 | "%u.\n", *treeblk); | 315 | "%u.\n", *treeblk); |
308 | goto out_buf; | 316 | goto out_buf; |
309 | } | 317 | } |
@@ -365,7 +373,7 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | |||
365 | if (!dquot->dq_off) { | 373 | if (!dquot->dq_off) { |
366 | ret = dq_insert_tree(info, dquot); | 374 | ret = dq_insert_tree(info, dquot); |
367 | if (ret < 0) { | 375 | if (ret < 0) { |
368 | printk(KERN_ERR "VFS: Error %zd occurred while " | 376 | q_warn(KERN_ERR "VFS: Error %zd occurred while " |
369 | "creating quota.\n", ret); | 377 | "creating quota.\n", ret); |
370 | kfree(ddquot); | 378 | kfree(ddquot); |
371 | return ret; | 379 | return ret; |
@@ -377,14 +385,14 @@ int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | |||
377 | ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size, | 385 | ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size, |
378 | dquot->dq_off); | 386 | dquot->dq_off); |
379 | if (ret != info->dqi_entry_size) { | 387 | if (ret != info->dqi_entry_size) { |
380 | printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", | 388 | q_warn(KERN_WARNING "VFS: dquota write failed on dev %s\n", |
381 | sb->s_id); | 389 | sb->s_id); |
382 | if (ret >= 0) | 390 | if (ret >= 0) |
383 | ret = -ENOSPC; | 391 | ret = -ENOSPC; |
384 | } else { | 392 | } else { |
385 | ret = 0; | 393 | ret = 0; |
386 | } | 394 | } |
387 | dqstats.writes++; | 395 | dqstats_inc(DQST_WRITES); |
388 | kfree(ddquot); | 396 | kfree(ddquot); |
389 | 397 | ||
390 | return ret; | 398 | return ret; |
@@ -402,14 +410,14 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, | |||
402 | if (!buf) | 410 | if (!buf) |
403 | return -ENOMEM; | 411 | return -ENOMEM; |
404 | if (dquot->dq_off >> info->dqi_blocksize_bits != blk) { | 412 | if (dquot->dq_off >> info->dqi_blocksize_bits != blk) { |
405 | printk(KERN_ERR "VFS: Quota structure has offset to other " | 413 | q_warn(KERN_ERR "VFS: Quota structure has offset to other " |
406 | "block (%u) than it should (%u).\n", blk, | 414 | "block (%u) than it should (%u).\n", blk, |
407 | (uint)(dquot->dq_off >> info->dqi_blocksize_bits)); | 415 | (uint)(dquot->dq_off >> info->dqi_blocksize_bits)); |
408 | goto out_buf; | 416 | goto out_buf; |
409 | } | 417 | } |
410 | ret = read_blk(info, blk, buf); | 418 | ret = read_blk(info, blk, buf); |
411 | if (ret < 0) { | 419 | if (ret < 0) { |
412 | printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk); | 420 | q_warn(KERN_ERR "VFS: Can't read quota data block %u\n", blk); |
413 | goto out_buf; | 421 | goto out_buf; |
414 | } | 422 | } |
415 | dh = (struct qt_disk_dqdbheader *)buf; | 423 | dh = (struct qt_disk_dqdbheader *)buf; |
@@ -419,7 +427,7 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, | |||
419 | if (ret >= 0) | 427 | if (ret >= 0) |
420 | ret = put_free_dqblk(info, buf, blk); | 428 | ret = put_free_dqblk(info, buf, blk); |
421 | if (ret < 0) { | 429 | if (ret < 0) { |
422 | printk(KERN_ERR "VFS: Can't move quota data block (%u) " | 430 | q_warn(KERN_ERR "VFS: Can't move quota data block (%u) " |
423 | "to free list.\n", blk); | 431 | "to free list.\n", blk); |
424 | goto out_buf; | 432 | goto out_buf; |
425 | } | 433 | } |
@@ -432,14 +440,14 @@ static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot, | |||
432 | /* Insert will write block itself */ | 440 | /* Insert will write block itself */ |
433 | ret = insert_free_dqentry(info, buf, blk); | 441 | ret = insert_free_dqentry(info, buf, blk); |
434 | if (ret < 0) { | 442 | if (ret < 0) { |
435 | printk(KERN_ERR "VFS: Can't insert quota data " | 443 | q_warn(KERN_ERR "VFS: Can't insert quota data " |
436 | "block (%u) to free entry list.\n", blk); | 444 | "block (%u) to free entry list.\n", blk); |
437 | goto out_buf; | 445 | goto out_buf; |
438 | } | 446 | } |
439 | } else { | 447 | } else { |
440 | ret = write_blk(info, blk, buf); | 448 | ret = write_blk(info, blk, buf); |
441 | if (ret < 0) { | 449 | if (ret < 0) { |
442 | printk(KERN_ERR "VFS: Can't write quota data " | 450 | q_warn(KERN_ERR "VFS: Can't write quota data " |
443 | "block %u\n", blk); | 451 | "block %u\n", blk); |
444 | goto out_buf; | 452 | goto out_buf; |
445 | } | 453 | } |
@@ -464,7 +472,7 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, | |||
464 | return -ENOMEM; | 472 | return -ENOMEM; |
465 | ret = read_blk(info, *blk, buf); | 473 | ret = read_blk(info, *blk, buf); |
466 | if (ret < 0) { | 474 | if (ret < 0) { |
467 | printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk); | 475 | q_warn(KERN_ERR "VFS: Can't read quota data block %u\n", *blk); |
468 | goto out_buf; | 476 | goto out_buf; |
469 | } | 477 | } |
470 | newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); | 478 | newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); |
@@ -488,7 +496,7 @@ static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot, | |||
488 | } else { | 496 | } else { |
489 | ret = write_blk(info, *blk, buf); | 497 | ret = write_blk(info, *blk, buf); |
490 | if (ret < 0) | 498 | if (ret < 0) |
491 | printk(KERN_ERR "VFS: Can't write quota tree " | 499 | q_warn(KERN_ERR "VFS: Can't write quota tree " |
492 | "block %u.\n", *blk); | 500 | "block %u.\n", *blk); |
493 | } | 501 | } |
494 | } | 502 | } |
@@ -521,7 +529,7 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, | |||
521 | return -ENOMEM; | 529 | return -ENOMEM; |
522 | ret = read_blk(info, blk, buf); | 530 | ret = read_blk(info, blk, buf); |
523 | if (ret < 0) { | 531 | if (ret < 0) { |
524 | printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); | 532 | q_warn(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); |
525 | goto out_buf; | 533 | goto out_buf; |
526 | } | 534 | } |
527 | ddquot = buf + sizeof(struct qt_disk_dqdbheader); | 535 | ddquot = buf + sizeof(struct qt_disk_dqdbheader); |
@@ -531,7 +539,7 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, | |||
531 | ddquot += info->dqi_entry_size; | 539 | ddquot += info->dqi_entry_size; |
532 | } | 540 | } |
533 | if (i == qtree_dqstr_in_blk(info)) { | 541 | if (i == qtree_dqstr_in_blk(info)) { |
534 | printk(KERN_ERR "VFS: Quota for id %u referenced " | 542 | q_warn(KERN_ERR "VFS: Quota for id %u referenced " |
535 | "but not present.\n", dquot->dq_id); | 543 | "but not present.\n", dquot->dq_id); |
536 | ret = -EIO; | 544 | ret = -EIO; |
537 | goto out_buf; | 545 | goto out_buf; |
@@ -556,7 +564,7 @@ static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info, | |||
556 | return -ENOMEM; | 564 | return -ENOMEM; |
557 | ret = read_blk(info, blk, buf); | 565 | ret = read_blk(info, blk, buf); |
558 | if (ret < 0) { | 566 | if (ret < 0) { |
559 | printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); | 567 | q_warn(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); |
560 | goto out_buf; | 568 | goto out_buf; |
561 | } | 569 | } |
562 | ret = 0; | 570 | ret = 0; |
@@ -599,7 +607,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | |||
599 | offset = find_dqentry(info, dquot); | 607 | offset = find_dqentry(info, dquot); |
600 | if (offset <= 0) { /* Entry not present? */ | 608 | if (offset <= 0) { /* Entry not present? */ |
601 | if (offset < 0) | 609 | if (offset < 0) |
602 | printk(KERN_ERR "VFS: Can't read quota " | 610 | q_warn(KERN_ERR "VFS: Can't read quota " |
603 | "structure for id %u.\n", dquot->dq_id); | 611 | "structure for id %u.\n", dquot->dq_id); |
604 | dquot->dq_off = 0; | 612 | dquot->dq_off = 0; |
605 | set_bit(DQ_FAKE_B, &dquot->dq_flags); | 613 | set_bit(DQ_FAKE_B, &dquot->dq_flags); |
@@ -617,7 +625,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | |||
617 | if (ret != info->dqi_entry_size) { | 625 | if (ret != info->dqi_entry_size) { |
618 | if (ret >= 0) | 626 | if (ret >= 0) |
619 | ret = -EIO; | 627 | ret = -EIO; |
620 | printk(KERN_ERR "VFS: Error while reading quota " | 628 | q_warn(KERN_ERR "VFS: Error while reading quota " |
621 | "structure for id %u.\n", dquot->dq_id); | 629 | "structure for id %u.\n", dquot->dq_id); |
622 | set_bit(DQ_FAKE_B, &dquot->dq_flags); | 630 | set_bit(DQ_FAKE_B, &dquot->dq_flags); |
623 | memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); | 631 | memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); |
@@ -634,7 +642,7 @@ int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | |||
634 | spin_unlock(&dq_data_lock); | 642 | spin_unlock(&dq_data_lock); |
635 | kfree(ddquot); | 643 | kfree(ddquot); |
636 | out: | 644 | out: |
637 | dqstats.reads++; | 645 | dqstats_inc(DQST_READS); |
638 | return ret; | 646 | return ret; |
639 | } | 647 | } |
640 | EXPORT_SYMBOL(qtree_read_dquot); | 648 | EXPORT_SYMBOL(qtree_read_dquot); |
diff --git a/fs/quota/quota_tree.h b/fs/quota/quota_tree.h index a1ab8db81a51..ccc3e71fb1d8 100644 --- a/fs/quota/quota_tree.h +++ b/fs/quota/quota_tree.h | |||
@@ -22,4 +22,10 @@ struct qt_disk_dqdbheader { | |||
22 | 22 | ||
23 | #define QT_TREEOFF 1 /* Offset of tree in file in blocks */ | 23 | #define QT_TREEOFF 1 /* Offset of tree in file in blocks */ |
24 | 24 | ||
25 | #define q_warn(fmt, args...) \ | ||
26 | do { \ | ||
27 | if (printk_ratelimit()) \ | ||
28 | printk(fmt, ## args); \ | ||
29 | } while(0) | ||
30 | |||
25 | #endif /* _LINUX_QUOTAIO_TREE_H */ | 31 | #endif /* _LINUX_QUOTAIO_TREE_H */ |
diff --git a/fs/quota/quota_v1.c b/fs/quota/quota_v1.c index 2ae757e9c008..4af344c5852a 100644 --- a/fs/quota/quota_v1.c +++ b/fs/quota/quota_v1.c | |||
@@ -71,7 +71,7 @@ static int v1_read_dqblk(struct dquot *dquot) | |||
71 | dquot->dq_dqb.dqb_ihardlimit == 0 && | 71 | dquot->dq_dqb.dqb_ihardlimit == 0 && |
72 | dquot->dq_dqb.dqb_isoftlimit == 0) | 72 | dquot->dq_dqb.dqb_isoftlimit == 0) |
73 | set_bit(DQ_FAKE_B, &dquot->dq_flags); | 73 | set_bit(DQ_FAKE_B, &dquot->dq_flags); |
74 | dqstats.reads++; | 74 | dqstats_inc(DQST_READS); |
75 | 75 | ||
76 | return 0; | 76 | return 0; |
77 | } | 77 | } |
@@ -104,7 +104,7 @@ static int v1_commit_dqblk(struct dquot *dquot) | |||
104 | ret = 0; | 104 | ret = 0; |
105 | 105 | ||
106 | out: | 106 | out: |
107 | dqstats.writes++; | 107 | dqstats_inc(DQST_WRITES); |
108 | 108 | ||
109 | return ret; | 109 | return ret; |
110 | } | 110 | } |
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index e3da02f4986f..135206af1458 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c | |||
@@ -63,7 +63,7 @@ static int v2_read_header(struct super_block *sb, int type, | |||
63 | size = sb->s_op->quota_read(sb, type, (char *)dqhead, | 63 | size = sb->s_op->quota_read(sb, type, (char *)dqhead, |
64 | sizeof(struct v2_disk_dqheader), 0); | 64 | sizeof(struct v2_disk_dqheader), 0); |
65 | if (size != sizeof(struct v2_disk_dqheader)) { | 65 | if (size != sizeof(struct v2_disk_dqheader)) { |
66 | printk(KERN_WARNING "quota_v2: Failed header read:" | 66 | q_warn(KERN_WARNING "quota_v2: Failed header read:" |
67 | " expected=%zd got=%zd\n", | 67 | " expected=%zd got=%zd\n", |
68 | sizeof(struct v2_disk_dqheader), size); | 68 | sizeof(struct v2_disk_dqheader), size); |
69 | return 0; | 69 | return 0; |
@@ -106,7 +106,7 @@ static int v2_read_file_info(struct super_block *sb, int type) | |||
106 | size = sb->s_op->quota_read(sb, type, (char *)&dinfo, | 106 | size = sb->s_op->quota_read(sb, type, (char *)&dinfo, |
107 | sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); | 107 | sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); |
108 | if (size != sizeof(struct v2_disk_dqinfo)) { | 108 | if (size != sizeof(struct v2_disk_dqinfo)) { |
109 | printk(KERN_WARNING "quota_v2: Can't read info structure on device %s.\n", | 109 | q_warn(KERN_WARNING "quota_v2: Can't read info structure on device %s.\n", |
110 | sb->s_id); | 110 | sb->s_id); |
111 | return -1; | 111 | return -1; |
112 | } | 112 | } |
@@ -167,7 +167,7 @@ static int v2_write_file_info(struct super_block *sb, int type) | |||
167 | size = sb->s_op->quota_write(sb, type, (char *)&dinfo, | 167 | size = sb->s_op->quota_write(sb, type, (char *)&dinfo, |
168 | sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); | 168 | sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); |
169 | if (size != sizeof(struct v2_disk_dqinfo)) { | 169 | if (size != sizeof(struct v2_disk_dqinfo)) { |
170 | printk(KERN_WARNING "Can't write info structure on device %s.\n", | 170 | q_warn(KERN_WARNING "Can't write info structure on device %s.\n", |
171 | sb->s_id); | 171 | sb->s_id); |
172 | return -1; | 172 | return -1; |
173 | } | 173 | } |