aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-13 19:45:40 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-13 19:45:40 -0400
commitcec997093bbff881c3da49084dfba4f76361e96a (patch)
tree7c84f8c30ceef7209a18d7cd216a3c16536008c5
parent8d2d441ac4af223eae466c3c31ff737cc31a1411 (diff)
parent01777836c87081e4f68c4a43c9abe6114805f91e (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull quota, reiserfs, UDF updates from Jan Kara: "Scalability improvements for quota, a few reiserfs fixes, and couple of misc cleanups (udf, ext2)" * 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: reiserfs: Fix use after free in journal teardown reiserfs: fix corruption introduced by balance_leaf refactor udf: avoid redundant memcpy when writing data in ICB fs/udf: re-use hex_asc_upper_{hi,lo} macros fs/quota: kernel-doc warning fixes udf: use linux/uaccess.h fs/ext2/super.c: Drop memory allocation cast quota: remove dqptr_sem quota: simplify remove_inode_dquot_ref() quota: avoid unnecessary dqget()/dqput() calls quota: protect Q_GETFMT by dqonoff_mutex
-rw-r--r--fs/ext2/super.c2
-rw-r--r--fs/quota/dquot.c180
-rw-r--r--fs/quota/kqid.c2
-rw-r--r--fs/quota/netlink.c3
-rw-r--r--fs/quota/quota.c6
-rw-r--r--fs/reiserfs/do_balan.c111
-rw-r--r--fs/reiserfs/journal.c22
-rw-r--r--fs/reiserfs/lbalance.c5
-rw-r--r--fs/reiserfs/reiserfs.h9
-rw-r--r--fs/reiserfs/super.c6
-rw-r--r--fs/super.c1
-rw-r--r--fs/udf/file.c22
-rw-r--r--fs/udf/lowlevel.c2
-rw-r--r--fs/udf/super.c2
-rw-r--r--fs/udf/symlink.c2
-rw-r--r--fs/udf/unicode.c9
-rw-r--r--include/linux/quota.h1
17 files changed, 189 insertions, 196 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 3750031cfa2f..b88edc05c230 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -161,7 +161,7 @@ static struct kmem_cache * ext2_inode_cachep;
161static struct inode *ext2_alloc_inode(struct super_block *sb) 161static struct inode *ext2_alloc_inode(struct super_block *sb)
162{ 162{
163 struct ext2_inode_info *ei; 163 struct ext2_inode_info *ei;
164 ei = (struct ext2_inode_info *)kmem_cache_alloc(ext2_inode_cachep, GFP_KERNEL); 164 ei = kmem_cache_alloc(ext2_inode_cachep, GFP_KERNEL);
165 if (!ei) 165 if (!ei)
166 return NULL; 166 return NULL;
167 ei->i_block_alloc_info = NULL; 167 ei->i_block_alloc_info = NULL;
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index 7f30bdc57d13..f2d0eee9d1f1 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -96,13 +96,16 @@
96 * Note that some things (eg. sb pointer, type, id) doesn't change during 96 * Note that some things (eg. sb pointer, type, id) doesn't change during
97 * the life of the dquot structure and so needn't to be protected by a lock 97 * the life of the dquot structure and so needn't to be protected by a lock
98 * 98 *
99 * Any operation working on dquots via inode pointers must hold dqptr_sem. If 99 * Operation accessing dquots via inode pointers are protected by dquot_srcu.
100 * operation is just reading pointers from inode (or not using them at all) the 100 * Operation of reading pointer needs srcu_read_lock(&dquot_srcu), and
101 * read lock is enough. If pointers are altered function must hold write lock. 101 * synchronize_srcu(&dquot_srcu) is called after clearing pointers from
102 * inode and before dropping dquot references to avoid use of dquots after
103 * they are freed. dq_data_lock is used to serialize the pointer setting and
104 * clearing operations.
102 * Special care needs to be taken about S_NOQUOTA inode flag (marking that 105 * Special care needs to be taken about S_NOQUOTA inode flag (marking that
103 * inode is a quota file). Functions adding pointers from inode to dquots have 106 * inode is a quota file). Functions adding pointers from inode to dquots have
104 * to check this flag under dqptr_sem and then (if S_NOQUOTA is not set) they 107 * to check this flag under dq_data_lock and then (if S_NOQUOTA is not set) they
105 * have to do all pointer modifications before dropping dqptr_sem. This makes 108 * have to do all pointer modifications before dropping dq_data_lock. This makes
106 * sure they cannot race with quotaon which first sets S_NOQUOTA flag and 109 * sure they cannot race with quotaon which first sets S_NOQUOTA flag and
107 * then drops all pointers to dquots from an inode. 110 * then drops all pointers to dquots from an inode.
108 * 111 *
@@ -116,21 +119,15 @@
116 * spinlock to internal buffers before writing. 119 * spinlock to internal buffers before writing.
117 * 120 *
118 * Lock ordering (including related VFS locks) is the following: 121 * Lock ordering (including related VFS locks) is the following:
119 * dqonoff_mutex > i_mutex > journal_lock > dqptr_sem > dquot->dq_lock > 122 * dqonoff_mutex > i_mutex > journal_lock > dquot->dq_lock > dqio_mutex
120 * dqio_mutex
121 * dqonoff_mutex > i_mutex comes from dquot_quota_sync, dquot_enable, etc. 123 * dqonoff_mutex > i_mutex comes from dquot_quota_sync, dquot_enable, etc.
122 * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem >
123 * dqptr_sem. But filesystem has to count with the fact that functions such as
124 * dquot_alloc_space() acquire dqptr_sem and they usually have to be called
125 * from inside a transaction to keep filesystem consistency after a crash. Also
126 * filesystems usually want to do some IO on dquot from ->mark_dirty which is
127 * called with dqptr_sem held.
128 */ 124 */
129 125
130static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); 126static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock);
131static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_state_lock); 127static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_state_lock);
132__cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock); 128__cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock);
133EXPORT_SYMBOL(dq_data_lock); 129EXPORT_SYMBOL(dq_data_lock);
130DEFINE_STATIC_SRCU(dquot_srcu);
134 131
135void __quota_error(struct super_block *sb, const char *func, 132void __quota_error(struct super_block *sb, const char *func,
136 const char *fmt, ...) 133 const char *fmt, ...)
@@ -733,7 +730,6 @@ static struct shrinker dqcache_shrinker = {
733 730
734/* 731/*
735 * Put reference to dquot 732 * Put reference to dquot
736 * NOTE: If you change this function please check whether dqput_blocks() works right...
737 */ 733 */
738void dqput(struct dquot *dquot) 734void dqput(struct dquot *dquot)
739{ 735{
@@ -963,46 +959,33 @@ static void add_dquot_ref(struct super_block *sb, int type)
963} 959}
964 960
965/* 961/*
966 * Return 0 if dqput() won't block.
967 * (note that 1 doesn't necessarily mean blocking)
968 */
969static inline int dqput_blocks(struct dquot *dquot)
970{
971 if (atomic_read(&dquot->dq_count) <= 1)
972 return 1;
973 return 0;
974}
975
976/*
977 * Remove references to dquots from inode and add dquot to list for freeing 962 * Remove references to dquots from inode and add dquot to list for freeing
978 * if we have the last reference to dquot 963 * if we have the last reference to dquot
979 * We can't race with anybody because we hold dqptr_sem for writing...
980 */ 964 */
981static int remove_inode_dquot_ref(struct inode *inode, int type, 965static void remove_inode_dquot_ref(struct inode *inode, int type,
982 struct list_head *tofree_head) 966 struct list_head *tofree_head)
983{ 967{
984 struct dquot *dquot = inode->i_dquot[type]; 968 struct dquot *dquot = inode->i_dquot[type];
985 969
986 inode->i_dquot[type] = NULL; 970 inode->i_dquot[type] = NULL;
987 if (dquot) { 971 if (!dquot)
988 if (dqput_blocks(dquot)) { 972 return;
989#ifdef CONFIG_QUOTA_DEBUG 973
990 if (atomic_read(&dquot->dq_count) != 1) 974 if (list_empty(&dquot->dq_free)) {
991 quota_error(inode->i_sb, "Adding dquot with " 975 /*
992 "dq_count %d to dispose list", 976 * The inode still has reference to dquot so it can't be in the
993 atomic_read(&dquot->dq_count)); 977 * free list
994#endif 978 */
995 spin_lock(&dq_list_lock); 979 spin_lock(&dq_list_lock);
996 /* As dquot must have currently users it can't be on 980 list_add(&dquot->dq_free, tofree_head);
997 * the free list... */ 981 spin_unlock(&dq_list_lock);
998 list_add(&dquot->dq_free, tofree_head); 982 } else {
999 spin_unlock(&dq_list_lock); 983 /*
1000 return 1; 984 * Dquot is already in a list to put so we won't drop the last
1001 } 985 * reference here.
1002 else 986 */
1003 dqput(dquot); /* We have guaranteed we won't block */ 987 dqput(dquot);
1004 } 988 }
1005 return 0;
1006} 989}
1007 990
1008/* 991/*
@@ -1037,13 +1020,15 @@ static void remove_dquot_ref(struct super_block *sb, int type,
1037 * We have to scan also I_NEW inodes because they can already 1020 * We have to scan also I_NEW inodes because they can already
1038 * have quota pointer initialized. Luckily, we need to touch 1021 * have quota pointer initialized. Luckily, we need to touch
1039 * only quota pointers and these have separate locking 1022 * only quota pointers and these have separate locking
1040 * (dqptr_sem). 1023 * (dq_data_lock).
1041 */ 1024 */
1025 spin_lock(&dq_data_lock);
1042 if (!IS_NOQUOTA(inode)) { 1026 if (!IS_NOQUOTA(inode)) {
1043 if (unlikely(inode_get_rsv_space(inode) > 0)) 1027 if (unlikely(inode_get_rsv_space(inode) > 0))
1044 reserved = 1; 1028 reserved = 1;