Blame view

fs/quota/dquot.c 78.9 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
9
10
11
  /*
   * Implementation of the diskquota system for the LINUX operating system. QUOTA
   * is implemented using the BSD system call interface as the means of
   * communication with the user level. This file contains the generic routines
   * called by the different filesystems on allocation of an inode or block.
   * These routines take care of the administration needed to have a consistent
   * diskquota tracking system. The ideas of both user and group quotas are based
   * on the Melbourne quota system as used on BSD derived systems. The internal
   * implementation is based on one of the several variants of the LINUX
   * inode-subsystem with added complexity of the diskquota system.
27942ef50   Sascha Hauer   quota: remove tra...
12
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
   * Author:	Marco van Wieringen <mvw@planets.elm.net>
   *
   * Fixes:   Dmitry Gorodchanin <pgmdsg@ibi.com>, 11 Feb 96
   *
   *		Revised list management to avoid races
   *		-- Bill Hawes, <whawes@star.net>, 9/98
   *
   *		Fixed races in dquot_transfer(), dqget() and dquot_alloc_...().
   *		As the consequence the locking was moved from dquot_decr_...(),
   *		dquot_incr_...() to calling functions.
   *		invalidate_dquots() now writes modified dquots.
   *		Serialized quota_off() and quota_on() for mount point.
   *		Fixed a few bugs in grow_dquots().
   *		Fixed deadlock in write_dquot() - we no longer account quotas on
   *		quota files
   *		remove_dquot_ref() moved to inode.c - it now traverses through inodes
   *		add_dquot_ref() restarts after blocking
   *		Added check for bogus uid and fixed check for group in quotactl.
   *		Jan Kara, <jack@suse.cz>, sponsored by SuSE CR, 10-11/99
   *
   *		Used struct list_head instead of own list struct
   *		Invalidation of referenced dquots is no longer possible
   *		Improved free_dquots list management
   *		Quota and i_blocks are now updated in one place to avoid races
   *		Warnings are now delayed so we won't block in critical section
   *		Write updated not to require dquot lock
   *		Jan Kara, <jack@suse.cz>, 9/2000
   *
   *		Added dynamic quota structure allocation
   *		Jan Kara <jack@suse.cz> 12/2000
   *
   *		Rewritten quota interface. Implemented new quota format and
   *		formats registering.
   *		Jan Kara, <jack@suse.cz>, 2001,2002
   *
   *		New SMP locking.
   *		Jan Kara, <jack@suse.cz>, 10/2002
   *
   *		Added journalled quota support, fix lock inversion problems
   *		Jan Kara, <jack@suse.cz>, 2003,2004
   *
27942ef50   Sascha Hauer   quota: remove tra...
54
   * (C) Copyright 1994 - 1997 Marco van Wieringen
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
   */
  
  #include <linux/errno.h>
  #include <linux/kernel.h>
  #include <linux/fs.h>
  #include <linux/mount.h>
  #include <linux/mm.h>
  #include <linux/time.h>
  #include <linux/types.h>
  #include <linux/string.h>
  #include <linux/fcntl.h>
  #include <linux/stat.h>
  #include <linux/tty.h>
  #include <linux/file.h>
  #include <linux/slab.h>
  #include <linux/sysctl.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
74
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/proc_fs.h>
  #include <linux/security.h>
404015308   Al Viro   security: trim se...
75
  #include <linux/sched.h>
5b825c3af   Ingo Molnar   sched/headers: Pr...
76
  #include <linux/cred.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
78
  #include <linux/kmod.h>
  #include <linux/namei.h>
16f7e0fe2   Randy Dunlap   [PATCH] capable/c...
79
  #include <linux/capability.h>
be586bab8   Adrian Bunk   [PATCH] quota: sm...
80
  #include <linux/quotaops.h>
55fa6091d   Dave Chinner   fs: move i_sb_lis...
81
  #include "../internal.h" /* ugh */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82

f3da93105   Jeff Liu   quota: fix checkp...
83
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
  /*
7b9ca4c61   Jan Kara   quota: Reduce con...
86
87
88
89
90
91
92
93
94
95
   * There are five quota SMP locks:
   * * dq_list_lock protects all lists with quotas and quota formats.
   * * dquot->dq_dqb_lock protects data from dq_dqb
   * * inode->i_lock protects inode->i_blocks, i_bytes and also guards
   *   consistency of dquot->dq_dqb with inode->i_blocks, i_bytes so that
   *   dquot_transfer() can stabilize amount it transfers
   * * dq_data_lock protects mem_dqinfo structures and modifications of dquot
   *   pointers in the inode
   * * dq_state_lock protects modifications of quota state (on quotaon and
   *   quotaoff) and readers who care about latest values take it as well.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
96
   *
7b9ca4c61   Jan Kara   quota: Reduce con...
97
98
   * The spinlock ordering is hence:
   *   dq_data_lock > dq_list_lock > i_lock > dquot->dq_dqb_lock,
cc33412fb   Jan Kara   quota: Improve lo...
99
   *   dq_list_lock > dq_state_lock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
102
103
   *
   * Note that some things (eg. sb pointer, type, id) doesn't change during
   * the life of the dquot structure and so needn't to be protected by a lock
   *
b9ba6f94b   Niu Yawei   quota: remove dqp...
104
105
106
107
108
109
   * Operation accessing dquots via inode pointers are protected by dquot_srcu.
   * Operation of reading pointer needs srcu_read_lock(&dquot_srcu), and
   * synchronize_srcu(&dquot_srcu) is called after clearing pointers from
   * inode and before dropping dquot references to avoid use of dquots after
   * they are freed. dq_data_lock is used to serialize the pointer setting and
   * clearing operations.
26245c949   Jan Kara   quota: Cleanup S_...
110
111
   * Special care needs to be taken about S_NOQUOTA inode flag (marking that
   * inode is a quota file). Functions adding pointers from inode to dquots have
b9ba6f94b   Niu Yawei   quota: remove dqp...
112
113
   * to check this flag under dq_data_lock and then (if S_NOQUOTA is not set) they
   * have to do all pointer modifications before dropping dq_data_lock. This makes
26245c949   Jan Kara   quota: Cleanup S_...
114
115
   * sure they cannot race with quotaon which first sets S_NOQUOTA flag and
   * then drops all pointers to dquots from an inode.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
   *
5e8cb9b62   Jan Kara   quota: Protect dq...
117
118
119
120
121
   * Each dquot has its dq_lock mutex.  Dquot is locked when it is being read to
   * memory (or space for it is being allocated) on the first dqget(), when it is
   * being written out, and when it is being released on the last dqput(). The
   * allocation and release operations are serialized by the dq_lock and by
   * checking the use count in dquot_release().
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
123
   *
   * Lock ordering (including related VFS locks) is the following:
bc8230ee8   Jan Kara   quota: Convert dq...
124
   *   s_umount > i_mutex > journal_lock > dquot->dq_lock > dqio_sem
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
125
   */
c516610cf   Jan Kara   quota: Make globa...
126
127
128
  static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock);
  static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_state_lock);
  __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock);
08d0350ce   Mingming Cao   quota: Move EXPOR...
129
  EXPORT_SYMBOL(dq_data_lock);
b9ba6f94b   Niu Yawei   quota: remove dqp...
130
  DEFINE_STATIC_SRCU(dquot_srcu);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131

503330f38   Jan Kara   quota: Remove dq_...
132
  static DECLARE_WAIT_QUEUE_HEAD(dquot_ref_wq);
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
133
  void __quota_error(struct super_block *sb, const char *func,
055adcbd7   Joe Perches   quota: Use %pV an...
134
  		   const char *fmt, ...)
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
135
  {
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
136
  	if (printk_ratelimit()) {
055adcbd7   Joe Perches   quota: Use %pV an...
137
138
  		va_list args;
  		struct va_format vaf;
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
139
  		va_start(args, fmt);
055adcbd7   Joe Perches   quota: Use %pV an...
140
141
142
143
144
145
146
  
  		vaf.fmt = fmt;
  		vaf.va = &args;
  
  		printk(KERN_ERR "Quota error (device %s): %s: %pV
  ",
  		       sb->s_id, func, &vaf);
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
147
148
149
150
  		va_end(args);
  	}
  }
  EXPORT_SYMBOL(__quota_error);
da8d1ba22   Sergey Senozhatsky   suppress warning:...
151
  #if defined(CONFIG_QUOTA_DEBUG) || defined(CONFIG_PRINT_QUOTA_WARNING)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
  static char *quotatypes[] = INITQFNAMES;
da8d1ba22   Sergey Senozhatsky   suppress warning:...
153
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
156
157
  static struct quota_format_type *quota_formats;	/* List of registered formats */
  static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES;
  
  /* SLAB cache for dquot structures */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
158
  static struct kmem_cache *dquot_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
160
161
162
163
164
165
166
167
  
  int register_quota_format(struct quota_format_type *fmt)
  {
  	spin_lock(&dq_list_lock);
  	fmt->qf_next = quota_formats;
  	quota_formats = fmt;
  	spin_unlock(&dq_list_lock);
  	return 0;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
168
  EXPORT_SYMBOL(register_quota_format);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
170
171
172
173
174
  
  void unregister_quota_format(struct quota_format_type *fmt)
  {
  	struct quota_format_type **actqf;
  
  	spin_lock(&dq_list_lock);
268157ba6   Jan Kara   quota: Coding sty...
175
176
177
  	for (actqf = &quota_formats; *actqf && *actqf != fmt;
  	     actqf = &(*actqf)->qf_next)
  		;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
180
181
  	if (*actqf)
  		*actqf = (*actqf)->qf_next;
  	spin_unlock(&dq_list_lock);
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
182
  EXPORT_SYMBOL(unregister_quota_format);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
184
185
186
187
188
  
  static struct quota_format_type *find_quota_format(int id)
  {
  	struct quota_format_type *actqf;
  
  	spin_lock(&dq_list_lock);
268157ba6   Jan Kara   quota: Coding sty...
189
190
191
  	for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id;
  	     actqf = actqf->qf_next)
  		;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
195
  	if (!actqf || !try_module_get(actqf->qf_owner)) {
  		int qm;
  
  		spin_unlock(&dq_list_lock);
27942ef50   Sascha Hauer   quota: remove tra...
196

268157ba6   Jan Kara   quota: Coding sty...
197
198
199
200
201
  		for (qm = 0; module_names[qm].qm_fmt_id &&
  			     module_names[qm].qm_fmt_id != id; qm++)
  			;
  		if (!module_names[qm].qm_fmt_id ||
  		    request_module(module_names[qm].qm_mod_name))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
203
204
  			return NULL;
  
  		spin_lock(&dq_list_lock);
268157ba6   Jan Kara   quota: Coding sty...
205
206
207
  		for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id;
  		     actqf = actqf->qf_next)
  			;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
209
210
211
212
213
214
215
216
217
218
219
220
221
  		if (actqf && !try_module_get(actqf->qf_owner))
  			actqf = NULL;
  	}
  	spin_unlock(&dq_list_lock);
  	return actqf;
  }
  
  static void put_quota_format(struct quota_format_type *fmt)
  {
  	module_put(fmt->qf_owner);
  }
  
  /*
   * Dquot List Management:
f44840ad1   Chengguang Xu   quota: add dqi_di...
222
223
224
   * The quota code uses four lists for dquot management: the inuse_list,
   * free_dquots, dqi_dirty_list, and dquot_hash[] array. A single dquot
   * structure may be on some of those lists, depending on its current state.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225
226
227
228
229
230
231
232
233
234
   *
   * All dquots are placed to the end of inuse_list when first created, and this
   * list is used for invalidate operation, which must look at every dquot.
   *
   * Unused dquots (dq_count == 0) are added to the free_dquots list when freed,
   * and this list is searched whenever we need an available dquot.  Dquots are
   * removed from the list as soon as they are used again, and
   * dqstats.free_dquots gives the number of dquots on the list. When
   * dquot is invalidated it's completely released from memory.
   *
f44840ad1   Chengguang Xu   quota: add dqi_di...
235
236
237
238
239
   * Dirty dquots are added to the dqi_dirty_list of quota_info when mark
   * dirtied, and this list is searched when writing dirty dquots back to
   * quota file. Note that some filesystems do dirty dquot tracking on their
   * own (e.g. in a journal) and thus don't use dqi_dirty_list.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
240
241
242
243
244
245
246
247
248
249
250
   * Dquots with a specific identity (device, type and id) are placed on
   * one of the dquot_hash[] hash chains. The provides an efficient search
   * mechanism to locate a specific dquot.
   */
  
  static LIST_HEAD(inuse_list);
  static LIST_HEAD(free_dquots);
  static unsigned int dq_hash_bits, dq_hash_mask;
  static struct hlist_head *dquot_hash;
  
  struct dqstats dqstats;
08d0350ce   Mingming Cao   quota: Move EXPOR...
251
  EXPORT_SYMBOL(dqstats);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
252

0a5a9c725   Jan Kara   quota: Fix warnin...
253
  static qsize_t inode_get_rsv_space(struct inode *inode);
7b9ca4c61   Jan Kara   quota: Reduce con...
254
  static qsize_t __inode_get_rsv_space(struct inode *inode);
6184fc0b8   Jan Kara   quota: Propagate ...
255
  static int __dquot_initialize(struct inode *inode, int type);
0a5a9c725   Jan Kara   quota: Fix warnin...
256

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
  static inline unsigned int
1a06d420c   Eric W. Biederman   userns: Convert q...
258
  hashfn(const struct super_block *sb, struct kqid qid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
  {
1a06d420c   Eric W. Biederman   userns: Convert q...
260
261
  	unsigned int id = from_kqid(&init_user_ns, qid);
  	int type = qid.type;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
262
263
264
265
266
267
268
269
270
271
272
  	unsigned long tmp;
  
  	tmp = (((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type);
  	return (tmp + (tmp >> dq_hash_bits)) & dq_hash_mask;
  }
  
  /*
   * Following list functions expect dq_list_lock to be held
   */
  static inline void insert_dquot_hash(struct dquot *dquot)
  {
268157ba6   Jan Kara   quota: Coding sty...
273
  	struct hlist_head *head;
1a06d420c   Eric W. Biederman   userns: Convert q...
274
  	head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
278
279
280
281
  	hlist_add_head(&dquot->dq_hash, head);
  }
  
  static inline void remove_dquot_hash(struct dquot *dquot)
  {
  	hlist_del_init(&dquot->dq_hash);
  }
7a2435d87   Jan Kara   quota: Remove sup...
282
  static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb,
1a06d420c   Eric W. Biederman   userns: Convert q...
283
  				struct kqid qid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
285
286
287
288
289
  {
  	struct hlist_node *node;
  	struct dquot *dquot;
  
  	hlist_for_each (node, dquot_hash+hashent) {
  		dquot = hlist_entry(node, struct dquot, dq_hash);
4c376dcae   Eric W. Biederman   userns: Convert s...
290
  		if (dquot->dq_sb == sb && qid_eq(dquot->dq_id, qid))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291
292
  			return dquot;
  	}
dd6f3c6d5   Jan Kara   quota: Remove NOD...
293
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
295
296
297
298
  }
  
  /* Add a dquot to the tail of the free list */
  static inline void put_dquot_last(struct dquot *dquot)
  {
8e13059a3   Akinobu Mita   [PATCH] use list_...
299
  	list_add_tail(&dquot->dq_free, &free_dquots);
dde958885   Dmitry Monakhov   quota: Make quota...
300
  	dqstats_inc(DQST_FREE_DQUOTS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
302
303
304
305
306
307
  }
  
  static inline void remove_free_dquot(struct dquot *dquot)
  {
  	if (list_empty(&dquot->dq_free))
  		return;
  	list_del_init(&dquot->dq_free);
dde958885   Dmitry Monakhov   quota: Make quota...
308
  	dqstats_dec(DQST_FREE_DQUOTS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
311
312
313
314
  }
  
  static inline void put_inuse(struct dquot *dquot)
  {
  	/* We add to the back of inuse list so we don't have to restart
  	 * when traversing this list and we block */
8e13059a3   Akinobu Mita   [PATCH] use list_...
315
  	list_add_tail(&dquot->dq_inuse, &inuse_list);
dde958885   Dmitry Monakhov   quota: Make quota...
316
  	dqstats_inc(DQST_ALLOC_DQUOTS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
318
319
320
  }
  
  static inline void remove_inuse(struct dquot *dquot)
  {
dde958885   Dmitry Monakhov   quota: Make quota...
321
  	dqstats_dec(DQST_ALLOC_DQUOTS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
323
324
325
326
327
328
329
  	list_del(&dquot->dq_inuse);
  }
  /*
   * End of list functions needing dq_list_lock
   */
  
  static void wait_on_dquot(struct dquot *dquot)
  {
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
330
331
  	mutex_lock(&dquot->dq_lock);
  	mutex_unlock(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
332
  }
03f6e92bd   Jan Kara   quota: various st...
333
334
335
336
337
338
339
340
341
  static inline int dquot_dirty(struct dquot *dquot)
  {
  	return test_bit(DQ_MOD_B, &dquot->dq_flags);
  }
  
  static inline int mark_dquot_dirty(struct dquot *dquot)
  {
  	return dquot->dq_sb->dq_op->mark_dirty(dquot);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342

eabf290d1   Dmitry Monakhov   quota: optimize m...
343
  /* Mark dquot dirty in atomic manner, and return it's old dirty flag state */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
345
  int dquot_mark_dquot_dirty(struct dquot *dquot)
  {
eabf290d1   Dmitry Monakhov   quota: optimize m...
346
  	int ret = 1;
4580b30ea   Jan Kara   quota: Do not dir...
347
348
  	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
  		return 0;
834057bf8   Jan Kara   quota: Allow disa...
349
350
  	if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NOLIST_DIRTY)
  		return test_and_set_bit(DQ_MOD_B, &dquot->dq_flags);
eabf290d1   Dmitry Monakhov   quota: optimize m...
351
352
353
  	/* If quota is dirty already, we don't have to acquire dq_list_lock */
  	if (test_bit(DQ_MOD_B, &dquot->dq_flags))
  		return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
  	spin_lock(&dq_list_lock);
eabf290d1   Dmitry Monakhov   quota: optimize m...
355
  	if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
356
  		list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)->
4c376dcae   Eric W. Biederman   userns: Convert s...
357
  				info[dquot->dq_id.type].dqi_dirty_list);
eabf290d1   Dmitry Monakhov   quota: optimize m...
358
359
  		ret = 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
  	spin_unlock(&dq_list_lock);
eabf290d1   Dmitry Monakhov   quota: optimize m...
361
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
363
  EXPORT_SYMBOL(dquot_mark_dquot_dirty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364

dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
  /* Dirtify all the dquots - this can block when journalling */
  static inline int mark_all_dquot_dirty(struct dquot * const *dquot)
  {
  	int ret, err, cnt;
  
  	ret = err = 0;
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		if (dquot[cnt])
  			/* Even in case of error we have to continue */
  			ret = mark_dquot_dirty(dquot[cnt]);
  		if (!err)
  			err = ret;
  	}
  	return err;
  }
  
  static inline void dqput_all(struct dquot **dquot)
  {
  	unsigned int cnt;
  
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
  		dqput(dquot[cnt]);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
389
  static inline int clear_dquot_dirty(struct dquot *dquot)
  {
834057bf8   Jan Kara   quota: Allow disa...
390
391
  	if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NOLIST_DIRTY)
  		return test_and_clear_bit(DQ_MOD_B, &dquot->dq_flags);
1e0b7cb06   Jan Kara   quota: Move locki...
392
393
394
  	spin_lock(&dq_list_lock);
  	if (!test_and_clear_bit(DQ_MOD_B, &dquot->dq_flags)) {
  		spin_unlock(&dq_list_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
  		return 0;
1e0b7cb06   Jan Kara   quota: Move locki...
396
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
  	list_del_init(&dquot->dq_dirty);
1e0b7cb06   Jan Kara   quota: Move locki...
398
  	spin_unlock(&dq_list_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
399
400
401
402
403
  	return 1;
  }
  
  void mark_info_dirty(struct super_block *sb, int type)
  {
15512377b   Jan Kara   quota: Fix possib...
404
405
406
  	spin_lock(&dq_data_lock);
  	sb_dqopt(sb)->info[type].dqi_flags |= DQF_INFO_DIRTY;
  	spin_unlock(&dq_data_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407
408
409
410
411
412
413
414
415
416
417
  }
  EXPORT_SYMBOL(mark_info_dirty);
  
  /*
   *	Read dquot from disk and alloc space for it
   */
  
  int dquot_acquire(struct dquot *dquot)
  {
  	int ret = 0, ret2 = 0;
  	struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
418
  	mutex_lock(&dquot->dq_lock);
3ef177ec9   Chengguang Xu   quota: fix wrong ...
419
  	if (!test_bit(DQ_READ_B, &dquot->dq_flags)) {
4c376dcae   Eric W. Biederman   userns: Convert s...
420
  		ret = dqopt->ops[dquot->dq_id.type]->read_dqblk(dquot);
3ef177ec9   Chengguang Xu   quota: fix wrong ...
421
422
423
  		if (ret < 0)
  			goto out_iolock;
  	}
044c9b675   Jan Kara   quota: Fix possib...
424
425
  	/* Make sure flags update is visible after dquot has been filled */
  	smp_mb__before_atomic();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
427
428
  	set_bit(DQ_READ_B, &dquot->dq_flags);
  	/* Instantiate dquot if needed */
  	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
4c376dcae   Eric W. Biederman   userns: Convert s...
429
  		ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
430
  		/* Write the info if needed */
4c376dcae   Eric W. Biederman   userns: Convert s...
431
432
433
  		if (info_dirty(&dqopt->info[dquot->dq_id.type])) {
  			ret2 = dqopt->ops[dquot->dq_id.type]->write_file_info(
  					dquot->dq_sb, dquot->dq_id.type);
268157ba6   Jan Kara   quota: Coding sty...
434
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
436
437
438
439
440
441
  		if (ret < 0)
  			goto out_iolock;
  		if (ret2 < 0) {
  			ret = ret2;
  			goto out_iolock;
  		}
  	}
044c9b675   Jan Kara   quota: Fix possib...
442
443
444
445
446
  	/*
  	 * Make sure flags update is visible after on-disk struct has been
  	 * allocated. Paired with smp_rmb() in dqget().
  	 */
  	smp_mb__before_atomic();
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
448
  	set_bit(DQ_ACTIVE_B, &dquot->dq_flags);
  out_iolock:
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
449
  	mutex_unlock(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
451
  	return ret;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
452
  EXPORT_SYMBOL(dquot_acquire);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
453
454
455
456
457
458
  
  /*
   *	Write dquot to disk
   */
  int dquot_commit(struct dquot *dquot)
  {
b03f24567   Jan Kara   quota: Don't writ...
459
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
460
  	struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
5e8cb9b62   Jan Kara   quota: Protect dq...
461
  	mutex_lock(&dquot->dq_lock);
1e0b7cb06   Jan Kara   quota: Move locki...
462
  	if (!clear_dquot_dirty(dquot))
5e8cb9b62   Jan Kara   quota: Protect dq...
463
  		goto out_lock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
465
  	/* Inactive dquot can be only if there was error during read/init
  	 * => we have better not writing it */
b03f24567   Jan Kara   quota: Don't writ...
466
  	if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
4c376dcae   Eric W. Biederman   userns: Convert s...
467
  		ret = dqopt->ops[dquot->dq_id.type]->commit_dqblk(dquot);
b03f24567   Jan Kara   quota: Don't writ...
468
469
  	else
  		ret = -EIO;
5e8cb9b62   Jan Kara   quota: Protect dq...
470
471
  out_lock:
  	mutex_unlock(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
473
  	return ret;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
474
  EXPORT_SYMBOL(dquot_commit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
476
477
478
479
480
481
482
  
  /*
   *	Release dquot
   */
  int dquot_release(struct dquot *dquot)
  {
  	int ret = 0, ret2 = 0;
  	struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
483
  	mutex_lock(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  	/* Check whether we are not racing with some other dqget() */
df4bb5d12   Dmitry Monakhov   quota: Check that...
485
  	if (dquot_is_busy(dquot))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
486
  		goto out_dqlock;
4c376dcae   Eric W. Biederman   userns: Convert s...
487
488
  	if (dqopt->ops[dquot->dq_id.type]->release_dqblk) {
  		ret = dqopt->ops[dquot->dq_id.type]->release_dqblk(dquot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
  		/* Write the info */
4c376dcae   Eric W. Biederman   userns: Convert s...
490
491
492
  		if (info_dirty(&dqopt->info[dquot->dq_id.type])) {
  			ret2 = dqopt->ops[dquot->dq_id.type]->write_file_info(
  						dquot->dq_sb, dquot->dq_id.type);
268157ba6   Jan Kara   quota: Coding sty...
493
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
494
495
496
497
  		if (ret >= 0)
  			ret = ret2;
  	}
  	clear_bit(DQ_ACTIVE_B, &dquot->dq_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
498
  out_dqlock:
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
499
  	mutex_unlock(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
500
501
  	return ret;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
502
  EXPORT_SYMBOL(dquot_release);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
503

7d9056ba2   Jan Kara   quota: Export dqu...
504
  void dquot_destroy(struct dquot *dquot)
74f783af9   Jan Kara   quota: Add callba...
505
506
507
  {
  	kmem_cache_free(dquot_cachep, dquot);
  }
7d9056ba2   Jan Kara   quota: Export dqu...
508
  EXPORT_SYMBOL(dquot_destroy);
74f783af9   Jan Kara   quota: Add callba...
509
510
511
512
513
  
  static inline void do_destroy_dquot(struct dquot *dquot)
  {
  	dquot->dq_sb->dq_op->destroy_dquot(dquot);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
514
515
  /* Invalidate all dquots on the list. Note that this function is called after
   * quota is disabled and pointers from inodes removed so there cannot be new
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
516
517
   * quota users. There can still be some users of quotas due to inodes being
   * just deleted or pruned by prune_icache() (those are not attached to any
cc33412fb   Jan Kara   quota: Improve lo...
518
   * list) or parallel quotactl call. We have to wait for such users.
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
519
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
520
521
  static void invalidate_dquots(struct super_block *sb, int type)
  {
c33ed2712   Domen Puncer   [PATCH] list_for_...
522
  	struct dquot *dquot, *tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
523

6362e4d4e   Jan Kara   [PATCH] Fix oops ...
524
  restart:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
525
  	spin_lock(&dq_list_lock);
c33ed2712   Domen Puncer   [PATCH] list_for_...
526
  	list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527
528
  		if (dquot->dq_sb != sb)
  			continue;
4c376dcae   Eric W. Biederman   userns: Convert s...
529
  		if (dquot->dq_id.type != type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
530
  			continue;
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
531
532
  		/* Wait for dquot users */
  		if (atomic_read(&dquot->dq_count)) {
9f985cb6c   Jan Kara   quota: provide fu...
533
  			dqgrab(dquot);
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
534
  			spin_unlock(&dq_list_lock);
503330f38   Jan Kara   quota: Remove dq_...
535
536
  			/*
  			 * Once dqput() wakes us up, we know it's time to free
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
537
538
539
540
541
542
  			 * the dquot.
  			 * IMPORTANT: we rely on the fact that there is always
  			 * at most one process waiting for dquot to free.
  			 * Otherwise dq_count would be > 1 and we would never
  			 * wake up.
  			 */
503330f38   Jan Kara   quota: Remove dq_...
543
544
  			wait_event(dquot_ref_wq,
  				   atomic_read(&dquot->dq_count) == 1);
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
545
546
547
548
549
550
551
552
553
554
  			dqput(dquot);
  			/* At this moment dquot() need not exist (it could be
  			 * reclaimed by prune_dqcache(). Hence we must
  			 * restart. */
  			goto restart;
  		}
  		/*
  		 * Quota now has no users and it has been written on last
  		 * dqput()
  		 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555
556
557
  		remove_dquot_hash(dquot);
  		remove_free_dquot(dquot);
  		remove_inuse(dquot);
74f783af9   Jan Kara   quota: Add callba...
558
  		do_destroy_dquot(dquot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
559
560
561
  	}
  	spin_unlock(&dq_list_lock);
  }
12c77527e   Jan Kara   quota: Implement ...
562
563
564
565
566
567
568
  /* Call callback for every active dquot on given filesystem */
  int dquot_scan_active(struct super_block *sb,
  		      int (*fn)(struct dquot *dquot, unsigned long priv),
  		      unsigned long priv)
  {
  	struct dquot *dquot, *old_dquot = NULL;
  	int ret = 0;
ee1ac541a   Jan Kara   quota: Remove dqo...
569
  	WARN_ON_ONCE(!rwsem_is_locked(&sb->s_umount));
12c77527e   Jan Kara   quota: Implement ...
570
571
572
573
574
575
576
577
  	spin_lock(&dq_list_lock);
  	list_for_each_entry(dquot, &inuse_list, dq_inuse) {
  		if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
  			continue;
  		if (dquot->dq_sb != sb)
  			continue;
  		/* Now we have active dquot so we can just increase use count */
  		atomic_inc(&dquot->dq_count);
12c77527e   Jan Kara   quota: Implement ...
578
579
580
  		spin_unlock(&dq_list_lock);
  		dqput(old_dquot);
  		old_dquot = dquot;
1362f4ea2   Jan Kara   quota: Fix race b...
581
582
583
584
585
586
587
588
589
590
591
  		/*
  		 * ->release_dquot() can be racing with us. Our reference
  		 * protects us from new calls to it so just wait for any
  		 * outstanding call and recheck the DQ_ACTIVE_B after that.
  		 */
  		wait_on_dquot(dquot);
  		if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
  			ret = fn(dquot, priv);
  			if (ret < 0)
  				goto out;
  		}
12c77527e   Jan Kara   quota: Implement ...
592
593
594
595
596
597
598
  		spin_lock(&dq_list_lock);
  		/* We are safe to continue now because our dquot could not
  		 * be moved out of the inuse list while we hold the reference */
  	}
  	spin_unlock(&dq_list_lock);
  out:
  	dqput(old_dquot);
12c77527e   Jan Kara   quota: Implement ...
599
600
  	return ret;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
601
  EXPORT_SYMBOL(dquot_scan_active);
12c77527e   Jan Kara   quota: Implement ...
602

ceed17236   Jan Kara   quota: Split dquo...
603
604
  /* Write all dquot structures to quota files */
  int dquot_writeback_dquots(struct super_block *sb, int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
605
  {
6ff33d99f   Dmitry Monakhov   quota: fix livelo...
606
  	struct list_head dirty;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
608
609
  	struct dquot *dquot;
  	struct quota_info *dqopt = sb_dqopt(sb);
  	int cnt;
ceed17236   Jan Kara   quota: Split dquo...
610
  	int err, ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
611

9d1ccbe70   Jan Kara   quota: Use s_umou...
612
  	WARN_ON_ONCE(!rwsem_is_locked(&sb->s_umount));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613
614
615
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		if (type != -1 && cnt != type)
  			continue;
f55abc0fb   Jan Kara   quota: Allow to s...
616
  		if (!sb_has_quota_active(sb, cnt))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
617
618
  			continue;
  		spin_lock(&dq_list_lock);
6ff33d99f   Dmitry Monakhov   quota: fix livelo...
619
620
621
622
  		/* Move list away to avoid livelock. */
  		list_replace_init(&dqopt->info[cnt].dqi_dirty_list, &dirty);
  		while (!list_empty(&dirty)) {
  			dquot = list_first_entry(&dirty, struct dquot,
268157ba6   Jan Kara   quota: Coding sty...
623
  						 dq_dirty);
4580b30ea   Jan Kara   quota: Do not dir...
624
625
  
  			WARN_ON(!test_bit(DQ_ACTIVE_B, &dquot->dq_flags));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
626
627
628
  			/* Now we have active dquot from which someone is
   			 * holding reference so we can safely just increase
  			 * use count */
9f985cb6c   Jan Kara   quota: provide fu...
629
  			dqgrab(dquot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
630
  			spin_unlock(&dq_list_lock);
ceed17236   Jan Kara   quota: Split dquo...
631
  			err = sb->dq_op->write_dquot(dquot);
dd5f62797   zhangyi (F)   quota: fix potent...
632
633
634
635
636
637
638
639
640
  			if (err) {
  				/*
  				 * Clear dirty bit anyway to avoid infinite
  				 * loop here.
  				 */
  				clear_dquot_dirty(dquot);
  				if (!ret)
  					ret = err;
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641
642
643
644
645
646
647
  			dqput(dquot);
  			spin_lock(&dq_list_lock);
  		}
  		spin_unlock(&dq_list_lock);
  	}
  
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
f55abc0fb   Jan Kara   quota: Allow to s...
648
649
  		if ((cnt == type || type == -1) && sb_has_quota_active(sb, cnt)
  		    && info_dirty(&dqopt->info[cnt]))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650
  			sb->dq_op->write_info(sb, cnt);
dde958885   Dmitry Monakhov   quota: Make quota...
651
  	dqstats_inc(DQST_SYNCS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652

ceed17236   Jan Kara   quota: Split dquo...
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
  	return ret;
  }
  EXPORT_SYMBOL(dquot_writeback_dquots);
  
  /* Write all dquot structures to disk and make them visible from userspace */
  int dquot_quota_sync(struct super_block *sb, int type)
  {
  	struct quota_info *dqopt = sb_dqopt(sb);
  	int cnt;
  	int ret;
  
  	ret = dquot_writeback_dquots(sb, type);
  	if (ret)
  		return ret;
  	if (dqopt->flags & DQUOT_QUOTA_SYS_FILE)
5fb324ad2   Christoph Hellwig   quota: move code ...
668
669
670
671
672
673
674
675
676
677
678
679
680
  		return 0;
  
  	/* This is not very clever (and fast) but currently I don't know about
  	 * any other simple way of getting quota data to disk and we must get
  	 * them there for userspace to be visible... */
  	if (sb->s_op->sync_fs)
  		sb->s_op->sync_fs(sb, 1);
  	sync_blockdev(sb->s_bdev);
  
  	/*
  	 * Now when everything is written we can discard the pagecache so
  	 * that userspace sees the changes.
  	 */
5fb324ad2   Christoph Hellwig   quota: move code ...
681
682
683
684
685
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		if (type != -1 && cnt != type)
  			continue;
  		if (!sb_has_quota_active(sb, cnt))
  			continue;
5955102c9   Al Viro   wrappers for ->i_...
686
  		inode_lock(dqopt->files[cnt]);
f9ef17841   Jan Kara   quota: Use precom...
687
  		truncate_inode_pages(&dqopt->files[cnt]->i_data, 0);
5955102c9   Al Viro   wrappers for ->i_...
688
  		inode_unlock(dqopt->files[cnt]);
5fb324ad2   Christoph Hellwig   quota: move code ...
689
  	}
5fb324ad2   Christoph Hellwig   quota: move code ...
690

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691
692
  	return 0;
  }
287a80958   Christoph Hellwig   quota: rename def...
693
  EXPORT_SYMBOL(dquot_quota_sync);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
694

1ab6c4997   Dave Chinner   fs: convert fs sh...
695
696
  static unsigned long
  dqcache_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
697
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
698
  	struct dquot *dquot;
1ab6c4997   Dave Chinner   fs: convert fs sh...
699
  	unsigned long freed = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
700

d68aab6b8   Niu Yawei   quota: missing lo...
701
  	spin_lock(&dq_list_lock);
1822193b5   Jan Kara   quota: Cleanup li...
702
703
  	while (!list_empty(&free_dquots) && sc->nr_to_scan) {
  		dquot = list_first_entry(&free_dquots, struct dquot, dq_free);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
704
705
706
  		remove_dquot_hash(dquot);
  		remove_free_dquot(dquot);
  		remove_inuse(dquot);
74f783af9   Jan Kara   quota: Add callba...
707
  		do_destroy_dquot(dquot);
1ab6c4997   Dave Chinner   fs: convert fs sh...
708
709
  		sc->nr_to_scan--;
  		freed++;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710
  	}
d68aab6b8   Niu Yawei   quota: missing lo...
711
  	spin_unlock(&dq_list_lock);
1ab6c4997   Dave Chinner   fs: convert fs sh...
712
  	return freed;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
713
  }
1ab6c4997   Dave Chinner   fs: convert fs sh...
714
715
  static unsigned long
  dqcache_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
716
  {
55f841ce9   Glauber Costa   super: fix calcul...
717
718
  	return vfs_pressure_ratio(
  	percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS]));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
719
  }
8e1f936b7   Rusty Russell   mm: clean up and ...
720
  static struct shrinker dqcache_shrinker = {
1ab6c4997   Dave Chinner   fs: convert fs sh...
721
722
  	.count_objects = dqcache_shrink_count,
  	.scan_objects = dqcache_shrink_scan,
8e1f936b7   Rusty Russell   mm: clean up and ...
723
724
  	.seeks = DEFAULT_SEEKS,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
725
726
  /*
   * Put reference to dquot
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727
   */
3d9ea253a   Jan Kara   quota: Add helper...
728
  void dqput(struct dquot *dquot)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
729
  {
b48d38054   Jan Kara   quota: fix possib...
730
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
731
732
  	if (!dquot)
  		return;
62af9b520   Jan Kara   quota: Convert __...
733
  #ifdef CONFIG_QUOTA_DEBUG
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
734
  	if (!atomic_read(&dquot->dq_count)) {
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
735
  		quota_error(dquot->dq_sb, "trying to free free dquot of %s %d",
4c376dcae   Eric W. Biederman   userns: Convert s...
736
737
  			    quotatypes[dquot->dq_id.type],
  			    from_kqid(&init_user_ns, dquot->dq_id));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
738
739
740
  		BUG();
  	}
  #endif
dde958885   Dmitry Monakhov   quota: Make quota...
741
  	dqstats_inc(DQST_DROPS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
742
743
744
745
746
  we_slept:
  	spin_lock(&dq_list_lock);
  	if (atomic_read(&dquot->dq_count) > 1) {
  		/* We have more than one user... nothing to do */
  		atomic_dec(&dquot->dq_count);
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
747
  		/* Releasing dquot during quotaoff phase? */
4c376dcae   Eric W. Biederman   userns: Convert s...
748
  		if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_id.type) &&
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
749
  		    atomic_read(&dquot->dq_count) == 1)
503330f38   Jan Kara   quota: Remove dq_...
750
  			wake_up(&dquot_ref_wq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
751
752
753
754
  		spin_unlock(&dq_list_lock);
  		return;
  	}
  	/* Need to release dquot? */
4580b30ea   Jan Kara   quota: Do not dir...
755
  	if (dquot_dirty(dquot)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
756
757
  		spin_unlock(&dq_list_lock);
  		/* Commit dquot before releasing */
b48d38054   Jan Kara   quota: fix possib...
758
759
  		ret = dquot->dq_sb->dq_op->write_dquot(dquot);
  		if (ret < 0) {
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
760
761
762
  			quota_error(dquot->dq_sb, "Can't write quota structure"
  				    " (error %d). Quota may get out of sync!",
  				    ret);
b48d38054   Jan Kara   quota: fix possib...
763
764
765
766
  			/*
  			 * We clear dirty bit anyway, so that we avoid
  			 * infinite loop here
  			 */
b48d38054   Jan Kara   quota: fix possib...
767
  			clear_dquot_dirty(dquot);
b48d38054   Jan Kara   quota: fix possib...
768
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
769
770
  		goto we_slept;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
771
772
773
774
775
776
  	if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
  		spin_unlock(&dq_list_lock);
  		dquot->dq_sb->dq_op->release_dquot(dquot);
  		goto we_slept;
  	}
  	atomic_dec(&dquot->dq_count);
62af9b520   Jan Kara   quota: Convert __...
777
  #ifdef CONFIG_QUOTA_DEBUG
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
778
  	/* sanity check */
8abf6a470   Eric Sesterhenn   BUG_ON() Conversi...
779
  	BUG_ON(!list_empty(&dquot->dq_free));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
780
781
782
783
  #endif
  	put_dquot_last(dquot);
  	spin_unlock(&dq_list_lock);
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
784
  EXPORT_SYMBOL(dqput);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
785

7d9056ba2   Jan Kara   quota: Export dqu...
786
  struct dquot *dquot_alloc(struct super_block *sb, int type)
74f783af9   Jan Kara   quota: Add callba...
787
788
789
  {
  	return kmem_cache_zalloc(dquot_cachep, GFP_NOFS);
  }
7d9056ba2   Jan Kara   quota: Export dqu...
790
  EXPORT_SYMBOL(dquot_alloc);
74f783af9   Jan Kara   quota: Add callba...
791

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
792
793
794
  static struct dquot *get_empty_dquot(struct super_block *sb, int type)
  {
  	struct dquot *dquot;
74f783af9   Jan Kara   quota: Add callba...
795
  	dquot = sb->dq_op->alloc_dquot(sb, type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
  	if(!dquot)
dd6f3c6d5   Jan Kara   quota: Remove NOD...
797
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798

d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
799
  	mutex_init(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
800
801
802
803
804
  	INIT_LIST_HEAD(&dquot->dq_free);
  	INIT_LIST_HEAD(&dquot->dq_inuse);
  	INIT_HLIST_NODE(&dquot->dq_hash);
  	INIT_LIST_HEAD(&dquot->dq_dirty);
  	dquot->dq_sb = sb;
1a06d420c   Eric W. Biederman   userns: Convert q...
805
  	dquot->dq_id = make_kqid_invalid(type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
806
  	atomic_set(&dquot->dq_count, 1);
7b9ca4c61   Jan Kara   quota: Reduce con...
807
  	spin_lock_init(&dquot->dq_dqb_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
808
809
810
811
812
813
  
  	return dquot;
  }
  
  /*
   * Get reference to dquot
cc33412fb   Jan Kara   quota: Improve lo...
814
815
816
817
818
   *
   * Locking is slightly tricky here. We are guarded from parallel quotaoff()
   * destroying our dquot by:
   *   a) checking for quota flags under dq_list_lock and
   *   b) getting a reference to dquot before we release dq_list_lock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
819
   */
aca645a6a   Eric W. Biederman   userns: Modify dq...
820
  struct dquot *dqget(struct super_block *sb, struct kqid qid)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
821
  {
1a06d420c   Eric W. Biederman   userns: Convert q...
822
  	unsigned int hashent = hashfn(sb, qid);
6184fc0b8   Jan Kara   quota: Propagate ...
823
  	struct dquot *dquot, *empty = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
824

d49d37624   Eric W. Biederman   quota: Ensure qid...
825
826
  	if (!qid_has_mapping(sb->s_user_ns, qid))
  		return ERR_PTR(-EINVAL);
1a06d420c   Eric W. Biederman   userns: Convert q...
827
          if (!sb_has_quota_active(sb, qid.type))
6184fc0b8   Jan Kara   quota: Propagate ...
828
  		return ERR_PTR(-ESRCH);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
829
830
  we_slept:
  	spin_lock(&dq_list_lock);
cc33412fb   Jan Kara   quota: Improve lo...
831
  	spin_lock(&dq_state_lock);
1a06d420c   Eric W. Biederman   userns: Convert q...
832
  	if (!sb_has_quota_active(sb, qid.type)) {
cc33412fb   Jan Kara   quota: Improve lo...
833
834
  		spin_unlock(&dq_state_lock);
  		spin_unlock(&dq_list_lock);
6184fc0b8   Jan Kara   quota: Propagate ...
835
  		dquot = ERR_PTR(-ESRCH);
cc33412fb   Jan Kara   quota: Improve lo...
836
837
838
  		goto out;
  	}
  	spin_unlock(&dq_state_lock);
1a06d420c   Eric W. Biederman   userns: Convert q...
839
  	dquot = find_dquot(hashent, sb, qid);
dd6f3c6d5   Jan Kara   quota: Remove NOD...
840
841
  	if (!dquot) {
  		if (!empty) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
842
  			spin_unlock(&dq_list_lock);
1a06d420c   Eric W. Biederman   userns: Convert q...
843
  			empty = get_empty_dquot(sb, qid.type);
dd6f3c6d5   Jan Kara   quota: Remove NOD...
844
  			if (!empty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
846
847
848
  				schedule();	/* Try to wait for a moment... */
  			goto we_slept;
  		}
  		dquot = empty;
dd6f3c6d5   Jan Kara   quota: Remove NOD...
849
  		empty = NULL;
4c376dcae   Eric W. Biederman   userns: Convert s...
850
  		dquot->dq_id = qid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851
852
853
854
  		/* all dquots go on the inuse_list */
  		put_inuse(dquot);
  		/* hash it first so it can be found */
  		insert_dquot_hash(dquot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
855
  		spin_unlock(&dq_list_lock);
dde958885   Dmitry Monakhov   quota: Make quota...
856
  		dqstats_inc(DQST_LOOKUPS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
857
858
859
860
  	} else {
  		if (!atomic_read(&dquot->dq_count))
  			remove_free_dquot(dquot);
  		atomic_inc(&dquot->dq_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
861
  		spin_unlock(&dq_list_lock);
dde958885   Dmitry Monakhov   quota: Make quota...
862
863
  		dqstats_inc(DQST_CACHE_HITS);
  		dqstats_inc(DQST_LOOKUPS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
864
  	}
268157ba6   Jan Kara   quota: Coding sty...
865
866
  	/* Wait for dq_lock - after this we know that either dquot_release() is
  	 * already finished or it will be canceled due to dq_count > 1 test */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
867
  	wait_on_dquot(dquot);
268157ba6   Jan Kara   quota: Coding sty...
868
  	/* Read the dquot / allocate space in quota file */
6184fc0b8   Jan Kara   quota: Propagate ...
869
870
871
872
873
874
875
876
877
  	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
  		int err;
  
  		err = sb->dq_op->acquire_dquot(dquot);
  		if (err < 0) {
  			dqput(dquot);
  			dquot = ERR_PTR(err);
  			goto out;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
878
  	}
044c9b675   Jan Kara   quota: Fix possib...
879
880
881
882
883
  	/*
  	 * Make sure following reads see filled structure - paired with
  	 * smp_mb__before_atomic() in dquot_acquire().
  	 */
  	smp_rmb();
62af9b520   Jan Kara   quota: Convert __...
884
  #ifdef CONFIG_QUOTA_DEBUG
8abf6a470   Eric Sesterhenn   BUG_ON() Conversi...
885
  	BUG_ON(!dquot->dq_sb);	/* Has somebody invalidated entry under us? */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
886
  #endif
cc33412fb   Jan Kara   quota: Improve lo...
887
888
889
  out:
  	if (empty)
  		do_destroy_dquot(empty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
890
891
892
  
  	return dquot;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
893
  EXPORT_SYMBOL(dqget);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
894

2d0fa4679   Jan Kara   quota: Use functi...
895
896
  static inline struct dquot **i_dquot(struct inode *inode)
  {
2d0fa4679   Jan Kara   quota: Use functi...
897
898
  	return inode->i_sb->s_op->get_dquots(inode);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
899
900
  static int dqinit_needed(struct inode *inode, int type)
  {
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
901
  	struct dquot * const *dquots;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
903
904
905
  	int cnt;
  
  	if (IS_NOQUOTA(inode))
  		return 0;
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
906
907
  
  	dquots = i_dquot(inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
908
  	if (type != -1)
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
909
  		return !dquots[type];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
910
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
911
  		if (!dquots[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
912
913
914
  			return 1;
  	return 0;
  }
c3b004460   Jan Kara   quota: Remove dqo...
915
  /* This routine is guarded by s_umount semaphore */
1a6152d36   Chao Yu   quota: propagate ...
916
  static int add_dquot_ref(struct super_block *sb, int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
917
  {
941d2380e   Jan Kara   quota: improve in...
918
  	struct inode *inode, *old_inode = NULL;
62af9b520   Jan Kara   quota: Convert __...
919
  #ifdef CONFIG_QUOTA_DEBUG
0a5a9c725   Jan Kara   quota: Fix warnin...
920
  	int reserved = 0;
4c5e6c0e7   Jan Kara   quota: Hide warni...
921
  #endif
1a6152d36   Chao Yu   quota: propagate ...
922
  	int err = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
923

74278da9f   Dave Chinner   inode: convert in...
924
  	spin_lock(&sb->s_inode_list_lock);
d003fb70f   Christoph Hellwig   [PATCH] remove sb...
925
  	list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
250df6ed2   Dave Chinner   fs: protect inode...
926
927
928
929
930
  		spin_lock(&inode->i_lock);
  		if ((inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW)) ||
  		    !atomic_read(&inode->i_writecount) ||
  		    !dqinit_needed(inode, type)) {
  			spin_unlock(&inode->i_lock);
aabb8fdb4   Nick Piggin   fs: avoid I_NEW i...
931
  			continue;
250df6ed2   Dave Chinner   fs: protect inode...
932
  		}
d003fb70f   Christoph Hellwig   [PATCH] remove sb...
933
  		__iget(inode);
250df6ed2   Dave Chinner   fs: protect inode...
934
  		spin_unlock(&inode->i_lock);
74278da9f   Dave Chinner   inode: convert in...
935
  		spin_unlock(&sb->s_inode_list_lock);
d003fb70f   Christoph Hellwig   [PATCH] remove sb...
936

d7e971176   Jan Kara   quota: Fix double...
937
938
939
940
  #ifdef CONFIG_QUOTA_DEBUG
  		if (unlikely(inode_get_rsv_space(inode) > 0))
  			reserved = 1;
  #endif
941d2380e   Jan Kara   quota: improve in...
941
  		iput(old_inode);
1a6152d36   Chao Yu   quota: propagate ...
942
943
944
945
946
  		err = __dquot_initialize(inode, type);
  		if (err) {
  			iput(inode);
  			goto out;
  		}
55fa6091d   Dave Chinner   fs: move i_sb_lis...
947
948
949
950
  
  		/*
  		 * We hold a reference to 'inode' so it couldn't have been
  		 * removed from s_inodes list while we dropped the
74278da9f   Dave Chinner   inode: convert in...
951
  		 * s_inode_list_lock. We cannot iput the inode now as we can be
55fa6091d   Dave Chinner   fs: move i_sb_lis...
952
  		 * holding the last reference and we cannot iput it under
74278da9f   Dave Chinner   inode: convert in...
953
  		 * s_inode_list_lock. So we keep the reference and iput it
55fa6091d   Dave Chinner   fs: move i_sb_lis...
954
955
  		 * later.
  		 */
941d2380e   Jan Kara   quota: improve in...
956
  		old_inode = inode;
04646aebd   Eric Sandeen   fs: avoid softloc...
957
  		cond_resched();
74278da9f   Dave Chinner   inode: convert in...
958
  		spin_lock(&sb->s_inode_list_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
959
  	}
74278da9f   Dave Chinner   inode: convert in...
960
  	spin_unlock(&sb->s_inode_list_lock);
941d2380e   Jan Kara   quota: improve in...
961
  	iput(old_inode);
1a6152d36   Chao Yu   quota: propagate ...
962
  out:
62af9b520   Jan Kara   quota: Convert __...
963
  #ifdef CONFIG_QUOTA_DEBUG
0a5a9c725   Jan Kara   quota: Fix warnin...
964
  	if (reserved) {
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
965
966
967
  		quota_error(sb, "Writes happened before quota was turned on "
  			"thus quota information is probably inconsistent. "
  			"Please run quotacheck(8)");
0a5a9c725   Jan Kara   quota: Fix warnin...
968
  	}
4c5e6c0e7   Jan Kara   quota: Hide warni...
969
  #endif
1a6152d36   Chao Yu   quota: propagate ...
970
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
971
  }
268157ba6   Jan Kara   quota: Coding sty...
972
  /*
268157ba6   Jan Kara   quota: Coding sty...
973
   * Remove references to dquots from inode and add dquot to list for freeing
25985edce   Lucas De Marchi   Fix common misspe...
974
   * if we have the last reference to dquot
268157ba6   Jan Kara   quota: Coding sty...
975
   */
9eb6463f3   Niu Yawei   quota: simplify r...
976
977
  static void remove_inode_dquot_ref(struct inode *inode, int type,
  				   struct list_head *tofree_head)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
978
  {
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
979
980
  	struct dquot **dquots = i_dquot(inode);
  	struct dquot *dquot = dquots[type];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
981

9eb6463f3   Niu Yawei   quota: simplify r...
982
983
  	if (!dquot)
  		return;
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
984
  	dquots[type] = NULL;
9eb6463f3   Niu Yawei   quota: simplify r...
985
986
987
988
989
990
991
992
993
994
995
996
997
998
  	if (list_empty(&dquot->dq_free)) {
  		/*
  		 * The inode still has reference to dquot so it can't be in the
  		 * free list
  		 */
  		spin_lock(&dq_list_lock);
  		list_add(&dquot->dq_free, tofree_head);
  		spin_unlock(&dq_list_lock);
  	} else {
  		/*
  		 * Dquot is already in a list to put so we won't drop the last
  		 * reference here.
  		 */
  		dqput(dquot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
999
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1000
  }
268157ba6   Jan Kara   quota: Coding sty...
1001
1002
1003
1004
1005
  /*
   * Free list of dquots
   * Dquots are removed from inodes and no new references can be got so we are
   * the only ones holding reference
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1006
1007
1008
1009
1010
1011
  static void put_dquot_list(struct list_head *tofree_head)
  {
  	struct list_head *act_head;
  	struct dquot *dquot;
  
  	act_head = tofree_head->next;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1012
1013
1014
  	while (act_head != tofree_head) {
  		dquot = list_entry(act_head, struct dquot, dq_free);
  		act_head = act_head->next;
268157ba6   Jan Kara   quota: Coding sty...
1015
1016
  		/* Remove dquot from the list so we won't have problems... */
  		list_del_init(&dquot->dq_free);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1017
1018
1019
  		dqput(dquot);
  	}
  }
fb58b7316   Christoph Hellwig   [PATCH] move remo...
1020
1021
1022
1023
  static void remove_dquot_ref(struct super_block *sb, int type,
  		struct list_head *tofree_head)
  {
  	struct inode *inode;
78bc3334a   Jiang Biao   fs/quota: erase u...
1024
  #ifdef CONFIG_QUOTA_DEBUG
7af9cce8a   Dmitry Monakhov   quota: check quot...
1025
  	int reserved = 0;
78bc3334a   Jiang Biao   fs/quota: erase u...
1026
  #endif
fb58b7316   Christoph Hellwig   [PATCH] move remo...
1027

74278da9f   Dave Chinner   inode: convert in...
1028
  	spin_lock(&sb->s_inode_list_lock);
fb58b7316   Christoph Hellwig   [PATCH] move remo...
1029
  	list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
aabb8fdb4   Nick Piggin   fs: avoid I_NEW i...
1030
1031
1032
1033
  		/*
  		 *  We have to scan also I_NEW inodes because they can already
  		 *  have quota pointer initialized. Luckily, we need to touch
  		 *  only quota pointers and these have separate locking
b9ba6f94b   Niu Yawei   quota: remove dqp...
1034
  		 *  (dq_data_lock).
aabb8fdb4   Nick Piggin   fs: avoid I_NEW i...
1035
  		 */
b9ba6f94b   Niu Yawei   quota: remove dqp...
1036
  		spin_lock(&dq_data_lock);
7af9cce8a   Dmitry Monakhov   quota: check quot...
1037
  		if (!IS_NOQUOTA(inode)) {
78bc3334a   Jiang Biao   fs/quota: erase u...
1038
  #ifdef CONFIG_QUOTA_DEBUG
7af9cce8a   Dmitry Monakhov   quota: check quot...
1039
1040
  			if (unlikely(inode_get_rsv_space(inode) > 0))
  				reserved = 1;
78bc3334a   Jiang Biao   fs/quota: erase u...
1041
  #endif
fb58b7316   Christoph Hellwig   [PATCH] move remo...
1042
  			remove_inode_dquot_ref(inode, type, tofree_head);
7af9cce8a   Dmitry Monakhov   quota: check quot...
1043
  		}
b9ba6f94b   Niu Yawei   quota: remove dqp...
1044
  		spin_unlock(&dq_data_lock);
fb58b7316   Christoph Hellwig   [PATCH] move remo...
1045
  	}
74278da9f   Dave Chinner   inode: convert in...
1046
  	spin_unlock(&sb->s_inode_list_lock);
7af9cce8a   Dmitry Monakhov   quota: check quot...
1047
1048
1049
1050
1051
1052
1053
1054
  #ifdef CONFIG_QUOTA_DEBUG
  	if (reserved) {
  		printk(KERN_WARNING "VFS (%s): Writes happened after quota"
  			" was disabled thus quota information is probably "
  			"inconsistent. Please run quotacheck(8).
  ", sb->s_id);
  	}
  #endif
fb58b7316   Christoph Hellwig   [PATCH] move remo...
1055
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1056
1057
1058
1059
  /* Gather all references from inodes and drop them */
  static void drop_dquot_ref(struct super_block *sb, int type)
  {
  	LIST_HEAD(tofree_head);
fb58b7316   Christoph Hellwig   [PATCH] move remo...
1060
  	if (sb->dq_op) {
fb58b7316   Christoph Hellwig   [PATCH] move remo...
1061
  		remove_dquot_ref(sb, type, &tofree_head);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1062
  		synchronize_srcu(&dquot_srcu);
fb58b7316   Christoph Hellwig   [PATCH] move remo...
1063
1064
  		put_dquot_list(&tofree_head);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1065
  }
740d9dcd9   Mingming Cao   quota: Add quota ...
1066
1067
1068
  static inline
  void dquot_free_reserved_space(struct dquot *dquot, qsize_t number)
  {
0a5a9c725   Jan Kara   quota: Fix warnin...
1069
1070
1071
1072
1073
1074
  	if (dquot->dq_dqb.dqb_rsvspace >= number)
  		dquot->dq_dqb.dqb_rsvspace -= number;
  	else {
  		WARN_ON_ONCE(1);
  		dquot->dq_dqb.dqb_rsvspace = 0;
  	}
41e327b58   zhangyi (F)   quota: correct sp...
1075
1076
1077
1078
  	if (dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace <=
  	    dquot->dq_dqb.dqb_bsoftlimit)
  		dquot->dq_dqb.dqb_btime = (time64_t) 0;
  	clear_bit(DQ_BLKS_B, &dquot->dq_flags);
740d9dcd9   Mingming Cao   quota: Add quota ...
1079
  }
7a2435d87   Jan Kara   quota: Remove sup...
1080
  static void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1081
  {
db49d2df4   Jan Kara   quota: Allow nega...
1082
1083
  	if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE ||
  	    dquot->dq_dqb.dqb_curinodes >= number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1084
1085
1086
1087
  		dquot->dq_dqb.dqb_curinodes -= number;
  	else
  		dquot->dq_dqb.dqb_curinodes = 0;
  	if (dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit)
e008bb613   Arnd Bergmann   quota: use time64...
1088
  		dquot->dq_dqb.dqb_itime = (time64_t) 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1089
1090
  	clear_bit(DQ_INODES_B, &dquot->dq_flags);
  }
7a2435d87   Jan Kara   quota: Remove sup...
1091
  static void dquot_decr_space(struct dquot *dquot, qsize_t number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1092
  {
db49d2df4   Jan Kara   quota: Allow nega...
1093
1094
  	if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE ||
  	    dquot->dq_dqb.dqb_curspace >= number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1095
1096
1097
  		dquot->dq_dqb.dqb_curspace -= number;
  	else
  		dquot->dq_dqb.dqb_curspace = 0;
41e327b58   zhangyi (F)   quota: correct sp...
1098
1099
  	if (dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace <=
  	    dquot->dq_dqb.dqb_bsoftlimit)
e008bb613   Arnd Bergmann   quota: use time64...
1100
  		dquot->dq_dqb.dqb_btime = (time64_t) 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1101
1102
  	clear_bit(DQ_BLKS_B, &dquot->dq_flags);
  }
bf097aaff   Jan Kara   quota: Make quota...
1103
1104
  struct dquot_warn {
  	struct super_block *w_sb;
7b9c7321c   Eric W. Biederman   userns: Convert s...
1105
  	struct kqid w_dq_id;
bf097aaff   Jan Kara   quota: Make quota...
1106
1107
  	short w_type;
  };
c525460e2   Jan Kara   Don't send quota ...
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
  static int warning_issued(struct dquot *dquot, const int warntype)
  {
  	int flag = (warntype == QUOTA_NL_BHARDWARN ||
  		warntype == QUOTA_NL_BSOFTLONGWARN) ? DQ_BLKS_B :
  		((warntype == QUOTA_NL_IHARDWARN ||
  		warntype == QUOTA_NL_ISOFTLONGWARN) ? DQ_INODES_B : 0);
  
  	if (!flag)
  		return 0;
  	return test_and_set_bit(flag, &dquot->dq_flags);
  }
8e8934695   Jan Kara   quota: send messa...
1119
  #ifdef CONFIG_PRINT_QUOTA_WARNING
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1120
  static int flag_print_warnings = 1;
bf097aaff   Jan Kara   quota: Make quota...
1121
  static int need_print_warning(struct dquot_warn *warn)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1122
1123
1124
  {
  	if (!flag_print_warnings)
  		return 0;
7b9c7321c   Eric W. Biederman   userns: Convert s...
1125
  	switch (warn->w_dq_id.type) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1126
  		case USRQUOTA:
1a06d420c   Eric W. Biederman   userns: Convert q...
1127
  			return uid_eq(current_fsuid(), warn->w_dq_id.uid);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1128
  		case GRPQUOTA:
7b9c7321c   Eric W. Biederman   userns: Convert s...
1129
  			return in_group_p(warn->w_dq_id.gid);
847aac644   Li Xi   vfs: Add general ...
1130
1131
  		case PRJQUOTA:
  			return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1132
1133
1134
  	}
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1135
  /* Print warning to user which exceeded quota */
bf097aaff   Jan Kara   quota: Make quota...
1136
  static void print_warning(struct dquot_warn *warn)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1137
1138
  {
  	char *msg = NULL;
24ec839c4   Peter Zijlstra   [PATCH] tty: ->si...
1139
  	struct tty_struct *tty;
bf097aaff   Jan Kara   quota: Make quota...
1140
  	int warntype = warn->w_type;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1141

657d3bfa9   Jan Kara   quota: implement ...
1142
1143
1144
  	if (warntype == QUOTA_NL_IHARDBELOW ||
  	    warntype == QUOTA_NL_ISOFTBELOW ||
  	    warntype == QUOTA_NL_BHARDBELOW ||
bf097aaff   Jan Kara   quota: Make quota...
1145
  	    warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(warn))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1146
  		return;
24ec839c4   Peter Zijlstra   [PATCH] tty: ->si...
1147
1148
  	tty = get_current_tty();
  	if (!tty)
452a00d2e   Alan Cox   tty: Make get_cur...
1149
  		return;
bf097aaff   Jan Kara   quota: Make quota...
1150
  	tty_write_message(tty, warn->w_sb->s_id);
8e8934695   Jan Kara   quota: send messa...
1151
  	if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN)
24ec839c4   Peter Zijlstra   [PATCH] tty: ->si...
1152
  		tty_write_message(tty, ": warning, ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1153
  	else
24ec839c4   Peter Zijlstra   [PATCH] tty: ->si...
1154
  		tty_write_message(tty, ": write failed, ");
7b9c7321c   Eric W. Biederman   userns: Convert s...
1155
  	tty_write_message(tty, quotatypes[warn->w_dq_id.type]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1156
  	switch (warntype) {
8e8934695   Jan Kara   quota: send messa...
1157
  		case QUOTA_NL_IHARDWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1158
1159
1160
  			msg = " file limit reached.\r
  ";
  			break;
8e8934695   Jan Kara   quota: send messa...
1161
  		case QUOTA_NL_ISOFTLONGWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1162
1163
1164
  			msg = " file quota exceeded too long.\r
  ";
  			break;
8e8934695   Jan Kara   quota: send messa...
1165
  		case QUOTA_NL_ISOFTWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1166
1167
1168
  			msg = " file quota exceeded.\r
  ";
  			break;
8e8934695   Jan Kara   quota: send messa...
1169
  		case QUOTA_NL_BHARDWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1170
1171
1172
  			msg = " block limit reached.\r
  ";
  			break;
8e8934695   Jan Kara   quota: send messa...
1173
  		case QUOTA_NL_BSOFTLONGWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1174
1175
1176
  			msg = " block quota exceeded too long.\r
  ";
  			break;
8e8934695   Jan Kara   quota: send messa...
1177
  		case QUOTA_NL_BSOFTWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1178
1179
1180
1181
  			msg = " block quota exceeded.\r
  ";
  			break;
  	}
24ec839c4   Peter Zijlstra   [PATCH] tty: ->si...
1182
  	tty_write_message(tty, msg);
452a00d2e   Alan Cox   tty: Make get_cur...
1183
  	tty_kref_put(tty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1184
  }
8e8934695   Jan Kara   quota: send messa...
1185
  #endif
bf097aaff   Jan Kara   quota: Make quota...
1186
1187
1188
1189
1190
1191
1192
1193
  static void prepare_warning(struct dquot_warn *warn, struct dquot *dquot,
  			    int warntype)
  {
  	if (warning_issued(dquot, warntype))
  		return;
  	warn->w_type = warntype;
  	warn->w_sb = dquot->dq_sb;
  	warn->w_dq_id = dquot->dq_id;
bf097aaff   Jan Kara   quota: Make quota...
1194
  }
f18df2289   Mingming Cao   quota: Add quota ...
1195
1196
1197
  /*
   * Write warnings to the console and send warning messages over netlink.
   *
bf097aaff   Jan Kara   quota: Make quota...
1198
   * Note that this function can call into tty and networking code.
f18df2289   Mingming Cao   quota: Add quota ...
1199
   */
bf097aaff   Jan Kara   quota: Make quota...
1200
  static void flush_warnings(struct dquot_warn *warn)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1201
1202
  {
  	int i;
86e931a35   Steven Whitehouse   VFS: Export dquot...
1203
  	for (i = 0; i < MAXQUOTAS; i++) {
bf097aaff   Jan Kara   quota: Make quota...
1204
1205
  		if (warn[i].w_type == QUOTA_NL_NOWARN)
  			continue;
8e8934695   Jan Kara   quota: send messa...
1206
  #ifdef CONFIG_PRINT_QUOTA_WARNING
bf097aaff   Jan Kara   quota: Make quota...
1207
  		print_warning(&warn[i]);
8e8934695   Jan Kara   quota: send messa...
1208
  #endif
7b9c7321c   Eric W. Biederman   userns: Convert s...
1209
  		quota_send_warning(warn[i].w_dq_id,
bf097aaff   Jan Kara   quota: Make quota...
1210
  				   warn[i].w_sb->s_dev, warn[i].w_type);
86e931a35   Steven Whitehouse   VFS: Export dquot...
1211
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1212
  }
7a2435d87   Jan Kara   quota: Remove sup...
1213
  static int ignore_hardlimit(struct dquot *dquot)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1214
  {
4c376dcae   Eric W. Biederman   userns: Convert s...
1215
  	struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1216
1217
  
  	return capable(CAP_SYS_RESOURCE) &&
268157ba6   Jan Kara   quota: Coding sty...
1218
  	       (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
9c45101e8   Jan Kara   quota: Cleanup fl...
1219
  		!(info->dqi_flags & DQF_ROOT_SQUASH));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1220
  }
7b9ca4c61   Jan Kara   quota: Reduce con...
1221
1222
  static int dquot_add_inodes(struct dquot *dquot, qsize_t inodes,
  			    struct dquot_warn *warn)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1223
  {
7b9ca4c61   Jan Kara   quota: Reduce con...
1224
1225
  	qsize_t newinodes;
  	int ret = 0;
268157ba6   Jan Kara   quota: Coding sty...
1226

7b9ca4c61   Jan Kara   quota: Reduce con...
1227
1228
  	spin_lock(&dquot->dq_dqb_lock);
  	newinodes = dquot->dq_dqb.dqb_curinodes + inodes;
4c376dcae   Eric W. Biederman   userns: Convert s...
1229
  	if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_id.type) ||
f55abc0fb   Jan Kara   quota: Allow to s...
1230
  	    test_bit(DQ_FAKE_B, &dquot->dq_flags))
7b9ca4c61   Jan Kara   quota: Reduce con...
1231
  		goto add;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1232
1233
  
  	if (dquot->dq_dqb.dqb_ihardlimit &&
268157ba6   Jan Kara   quota: Coding sty...
1234
  	    newinodes > dquot->dq_dqb.dqb_ihardlimit &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1235
              !ignore_hardlimit(dquot)) {
bf097aaff   Jan Kara   quota: Make quota...
1236
  		prepare_warning(warn, dquot, QUOTA_NL_IHARDWARN);
7b9ca4c61   Jan Kara   quota: Reduce con...
1237
1238
  		ret = -EDQUOT;
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1239
1240
1241
  	}
  
  	if (dquot->dq_dqb.dqb_isoftlimit &&
268157ba6   Jan Kara   quota: Coding sty...
1242
1243
  	    newinodes > dquot->dq_dqb.dqb_isoftlimit &&
  	    dquot->dq_dqb.dqb_itime &&
e008bb613   Arnd Bergmann   quota: use time64...
1244
  	    ktime_get_real_seconds() >= dquot->dq_dqb.dqb_itime &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1245
              !ignore_hardlimit(dquot)) {
bf097aaff   Jan Kara   quota: Make quota...
1246
  		prepare_warning(warn, dquot, QUOTA_NL_ISOFTLONGWARN);
7b9ca4c61   Jan Kara   quota: Reduce con...
1247
1248
  		ret = -EDQUOT;
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1249
1250
1251
  	}
  
  	if (dquot->dq_dqb.dqb_isoftlimit &&
268157ba6   Jan Kara   quota: Coding sty...
1252
  	    newinodes > dquot->dq_dqb.dqb_isoftlimit &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1253
  	    dquot->dq_dqb.dqb_itime == 0) {
bf097aaff   Jan Kara   quota: Make quota...
1254
  		prepare_warning(warn, dquot, QUOTA_NL_ISOFTWARN);
e008bb613   Arnd Bergmann   quota: use time64...
1255
  		dquot->dq_dqb.dqb_itime = ktime_get_real_seconds() +
4c376dcae   Eric W. Biederman   userns: Convert s...
1256
  		    sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type].dqi_igrace;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1257
  	}
7b9ca4c61   Jan Kara   quota: Reduce con...
1258
1259
  add:
  	dquot->dq_dqb.dqb_curinodes = newinodes;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1260

7b9ca4c61   Jan Kara   quota: Reduce con...
1261
1262
1263
  out:
  	spin_unlock(&dquot->dq_dqb_lock);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1264
  }
7b9ca4c61   Jan Kara   quota: Reduce con...
1265
1266
1267
  static int dquot_add_space(struct dquot *dquot, qsize_t space,
  			   qsize_t rsv_space, unsigned int flags,
  			   struct dquot_warn *warn)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1268
  {
f18df2289   Mingming Cao   quota: Add quota ...
1269
  	qsize_t tspace;
268157ba6   Jan Kara   quota: Coding sty...
1270
  	struct super_block *sb = dquot->dq_sb;
7b9ca4c61   Jan Kara   quota: Reduce con...
1271
  	int ret = 0;
f18df2289   Mingming Cao   quota: Add quota ...
1272

7b9ca4c61   Jan Kara   quota: Reduce con...
1273
  	spin_lock(&dquot->dq_dqb_lock);
4c376dcae   Eric W. Biederman   userns: Convert s...
1274
  	if (!sb_has_quota_limits_enabled(sb, dquot->dq_id.type) ||
f55abc0fb   Jan Kara   quota: Allow to s...
1275
  	    test_bit(DQ_FAKE_B, &dquot->dq_flags))
ac3d79392   Jan Kara   quota: Generate w...
1276
  		goto finish;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1277

f18df2289   Mingming Cao   quota: Add quota ...
1278
  	tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace
7b9ca4c61   Jan Kara   quota: Reduce con...
1279
  		+ space + rsv_space;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1280
  	if (dquot->dq_dqb.dqb_bhardlimit &&
f18df2289   Mingming Cao   quota: Add quota ...
1281
  	    tspace > dquot->dq_dqb.dqb_bhardlimit &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1282
              !ignore_hardlimit(dquot)) {
7b9ca4c61   Jan Kara   quota: Reduce con...
1283
  		if (flags & DQUOT_SPACE_WARN)
bf097aaff   Jan Kara   quota: Make quota...
1284
  			prepare_warning(warn, dquot, QUOTA_NL_BHARDWARN);
7b9ca4c61   Jan Kara   quota: Reduce con...
1285
  		ret = -EDQUOT;
ac3d79392   Jan Kara   quota: Generate w...
1286
  		goto finish;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1287
1288
1289
  	}
  
  	if (dquot->dq_dqb.dqb_bsoftlimit &&
f18df2289   Mingming Cao   quota: Add quota ...
1290
  	    tspace > dquot->dq_dqb.dqb_bsoftlimit &&
268157ba6   Jan Kara   quota: Coding sty...
1291
  	    dquot->dq_dqb.dqb_btime &&
e008bb613   Arnd Bergmann   quota: use time64...
1292
  	    ktime_get_real_seconds() >= dquot->dq_dqb.dqb_btime &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1293
              !ignore_hardlimit(dquot)) {
7b9ca4c61   Jan Kara   quota: Reduce con...
1294
  		if (flags & DQUOT_SPACE_WARN)
bf097aaff   Jan Kara   quota: Make quota...
1295
  			prepare_warning(warn, dquot, QUOTA_NL_BSOFTLONGWARN);
7b9ca4c61   Jan Kara   quota: Reduce con...
1296
  		ret = -EDQUOT;
ac3d79392   Jan Kara   quota: Generate w...
1297
  		goto finish;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1298
1299
1300
  	}
  
  	if (dquot->dq_dqb.dqb_bsoftlimit &&
f18df2289   Mingming Cao   quota: Add quota ...
1301
  	    tspace > dquot->dq_dqb.dqb_bsoftlimit &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1302
  	    dquot->dq_dqb.dqb_btime == 0) {
7b9ca4c61   Jan Kara   quota: Reduce con...
1303
  		if (flags & DQUOT_SPACE_WARN) {
bf097aaff   Jan Kara   quota: Make quota...
1304
  			prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN);
e008bb613   Arnd Bergmann   quota: use time64...
1305
  			dquot->dq_dqb.dqb_btime = ktime_get_real_seconds() +
4c376dcae   Eric W. Biederman   userns: Convert s...
1306
  			    sb_dqopt(sb)->info[dquot->dq_id.type].dqi_bgrace;
7b9ca4c61   Jan Kara   quota: Reduce con...
1307
  		} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1308
1309
1310
1311
  			/*
  			 * We don't allow preallocation to exceed softlimit so exceeding will
  			 * be always printed
  			 */
7b9ca4c61   Jan Kara   quota: Reduce con...
1312
  			ret = -EDQUOT;
ac3d79392   Jan Kara   quota: Generate w...
1313
  			goto finish;
7b9ca4c61   Jan Kara   quota: Reduce con...
1314
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1315
  	}
ac3d79392   Jan Kara   quota: Generate w...
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
  finish:
  	/*
  	 * We have to be careful and go through warning generation & grace time
  	 * setting even if DQUOT_SPACE_NOFAIL is set. That's why we check it
  	 * only here...
  	 */
  	if (flags & DQUOT_SPACE_NOFAIL)
  		ret = 0;
  	if (!ret) {
  		dquot->dq_dqb.dqb_rsvspace += rsv_space;
  		dquot->dq_dqb.dqb_curspace += space;
  	}
7b9ca4c61   Jan Kara   quota: Reduce con...
1328
1329
  	spin_unlock(&dquot->dq_dqb_lock);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1330
  }
12095460f   Jan Kara   quota: Increase s...
1331
  static int info_idq_free(struct dquot *dquot, qsize_t inodes)
657d3bfa9   Jan Kara   quota: implement ...
1332
  {
268157ba6   Jan Kara   quota: Coding sty...
1333
  	qsize_t newinodes;
657d3bfa9   Jan Kara   quota: implement ...
1334
  	if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
f55abc0fb   Jan Kara   quota: Allow to s...
1335
  	    dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit ||
4c376dcae   Eric W. Biederman   userns: Convert s...
1336
  	    !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_id.type))
657d3bfa9   Jan Kara   quota: implement ...
1337
  		return QUOTA_NL_NOWARN;
268157ba6   Jan Kara   quota: Coding sty...
1338
1339
  	newinodes = dquot->dq_dqb.dqb_curinodes - inodes;
  	if (newinodes <= dquot->dq_dqb.dqb_isoftlimit)
657d3bfa9   Jan Kara   quota: implement ...
1340
1341
  		return QUOTA_NL_ISOFTBELOW;
  	if (dquot->dq_dqb.dqb_curinodes >= dquot->dq_dqb.dqb_ihardlimit &&
268157ba6   Jan Kara   quota: Coding sty...
1342
  	    newinodes < dquot->dq_dqb.dqb_ihardlimit)
657d3bfa9   Jan Kara   quota: implement ...
1343
1344
1345
1346
1347
1348
  		return QUOTA_NL_IHARDBELOW;
  	return QUOTA_NL_NOWARN;
  }
  
  static int info_bdq_free(struct dquot *dquot, qsize_t space)
  {
41e327b58   zhangyi (F)   quota: correct sp...
1349
1350
1351
  	qsize_t tspace;
  
  	tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace;
657d3bfa9   Jan Kara   quota: implement ...
1352
  	if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
41e327b58   zhangyi (F)   quota: correct sp...
1353
  	    tspace <= dquot->dq_dqb.dqb_bsoftlimit)
657d3bfa9   Jan Kara   quota: implement ...
1354
  		return QUOTA_NL_NOWARN;
41e327b58   zhangyi (F)   quota: correct sp...
1355
  	if (tspace - space <= dquot->dq_dqb.dqb_bsoftlimit)
657d3bfa9   Jan Kara   quota: implement ...
1356
  		return QUOTA_NL_BSOFTBELOW;
41e327b58   zhangyi (F)   quota: correct sp...
1357
1358
  	if (tspace >= dquot->dq_dqb.dqb_bhardlimit &&
  	    tspace - space < dquot->dq_dqb.dqb_bhardlimit)
657d3bfa9   Jan Kara   quota: implement ...
1359
1360
1361
  		return QUOTA_NL_BHARDBELOW;
  	return QUOTA_NL_NOWARN;
  }
0a5a9c725   Jan Kara   quota: Fix warnin...
1362

189eef59e   Christoph Hellwig   quota: clean up q...
1363
1364
1365
1366
1367
1368
1369
1370
  static int dquot_active(const struct inode *inode)
  {
  	struct super_block *sb = inode->i_sb;
  
  	if (IS_NOQUOTA(inode))
  		return 0;
  	return sb_any_quota_loaded(sb) & ~sb_any_quota_suspended(sb);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1371
  /*
871a29315   Christoph Hellwig   dquot: cleanup dq...
1372
1373
   * Initialize quota pointers in inode
   *
871a29315   Christoph Hellwig   dquot: cleanup dq...
1374
1375
   * It is better to call this function outside of any transaction as it
   * might need a lot of space in journal for dquot structure allocation.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1376
   */
6184fc0b8   Jan Kara   quota: Propagate ...
1377
  static int __dquot_initialize(struct inode *inode, int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1378
  {
1ea06bec7   Niu Yawei   quota: avoid unne...
1379
  	int cnt, init_needed = 0;
ab73ef463   Nikolay Borisov   quota: Fix possib...
1380
  	struct dquot **dquots, *got[MAXQUOTAS] = {};
cc33412fb   Jan Kara   quota: Improve lo...
1381
  	struct super_block *sb = inode->i_sb;
0a5a9c725   Jan Kara   quota: Fix warnin...
1382
  	qsize_t rsv;
6184fc0b8   Jan Kara   quota: Propagate ...
1383
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1384

189eef59e   Christoph Hellwig   quota: clean up q...
1385
  	if (!dquot_active(inode))
6184fc0b8   Jan Kara   quota: Propagate ...
1386
  		return 0;
cc33412fb   Jan Kara   quota: Improve lo...
1387

5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1388
  	dquots = i_dquot(inode);
cc33412fb   Jan Kara   quota: Improve lo...
1389
1390
  	/* First get references to structures we might need. */
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
aca645a6a   Eric W. Biederman   userns: Modify dq...
1391
  		struct kqid qid;
847aac644   Li Xi   vfs: Add general ...
1392
1393
  		kprojid_t projid;
  		int rc;
6184fc0b8   Jan Kara   quota: Propagate ...
1394
  		struct dquot *dquot;
847aac644   Li Xi   vfs: Add general ...
1395

cc33412fb   Jan Kara   quota: Improve lo...
1396
1397
  		if (type != -1 && cnt != type)
  			continue;
1ea06bec7   Niu Yawei   quota: avoid unne...
1398
1399
1400
1401
1402
  		/*
  		 * The i_dquot should have been initialized in most cases,
  		 * we check it without locking here to avoid unnecessary
  		 * dqget()/dqput() calls.
  		 */
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1403
  		if (dquots[cnt])
1ea06bec7   Niu Yawei   quota: avoid unne...
1404
  			continue;
847aac644   Li Xi   vfs: Add general ...
1405
1406
1407
  
  		if (!sb_has_quota_active(sb, cnt))
  			continue;
1ea06bec7   Niu Yawei   quota: avoid unne...
1408
  		init_needed = 1;
cc33412fb   Jan Kara   quota: Improve lo...
1409
1410
  		switch (cnt) {
  		case USRQUOTA:
aca645a6a   Eric W. Biederman   userns: Modify dq...
1411
  			qid = make_kqid_uid(inode->i_uid);
cc33412fb   Jan Kara   quota: Improve lo...
1412
1413
  			break;
  		case GRPQUOTA:
aca645a6a   Eric W. Biederman   userns: Modify dq...
1414
  			qid = make_kqid_gid(inode->i_gid);
cc33412fb   Jan Kara   quota: Improve lo...
1415
  			break;
847aac644   Li Xi   vfs: Add general ...
1416
1417
1418
1419
1420
1421
  		case PRJQUOTA:
  			rc = inode->i_sb->dq_op->get_projid(inode, &projid);
  			if (rc)
  				continue;
  			qid = make_kqid_projid(projid);
  			break;
cc33412fb   Jan Kara   quota: Improve lo...
1422
  		}
6184fc0b8   Jan Kara   quota: Propagate ...
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
  		dquot = dqget(sb, qid);
  		if (IS_ERR(dquot)) {
  			/* We raced with somebody turning quotas off... */
  			if (PTR_ERR(dquot) != -ESRCH) {
  				ret = PTR_ERR(dquot);
  				goto out_put;
  			}
  			dquot = NULL;
  		}
  		got[cnt] = dquot;
cc33412fb   Jan Kara   quota: Improve lo...
1433
  	}
1ea06bec7   Niu Yawei   quota: avoid unne...
1434
1435
  	/* All required i_dquot has been initialized */
  	if (!init_needed)
6184fc0b8   Jan Kara   quota: Propagate ...
1436
  		return 0;
1ea06bec7   Niu Yawei   quota: avoid unne...
1437

b9ba6f94b   Niu Yawei   quota: remove dqp...
1438
  	spin_lock(&dq_data_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1439
  	if (IS_NOQUOTA(inode))
6184fc0b8   Jan Kara   quota: Propagate ...
1440
  		goto out_lock;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1441
1442
1443
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		if (type != -1 && cnt != type)
  			continue;
cc33412fb   Jan Kara   quota: Improve lo...
1444
1445
1446
  		/* Avoid races with quotaoff() */
  		if (!sb_has_quota_active(sb, cnt))
  			continue;
4408ea41c   Jan Kara   quota: Fix possib...
1447
1448
1449
  		/* We could race with quotaon or dqget() could have failed */
  		if (!got[cnt])
  			continue;
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1450
1451
  		if (!dquots[cnt]) {
  			dquots[cnt] = got[cnt];
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1452
  			got[cnt] = NULL;
0a5a9c725   Jan Kara   quota: Fix warnin...
1453
1454
1455
1456
1457
  			/*
  			 * Make quota reservation system happy if someone
  			 * did a write before quota was turned on
  			 */
  			rsv = inode_get_rsv_space(inode);
7b9ca4c61   Jan Kara   quota: Reduce con...
1458
1459
1460
1461
1462
1463
1464
1465
1466
  			if (unlikely(rsv)) {
  				spin_lock(&inode->i_lock);
  				/* Get reservation again under proper lock */
  				rsv = __inode_get_rsv_space(inode);
  				spin_lock(&dquots[cnt]->dq_dqb_lock);
  				dquots[cnt]->dq_dqb.dqb_rsvspace += rsv;
  				spin_unlock(&dquots[cnt]->dq_dqb_lock);
  				spin_unlock(&inode->i_lock);
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1467
1468
  		}
  	}
6184fc0b8   Jan Kara   quota: Propagate ...
1469
  out_lock:
b9ba6f94b   Niu Yawei   quota: remove dqp...
1470
  	spin_unlock(&dq_data_lock);
6184fc0b8   Jan Kara   quota: Propagate ...
1471
  out_put:
cc33412fb   Jan Kara   quota: Improve lo...
1472
  	/* Drop unused references */
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1473
  	dqput_all(got);
6184fc0b8   Jan Kara   quota: Propagate ...
1474
1475
  
  	return ret;
871a29315   Christoph Hellwig   dquot: cleanup dq...
1476
  }
6184fc0b8   Jan Kara   quota: Propagate ...
1477
  int dquot_initialize(struct inode *inode)
871a29315   Christoph Hellwig   dquot: cleanup dq...
1478
  {
6184fc0b8   Jan Kara   quota: Propagate ...
1479
  	return __dquot_initialize(inode, -1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1480
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
1481
  EXPORT_SYMBOL(dquot_initialize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1482

b8cb5a545   Tahsin Erdogan   ext4: fix quota c...
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
  bool dquot_initialize_needed(struct inode *inode)
  {
  	struct dquot **dquots;
  	int i;
  
  	if (!dquot_active(inode))
  		return false;
  
  	dquots = i_dquot(inode);
  	for (i = 0; i < MAXQUOTAS; i++)
  		if (!dquots[i] && sb_has_quota_active(inode->i_sb, i))
  			return true;
  	return false;
  }
  EXPORT_SYMBOL(dquot_initialize_needed);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1498
  /*
b9ba6f94b   Niu Yawei   quota: remove dqp...
1499
1500
1501
1502
1503
1504
   * Release all quotas referenced by inode.
   *
   * This function only be called on inode free or converting
   * a file to quota file, no other users for the i_dquot in
   * both cases, so we needn't call synchronize_srcu() after
   * clearing i_dquot.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1505
   */
9f7547580   Christoph Hellwig   dquot: cleanup dq...
1506
  static void __dquot_drop(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1507
1508
  {
  	int cnt;
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1509
  	struct dquot **dquots = i_dquot(inode);
cc33412fb   Jan Kara   quota: Improve lo...
1510
  	struct dquot *put[MAXQUOTAS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1511

b9ba6f94b   Niu Yawei   quota: remove dqp...
1512
  	spin_lock(&dq_data_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1513
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1514
1515
  		put[cnt] = dquots[cnt];
  		dquots[cnt] = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1516
  	}
b9ba6f94b   Niu Yawei   quota: remove dqp...
1517
  	spin_unlock(&dq_data_lock);
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1518
  	dqput_all(put);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1519
  }
9f7547580   Christoph Hellwig   dquot: cleanup dq...
1520
1521
  void dquot_drop(struct inode *inode)
  {
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1522
  	struct dquot * const *dquots;
9f7547580   Christoph Hellwig   dquot: cleanup dq...
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
  	int cnt;
  
  	if (IS_NOQUOTA(inode))
  		return;
  
  	/*
  	 * Test before calling to rule out calls from proc and such
  	 * where we are not allowed to block. Note that this is
  	 * actually reliable test even without the lock - the caller
  	 * must assure that nobody can come after the DQUOT_DROP and
  	 * add quota pointers back anyway.
  	 */
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1535
  	dquots = i_dquot(inode);
9f7547580   Christoph Hellwig   dquot: cleanup dq...
1536
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1537
  		if (dquots[cnt])
9f7547580   Christoph Hellwig   dquot: cleanup dq...
1538
1539
1540
1541
1542
1543
1544
  			break;
  	}
  
  	if (cnt < MAXQUOTAS)
  		__dquot_drop(inode);
  }
  EXPORT_SYMBOL(dquot_drop);
b85f4b87a   Jan Kara   quota: rename quo...
1545

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1546
  /*
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
   * inode_reserved_space is managed internally by quota, and protected by
   * i_lock similar to i_blocks+i_bytes.
   */
  static qsize_t *inode_reserved_space(struct inode * inode)
  {
  	/* Filesystem must explicitly define it's own method in order to use
  	 * quota reservation interface */
  	BUG_ON(!inode->i_sb->dq_op->get_reserved_space);
  	return inode->i_sb->dq_op->get_reserved_space(inode);
  }
7b9ca4c61   Jan Kara   quota: Reduce con...
1557
  static qsize_t __inode_get_rsv_space(struct inode *inode)
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1558
  {
7b9ca4c61   Jan Kara   quota: Reduce con...
1559
1560
1561
  	if (!inode->i_sb->dq_op->get_reserved_space)
  		return 0;
  	return *inode_reserved_space(inode);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1562
1563
1564
1565
1566
  }
  
  static qsize_t inode_get_rsv_space(struct inode *inode)
  {
  	qsize_t ret;
05b5d8982   Jan Kara   quota: Fix dquot_...
1567
1568
1569
  
  	if (!inode->i_sb->dq_op->get_reserved_space)
  		return 0;
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1570
  	spin_lock(&inode->i_lock);
7b9ca4c61   Jan Kara   quota: Reduce con...
1571
  	ret = __inode_get_rsv_space(inode);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1572
1573
1574
  	spin_unlock(&inode->i_lock);
  	return ret;
  }
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1575
  /*
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1576
1577
1578
1579
1580
1581
1582
   * This functions updates i_blocks+i_bytes fields and quota information
   * (together with appropriate checks).
   *
   * NOTE: We absolutely rely on the fact that caller dirties the inode
   * (usually helpers in quotaops.h care about this) and holds a handle for
   * the current transaction so that dquot write and inode write go into the
   * same transaction.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1583
1584
1585
1586
1587
   */
  
  /*
   * This operation can block, but only after everything is updated
   */
56246f9ae   Eric Sandeen   quota: use flags ...
1588
  int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1589
  {
b9ba6f94b   Niu Yawei   quota: remove dqp...
1590
  	int cnt, ret = 0, index;
bf097aaff   Jan Kara   quota: Make quota...
1591
  	struct dquot_warn warn[MAXQUOTAS];
56246f9ae   Eric Sandeen   quota: use flags ...
1592
  	int reserve = flags & DQUOT_SPACE_RESERVE;
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1593
  	struct dquot **dquots;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1594

189eef59e   Christoph Hellwig   quota: clean up q...
1595
  	if (!dquot_active(inode)) {
a478e522e   Jan Kara   quota: Inline ino...
1596
1597
1598
1599
1600
1601
1602
  		if (reserve) {
  			spin_lock(&inode->i_lock);
  			*inode_reserved_space(inode) += number;
  			spin_unlock(&inode->i_lock);
  		} else {
  			inode_add_bytes(inode, number);
  		}
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1603
1604
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1605
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
bf097aaff   Jan Kara   quota: Make quota...
1606
  		warn[cnt].w_type = QUOTA_NL_NOWARN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1607

5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1608
  	dquots = i_dquot(inode);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1609
  	index = srcu_read_lock(&dquot_srcu);
7b9ca4c61   Jan Kara   quota: Reduce con...
1610
  	spin_lock(&inode->i_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1611
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
bf097aaff   Jan Kara   quota: Make quota...
1612
  		if (!dquots[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1613
  			continue;
df15a2a59   Chengguang Xu   quota: code clean...
1614
  		if (reserve) {
7b9ca4c61   Jan Kara   quota: Reduce con...
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
  			ret = dquot_add_space(dquots[cnt], 0, number, flags,
  					      &warn[cnt]);
  		} else {
  			ret = dquot_add_space(dquots[cnt], number, 0, flags,
  					      &warn[cnt]);
  		}
  		if (ret) {
  			/* Back out changes we already did */
  			for (cnt--; cnt >= 0; cnt--) {
  				if (!dquots[cnt])
  					continue;
  				spin_lock(&dquots[cnt]->dq_dqb_lock);
632a9f3ac   Chengguang Xu   quota: check time...
1627
1628
1629
1630
1631
  				if (reserve)
  					dquot_free_reserved_space(dquots[cnt],
  								  number);
  				else
  					dquot_decr_space(dquots[cnt], number);
7b9ca4c61   Jan Kara   quota: Reduce con...
1632
1633
1634
  				spin_unlock(&dquots[cnt]->dq_dqb_lock);
  			}
  			spin_unlock(&inode->i_lock);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1635
  			goto out_flush_warn;
f18df2289   Mingming Cao   quota: Add quota ...
1636
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1637
  	}
7b9ca4c61   Jan Kara   quota: Reduce con...
1638
  	if (reserve)
a478e522e   Jan Kara   quota: Inline ino...
1639
  		*inode_reserved_space(inode) += number;
7b9ca4c61   Jan Kara   quota: Reduce con...
1640
1641
1642
  	else
  		__inode_add_bytes(inode, number);
  	spin_unlock(&inode->i_lock);
f18df2289   Mingming Cao   quota: Add quota ...
1643

fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1644
1645
  	if (reserve)
  		goto out_flush_warn;
bf097aaff   Jan Kara   quota: Make quota...
1646
  	mark_all_dquot_dirty(dquots);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1647
  out_flush_warn:
b9ba6f94b   Niu Yawei   quota: remove dqp...
1648
  	srcu_read_unlock(&dquot_srcu, index);
bf097aaff   Jan Kara   quota: Make quota...
1649
  	flush_warnings(warn);
f18df2289   Mingming Cao   quota: Add quota ...
1650
1651
1652
  out:
  	return ret;
  }
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1653
  EXPORT_SYMBOL(__dquot_alloc_space);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1654
1655
1656
1657
  
  /*
   * This operation can block, but only after everything is updated
   */
6bab3596b   Jan Kara   quota: Remove con...
1658
  int dquot_alloc_inode(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1659
  {
b9ba6f94b   Niu Yawei   quota: remove dqp...
1660
  	int cnt, ret = 0, index;
bf097aaff   Jan Kara   quota: Make quota...
1661
  	struct dquot_warn warn[MAXQUOTAS];
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1662
  	struct dquot * const *dquots;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1663

189eef59e   Christoph Hellwig   quota: clean up q...
1664
  	if (!dquot_active(inode))
63936ddaa   Christoph Hellwig   dquot: cleanup in...
1665
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1666
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
bf097aaff   Jan Kara   quota: Make quota...
1667
  		warn[cnt].w_type = QUOTA_NL_NOWARN;
b9ba6f94b   Niu Yawei   quota: remove dqp...
1668

5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1669
  	dquots = i_dquot(inode);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1670
  	index = srcu_read_lock(&dquot_srcu);
7b9ca4c61   Jan Kara   quota: Reduce con...
1671
  	spin_lock(&inode->i_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1672
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
bf097aaff   Jan Kara   quota: Make quota...
1673
  		if (!dquots[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1674
  			continue;
7b9ca4c61   Jan Kara   quota: Reduce con...
1675
1676
1677
1678
1679
1680
1681
  		ret = dquot_add_inodes(dquots[cnt], 1, &warn[cnt]);
  		if (ret) {
  			for (cnt--; cnt >= 0; cnt--) {
  				if (!dquots[cnt])
  					continue;
  				/* Back out changes we already did */
  				spin_lock(&dquots[cnt]->dq_dqb_lock);
632a9f3ac   Chengguang Xu   quota: check time...
1682
  				dquot_decr_inodes(dquots[cnt], 1);
7b9ca4c61   Jan Kara   quota: Reduce con...
1683
1684
  				spin_unlock(&dquots[cnt]->dq_dqb_lock);
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1685
  			goto warn_put_all;
7b9ca4c61   Jan Kara   quota: Reduce con...
1686
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1687
  	}
efd8f0e6f   Christoph Hellwig   quota: stop using...
1688

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1689
  warn_put_all:
7b9ca4c61   Jan Kara   quota: Reduce con...
1690
  	spin_unlock(&inode->i_lock);
63936ddaa   Christoph Hellwig   dquot: cleanup in...
1691
  	if (ret == 0)
bf097aaff   Jan Kara   quota: Make quota...
1692
  		mark_all_dquot_dirty(dquots);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1693
  	srcu_read_unlock(&dquot_srcu, index);
bf097aaff   Jan Kara   quota: Make quota...
1694
  	flush_warnings(warn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1695
1696
  	return ret;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
1697
  EXPORT_SYMBOL(dquot_alloc_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1698

5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1699
1700
1701
1702
  /*
   * Convert in-memory reserved quotas to real consumed quotas
   */
  int dquot_claim_space_nodirty(struct inode *inode, qsize_t number)
740d9dcd9   Mingming Cao   quota: Add quota ...
1703
  {
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1704
  	struct dquot **dquots;
b9ba6f94b   Niu Yawei   quota: remove dqp...
1705
  	int cnt, index;
740d9dcd9   Mingming Cao   quota: Add quota ...
1706

189eef59e   Christoph Hellwig   quota: clean up q...
1707
  	if (!dquot_active(inode)) {
0ed60de34   Jan Kara   quota: Inline fun...
1708
1709
1710
1711
  		spin_lock(&inode->i_lock);
  		*inode_reserved_space(inode) -= number;
  		__inode_add_bytes(inode, number);
  		spin_unlock(&inode->i_lock);
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1712
  		return 0;
740d9dcd9   Mingming Cao   quota: Add quota ...
1713
  	}
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1714
  	dquots = i_dquot(inode);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1715
  	index = srcu_read_lock(&dquot_srcu);
7b9ca4c61   Jan Kara   quota: Reduce con...
1716
  	spin_lock(&inode->i_lock);
740d9dcd9   Mingming Cao   quota: Add quota ...
1717
1718
  	/* Claim reserved quotas to allocated quotas */
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
3ab167d2b   Jan Kara   quota: Inline dqu...
1719
1720
  		if (dquots[cnt]) {
  			struct dquot *dquot = dquots[cnt];
7b9ca4c61   Jan Kara   quota: Reduce con...
1721
  			spin_lock(&dquot->dq_dqb_lock);
3ab167d2b   Jan Kara   quota: Inline dqu...
1722
1723
1724
1725
  			if (WARN_ON_ONCE(dquot->dq_dqb.dqb_rsvspace < number))
  				number = dquot->dq_dqb.dqb_rsvspace;
  			dquot->dq_dqb.dqb_curspace += number;
  			dquot->dq_dqb.dqb_rsvspace -= number;
7b9ca4c61   Jan Kara   quota: Reduce con...
1726
  			spin_unlock(&dquot->dq_dqb_lock);
3ab167d2b   Jan Kara   quota: Inline dqu...
1727
  		}
740d9dcd9   Mingming Cao   quota: Add quota ...
1728
1729
  	}
  	/* Update inode bytes */
0ed60de34   Jan Kara   quota: Inline fun...
1730
1731
1732
  	*inode_reserved_space(inode) -= number;
  	__inode_add_bytes(inode, number);
  	spin_unlock(&inode->i_lock);
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1733
  	mark_all_dquot_dirty(dquots);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1734
  	srcu_read_unlock(&dquot_srcu, index);
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1735
  	return 0;
740d9dcd9   Mingming Cao   quota: Add quota ...
1736
  }
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1737
  EXPORT_SYMBOL(dquot_claim_space_nodirty);
740d9dcd9   Mingming Cao   quota: Add quota ...
1738
1739
  
  /*
1c8924eb1   Jan Kara   quota: provide in...
1740
1741
1742
1743
   * Convert allocated space back to in-memory reserved quotas
   */
  void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number)
  {
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1744
  	struct dquot **dquots;
b9ba6f94b   Niu Yawei   quota: remove dqp...
1745
  	int cnt, index;
1c8924eb1   Jan Kara   quota: provide in...
1746
1747
  
  	if (!dquot_active(inode)) {
0ed60de34   Jan Kara   quota: Inline fun...
1748
1749
1750
1751
  		spin_lock(&inode->i_lock);
  		*inode_reserved_space(inode) += number;
  		__inode_sub_bytes(inode, number);
  		spin_unlock(&inode->i_lock);
1c8924eb1   Jan Kara   quota: provide in...
1752
1753
  		return;
  	}
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1754
  	dquots = i_dquot(inode);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1755
  	index = srcu_read_lock(&dquot_srcu);
7b9ca4c61   Jan Kara   quota: Reduce con...
1756
  	spin_lock(&inode->i_lock);
1c8924eb1   Jan Kara   quota: provide in...
1757
1758
  	/* Claim reserved quotas to allocated quotas */
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
3ab167d2b   Jan Kara   quota: Inline dqu...
1759
1760
  		if (dquots[cnt]) {
  			struct dquot *dquot = dquots[cnt];
7b9ca4c61   Jan Kara   quota: Reduce con...
1761
  			spin_lock(&dquot->dq_dqb_lock);
3ab167d2b   Jan Kara   quota: Inline dqu...
1762
1763
1764
1765
  			if (WARN_ON_ONCE(dquot->dq_dqb.dqb_curspace < number))
  				number = dquot->dq_dqb.dqb_curspace;
  			dquot->dq_dqb.dqb_rsvspace += number;
  			dquot->dq_dqb.dqb_curspace -= number;
7b9ca4c61   Jan Kara   quota: Reduce con...
1766
  			spin_unlock(&dquot->dq_dqb_lock);
3ab167d2b   Jan Kara   quota: Inline dqu...
1767
  		}
1c8924eb1   Jan Kara   quota: provide in...
1768
1769
  	}
  	/* Update inode bytes */
0ed60de34   Jan Kara   quota: Inline fun...
1770
1771
1772
  	*inode_reserved_space(inode) += number;
  	__inode_sub_bytes(inode, number);
  	spin_unlock(&inode->i_lock);
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1773
  	mark_all_dquot_dirty(dquots);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1774
  	srcu_read_unlock(&dquot_srcu, index);
1c8924eb1   Jan Kara   quota: provide in...
1775
1776
1777
1778
1779
  	return;
  }
  EXPORT_SYMBOL(dquot_reclaim_space_nodirty);
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1780
1781
   * This operation can block, but only after everything is updated
   */
56246f9ae   Eric Sandeen   quota: use flags ...
1782
  void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1783
1784
  {
  	unsigned int cnt;
bf097aaff   Jan Kara   quota: Make quota...
1785
  	struct dquot_warn warn[MAXQUOTAS];
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1786
  	struct dquot **dquots;
b9ba6f94b   Niu Yawei   quota: remove dqp...
1787
  	int reserve = flags & DQUOT_SPACE_RESERVE, index;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1788

189eef59e   Christoph Hellwig   quota: clean up q...
1789
  	if (!dquot_active(inode)) {
a478e522e   Jan Kara   quota: Inline ino...
1790
1791
1792
1793
1794
1795
1796
  		if (reserve) {
  			spin_lock(&inode->i_lock);
  			*inode_reserved_space(inode) -= number;
  			spin_unlock(&inode->i_lock);
  		} else {
  			inode_sub_bytes(inode, number);
  		}
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1797
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1798
  	}
657d3bfa9   Jan Kara   quota: implement ...
1799

5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1800
  	dquots = i_dquot(inode);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1801
  	index = srcu_read_lock(&dquot_srcu);
7b9ca4c61   Jan Kara   quota: Reduce con...
1802
  	spin_lock(&inode->i_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1803
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
bf097aaff   Jan Kara   quota: Make quota...
1804
1805
1806
1807
  		int wtype;
  
  		warn[cnt].w_type = QUOTA_NL_NOWARN;
  		if (!dquots[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1808
  			continue;
7b9ca4c61   Jan Kara   quota: Reduce con...
1809
  		spin_lock(&dquots[cnt]->dq_dqb_lock);
bf097aaff   Jan Kara   quota: Make quota...
1810
1811
1812
  		wtype = info_bdq_free(dquots[cnt], number);
  		if (wtype != QUOTA_NL_NOWARN)
  			prepare_warning(&warn[cnt], dquots[cnt], wtype);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1813
  		if (reserve)
bf097aaff   Jan Kara   quota: Make quota...
1814
  			dquot_free_reserved_space(dquots[cnt], number);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1815
  		else
bf097aaff   Jan Kara   quota: Make quota...
1816
  			dquot_decr_space(dquots[cnt], number);
7b9ca4c61   Jan Kara   quota: Reduce con...
1817
  		spin_unlock(&dquots[cnt]->dq_dqb_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1818
  	}
7b9ca4c61   Jan Kara   quota: Reduce con...
1819
  	if (reserve)
a478e522e   Jan Kara   quota: Inline ino...
1820
  		*inode_reserved_space(inode) -= number;
7b9ca4c61   Jan Kara   quota: Reduce con...
1821
1822
1823
  	else
  		__inode_sub_bytes(inode, number);
  	spin_unlock(&inode->i_lock);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1824
1825
1826
  
  	if (reserve)
  		goto out_unlock;
bf097aaff   Jan Kara   quota: Make quota...
1827
  	mark_all_dquot_dirty(dquots);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1828
  out_unlock:
b9ba6f94b   Niu Yawei   quota: remove dqp...
1829
  	srcu_read_unlock(&dquot_srcu, index);
bf097aaff   Jan Kara   quota: Make quota...
1830
  	flush_warnings(warn);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1831
  }
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1832
  EXPORT_SYMBOL(__dquot_free_space);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1833
1834
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1835
1836
   * This operation can block, but only after everything is updated
   */
6bab3596b   Jan Kara   quota: Remove con...
1837
  void dquot_free_inode(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1838
1839
  {
  	unsigned int cnt;
bf097aaff   Jan Kara   quota: Make quota...
1840
  	struct dquot_warn warn[MAXQUOTAS];
5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1841
  	struct dquot * const *dquots;
b9ba6f94b   Niu Yawei   quota: remove dqp...
1842
  	int index;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1843

189eef59e   Christoph Hellwig   quota: clean up q...
1844
  	if (!dquot_active(inode))
63936ddaa   Christoph Hellwig   dquot: cleanup in...
1845
  		return;
657d3bfa9   Jan Kara   quota: implement ...
1846

5bcd3b6f6   Konstantin Khlebnikov   quota: optimize i...
1847
  	dquots = i_dquot(inode);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1848
  	index = srcu_read_lock(&dquot_srcu);
7b9ca4c61   Jan Kara   quota: Reduce con...
1849
  	spin_lock(&inode->i_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1850
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
bf097aaff   Jan Kara   quota: Make quota...
1851
1852
1853
1854
  		int wtype;
  
  		warn[cnt].w_type = QUOTA_NL_NOWARN;
  		if (!dquots[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1855
  			continue;
7b9ca4c61   Jan Kara   quota: Reduce con...
1856
  		spin_lock(&dquots[cnt]->dq_dqb_lock);
bf097aaff   Jan Kara   quota: Make quota...
1857
1858
1859
1860
  		wtype = info_idq_free(dquots[cnt], 1);
  		if (wtype != QUOTA_NL_NOWARN)
  			prepare_warning(&warn[cnt], dquots[cnt], wtype);
  		dquot_decr_inodes(dquots[cnt], 1);
7b9ca4c61   Jan Kara   quota: Reduce con...
1861
  		spin_unlock(&dquots[cnt]->dq_dqb_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1862
  	}
7b9ca4c61   Jan Kara   quota: Reduce con...
1863
  	spin_unlock(&inode->i_lock);
bf097aaff   Jan Kara   quota: Make quota...
1864
  	mark_all_dquot_dirty(dquots);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1865
  	srcu_read_unlock(&dquot_srcu, index);
bf097aaff   Jan Kara   quota: Make quota...
1866
  	flush_warnings(warn);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1867
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
1868
  EXPORT_SYMBOL(dquot_free_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1869
1870
1871
  
  /*
   * Transfer the number of inode and blocks from one diskquota to an other.
bc8e5f073   Jan Kara   quota: Refactor d...
1872
1873
1874
   * On success, dquot references in transfer_to are consumed and references
   * to original dquots that need to be released are placed there. On failure,
   * references are kept untouched.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1875
1876
1877
   *
   * This operation can block, but only after everything is updated
   * A transaction must be started when entering this function.
bc8e5f073   Jan Kara   quota: Refactor d...
1878
   *
b9ba6f94b   Niu Yawei   quota: remove dqp...
1879
1880
   * We are holding reference on transfer_from & transfer_to, no need to
   * protect them by srcu_read_lock().
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1881
   */
bc8e5f073   Jan Kara   quota: Refactor d...
1882
  int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1883
  {
7b9ca4c61   Jan Kara   quota: Reduce con...
1884
  	qsize_t cur_space;
740d9dcd9   Mingming Cao   quota: Add quota ...
1885
  	qsize_t rsv_space = 0;
7a9ca53ae   Tahsin Erdogan   quota: add get_in...
1886
  	qsize_t inode_usage = 1;
bc8e5f073   Jan Kara   quota: Refactor d...
1887
  	struct dquot *transfer_from[MAXQUOTAS] = {};
efd8f0e6f   Christoph Hellwig   quota: stop using...
1888
  	int cnt, ret = 0;
9e32784b7   Dmitry   quota: fix dquot_...
1889
  	char is_valid[MAXQUOTAS] = {};
bf097aaff   Jan Kara   quota: Make quota...
1890
1891
1892
  	struct dquot_warn warn_to[MAXQUOTAS];
  	struct dquot_warn warn_from_inodes[MAXQUOTAS];
  	struct dquot_warn warn_from_space[MAXQUOTAS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1893

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1894
  	if (IS_NOQUOTA(inode))
efd8f0e6f   Christoph Hellwig   quota: stop using...
1895
  		return 0;
7a9ca53ae   Tahsin Erdogan   quota: add get_in...
1896
1897
1898
1899
1900
1901
  
  	if (inode->i_sb->dq_op->get_inode_usage) {
  		ret = inode->i_sb->dq_op->get_inode_usage(inode, &inode_usage);
  		if (ret)
  			return ret;
  	}
cc33412fb   Jan Kara   quota: Improve lo...
1902
  	/* Initialize the arrays */
bf097aaff   Jan Kara   quota: Make quota...
1903
1904
1905
1906
1907
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		warn_to[cnt].w_type = QUOTA_NL_NOWARN;
  		warn_from_inodes[cnt].w_type = QUOTA_NL_NOWARN;
  		warn_from_space[cnt].w_type = QUOTA_NL_NOWARN;
  	}
b9ba6f94b   Niu Yawei   quota: remove dqp...
1908
1909
  
  	spin_lock(&dq_data_lock);
7b9ca4c61   Jan Kara   quota: Reduce con...
1910
  	spin_lock(&inode->i_lock);
cc33412fb   Jan Kara   quota: Improve lo...
1911
  	if (IS_NOQUOTA(inode)) {	/* File without quota accounting? */
7b9ca4c61   Jan Kara   quota: Reduce con...
1912
  		spin_unlock(&inode->i_lock);
b9ba6f94b   Niu Yawei   quota: remove dqp...
1913
  		spin_unlock(&dq_data_lock);
bc8e5f073   Jan Kara   quota: Refactor d...
1914
  		return 0;
cc33412fb   Jan Kara   quota: Improve lo...
1915
  	}
7b9ca4c61   Jan Kara   quota: Reduce con...
1916
1917
1918
1919
1920
1921
  	cur_space = __inode_get_bytes(inode);
  	rsv_space = __inode_get_rsv_space(inode);
  	/*
  	 * Build the transfer_from list, check limits, and update usage in
  	 * the target structures.
  	 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1922
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
9e32784b7   Dmitry   quota: fix dquot_...
1923
1924
1925
  		/*
  		 * Skip changes for same uid or gid or for turned off quota-type.
  		 */
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1926
  		if (!transfer_to[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1927
  			continue;
9e32784b7   Dmitry   quota: fix dquot_...
1928
1929
1930
1931
  		/* Avoid races with quotaoff() */
  		if (!sb_has_quota_active(inode->i_sb, cnt))
  			continue;
  		is_valid[cnt] = 1;
2d0fa4679   Jan Kara   quota: Use functi...
1932
  		transfer_from[cnt] = i_dquot(inode)[cnt];
7b9ca4c61   Jan Kara   quota: Reduce con...
1933
1934
  		ret = dquot_add_inodes(transfer_to[cnt], inode_usage,
  				       &warn_to[cnt]);
efd8f0e6f   Christoph Hellwig   quota: stop using...
1935
1936
  		if (ret)
  			goto over_quota;
c6d9c35d1   yangerkun   quota: fix a prob...
1937
1938
  		ret = dquot_add_space(transfer_to[cnt], cur_space, rsv_space,
  				      DQUOT_SPACE_WARN, &warn_to[cnt]);
7b9ca4c61   Jan Kara   quota: Reduce con...
1939
  		if (ret) {
0a51fb717   Konstantin Khlebnikov   quota: add missin...
1940
  			spin_lock(&transfer_to[cnt]->dq_dqb_lock);
7b9ca4c61   Jan Kara   quota: Reduce con...
1941
  			dquot_decr_inodes(transfer_to[cnt], inode_usage);
0a51fb717   Konstantin Khlebnikov   quota: add missin...
1942
  			spin_unlock(&transfer_to[cnt]->dq_dqb_lock);
cc33412fb   Jan Kara   quota: Improve lo...
1943
  			goto over_quota;
7b9ca4c61   Jan Kara   quota: Reduce con...
1944
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1945
  	}
7b9ca4c61   Jan Kara   quota: Reduce con...
1946
  	/* Decrease usage for source structures and update quota pointers */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1947
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
9e32784b7   Dmitry   quota: fix dquot_...
1948
  		if (!is_valid[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1949
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1950
1951
  		/* Due to IO error we might not have transfer_from[] structure */
  		if (transfer_from[cnt]) {
bf097aaff   Jan Kara   quota: Make quota...
1952
  			int wtype;
7b9ca4c61   Jan Kara   quota: Reduce con...
1953
1954
  
  			spin_lock(&transfer_from[cnt]->dq_dqb_lock);
7a9ca53ae   Tahsin Erdogan   quota: add get_in...
1955
  			wtype = info_idq_free(transfer_from[cnt], inode_usage);
bf097aaff   Jan Kara   quota: Make quota...
1956
1957
1958
  			if (wtype != QUOTA_NL_NOWARN)
  				prepare_warning(&warn_from_inodes[cnt],
  						transfer_from[cnt], wtype);
7b9ca4c61   Jan Kara   quota: Reduce con...
1959
1960
  			wtype = info_bdq_free(transfer_from[cnt],
  					      cur_space + rsv_space);
bf097aaff   Jan Kara   quota: Make quota...
1961
1962
1963
  			if (wtype != QUOTA_NL_NOWARN)
  				prepare_warning(&warn_from_space[cnt],
  						transfer_from[cnt], wtype);
7a9ca53ae   Tahsin Erdogan   quota: add get_in...
1964
  			dquot_decr_inodes(transfer_from[cnt], inode_usage);
740d9dcd9   Mingming Cao   quota: Add quota ...
1965
1966
1967
  			dquot_decr_space(transfer_from[cnt], cur_space);
  			dquot_free_reserved_space(transfer_from[cnt],
  						  rsv_space);
7b9ca4c61   Jan Kara   quota: Reduce con...
1968
  			spin_unlock(&transfer_from[cnt]->dq_dqb_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1969
  		}
2d0fa4679   Jan Kara   quota: Use functi...
1970
  		i_dquot(inode)[cnt] = transfer_to[cnt];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1971
  	}
7b9ca4c61   Jan Kara   quota: Reduce con...
1972
  	spin_unlock(&inode->i_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1973
  	spin_unlock(&dq_data_lock);
cc33412fb   Jan Kara   quota: Improve lo...
1974

dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1975
1976
  	mark_all_dquot_dirty(transfer_from);
  	mark_all_dquot_dirty(transfer_to);
bf097aaff   Jan Kara   quota: Make quota...
1977
1978
1979
  	flush_warnings(warn_to);
  	flush_warnings(warn_from_inodes);
  	flush_warnings(warn_from_space);
bc8e5f073   Jan Kara   quota: Refactor d...
1980
  	/* Pass back references to put */
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1981
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
9e32784b7   Dmitry   quota: fix dquot_...
1982
1983
  		if (is_valid[cnt])
  			transfer_to[cnt] = transfer_from[cnt];
86f3cbec4   Jan Kara   quota: Fix issuin...
1984
  	return 0;
cc33412fb   Jan Kara   quota: Improve lo...
1985
  over_quota:
7b9ca4c61   Jan Kara   quota: Reduce con...
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
  	/* Back out changes we already did */
  	for (cnt--; cnt >= 0; cnt--) {
  		if (!is_valid[cnt])
  			continue;
  		spin_lock(&transfer_to[cnt]->dq_dqb_lock);
  		dquot_decr_inodes(transfer_to[cnt], inode_usage);
  		dquot_decr_space(transfer_to[cnt], cur_space);
  		dquot_free_reserved_space(transfer_to[cnt], rsv_space);
  		spin_unlock(&transfer_to[cnt]->dq_dqb_lock);
  	}
  	spin_unlock(&inode->i_lock);
cc33412fb   Jan Kara   quota: Improve lo...
1997
  	spin_unlock(&dq_data_lock);
bf097aaff   Jan Kara   quota: Make quota...
1998
  	flush_warnings(warn_to);
86f3cbec4   Jan Kara   quota: Fix issuin...
1999
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2000
  }
bc8e5f073   Jan Kara   quota: Refactor d...
2001
  EXPORT_SYMBOL(__dquot_transfer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2002

8ddd69d6d   Dmitry Monakhov   quota: generalize...
2003
2004
2005
  /* Wrapper for transferring ownership of an inode for uid/gid only
   * Called from FSXXX_setattr()
   */
b43fa8284   Christoph Hellwig   dquot: cleanup dq...
2006
  int dquot_transfer(struct inode *inode, struct iattr *iattr)
b85f4b87a   Jan Kara   quota: rename quo...
2007
  {
bc8e5f073   Jan Kara   quota: Refactor d...
2008
  	struct dquot *transfer_to[MAXQUOTAS] = {};
6184fc0b8   Jan Kara   quota: Propagate ...
2009
  	struct dquot *dquot;
bc8e5f073   Jan Kara   quota: Refactor d...
2010
2011
  	struct super_block *sb = inode->i_sb;
  	int ret;
8ddd69d6d   Dmitry Monakhov   quota: generalize...
2012

189eef59e   Christoph Hellwig   quota: clean up q...
2013
  	if (!dquot_active(inode))
bc8e5f073   Jan Kara   quota: Refactor d...
2014
  		return 0;
12755627b   Dmitry Monakhov   quota: unify quot...
2015

6184fc0b8   Jan Kara   quota: Propagate ...
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
  	if (iattr->ia_valid & ATTR_UID && !uid_eq(iattr->ia_uid, inode->i_uid)){
  		dquot = dqget(sb, make_kqid_uid(iattr->ia_uid));
  		if (IS_ERR(dquot)) {
  			if (PTR_ERR(dquot) != -ESRCH) {
  				ret = PTR_ERR(dquot);
  				goto out_put;
  			}
  			dquot = NULL;
  		}
  		transfer_to[USRQUOTA] = dquot;
  	}
  	if (iattr->ia_valid & ATTR_GID && !gid_eq(iattr->ia_gid, inode->i_gid)){
  		dquot = dqget(sb, make_kqid_gid(iattr->ia_gid));
  		if (IS_ERR(dquot)) {
  			if (PTR_ERR(dquot) != -ESRCH) {
  				ret = PTR_ERR(dquot);
  				goto out_put;
  			}
  			dquot = NULL;
  		}
  		transfer_to[GRPQUOTA] = dquot;
  	}
bc8e5f073   Jan Kara   quota: Refactor d...
2038
  	ret = __dquot_transfer(inode, transfer_to);
6184fc0b8   Jan Kara   quota: Propagate ...
2039
  out_put:
bc8e5f073   Jan Kara   quota: Refactor d...
2040
2041
  	dqput_all(transfer_to);
  	return ret;
b85f4b87a   Jan Kara   quota: rename quo...
2042
  }
b43fa8284   Christoph Hellwig   dquot: cleanup dq...
2043
  EXPORT_SYMBOL(dquot_transfer);
b85f4b87a   Jan Kara   quota: rename quo...
2044

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2045
2046
2047
2048
2049
  /*
   * Write info of quota file to disk
   */
  int dquot_commit_info(struct super_block *sb, int type)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2050
  	struct quota_info *dqopt = sb_dqopt(sb);
9a8ae30e7   Jan Kara   quota: Push dqio_...
2051
  	return dqopt->ops[type]->write_file_info(sb, type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2052
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
2053
  EXPORT_SYMBOL(dquot_commit_info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2054

be6257b25   Jan Kara   quota: Add suppor...
2055
2056
2057
  int dquot_get_next_id(struct super_block *sb, struct kqid *qid)
  {
  	struct quota_info *dqopt = sb_dqopt(sb);
be6257b25   Jan Kara   quota: Add suppor...
2058

9d1ccbe70   Jan Kara   quota: Use s_umou...
2059
2060
2061
2062
  	if (!sb_has_quota_active(sb, qid->type))
  		return -ESRCH;
  	if (!dqopt->ops[qid->type]->get_next_id)
  		return -ENOSYS;
f14618c68   Jan Kara   quota: Push dqio_...
2063
  	return dqopt->ops[qid->type]->get_next_id(sb, qid);
be6257b25   Jan Kara   quota: Add suppor...
2064
2065
  }
  EXPORT_SYMBOL(dquot_get_next_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2066
2067
2068
  /*
   * Definitions of diskquota operations.
   */
61e225dc3   Alexey Dobriyan   const: make struc...
2069
  const struct dquot_operations dquot_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2070
2071
2072
2073
  	.write_dquot	= dquot_commit,
  	.acquire_dquot	= dquot_acquire,
  	.release_dquot	= dquot_release,
  	.mark_dirty	= dquot_mark_dquot_dirty,
74f783af9   Jan Kara   quota: Add callba...
2074
2075
2076
  	.write_info	= dquot_commit_info,
  	.alloc_dquot	= dquot_alloc,
  	.destroy_dquot	= dquot_destroy,
be6257b25   Jan Kara   quota: Add suppor...
2077
  	.get_next_id	= dquot_get_next_id,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2078
  };
123e9caf1   Christoph Hellwig   quota: explicitly...
2079
  EXPORT_SYMBOL(dquot_operations);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2080

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2081
  /*
907f4554e   Christoph Hellwig   dquot: move dquot...
2082
2083
2084
2085
2086
2087
2088
2089
   * Generic helper for ->open on filesystems supporting disk quotas.
   */
  int dquot_file_open(struct inode *inode, struct file *file)
  {
  	int error;
  
  	error = generic_file_open(inode, file);
  	if (!error && (file->f_mode & FMODE_WRITE))
88d8ff976   Chao Yu   quota: be aware o...
2090
  		error = dquot_initialize(inode);
907f4554e   Christoph Hellwig   dquot: move dquot...
2091
2092
2093
  	return error;
  }
  EXPORT_SYMBOL(dquot_file_open);
2ec1f3011   Jan Kara   quota: Make dquot...
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
  static void vfs_cleanup_quota_inode(struct super_block *sb, int type)
  {
  	struct quota_info *dqopt = sb_dqopt(sb);
  	struct inode *inode = dqopt->files[type];
  
  	if (!inode)
  		return;
  	if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
  		inode_lock(inode);
  		inode->i_flags &= ~S_NOQUOTA;
  		inode_unlock(inode);
  	}
  	dqopt->files[type] = NULL;
  	iput(inode);
  }
907f4554e   Christoph Hellwig   dquot: move dquot...
2109
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2110
2111
   * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
   */
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2112
  int dquot_disable(struct super_block *sb, int type, unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2113
  {
2ec1f3011   Jan Kara   quota: Make dquot...
2114
  	int cnt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2115
  	struct quota_info *dqopt = sb_dqopt(sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2116

7d6cd73d3   Jan Kara   quota: Hold s_umo...
2117
2118
2119
  	/* s_umount should be held in exclusive mode */
  	if (WARN_ON_ONCE(down_read_trylock(&sb->s_umount)))
  		up_read(&sb->s_umount);
f55abc0fb   Jan Kara   quota: Allow to s...
2120
2121
2122
2123
2124
2125
  	/* Cannot turn off usage accounting without turning off limits, or
  	 * suspend quotas and simultaneously turn quotas off. */
  	if ((flags & DQUOT_USAGE_ENABLED && !(flags & DQUOT_LIMITS_ENABLED))
  	    || (flags & DQUOT_SUSPENDED && flags & (DQUOT_LIMITS_ENABLED |
  	    DQUOT_USAGE_ENABLED)))
  		return -EINVAL;
9377abd02   Jan Kara   quota: don't call...
2126
2127
2128
2129
2130
  	/*
  	 * Skip everything if there's nothing to do. We have to do this because
  	 * sometimes we are called when fill_super() failed and calling
  	 * sync_fs() in such cases does no good.
  	 */
c3b004460   Jan Kara   quota: Remove dqo...
2131
  	if (!sb_any_quota_loaded(sb))
9377abd02   Jan Kara   quota: don't call...
2132
  		return 0;
c3b004460   Jan Kara   quota: Remove dqo...
2133

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2134
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2135
2136
  		if (type != -1 && cnt != type)
  			continue;
f55abc0fb   Jan Kara   quota: Allow to s...
2137
  		if (!sb_has_quota_loaded(sb, cnt))
0ff5af834   Jan Kara   quota: quota core...
2138
  			continue;
f55abc0fb   Jan Kara   quota: Allow to s...
2139
2140
  
  		if (flags & DQUOT_SUSPENDED) {
cc33412fb   Jan Kara   quota: Improve lo...
2141
  			spin_lock(&dq_state_lock);
f55abc0fb   Jan Kara   quota: Allow to s...
2142
2143
  			dqopt->flags |=
  				dquot_state_flag(DQUOT_SUSPENDED, cnt);
cc33412fb   Jan Kara   quota: Improve lo...
2144
  			spin_unlock(&dq_state_lock);
f55abc0fb   Jan Kara   quota: Allow to s...
2145
  		} else {
cc33412fb   Jan Kara   quota: Improve lo...
2146
  			spin_lock(&dq_state_lock);
f55abc0fb   Jan Kara   quota: Allow to s...
2147
2148
2149
2150
2151
2152
  			dqopt->flags &= ~dquot_state_flag(flags, cnt);
  			/* Turning off suspended quotas? */
  			if (!sb_has_quota_loaded(sb, cnt) &&
  			    sb_has_quota_suspended(sb, cnt)) {
  				dqopt->flags &=	~dquot_state_flag(
  							DQUOT_SUSPENDED, cnt);
cc33412fb   Jan Kara   quota: Improve lo...
2153
  				spin_unlock(&dq_state_lock);
2ec1f3011   Jan Kara   quota: Make dquot...
2154
  				vfs_cleanup_quota_inode(sb, cnt);
f55abc0fb   Jan Kara   quota: Allow to s...
2155
2156
  				continue;
  			}
cc33412fb   Jan Kara   quota: Improve lo...
2157
  			spin_unlock(&dq_state_lock);
0ff5af834   Jan Kara   quota: quota core...
2158
  		}
f55abc0fb   Jan Kara   quota: Allow to s...
2159
2160
2161
  
  		/* We still have to keep quota loaded? */
  		if (sb_has_quota_loaded(sb, cnt) && !(flags & DQUOT_SUSPENDED))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2162
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2163
2164
2165
2166
2167
  
  		/* Note: these are blocking operations */
  		drop_dquot_ref(sb, cnt);
  		invalidate_dquots(sb, cnt);
  		/*
268157ba6   Jan Kara   quota: Coding sty...
2168
2169
  		 * Now all dquots should be invalidated, all writes done so we
  		 * should be only users of the info. No locks needed.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2170
2171
2172
2173
2174
2175
  		 */
  		if (info_dirty(&dqopt->info[cnt]))
  			sb->dq_op->write_info(sb, cnt);
  		if (dqopt->ops[cnt]->free_file_info)
  			dqopt->ops[cnt]->free_file_info(sb, cnt);
  		put_quota_format(dqopt->info[cnt].dqi_format);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2176
2177
2178
2179
2180
  		dqopt->info[cnt].dqi_flags = 0;
  		dqopt->info[cnt].dqi_igrace = 0;
  		dqopt->info[cnt].dqi_bgrace = 0;
  		dqopt->ops[cnt] = NULL;
  	}
ca785ec66   Jan Kara   quota: Introduce ...
2181
2182
2183
2184
  
  	/* Skip syncing and setting flags if quota files are hidden */
  	if (dqopt->flags & DQUOT_QUOTA_SYS_FILE)
  		goto put_inodes;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2185
  	/* Sync the superblock so that buffers with quota data are written to
7b7b1ace2   Al Viro   [PATCH] saner han...
2186
  	 * disk (and so userspace sees correct data afterwards). */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2187
2188
2189
2190
2191
2192
2193
2194
2195
  	if (sb->s_op->sync_fs)
  		sb->s_op->sync_fs(sb, 1);
  	sync_blockdev(sb->s_bdev);
  	/* Now the quota files are just ordinary files and we can set the
  	 * inode flags back. Moreover we discard the pagecache so that
  	 * userspace sees the writes we did bypassing the pagecache. We
  	 * must also discard the blockdev buffers so that we see the
  	 * changes done by userspace on the next quotaon() */
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
2ec1f3011   Jan Kara   quota: Make dquot...
2196
2197
2198
2199
  		if (!sb_has_quota_loaded(sb, cnt) && dqopt->files[cnt]) {
  			inode_lock(dqopt->files[cnt]);
  			truncate_inode_pages(&dqopt->files[cnt]->i_data, 0);
  			inode_unlock(dqopt->files[cnt]);
ca785ec66   Jan Kara   quota: Introduce ...
2200
2201
2202
2203
  		}
  	if (sb->s_bdev)
  		invalidate_bdev(sb->s_bdev);
  put_inodes:
2ec1f3011   Jan Kara   quota: Make dquot...
2204
2205
2206
  	/* We are done when suspending quotas */
  	if (flags & DQUOT_SUSPENDED)
  		return 0;
ca785ec66   Jan Kara   quota: Introduce ...
2207
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
2ec1f3011   Jan Kara   quota: Make dquot...
2208
2209
2210
  		if (!sb_has_quota_loaded(sb, cnt))
  			vfs_cleanup_quota_inode(sb, cnt);
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2211
  }
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2212
  EXPORT_SYMBOL(dquot_disable);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2213

287a80958   Christoph Hellwig   quota: rename def...
2214
  int dquot_quota_off(struct super_block *sb, int type)
f55abc0fb   Jan Kara   quota: Allow to s...
2215
  {
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2216
2217
  	return dquot_disable(sb, type,
  			     DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
f55abc0fb   Jan Kara   quota: Allow to s...
2218
  }
287a80958   Christoph Hellwig   quota: rename def...
2219
  EXPORT_SYMBOL(dquot_quota_off);
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2220

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2221
2222
2223
  /*
   *	Turn quotas on on a device
   */
c7d3d2836   Jan Kara   quota: Factor out...
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
  static int vfs_setup_quota_inode(struct inode *inode, int type)
  {
  	struct super_block *sb = inode->i_sb;
  	struct quota_info *dqopt = sb_dqopt(sb);
  
  	if (!S_ISREG(inode->i_mode))
  		return -EACCES;
  	if (IS_RDONLY(inode))
  		return -EROFS;
  	if (sb_has_quota_loaded(sb, type))
  		return -EBUSY;
  
  	dqopt->files[type] = igrab(inode);
  	if (!dqopt->files[type])
  		return -EIO;
  	if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
  		/* We don't want quota and atime on quota files (deadlocks
  		 * possible) Also nobody should write to the file - we use
  		 * special IO operations which ignore the immutable bit. */
  		inode_lock(inode);
  		inode->i_flags |= S_NOQUOTA;
  		inode_unlock(inode);
  		/*
  		 * When S_NOQUOTA is set, remove dquot references as no more
  		 * references can be added
  		 */
  		__dquot_drop(inode);
  	}
  	return 0;
  }
c7d3d2836   Jan Kara   quota: Factor out...
2254
  int dquot_load_quota_sb(struct super_block *sb, int type, int format_id,
f55abc0fb   Jan Kara   quota: Allow to s...
2255
  	unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2256
2257
  {
  	struct quota_format_type *fmt = find_quota_format(format_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2258
2259
  	struct quota_info *dqopt = sb_dqopt(sb);
  	int error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2260

dc19432ae   Jan Kara   quota: Rename vfs...
2261
2262
2263
2264
2265
  	/* Just unsuspend quotas? */
  	BUG_ON(flags & DQUOT_SUSPENDED);
  	/* s_umount should be held in exclusive mode */
  	if (WARN_ON_ONCE(down_read_trylock(&sb->s_umount)))
  		up_read(&sb->s_umount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2266
2267
  	if (!fmt)
  		return -ESRCH;
847aac644   Li Xi   vfs: Add general ...
2268
2269
  	if (!sb->s_op->quota_write || !sb->s_op->quota_read ||
  	    (type == PRJQUOTA && sb->dq_op->get_projid == NULL)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2270
2271
2272
  		error = -EINVAL;
  		goto out_fmt;
  	}
5c0048280   Eric W. Biederman   dquot: For now ex...
2273
2274
2275
2276
2277
  	/* Filesystems outside of init_user_ns not yet supported */
  	if (sb->s_user_ns != &init_user_ns) {
  		error = -EINVAL;
  		goto out_fmt;
  	}
f55abc0fb   Jan Kara   quota: Allow to s...
2278
2279
2280
2281
2282
  	/* Usage always has to be set... */
  	if (!(flags & DQUOT_USAGE_ENABLED)) {
  		error = -EINVAL;
  		goto out_fmt;
  	}
c3b004460   Jan Kara   quota: Remove dqo...
2283
2284
2285
2286
  	if (sb_has_quota_loaded(sb, type)) {
  		error = -EBUSY;
  		goto out_fmt;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2287

ca785ec66   Jan Kara   quota: Introduce ...
2288
  	if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
ab94c39b6   Jan Kara   quota: Properly i...
2289
2290
2291
2292
2293
2294
2295
  		/* As we bypass the pagecache we must now flush all the
  		 * dirty data and invalidate caches so that kernel sees
  		 * changes from userspace. It is not enough to just flush
  		 * the quota file since if blocksize < pagesize, invalidation
  		 * of the cache could fail because of other unrelated dirty
  		 * data */
  		sync_filesystem(sb);
ca785ec66   Jan Kara   quota: Introduce ...
2296
2297
  		invalidate_bdev(sb->s_bdev);
  	}
ca785ec66   Jan Kara   quota: Introduce ...
2298

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2299
2300
  	error = -EINVAL;
  	if (!fmt->qf_ops->check_quota_file(sb, type))
c7d3d2836   Jan Kara   quota: Factor out...
2301
  		goto out_fmt;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2302
2303
2304
  
  	dqopt->ops[type] = fmt->qf_ops;
  	dqopt->info[type].dqi_format = fmt;
0ff5af834   Jan Kara   quota: quota core...
2305
  	dqopt->info[type].dqi_fmt_id = format_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2306
  	INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
268157ba6   Jan Kara   quota: Coding sty...
2307
  	error = dqopt->ops[type]->read_file_info(sb, type);
42fdb8583   Jan Kara   quota: Push dqio_...
2308
  	if (error < 0)
c7d3d2836   Jan Kara   quota: Factor out...
2309
  		goto out_fmt;
15512377b   Jan Kara   quota: Fix possib...
2310
2311
  	if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) {
  		spin_lock(&dq_data_lock);
46fe44ce8   Jan Kara   quota: Pass infor...
2312
  		dqopt->info[type].dqi_flags |= DQF_SYS_FILE;
15512377b   Jan Kara   quota: Fix possib...
2313
2314
  		spin_unlock(&dq_data_lock);
  	}
cc33412fb   Jan Kara   quota: Improve lo...
2315
  	spin_lock(&dq_state_lock);
f55abc0fb   Jan Kara   quota: Allow to s...
2316
  	dqopt->flags |= dquot_state_flag(flags, type);
cc33412fb   Jan Kara   quota: Improve lo...
2317
  	spin_unlock(&dq_state_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2318

1a6152d36   Chao Yu   quota: propagate ...
2319
2320
2321
  	error = add_dquot_ref(sb, type);
  	if (error)
  		dquot_disable(sb, type, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2322

1a6152d36   Chao Yu   quota: propagate ...
2323
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2324
2325
  out_fmt:
  	put_quota_format(fmt);
27942ef50   Sascha Hauer   quota: remove tra...
2326
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2327
  }
c7d3d2836   Jan Kara   quota: Factor out...
2328
2329
2330
  EXPORT_SYMBOL(dquot_load_quota_sb);
  
  /*
dc19432ae   Jan Kara   quota: Rename vfs...
2331
2332
   * More powerful function for turning on quotas on given quota inode allowing
   * setting of individual quota flags
c7d3d2836   Jan Kara   quota: Factor out...
2333
   */
dc19432ae   Jan Kara   quota: Rename vfs...
2334
  int dquot_load_quota_inode(struct inode *inode, int type, int format_id,
c7d3d2836   Jan Kara   quota: Factor out...
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
  	unsigned int flags)
  {
  	int err;
  
  	err = vfs_setup_quota_inode(inode, type);
  	if (err < 0)
  		return err;
  	err = dquot_load_quota_sb(inode->i_sb, type, format_id, flags);
  	if (err < 0)
  		vfs_cleanup_quota_inode(inode->i_sb, type);
  	return err;
  }
dc19432ae   Jan Kara   quota: Rename vfs...
2347
  EXPORT_SYMBOL(dquot_load_quota_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2348

0ff5af834   Jan Kara   quota: quota core...
2349
  /* Reenable quotas on remount RW */
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2350
  int dquot_resume(struct super_block *sb, int type)
0ff5af834   Jan Kara   quota: quota core...
2351
2352
  {
  	struct quota_info *dqopt = sb_dqopt(sb);
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2353
  	int ret = 0, cnt;
f55abc0fb   Jan Kara   quota: Allow to s...
2354
  	unsigned int flags;
0ff5af834   Jan Kara   quota: quota core...
2355

7d6cd73d3   Jan Kara   quota: Hold s_umo...
2356
2357
2358
  	/* s_umount should be held in exclusive mode */
  	if (WARN_ON_ONCE(down_read_trylock(&sb->s_umount)))
  		up_read(&sb->s_umount);
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2359
2360
2361
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		if (type != -1 && cnt != type)
  			continue;
c3b004460   Jan Kara   quota: Remove dqo...
2362
  		if (!sb_has_quota_suspended(sb, cnt))
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2363
  			continue;
c3b004460   Jan Kara   quota: Remove dqo...
2364

0f0dd62fd   Christoph Hellwig   quota: kill the v...
2365
2366
2367
2368
2369
2370
  		spin_lock(&dq_state_lock);
  		flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED |
  							DQUOT_LIMITS_ENABLED,
  							cnt);
  		dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, cnt);
  		spin_unlock(&dq_state_lock);
0ff5af834   Jan Kara   quota: quota core...
2371

0f0dd62fd   Christoph Hellwig   quota: kill the v...
2372
  		flags = dquot_generic_flag(flags, cnt);
ae45f07d4   Jan Kara   quota: Simplify d...
2373
2374
2375
2376
  		ret = dquot_load_quota_sb(sb, cnt, dqopt->info[cnt].dqi_fmt_id,
  					  flags);
  		if (ret < 0)
  			vfs_cleanup_quota_inode(sb, type);
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2377
  	}
0ff5af834   Jan Kara   quota: quota core...
2378
2379
2380
  
  	return ret;
  }
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2381
  EXPORT_SYMBOL(dquot_resume);
0ff5af834   Jan Kara   quota: quota core...
2382

f00c9e44a   Jan Kara   quota: Fix deadlo...
2383
  int dquot_quota_on(struct super_block *sb, int type, int format_id,
8c54ca9c6   Al Viro   quota: constify s...
2384
  		   const struct path *path)
77e69dac3   Al Viro   [PATCH] fix races...
2385
2386
2387
2388
2389
  {
  	int error = security_quota_on(path->dentry);
  	if (error)
  		return error;
  	/* Quota file not on the same filesystem? */
d8c9584ea   Al Viro   vfs: prefer ->den...
2390
  	if (path->dentry->d_sb != sb)
77e69dac3   Al Viro   [PATCH] fix races...
2391
2392
  		error = -EXDEV;
  	else
dc19432ae   Jan Kara   quota: Rename vfs...
2393
  		error = dquot_load_quota_inode(d_inode(path->dentry), type,
f55abc0fb   Jan Kara   quota: Allow to s...
2394
2395
  					     format_id, DQUOT_USAGE_ENABLED |
  					     DQUOT_LIMITS_ENABLED);
77e69dac3   Al Viro   [PATCH] fix races...
2396
2397
  	return error;
  }
287a80958   Christoph Hellwig   quota: rename def...
2398
  EXPORT_SYMBOL(dquot_quota_on);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2399
2400
2401
2402
2403
  
  /*
   * This function is used when filesystem needs to initialize quotas
   * during mount time.
   */
287a80958   Christoph Hellwig   quota: rename def...
2404
  int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
84de856ed   Christoph Hellwig   [PATCH] quota: co...
2405
  		int format_id, int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2406
  {
84de856ed   Christoph Hellwig   [PATCH] quota: co...
2407
  	struct dentry *dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2408
  	int error;
6c2d4798a   Al Viro   new helper: looku...
2409
  	dentry = lookup_positive_unlocked(qf_name, sb->s_root, strlen(qf_name));
84de856ed   Christoph Hellwig   [PATCH] quota: co...
2410
2411
  	if (IS_ERR(dentry))
  		return PTR_ERR(dentry);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2412
  	error = security_quota_on(dentry);
84de856ed   Christoph Hellwig   [PATCH] quota: co...
2413
  	if (!error)
dc19432ae   Jan Kara   quota: Rename vfs...
2414
  		error = dquot_load_quota_inode(d_inode(dentry), type, format_id,
f55abc0fb   Jan Kara   quota: Allow to s...
2415
  				DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
84de856ed   Christoph Hellwig   [PATCH] quota: co...
2416

84de856ed   Christoph Hellwig   [PATCH] quota: co...
2417
2418
  	dput(dentry);
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2419
  }
287a80958   Christoph Hellwig   quota: rename def...
2420
  EXPORT_SYMBOL(dquot_quota_on_mount);
b85f4b87a   Jan Kara   quota: rename quo...
2421

3e2af67e6   Jan Kara   quota: Add ->quot...
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
  static int dquot_quota_enable(struct super_block *sb, unsigned int flags)
  {
  	int ret;
  	int type;
  	struct quota_info *dqopt = sb_dqopt(sb);
  
  	if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE))
  		return -ENOSYS;
  	/* Accounting cannot be turned on while fs is mounted */
  	flags &= ~(FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT | FS_QUOTA_PDQ_ACCT);
  	if (!flags)
  		return -EINVAL;
  	for (type = 0; type < MAXQUOTAS; type++) {
  		if (!(flags & qtype_enforce_flag(type)))
  			continue;
  		/* Can't enforce without accounting */
069a91663   Jan Kara   quota: Drop dquot...
2438
2439
2440
2441
2442
2443
  		if (!sb_has_quota_usage_enabled(sb, type)) {
  			ret = -EINVAL;
  			goto out_err;
  		}
  		if (sb_has_quota_limits_enabled(sb, type)) {
  			ret = -EBUSY;
3e2af67e6   Jan Kara   quota: Add ->quot...
2444
  			goto out_err;
069a91663   Jan Kara   quota: Drop dquot...
2445
2446
2447
2448
  		}
  		spin_lock(&dq_state_lock);
  		dqopt->flags |= dquot_state_flag(DQUOT_LIMITS_ENABLED, type);
  		spin_unlock(&dq_state_lock);
3e2af67e6   Jan Kara   quota: Add ->quot...
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
  	}
  	return 0;
  out_err:
  	/* Backout enforcement enablement we already did */
  	for (type--; type >= 0; type--)  {
  		if (flags & qtype_enforce_flag(type))
  			dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
  	}
  	/* Error code translation for better compatibility with XFS */
  	if (ret == -EBUSY)
  		ret = -EEXIST;
  	return ret;
  }
  
  static int dquot_quota_disable(struct super_block *sb, unsigned int flags)
  {
  	int ret;
  	int type;
  	struct quota_info *dqopt = sb_dqopt(sb);
  
  	if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE))
  		return -ENOSYS;
  	/*
  	 * We don't support turning off accounting via quotactl. In principle
  	 * quota infrastructure can do this but filesystems don't expect
  	 * userspace to be able to do it.
  	 */
  	if (flags &
  		  (FS_QUOTA_UDQ_ACCT | FS_QUOTA_GDQ_ACCT | FS_QUOTA_PDQ_ACCT))
  		return -EOPNOTSUPP;
  
  	/* Filter out limits not enabled */
  	for (type = 0; type < MAXQUOTAS; type++)
  		if (!sb_has_quota_limits_enabled(sb, type))
  			flags &= ~qtype_enforce_flag(type);
  	/* Nothing left? */
  	if (!flags)
  		return -EEXIST;
  	for (type = 0; type < MAXQUOTAS; type++) {
  		if (flags & qtype_enforce_flag(type)) {
  			ret = dquot_disable(sb, type, DQUOT_LIMITS_ENABLED);
  			if (ret < 0)
  				goto out_err;
  		}
  	}
  	return 0;
  out_err:
  	/* Backout enforcement disabling we already did */
  	for (type--; type >= 0; type--)  {
069a91663   Jan Kara   quota: Drop dquot...
2498
2499
2500
2501
2502
2503
  		if (flags & qtype_enforce_flag(type)) {
  			spin_lock(&dq_state_lock);
  			dqopt->flags |=
  				dquot_state_flag(DQUOT_LIMITS_ENABLED, type);
  			spin_unlock(&dq_state_lock);
  		}
3e2af67e6   Jan Kara   quota: Add ->quot...
2504
2505
2506
  	}
  	return ret;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2507
  /* Generic routine for getting common part of quota structure */
14bf61ffe   Jan Kara   quota: Switch ->g...
2508
  static void do_get_dqblk(struct dquot *dquot, struct qc_dqblk *di)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2509
2510
  {
  	struct mem_dqblk *dm = &dquot->dq_dqb;
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
2511
  	memset(di, 0, sizeof(*di));
7b9ca4c61   Jan Kara   quota: Reduce con...
2512
  	spin_lock(&dquot->dq_dqb_lock);
14bf61ffe   Jan Kara   quota: Switch ->g...
2513
2514
  	di->d_spc_hardlimit = dm->dqb_bhardlimit;
  	di->d_spc_softlimit = dm->dqb_bsoftlimit;
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
2515
2516
  	di->d_ino_hardlimit = dm->dqb_ihardlimit;
  	di->d_ino_softlimit = dm->dqb_isoftlimit;
14bf61ffe   Jan Kara   quota: Switch ->g...
2517
2518
2519
2520
  	di->d_space = dm->dqb_curspace + dm->dqb_rsvspace;
  	di->d_ino_count = dm->dqb_curinodes;
  	di->d_spc_timer = dm->dqb_btime;
  	di->d_ino_timer = dm->dqb_itime;
7b9ca4c61   Jan Kara   quota: Reduce con...
2521
  	spin_unlock(&dquot->dq_dqb_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2522
  }
74a8a1037   Eric W. Biederman   userns: Convert q...
2523
  int dquot_get_dqblk(struct super_block *sb, struct kqid qid,
14bf61ffe   Jan Kara   quota: Switch ->g...
2524
  		    struct qc_dqblk *di)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2525
2526
  {
  	struct dquot *dquot;
aca645a6a   Eric W. Biederman   userns: Modify dq...
2527
  	dquot = dqget(sb, qid);
6184fc0b8   Jan Kara   quota: Propagate ...
2528
2529
  	if (IS_ERR(dquot))
  		return PTR_ERR(dquot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2530
2531
  	do_get_dqblk(dquot, di);
  	dqput(dquot);
cc33412fb   Jan Kara   quota: Improve lo...
2532

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2533
2534
  	return 0;
  }
287a80958   Christoph Hellwig   quota: rename def...
2535
  EXPORT_SYMBOL(dquot_get_dqblk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2536

be6257b25   Jan Kara   quota: Add suppor...
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
  int dquot_get_next_dqblk(struct super_block *sb, struct kqid *qid,
  			 struct qc_dqblk *di)
  {
  	struct dquot *dquot;
  	int err;
  
  	if (!sb->dq_op->get_next_id)
  		return -ENOSYS;
  	err = sb->dq_op->get_next_id(sb, qid);
  	if (err < 0)
  		return err;
  	dquot = dqget(sb, *qid);
  	if (IS_ERR(dquot))
  		return PTR_ERR(dquot);
  	do_get_dqblk(dquot, di);
  	dqput(dquot);
  
  	return 0;
  }
  EXPORT_SYMBOL(dquot_get_next_dqblk);
14bf61ffe   Jan Kara   quota: Switch ->g...
2557
2558
2559
2560
  #define VFS_QC_MASK \
  	(QC_SPACE | QC_SPC_SOFT | QC_SPC_HARD | \
  	 QC_INO_COUNT | QC_INO_SOFT | QC_INO_HARD | \
  	 QC_SPC_TIMER | QC_INO_TIMER)
c472b4327   Christoph Hellwig   quota: unify ->se...
2561

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2562
  /* Generic routine for setting common part of quota structure */
14bf61ffe   Jan Kara   quota: Switch ->g...
2563
  static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2564
2565
2566
  {
  	struct mem_dqblk *dm = &dquot->dq_dqb;
  	int check_blim = 0, check_ilim = 0;
4c376dcae   Eric W. Biederman   userns: Convert s...
2567
  	struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type];
338bf9afd   Andrew Perepechko   quota: do not all...
2568

14bf61ffe   Jan Kara   quota: Switch ->g...
2569
  	if (di->d_fieldmask & ~VFS_QC_MASK)
c472b4327   Christoph Hellwig   quota: unify ->se...
2570
  		return -EINVAL;
14bf61ffe   Jan Kara   quota: Switch ->g...
2571
  	if (((di->d_fieldmask & QC_SPC_SOFT) &&
b10a08194   Jan Kara   quota: Store maxi...
2572
  	     di->d_spc_softlimit > dqi->dqi_max_spc_limit) ||
14bf61ffe   Jan Kara   quota: Switch ->g...
2573
  	    ((di->d_fieldmask & QC_SPC_HARD) &&
b10a08194   Jan Kara   quota: Store maxi...
2574
  	     di->d_spc_hardlimit > dqi->dqi_max_spc_limit) ||
14bf61ffe   Jan Kara   quota: Switch ->g...
2575
  	    ((di->d_fieldmask & QC_INO_SOFT) &&
b10a08194   Jan Kara   quota: Store maxi...
2576
  	     (di->d_ino_softlimit > dqi->dqi_max_ino_limit)) ||
14bf61ffe   Jan Kara   quota: Switch ->g...
2577
  	    ((di->d_fieldmask & QC_INO_HARD) &&
b10a08194   Jan Kara   quota: Store maxi...
2578
  	     (di->d_ino_hardlimit > dqi->dqi_max_ino_limit)))
338bf9afd   Andrew Perepechko   quota: do not all...
2579
  		return -ERANGE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2580

7b9ca4c61   Jan Kara   quota: Reduce con...
2581
  	spin_lock(&dquot->dq_dqb_lock);
14bf61ffe   Jan Kara   quota: Switch ->g...
2582
2583
  	if (di->d_fieldmask & QC_SPACE) {
  		dm->dqb_curspace = di->d_space - dm->dqb_rsvspace;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2584
  		check_blim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2585
  		set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2586
  	}
c472b4327   Christoph Hellwig   quota: unify ->se...
2587

14bf61ffe   Jan Kara   quota: Switch ->g...
2588
2589
2590
2591
2592
  	if (di->d_fieldmask & QC_SPC_SOFT)
  		dm->dqb_bsoftlimit = di->d_spc_softlimit;
  	if (di->d_fieldmask & QC_SPC_HARD)
  		dm->dqb_bhardlimit = di->d_spc_hardlimit;
  	if (di->d_fieldmask & (QC_SPC_SOFT | QC_SPC_HARD)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2593
  		check_blim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2594
  		set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2595
  	}
c472b4327   Christoph Hellwig   quota: unify ->se...
2596

14bf61ffe   Jan Kara   quota: Switch ->g...
2597
2598
  	if (di->d_fieldmask & QC_INO_COUNT) {
  		dm->dqb_curinodes = di->d_ino_count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2599
  		check_ilim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2600
  		set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2601
  	}
c472b4327   Christoph Hellwig   quota: unify ->se...
2602

14bf61ffe   Jan Kara   quota: Switch ->g...
2603
  	if (di->d_fieldmask & QC_INO_SOFT)
c472b4327   Christoph Hellwig   quota: unify ->se...
2604
  		dm->dqb_isoftlimit = di->d_ino_softlimit;
14bf61ffe   Jan Kara   quota: Switch ->g...
2605
  	if (di->d_fieldmask & QC_INO_HARD)
c472b4327   Christoph Hellwig   quota: unify ->se...
2606
  		dm->dqb_ihardlimit = di->d_ino_hardlimit;
14bf61ffe   Jan Kara   quota: Switch ->g...
2607
  	if (di->d_fieldmask & (QC_INO_SOFT | QC_INO_HARD)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2608
  		check_ilim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2609
  		set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2610
  	}
c472b4327   Christoph Hellwig   quota: unify ->se...
2611

14bf61ffe   Jan Kara   quota: Switch ->g...
2612
2613
  	if (di->d_fieldmask & QC_SPC_TIMER) {
  		dm->dqb_btime = di->d_spc_timer;
e04a88a92   Jan Kara   quota: don't set ...
2614
  		check_blim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2615
  		set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
4d59bce4f   Jan Kara   quota: Keep which...
2616
  	}
c472b4327   Christoph Hellwig   quota: unify ->se...
2617

14bf61ffe   Jan Kara   quota: Switch ->g...
2618
2619
  	if (di->d_fieldmask & QC_INO_TIMER) {
  		dm->dqb_itime = di->d_ino_timer;
e04a88a92   Jan Kara   quota: don't set ...
2620
  		check_ilim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2621
  		set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
4d59bce4f   Jan Kara   quota: Keep which...
2622
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2623
2624
  
  	if (check_blim) {
268157ba6   Jan Kara   quota: Coding sty...
2625
  		if (!dm->dqb_bsoftlimit ||
4b8e1106d   Chengguang Xu   quota: fix condit...
2626
  		    dm->dqb_curspace + dm->dqb_rsvspace <= dm->dqb_bsoftlimit) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2627
2628
  			dm->dqb_btime = 0;
  			clear_bit(DQ_BLKS_B, &dquot->dq_flags);
14bf61ffe   Jan Kara   quota: Switch ->g...
2629
  		} else if (!(di->d_fieldmask & QC_SPC_TIMER))
268157ba6   Jan Kara   quota: Coding sty...
2630
  			/* Set grace only if user hasn't provided his own... */
e008bb613   Arnd Bergmann   quota: use time64...
2631
  			dm->dqb_btime = ktime_get_real_seconds() + dqi->dqi_bgrace;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2632
2633
  	}
  	if (check_ilim) {
268157ba6   Jan Kara   quota: Coding sty...
2634
  		if (!dm->dqb_isoftlimit ||
4b8e1106d   Chengguang Xu   quota: fix condit...
2635
  		    dm->dqb_curinodes <= dm->dqb_isoftlimit) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2636
2637
  			dm->dqb_itime = 0;
  			clear_bit(DQ_INODES_B, &dquot->dq_flags);
14bf61ffe   Jan Kara   quota: Switch ->g...
2638
  		} else if (!(di->d_fieldmask & QC_INO_TIMER))
268157ba6   Jan Kara   quota: Coding sty...
2639
  			/* Set grace only if user hasn't provided his own... */
e008bb613   Arnd Bergmann   quota: use time64...
2640
  			dm->dqb_itime = ktime_get_real_seconds() + dqi->dqi_igrace;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2641
  	}
268157ba6   Jan Kara   quota: Coding sty...
2642
2643
  	if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit ||
  	    dm->dqb_isoftlimit)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2644
2645
2646
  		clear_bit(DQ_FAKE_B, &dquot->dq_flags);
  	else
  		set_bit(DQ_FAKE_B, &dquot->dq_flags);
7b9ca4c61   Jan Kara   quota: Reduce con...
2647
  	spin_unlock(&dquot->dq_dqb_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2648
  	mark_dquot_dirty(dquot);
338bf9afd   Andrew Perepechko   quota: do not all...
2649
2650
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2651
  }
74a8a1037   Eric W. Biederman   userns: Convert q...
2652
  int dquot_set_dqblk(struct super_block *sb, struct kqid qid,
14bf61ffe   Jan Kara   quota: Switch ->g...
2653
  		  struct qc_dqblk *di)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2654
2655
  {
  	struct dquot *dquot;
338bf9afd   Andrew Perepechko   quota: do not all...
2656
  	int rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2657

aca645a6a   Eric W. Biederman   userns: Modify dq...
2658
  	dquot = dqget(sb, qid);
6184fc0b8   Jan Kara   quota: Propagate ...
2659
2660
  	if (IS_ERR(dquot)) {
  		rc = PTR_ERR(dquot);
f55abc0fb   Jan Kara   quota: Allow to s...
2661
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2662
  	}
338bf9afd   Andrew Perepechko   quota: do not all...
2663
  	rc = do_set_dqblk(dquot, di);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2664
  	dqput(dquot);
f55abc0fb   Jan Kara   quota: Allow to s...
2665
  out:
338bf9afd   Andrew Perepechko   quota: do not all...
2666
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2667
  }
287a80958   Christoph Hellwig   quota: rename def...
2668
  EXPORT_SYMBOL(dquot_set_dqblk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2669
2670
  
  /* Generic routine for getting common part of quota file information */
0a240339a   Jan Kara   quota: Make VFS q...
2671
  int dquot_get_state(struct super_block *sb, struct qc_state *state)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2672
2673
  {
  	struct mem_dqinfo *mi;
0a240339a   Jan Kara   quota: Make VFS q...
2674
2675
2676
  	struct qc_type_state *tstate;
  	struct quota_info *dqopt = sb_dqopt(sb);
  	int type;
27942ef50   Sascha Hauer   quota: remove tra...
2677

0a240339a   Jan Kara   quota: Make VFS q...
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
  	memset(state, 0, sizeof(*state));
  	for (type = 0; type < MAXQUOTAS; type++) {
  		if (!sb_has_quota_active(sb, type))
  			continue;
  		tstate = state->s_state + type;
  		mi = sb_dqopt(sb)->info + type;
  		tstate->flags = QCI_ACCT_ENABLED;
  		spin_lock(&dq_data_lock);
  		if (mi->dqi_flags & DQF_SYS_FILE)
  			tstate->flags |= QCI_SYSFILE;
  		if (mi->dqi_flags & DQF_ROOT_SQUASH)
  			tstate->flags |= QCI_ROOT_SQUASH;
  		if (sb_has_quota_limits_enabled(sb, type))
  			tstate->flags |= QCI_LIMITS_ENFORCED;
  		tstate->spc_timelimit = mi->dqi_bgrace;
  		tstate->ino_timelimit = mi->dqi_igrace;
a0828b6cc   Jan Kara   quota: Handle quo...
2694
2695
2696
2697
  		if (dqopt->files[type]) {
  			tstate->ino = dqopt->files[type]->i_ino;
  			tstate->blocks = dqopt->files[type]->i_blocks;
  		}
0a240339a   Jan Kara   quota: Make VFS q...
2698
2699
  		tstate->nextents = 1;	/* We don't know... */
  		spin_unlock(&dq_data_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2700
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2701
2702
  	return 0;
  }
0a240339a   Jan Kara   quota: Make VFS q...
2703
  EXPORT_SYMBOL(dquot_get_state);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2704
2705
  
  /* Generic routine for setting common part of quota file information */
5eacb2ac0   Jan Kara   quota: Make ->set...
2706
  int dquot_set_dqinfo(struct super_block *sb, int type, struct qc_info *ii)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2707
2708
  {
  	struct mem_dqinfo *mi;
f55abc0fb   Jan Kara   quota: Allow to s...
2709
  	int err = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2710

5eacb2ac0   Jan Kara   quota: Make ->set...
2711
2712
2713
  	if ((ii->i_fieldmask & QC_WARNS_MASK) ||
  	    (ii->i_fieldmask & QC_RT_SPC_TIMER))
  		return -EINVAL;
9d1ccbe70   Jan Kara   quota: Use s_umou...
2714
2715
  	if (!sb_has_quota_active(sb, type))
  		return -ESRCH;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2716
  	mi = sb_dqopt(sb)->info + type;
5eacb2ac0   Jan Kara   quota: Make ->set...
2717
2718
  	if (ii->i_fieldmask & QC_FLAGS) {
  		if ((ii->i_flags & QCI_ROOT_SQUASH &&
9d1ccbe70   Jan Kara   quota: Use s_umou...
2719
2720
  		     mi->dqi_format->qf_fmt_id != QFMT_VFS_OLD))
  			return -EINVAL;
ca6cb0918   Jan Kara   quota: Verify fla...
2721
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2722
  	spin_lock(&dq_data_lock);
5eacb2ac0   Jan Kara   quota: Make ->set...
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
  	if (ii->i_fieldmask & QC_SPC_TIMER)
  		mi->dqi_bgrace = ii->i_spc_timelimit;
  	if (ii->i_fieldmask & QC_INO_TIMER)
  		mi->dqi_igrace = ii->i_ino_timelimit;
  	if (ii->i_fieldmask & QC_FLAGS) {
  		if (ii->i_flags & QCI_ROOT_SQUASH)
  			mi->dqi_flags |= DQF_ROOT_SQUASH;
  		else
  			mi->dqi_flags &= ~DQF_ROOT_SQUASH;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2733
2734
2735
2736
  	spin_unlock(&dq_data_lock);
  	mark_info_dirty(sb, type);
  	/* Force write to disk */
  	sb->dq_op->write_info(sb, type);
f55abc0fb   Jan Kara   quota: Allow to s...
2737
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2738
  }
287a80958   Christoph Hellwig   quota: rename def...
2739
  EXPORT_SYMBOL(dquot_set_dqinfo);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2740

3e2af67e6   Jan Kara   quota: Add ->quot...
2741
2742
2743
2744
  const struct quotactl_ops dquot_quotactl_sysfile_ops = {
  	.quota_enable	= dquot_quota_enable,
  	.quota_disable	= dquot_quota_disable,
  	.quota_sync	= dquot_quota_sync,
0a240339a   Jan Kara   quota: Make VFS q...
2745
  	.get_state	= dquot_get_state,
3e2af67e6   Jan Kara   quota: Add ->quot...
2746
2747
  	.set_info	= dquot_set_dqinfo,
  	.get_dqblk	= dquot_get_dqblk,
be6257b25   Jan Kara   quota: Add suppor...
2748
  	.get_nextdqblk	= dquot_get_next_dqblk,
3e2af67e6   Jan Kara   quota: Add ->quot...
2749
2750
2751
  	.set_dqblk	= dquot_set_dqblk
  };
  EXPORT_SYMBOL(dquot_quotactl_sysfile_ops);
dde958885   Dmitry Monakhov   quota: Make quota...
2752
2753
2754
  static int do_proc_dqstats(struct ctl_table *table, int write,
  		     void __user *buffer, size_t *lenp, loff_t *ppos)
  {
6fcbcec9c   Konstantin Khlebnikov   fs/quota: handle ...
2755
2756
2757
2758
2759
2760
2761
  	unsigned int type = (unsigned long *)table->data - dqstats.stat;
  	s64 value = percpu_counter_sum(&dqstats.counter[type]);
  
  	/* Filter negative values for non-monotonic counters */
  	if (value < 0 && (type == DQST_ALLOC_DQUOTS ||
  			  type == DQST_FREE_DQUOTS))
  		value = 0;
f32764bd2   Dmitry Monakhov   quota: Convert qu...
2762
2763
  
  	/* Update global table */
6fcbcec9c   Konstantin Khlebnikov   fs/quota: handle ...
2764
2765
  	dqstats.stat[type] = value;
  	return proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
dde958885   Dmitry Monakhov   quota: Make quota...
2766
  }
e628753bf   Joe Perches   quota: Convert us...
2767
  static struct ctl_table fs_dqstats_table[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2768
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2769
  		.procname	= "lookups",
dde958885   Dmitry Monakhov   quota: Make quota...
2770
  		.data		= &dqstats.stat[DQST_LOOKUPS],
6fcbcec9c   Konstantin Khlebnikov   fs/quota: handle ...
2771
  		.maxlen		= sizeof(unsigned long),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2772
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2773
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2774
2775
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2776
  		.procname	= "drops",
dde958885   Dmitry Monakhov   quota: Make quota...
2777
  		.data		= &dqstats.stat[DQST_DROPS],
6fcbcec9c   Konstantin Khlebnikov   fs/quota: handle ...
2778
  		.maxlen		= sizeof(unsigned long),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2779
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2780
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2781
2782
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2783
  		.procname	= "reads",
dde958885   Dmitry Monakhov   quota: Make quota...
2784
  		.data		= &dqstats.stat[DQST_READS],
6fcbcec9c   Konstantin Khlebnikov   fs/quota: handle ...
2785
  		.maxlen		= sizeof(unsigned long),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2786
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2787
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2788
2789
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2790
  		.procname	= "writes",
dde958885   Dmitry Monakhov   quota: Make quota...
2791
  		.data		= &dqstats.stat[DQST_WRITES],
6fcbcec9c   Konstantin Khlebnikov   fs/quota: handle ...
2792
  		.maxlen		= sizeof(unsigned long),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2793
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2794
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2795
2796
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2797
  		.procname	= "cache_hits",
dde958885   Dmitry Monakhov   quota: Make quota...
2798
  		.data		= &dqstats.stat[DQST_CACHE_HITS],
6fcbcec9c   Konstantin Khlebnikov   fs/quota: handle ...
2799
  		.maxlen		= sizeof(unsigned long),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2800
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2801
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2802
2803
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2804
  		.procname	= "allocated_dquots",
dde958885   Dmitry Monakhov   quota: Make quota...
2805
  		.data		= &dqstats.stat[DQST_ALLOC_DQUOTS],
6fcbcec9c   Konstantin Khlebnikov   fs/quota: handle ...
2806
  		.maxlen		= sizeof(unsigned long),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2807
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2808
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2809
2810
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2811
  		.procname	= "free_dquots",
dde958885   Dmitry Monakhov   quota: Make quota...
2812
  		.data		= &dqstats.stat[DQST_FREE_DQUOTS],
6fcbcec9c   Konstantin Khlebnikov   fs/quota: handle ...
2813
  		.maxlen		= sizeof(unsigned long),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2814
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2815
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2816
2817
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2818
  		.procname	= "syncs",
dde958885   Dmitry Monakhov   quota: Make quota...
2819
  		.data		= &dqstats.stat[DQST_SYNCS],
6fcbcec9c   Konstantin Khlebnikov   fs/quota: handle ...
2820
  		.maxlen		= sizeof(unsigned long),
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2821
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2822
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2823
  	},
8e8934695   Jan Kara   quota: send messa...
2824
  #ifdef CONFIG_PRINT_QUOTA_WARNING
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2825
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2826
2827
2828
2829
  		.procname	= "warnings",
  		.data		= &flag_print_warnings,
  		.maxlen		= sizeof(int),
  		.mode		= 0644,
6d4561110   Eric W. Biederman   sysctl: Drop & in...
2830
  		.proc_handler	= proc_dointvec,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2831
  	},
8e8934695   Jan Kara   quota: send messa...
2832
  #endif
ab09203e3   Eric W. Biederman   sysctl fs: Remove...
2833
  	{ },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2834
  };
e628753bf   Joe Perches   quota: Convert us...
2835
  static struct ctl_table fs_table[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2836
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2837
2838
2839
2840
  		.procname	= "quota",
  		.mode		= 0555,
  		.child		= fs_dqstats_table,
  	},
ab09203e3   Eric W. Biederman   sysctl fs: Remove...
2841
  	{ },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2842
  };
e628753bf   Joe Perches   quota: Convert us...
2843
  static struct ctl_table sys_table[] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2844
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2845
2846
2847
2848
  		.procname	= "fs",
  		.mode		= 0555,
  		.child		= fs_table,
  	},
ab09203e3   Eric W. Biederman   sysctl fs: Remove...
2849
  	{ },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2850
2851
2852
2853
  };
  
  static int __init dquot_init(void)
  {
f32764bd2   Dmitry Monakhov   quota: Convert qu...
2854
  	int i, ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2855
2856
2857
2858
  	unsigned long nr_hash, order;
  
  	printk(KERN_NOTICE "VFS: Disk quotas %s
  ", __DQUOT_VERSION__);
0b4d41471   Eric W. Biederman   [PATCH] sysctl: r...
2859
  	register_sysctl_table(sys_table);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2860

20c2df83d   Paul Mundt   mm: Remove slab d...
2861
  	dquot_cachep = kmem_cache_create("dquot",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2862
  			sizeof(struct dquot), sizeof(unsigned long) * 4,
fffb60f93   Paul Jackson   [PATCH] cpuset me...
2863
2864
  			(SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
  				SLAB_MEM_SPREAD|SLAB_PANIC),
20c2df83d   Paul Mundt   mm: Remove slab d...
2865
  			NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2866
2867
  
  	order = 0;
1aa3b3e0c   Jia-Ju Bai   fs: quota: Replac...
2868
  	dquot_hash = (struct hlist_head *)__get_free_pages(GFP_KERNEL, order);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2869
2870
  	if (!dquot_hash)
  		panic("Cannot create dquot hash table");
f32764bd2   Dmitry Monakhov   quota: Convert qu...
2871
  	for (i = 0; i < _DQST_DQSTAT_LAST; i++) {
908c7f194   Tejun Heo   percpu_counter: a...
2872
  		ret = percpu_counter_init(&dqstats.counter[i], 0, GFP_KERNEL);
f32764bd2   Dmitry Monakhov   quota: Convert qu...
2873
2874
2875
  		if (ret)
  			panic("Cannot create dquot stat counters");
  	}
dde958885   Dmitry Monakhov   quota: Make quota...
2876

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2877
2878
  	/* Find power-of-two hlist_heads which can fit into allocation */
  	nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head);
24fc755f5   Chengguang Xu   quota: code clean...
2879
  	dq_hash_bits = ilog2(nr_hash);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2880
2881
2882
2883
2884
  
  	nr_hash = 1UL << dq_hash_bits;
  	dq_hash_mask = nr_hash - 1;
  	for (i = 0; i < nr_hash; i++)
  		INIT_HLIST_HEAD(dquot_hash + i);
19858e7bd   Anton Blanchard   quota: Add log le...
2885
2886
2887
  	pr_info("VFS: Dquot-cache hash table entries: %ld (order %ld,"
  		" %ld bytes)
  ", nr_hash, order, (PAGE_SIZE << order));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2888

88bc0ede8   Tetsuo Handa   quota: Check for ...
2889
2890
  	if (register_shrinker(&dqcache_shrinker))
  		panic("Cannot register dquot shrinker");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2891
2892
2893
  
  	return 0;
  }
331221fac   Paul Gortmaker   fs: make quota/dq...
2894
  fs_initcall(dquot_init);