Blame view

fs/quota/dquot.c 71.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
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.
   * 
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
   * 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
   *
   * (C) Copyright 1994 - 1997 Marco van Wieringen 
   */
  
  #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
70
71
72
73
74
75
  #include <linux/init.h>
  #include <linux/module.h>
  #include <linux/proc_fs.h>
  #include <linux/security.h>
  #include <linux/kmod.h>
  #include <linux/namei.h>
16f7e0fe2   Randy Dunlap   [PATCH] capable/c...
76
  #include <linux/capability.h>
be586bab8   Adrian Bunk   [PATCH] quota: sm...
77
  #include <linux/quotaops.h>
55fa6091d   Dave Chinner   fs: move i_sb_lis...
78
  #include "../internal.h" /* ugh */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
80
  
  #include <asm/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
  /*
cc33412fb   Jan Kara   quota: Improve lo...
82
   * There are three quota SMP locks. dq_list_lock protects all lists with quotas
dde958885   Dmitry Monakhov   quota: Make quota...
83
   * and quota formats.
cc33412fb   Jan Kara   quota: Improve lo...
84
85
   * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and
   * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
   * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly
cc33412fb   Jan Kara   quota: Improve lo...
87
88
89
   * in inode_add_bytes() and inode_sub_bytes(). 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
90
   *
cc33412fb   Jan Kara   quota: Improve lo...
91
92
   * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock,
   *   dq_list_lock > dq_state_lock
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
94
95
96
97
98
   *
   * 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
   *
   * Any operation working on dquots via inode pointers must hold dqptr_sem.  If
   * operation is just reading pointers from inode (or not using them at all) the
26245c949   Jan Kara   quota: Cleanup S_...
99
100
101
102
103
104
105
   * read lock is enough. If pointers are altered function must hold write lock.
   * 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
   * to check this flag under dqptr_sem and then (if S_NOQUOTA is not set) they
   * have to do all pointer modifications before dropping dqptr_sem. This makes
   * 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
106
   *
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
107
   * Each dquot has its dq_lock mutex. Locked dquots might not be referenced
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
110
111
112
113
114
115
116
   * from inodes (dquot_alloc_space() and such don't check the dq_lock).
   * Currently dquot is locked only when it is being read to memory (or space for
   * it is being allocated) on the first dqget() and when it is being released on
   * the last dqput(). The allocation and release oparations are serialized by
   * the dq_lock and by checking the use count in dquot_release().  Write
   * operations on dquots don't hold dq_lock as they copy data under dq_data_lock
   * spinlock to internal buffers before writing.
   *
   * Lock ordering (including related VFS locks) is the following:
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
117
118
   *   i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock >
   *   dqio_mutex
cc33412fb   Jan Kara   quota: Improve lo...
119
120
121
122
123
124
   * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem >
   * dqptr_sem. But filesystem has to count with the fact that functions such as
   * dquot_alloc_space() acquire dqptr_sem and they usually have to be called
   * from inside a transaction to keep filesystem consistency after a crash. Also
   * filesystems usually want to do some IO on dquot from ->mark_dirty which is
   * called with dqptr_sem held.
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
125
   * i_mutex on quota files is special (it's below dqio_mutex)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
   */
c516610cf   Jan Kara   quota: Make globa...
127
128
129
  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...
130
  EXPORT_SYMBOL(dq_data_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131

fb5ffb0e1   Jiaying Zhang   quota: Change quo...
132
  void __quota_error(struct super_block *sb, const char *func,
055adcbd7   Joe Perches   quota: Use %pV an...
133
  		   const char *fmt, ...)
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
134
  {
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
135
  	if (printk_ratelimit()) {
055adcbd7   Joe Perches   quota: Use %pV an...
136
137
  		va_list args;
  		struct va_format vaf;
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
138
  		va_start(args, fmt);
055adcbd7   Joe Perches   quota: Use %pV an...
139
140
141
142
143
144
145
  
  		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...
146
147
148
149
  		va_end(args);
  	}
  }
  EXPORT_SYMBOL(__quota_error);
da8d1ba22   Sergey Senozhatsky   suppress warning:...
150
  #if defined(CONFIG_QUOTA_DEBUG) || defined(CONFIG_PRINT_QUOTA_WARNING)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
  static char *quotatypes[] = INITQFNAMES;
da8d1ba22   Sergey Senozhatsky   suppress warning:...
152
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
154
155
156
  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...
157
  static struct kmem_cache *dquot_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
158
159
160
161
162
163
164
165
166
  
  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...
167
  EXPORT_SYMBOL(register_quota_format);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
170
171
172
173
  
  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...
174
175
176
  	for (actqf = &quota_formats; *actqf && *actqf != fmt;
  	     actqf = &(*actqf)->qf_next)
  		;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
178
179
180
  	if (*actqf)
  		*actqf = (*actqf)->qf_next;
  	spin_unlock(&dq_list_lock);
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
181
  EXPORT_SYMBOL(unregister_quota_format);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
183
184
185
186
187
  
  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...
188
189
190
  	for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id;
  	     actqf = actqf->qf_next)
  		;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
193
194
195
  	if (!actqf || !try_module_get(actqf->qf_owner)) {
  		int qm;
  
  		spin_unlock(&dq_list_lock);
  		
268157ba6   Jan Kara   quota: Coding sty...
196
197
198
199
200
  		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
201
202
203
  			return NULL;
  
  		spin_lock(&dq_list_lock);
268157ba6   Jan Kara   quota: Coding sty...
204
205
206
  		for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id;
  		     actqf = actqf->qf_next)
  			;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
  		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:
   * The quota code uses three lists for dquot management: the inuse_list,
   * free_dquots, and dquot_hash[] array. A single dquot structure may be
   * on all three lists, depending on its current state.
   *
   * 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.
   *
   * 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...
245
  EXPORT_SYMBOL(dqstats);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
246

0a5a9c725   Jan Kara   quota: Fix warnin...
247
  static qsize_t inode_get_rsv_space(struct inode *inode);
871a29315   Christoph Hellwig   dquot: cleanup dq...
248
  static void __dquot_initialize(struct inode *inode, int type);
0a5a9c725   Jan Kara   quota: Fix warnin...
249

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
251
252
253
254
255
256
257
258
259
260
261
262
263
  static inline unsigned int
  hashfn(const struct super_block *sb, unsigned int id, int type)
  {
  	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...
264
265
  	struct hlist_head *head;
  	head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
266
267
268
269
270
271
272
  	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...
273
274
  static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb,
  				unsigned int id, int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
277
278
279
280
  {
  	struct hlist_node *node;
  	struct dquot *dquot;
  
  	hlist_for_each (node, dquot_hash+hashent) {
  		dquot = hlist_entry(node, struct dquot, dq_hash);
268157ba6   Jan Kara   quota: Coding sty...
281
282
  		if (dquot->dq_sb == sb && dquot->dq_id == id &&
  		    dquot->dq_type == type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283
284
  			return dquot;
  	}
dd6f3c6d5   Jan Kara   quota: Remove NOD...
285
  	return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
287
288
289
290
  }
  
  /* 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_...
291
  	list_add_tail(&dquot->dq_free, &free_dquots);
dde958885   Dmitry Monakhov   quota: Make quota...
292
  	dqstats_inc(DQST_FREE_DQUOTS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
294
295
296
297
298
299
  }
  
  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...
300
  	dqstats_dec(DQST_FREE_DQUOTS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
301
302
303
304
305
306
  }
  
  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_...
307
  	list_add_tail(&dquot->dq_inuse, &inuse_list);
dde958885   Dmitry Monakhov   quota: Make quota...
308
  	dqstats_inc(DQST_ALLOC_DQUOTS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
309
310
311
312
  }
  
  static inline void remove_inuse(struct dquot *dquot)
  {
dde958885   Dmitry Monakhov   quota: Make quota...
313
  	dqstats_dec(DQST_ALLOC_DQUOTS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
314
315
316
317
318
319
320
321
  	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...
322
323
  	mutex_lock(&dquot->dq_lock);
  	mutex_unlock(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324
  }
03f6e92bd   Jan Kara   quota: various st...
325
326
327
328
329
330
331
332
333
  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
334

eabf290d1   Dmitry Monakhov   quota: optimize m...
335
  /* Mark dquot dirty in atomic manner, and return it's old dirty flag state */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
337
  int dquot_mark_dquot_dirty(struct dquot *dquot)
  {
eabf290d1   Dmitry Monakhov   quota: optimize m...
338
339
340
341
342
  	int ret = 1;
  
  	/* 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
343
  	spin_lock(&dq_list_lock);
eabf290d1   Dmitry Monakhov   quota: optimize m...
344
  	if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
346
  		list_add(&dquot->dq_dirty, &sb_dqopt(dquot->dq_sb)->
  				info[dquot->dq_type].dqi_dirty_list);
eabf290d1   Dmitry Monakhov   quota: optimize m...
347
348
  		ret = 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
  	spin_unlock(&dq_list_lock);
eabf290d1   Dmitry Monakhov   quota: optimize m...
350
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
352
  EXPORT_SYMBOL(dquot_mark_dquot_dirty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353

dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
  /* 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
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
  /* This function needs dq_list_lock */
  static inline int clear_dquot_dirty(struct dquot *dquot)
  {
  	if (!test_and_clear_bit(DQ_MOD_B, &dquot->dq_flags))
  		return 0;
  	list_del_init(&dquot->dq_dirty);
  	return 1;
  }
  
  void mark_info_dirty(struct super_block *sb, int type)
  {
  	set_bit(DQF_INFO_DIRTY_B, &sb_dqopt(sb)->info[type].dqi_flags);
  }
  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...
400
401
  	mutex_lock(&dquot->dq_lock);
  	mutex_lock(&dqopt->dqio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
403
404
405
406
407
408
409
410
  	if (!test_bit(DQ_READ_B, &dquot->dq_flags))
  		ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot);
  	if (ret < 0)
  		goto out_iolock;
  	set_bit(DQ_READ_B, &dquot->dq_flags);
  	/* Instantiate dquot if needed */
  	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
  		ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
  		/* Write the info if needed */
268157ba6   Jan Kara   quota: Coding sty...
411
412
413
414
  		if (info_dirty(&dqopt->info[dquot->dq_type])) {
  			ret2 = dqopt->ops[dquot->dq_type]->write_file_info(
  						dquot->dq_sb, dquot->dq_type);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
416
417
418
419
420
421
422
423
  		if (ret < 0)
  			goto out_iolock;
  		if (ret2 < 0) {
  			ret = ret2;
  			goto out_iolock;
  		}
  	}
  	set_bit(DQ_ACTIVE_B, &dquot->dq_flags);
  out_iolock:
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
424
425
  	mutex_unlock(&dqopt->dqio_mutex);
  	mutex_unlock(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
427
  	return ret;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
428
  EXPORT_SYMBOL(dquot_acquire);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
429
430
431
432
433
434
  
  /*
   *	Write dquot to disk
   */
  int dquot_commit(struct dquot *dquot)
  {
b03f24567   Jan Kara   quota: Don't writ...
435
  	int ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
  	struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
437
  	mutex_lock(&dqopt->dqio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
439
440
441
442
443
444
445
  	spin_lock(&dq_list_lock);
  	if (!clear_dquot_dirty(dquot)) {
  		spin_unlock(&dq_list_lock);
  		goto out_sem;
  	}
  	spin_unlock(&dq_list_lock);
  	/* 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...
446
  	if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
447
  		ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
b03f24567   Jan Kara   quota: Don't writ...
448
449
  	else
  		ret = -EIO;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
  out_sem:
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
451
  	mutex_unlock(&dqopt->dqio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
452
453
  	return ret;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
454
  EXPORT_SYMBOL(dquot_commit);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455
456
457
458
459
460
461
462
  
  /*
   *	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...
463
  	mutex_lock(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
465
466
  	/* Check whether we are not racing with some other dqget() */
  	if (atomic_read(&dquot->dq_count) > 1)
  		goto out_dqlock;
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
467
  	mutex_lock(&dqopt->dqio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
468
469
470
  	if (dqopt->ops[dquot->dq_type]->release_dqblk) {
  		ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);
  		/* Write the info */
268157ba6   Jan Kara   quota: Coding sty...
471
472
473
474
  		if (info_dirty(&dqopt->info[dquot->dq_type])) {
  			ret2 = dqopt->ops[dquot->dq_type]->write_file_info(
  						dquot->dq_sb, dquot->dq_type);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
476
477
478
  		if (ret >= 0)
  			ret = ret2;
  	}
  	clear_bit(DQ_ACTIVE_B, &dquot->dq_flags);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
479
  	mutex_unlock(&dqopt->dqio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480
  out_dqlock:
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
481
  	mutex_unlock(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
482
483
  	return ret;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
484
  EXPORT_SYMBOL(dquot_release);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485

7d9056ba2   Jan Kara   quota: Export dqu...
486
  void dquot_destroy(struct dquot *dquot)
74f783af9   Jan Kara   quota: Add callba...
487
488
489
  {
  	kmem_cache_free(dquot_cachep, dquot);
  }
7d9056ba2   Jan Kara   quota: Export dqu...
490
  EXPORT_SYMBOL(dquot_destroy);
74f783af9   Jan Kara   quota: Add callba...
491
492
493
494
495
  
  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
496
497
  /* 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 ...
498
499
   * 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...
500
   * list) or parallel quotactl call. We have to wait for such users.
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
501
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
503
  static void invalidate_dquots(struct super_block *sb, int type)
  {
c33ed2712   Domen Puncer   [PATCH] list_for_...
504
  	struct dquot *dquot, *tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
505

6362e4d4e   Jan Kara   [PATCH] Fix oops ...
506
  restart:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
  	spin_lock(&dq_list_lock);
c33ed2712   Domen Puncer   [PATCH] list_for_...
508
  	list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
509
510
511
512
  		if (dquot->dq_sb != sb)
  			continue;
  		if (dquot->dq_type != type)
  			continue;
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
  		/* Wait for dquot users */
  		if (atomic_read(&dquot->dq_count)) {
  			DEFINE_WAIT(wait);
  
  			atomic_inc(&dquot->dq_count);
  			prepare_to_wait(&dquot->dq_wait_unused, &wait,
  					TASK_UNINTERRUPTIBLE);
  			spin_unlock(&dq_list_lock);
  			/* Once dqput() wakes us up, we know it's time to free
  			 * 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.
  			 */
  			if (atomic_read(&dquot->dq_count) > 1)
  				schedule();
  			finish_wait(&dquot->dq_wait_unused, &wait);
  			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
541
542
543
  		remove_dquot_hash(dquot);
  		remove_free_dquot(dquot);
  		remove_inuse(dquot);
74f783af9   Jan Kara   quota: Add callba...
544
  		do_destroy_dquot(dquot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
545
546
547
  	}
  	spin_unlock(&dq_list_lock);
  }
12c77527e   Jan Kara   quota: Implement ...
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
  /* 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;
  
  	mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
  	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 ...
565
  		spin_unlock(&dq_list_lock);
dde958885   Dmitry Monakhov   quota: Make quota...
566
  		dqstats_inc(DQST_LOOKUPS);
12c77527e   Jan Kara   quota: Implement ...
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
  		dqput(old_dquot);
  		old_dquot = dquot;
  		ret = fn(dquot, priv);
  		if (ret < 0)
  			goto out;
  		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);
  	mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
  	return ret;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
582
  EXPORT_SYMBOL(dquot_scan_active);
12c77527e   Jan Kara   quota: Implement ...
583

287a80958   Christoph Hellwig   quota: rename def...
584
  int dquot_quota_sync(struct super_block *sb, int type, int wait)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
585
586
587
588
589
  {
  	struct list_head *dirty;
  	struct dquot *dquot;
  	struct quota_info *dqopt = sb_dqopt(sb);
  	int cnt;
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
590
  	mutex_lock(&dqopt->dqonoff_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
591
592
593
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		if (type != -1 && cnt != type)
  			continue;
f55abc0fb   Jan Kara   quota: Allow to s...
594
  		if (!sb_has_quota_active(sb, cnt))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
596
597
598
  			continue;
  		spin_lock(&dq_list_lock);
  		dirty = &dqopt->info[cnt].dqi_dirty_list;
  		while (!list_empty(dirty)) {
268157ba6   Jan Kara   quota: Coding sty...
599
600
  			dquot = list_first_entry(dirty, struct dquot,
  						 dq_dirty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
601
602
603
604
605
606
607
608
609
  			/* Dirty and inactive can be only bad dquot... */
  			if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
  				clear_dquot_dirty(dquot);
  				continue;
  			}
  			/* Now we have active dquot from which someone is
   			 * holding reference so we can safely just increase
  			 * use count */
  			atomic_inc(&dquot->dq_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
610
  			spin_unlock(&dq_list_lock);
dde958885   Dmitry Monakhov   quota: Make quota...
611
  			dqstats_inc(DQST_LOOKUPS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
612
613
614
615
616
617
618
619
  			sb->dq_op->write_dquot(dquot);
  			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...
620
621
  		if ((cnt == type || type == -1) && sb_has_quota_active(sb, cnt)
  		    && info_dirty(&dqopt->info[cnt]))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
622
  			sb->dq_op->write_info(sb, cnt);
dde958885   Dmitry Monakhov   quota: Make quota...
623
  	dqstats_inc(DQST_SYNCS);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
624
  	mutex_unlock(&dqopt->dqonoff_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
625

5fb324ad2   Christoph Hellwig   quota: move code ...
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
  	if (!wait || (sb_dqopt(sb)->flags & DQUOT_QUOTA_SYS_FILE))
  		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.
  	 */
  	mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		if (type != -1 && cnt != type)
  			continue;
  		if (!sb_has_quota_active(sb, cnt))
  			continue;
  		mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex,
  				  I_MUTEX_QUOTA);
  		truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0);
  		mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex);
  	}
  	mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
653
  	return 0;
  }
287a80958   Christoph Hellwig   quota: rename def...
654
  EXPORT_SYMBOL(dquot_quota_sync);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
655
656
657
658
659
660
661
662
663
664
665
666
667
  
  /* Free unused dquots from cache */
  static void prune_dqcache(int count)
  {
  	struct list_head *head;
  	struct dquot *dquot;
  
  	head = free_dquots.prev;
  	while (head != &free_dquots && count) {
  		dquot = list_entry(head, struct dquot, dq_free);
  		remove_dquot_hash(dquot);
  		remove_free_dquot(dquot);
  		remove_inuse(dquot);
74f783af9   Jan Kara   quota: Add callba...
668
  		do_destroy_dquot(dquot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
669
670
671
672
673
674
675
676
677
  		count--;
  		head = free_dquots.prev;
  	}
  }
  
  /*
   * This is called from kswapd when we think we need some
   * more memory
   */
1495f230f   Ying Han   vmscan: change sh...
678
679
  static int shrink_dqcache_memory(struct shrinker *shrink,
  				 struct shrink_control *sc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
680
  {
1495f230f   Ying Han   vmscan: change sh...
681
  	int nr = sc->nr_to_scan;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
682
683
684
685
686
  	if (nr) {
  		spin_lock(&dq_list_lock);
  		prune_dqcache(nr);
  		spin_unlock(&dq_list_lock);
  	}
f32764bd2   Dmitry Monakhov   quota: Convert qu...
687
688
689
  	return ((unsigned)
  		percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS])
  		/100) * sysctl_vfs_cache_pressure;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
690
  }
8e1f936b7   Rusty Russell   mm: clean up and ...
691
692
693
694
  static struct shrinker dqcache_shrinker = {
  	.shrink = shrink_dqcache_memory,
  	.seeks = DEFAULT_SEEKS,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
695
696
697
  /*
   * Put reference to dquot
   * NOTE: If you change this function please check whether dqput_blocks() works right...
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
698
   */
3d9ea253a   Jan Kara   quota: Add helper...
699
  void dqput(struct dquot *dquot)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
700
  {
b48d38054   Jan Kara   quota: fix possib...
701
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
702
703
  	if (!dquot)
  		return;
62af9b520   Jan Kara   quota: Convert __...
704
  #ifdef CONFIG_QUOTA_DEBUG
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
705
  	if (!atomic_read(&dquot->dq_count)) {
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
706
707
  		quota_error(dquot->dq_sb, "trying to free free dquot of %s %d",
  			    quotatypes[dquot->dq_type], dquot->dq_id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
708
709
710
  		BUG();
  	}
  #endif
dde958885   Dmitry Monakhov   quota: Make quota...
711
  	dqstats_inc(DQST_DROPS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
712
713
714
715
716
  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 ...
717
  		/* Releasing dquot during quotaoff phase? */
f55abc0fb   Jan Kara   quota: Allow to s...
718
  		if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_type) &&
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
719
720
  		    atomic_read(&dquot->dq_count) == 1)
  			wake_up(&dquot->dq_wait_unused);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
721
722
723
724
725
726
727
  		spin_unlock(&dq_list_lock);
  		return;
  	}
  	/* Need to release dquot? */
  	if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && dquot_dirty(dquot)) {
  		spin_unlock(&dq_list_lock);
  		/* Commit dquot before releasing */
b48d38054   Jan Kara   quota: fix possib...
728
729
  		ret = dquot->dq_sb->dq_op->write_dquot(dquot);
  		if (ret < 0) {
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
730
731
732
  			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...
733
734
735
736
737
738
739
740
  			/*
  			 * We clear dirty bit anyway, so that we avoid
  			 * infinite loop here
  			 */
  			spin_lock(&dq_list_lock);
  			clear_dquot_dirty(dquot);
  			spin_unlock(&dq_list_lock);
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
741
742
743
744
745
746
747
748
749
750
  		goto we_slept;
  	}
  	/* Clear flag in case dquot was inactive (something bad happened) */
  	clear_dquot_dirty(dquot);
  	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 __...
751
  #ifdef CONFIG_QUOTA_DEBUG
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
  	/* sanity check */
8abf6a470   Eric Sesterhenn   BUG_ON() Conversi...
753
  	BUG_ON(!list_empty(&dquot->dq_free));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
755
756
757
  #endif
  	put_dquot_last(dquot);
  	spin_unlock(&dq_list_lock);
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
758
  EXPORT_SYMBOL(dqput);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
759

7d9056ba2   Jan Kara   quota: Export dqu...
760
  struct dquot *dquot_alloc(struct super_block *sb, int type)
74f783af9   Jan Kara   quota: Add callba...
761
762
763
  {
  	return kmem_cache_zalloc(dquot_cachep, GFP_NOFS);
  }
7d9056ba2   Jan Kara   quota: Export dqu...
764
  EXPORT_SYMBOL(dquot_alloc);
74f783af9   Jan Kara   quota: Add callba...
765

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
766
767
768
  static struct dquot *get_empty_dquot(struct super_block *sb, int type)
  {
  	struct dquot *dquot;
74f783af9   Jan Kara   quota: Add callba...
769
  	dquot = sb->dq_op->alloc_dquot(sb, type);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
770
  	if(!dquot)
dd6f3c6d5   Jan Kara   quota: Remove NOD...
771
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
772

d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
773
  	mutex_init(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
774
775
776
777
  	INIT_LIST_HEAD(&dquot->dq_free);
  	INIT_LIST_HEAD(&dquot->dq_inuse);
  	INIT_HLIST_NODE(&dquot->dq_hash);
  	INIT_LIST_HEAD(&dquot->dq_dirty);
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
778
  	init_waitqueue_head(&dquot->dq_wait_unused);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779
780
781
782
783
784
785
786
787
  	dquot->dq_sb = sb;
  	dquot->dq_type = type;
  	atomic_set(&dquot->dq_count, 1);
  
  	return dquot;
  }
  
  /*
   * Get reference to dquot
cc33412fb   Jan Kara   quota: Improve lo...
788
789
790
791
792
   *
   * 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
793
   */
3d9ea253a   Jan Kara   quota: Add helper...
794
  struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
795
796
  {
  	unsigned int hashent = hashfn(sb, id, type);
dd6f3c6d5   Jan Kara   quota: Remove NOD...
797
  	struct dquot *dquot = NULL, *empty = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798

f55abc0fb   Jan Kara   quota: Allow to s...
799
          if (!sb_has_quota_active(sb, type))
dd6f3c6d5   Jan Kara   quota: Remove NOD...
800
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
801
802
  we_slept:
  	spin_lock(&dq_list_lock);
cc33412fb   Jan Kara   quota: Improve lo...
803
804
805
806
807
808
809
  	spin_lock(&dq_state_lock);
  	if (!sb_has_quota_active(sb, type)) {
  		spin_unlock(&dq_state_lock);
  		spin_unlock(&dq_list_lock);
  		goto out;
  	}
  	spin_unlock(&dq_state_lock);
dd6f3c6d5   Jan Kara   quota: Remove NOD...
810
811
812
  	dquot = find_dquot(hashent, sb, id, type);
  	if (!dquot) {
  		if (!empty) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
813
  			spin_unlock(&dq_list_lock);
dd6f3c6d5   Jan Kara   quota: Remove NOD...
814
815
  			empty = get_empty_dquot(sb, type);
  			if (!empty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
816
817
818
819
  				schedule();	/* Try to wait for a moment... */
  			goto we_slept;
  		}
  		dquot = empty;
dd6f3c6d5   Jan Kara   quota: Remove NOD...
820
  		empty = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
821
822
823
824
825
  		dquot->dq_id = id;
  		/* 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
826
  		spin_unlock(&dq_list_lock);
dde958885   Dmitry Monakhov   quota: Make quota...
827
  		dqstats_inc(DQST_LOOKUPS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
829
830
831
  	} else {
  		if (!atomic_read(&dquot->dq_count))
  			remove_free_dquot(dquot);
  		atomic_inc(&dquot->dq_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
832
  		spin_unlock(&dq_list_lock);
dde958885   Dmitry Monakhov   quota: Make quota...
833
834
  		dqstats_inc(DQST_CACHE_HITS);
  		dqstats_inc(DQST_LOOKUPS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
835
  	}
268157ba6   Jan Kara   quota: Coding sty...
836
837
  	/* 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
838
  	wait_on_dquot(dquot);
268157ba6   Jan Kara   quota: Coding sty...
839
840
841
  	/* Read the dquot / allocate space in quota file */
  	if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) &&
  	    sb->dq_op->acquire_dquot(dquot) < 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
842
  		dqput(dquot);
dd6f3c6d5   Jan Kara   quota: Remove NOD...
843
  		dquot = NULL;
cc33412fb   Jan Kara   quota: Improve lo...
844
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
  	}
62af9b520   Jan Kara   quota: Convert __...
846
  #ifdef CONFIG_QUOTA_DEBUG
8abf6a470   Eric Sesterhenn   BUG_ON() Conversi...
847
  	BUG_ON(!dquot->dq_sb);	/* Has somebody invalidated entry under us? */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
848
  #endif
cc33412fb   Jan Kara   quota: Improve lo...
849
850
851
  out:
  	if (empty)
  		do_destroy_dquot(empty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
852
853
854
  
  	return dquot;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
855
  EXPORT_SYMBOL(dqget);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
857
858
859
860
861
862
863
  
  static int dqinit_needed(struct inode *inode, int type)
  {
  	int cnt;
  
  	if (IS_NOQUOTA(inode))
  		return 0;
  	if (type != -1)
dd6f3c6d5   Jan Kara   quota: Remove NOD...
864
  		return !inode->i_dquot[type];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
865
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
dd6f3c6d5   Jan Kara   quota: Remove NOD...
866
  		if (!inode->i_dquot[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
867
868
869
  			return 1;
  	return 0;
  }
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
870
  /* This routine is guarded by dqonoff_mutex mutex */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
871
872
  static void add_dquot_ref(struct super_block *sb, int type)
  {
941d2380e   Jan Kara   quota: improve in...
873
  	struct inode *inode, *old_inode = NULL;
62af9b520   Jan Kara   quota: Convert __...
874
  #ifdef CONFIG_QUOTA_DEBUG
0a5a9c725   Jan Kara   quota: Fix warnin...
875
  	int reserved = 0;
4c5e6c0e7   Jan Kara   quota: Hide warni...
876
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
877

55fa6091d   Dave Chinner   fs: move i_sb_lis...
878
  	spin_lock(&inode_sb_list_lock);
d003fb70f   Christoph Hellwig   [PATCH] remove sb...
879
  	list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
250df6ed2   Dave Chinner   fs: protect inode...
880
881
882
883
884
  		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...
885
  			continue;
250df6ed2   Dave Chinner   fs: protect inode...
886
  		}
62af9b520   Jan Kara   quota: Convert __...
887
  #ifdef CONFIG_QUOTA_DEBUG
0a5a9c725   Jan Kara   quota: Fix warnin...
888
889
  		if (unlikely(inode_get_rsv_space(inode) > 0))
  			reserved = 1;
4c5e6c0e7   Jan Kara   quota: Hide warni...
890
  #endif
d003fb70f   Christoph Hellwig   [PATCH] remove sb...
891
  		__iget(inode);
250df6ed2   Dave Chinner   fs: protect inode...
892
  		spin_unlock(&inode->i_lock);
55fa6091d   Dave Chinner   fs: move i_sb_lis...
893
  		spin_unlock(&inode_sb_list_lock);
d003fb70f   Christoph Hellwig   [PATCH] remove sb...
894

941d2380e   Jan Kara   quota: improve in...
895
  		iput(old_inode);
871a29315   Christoph Hellwig   dquot: cleanup dq...
896
  		__dquot_initialize(inode, type);
55fa6091d   Dave Chinner   fs: move i_sb_lis...
897
898
899
900
901
902
903
904
905
  
  		/*
  		 * We hold a reference to 'inode' so it couldn't have been
  		 * removed from s_inodes list while we dropped the
  		 * inode_sb_list_lock We cannot iput the inode now as we can be
  		 * holding the last reference and we cannot iput it under
  		 * inode_sb_list_lock. So we keep the reference and iput it
  		 * later.
  		 */
941d2380e   Jan Kara   quota: improve in...
906
  		old_inode = inode;
55fa6091d   Dave Chinner   fs: move i_sb_lis...
907
  		spin_lock(&inode_sb_list_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
908
  	}
55fa6091d   Dave Chinner   fs: move i_sb_lis...
909
  	spin_unlock(&inode_sb_list_lock);
941d2380e   Jan Kara   quota: improve in...
910
  	iput(old_inode);
0a5a9c725   Jan Kara   quota: Fix warnin...
911

62af9b520   Jan Kara   quota: Convert __...
912
  #ifdef CONFIG_QUOTA_DEBUG
0a5a9c725   Jan Kara   quota: Fix warnin...
913
  	if (reserved) {
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
914
915
916
  		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...
917
  	}
4c5e6c0e7   Jan Kara   quota: Hide warni...
918
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
919
  }
268157ba6   Jan Kara   quota: Coding sty...
920
921
922
923
  /*
   * Return 0 if dqput() won't block.
   * (note that 1 doesn't necessarily mean blocking)
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
924
925
926
927
928
929
  static inline int dqput_blocks(struct dquot *dquot)
  {
  	if (atomic_read(&dquot->dq_count) <= 1)
  		return 1;
  	return 0;
  }
268157ba6   Jan Kara   quota: Coding sty...
930
931
  /*
   * Remove references to dquots from inode and add dquot to list for freeing
25985edce   Lucas De Marchi   Fix common misspe...
932
   * if we have the last reference to dquot
268157ba6   Jan Kara   quota: Coding sty...
933
934
   * We can't race with anybody because we hold dqptr_sem for writing...
   */
e5f00f42f   Adrian Bunk   make remove_inode...
935
936
  static int remove_inode_dquot_ref(struct inode *inode, int type,
  				  struct list_head *tofree_head)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937
938
  {
  	struct dquot *dquot = inode->i_dquot[type];
dd6f3c6d5   Jan Kara   quota: Remove NOD...
939
940
  	inode->i_dquot[type] = NULL;
  	if (dquot) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
941
  		if (dqput_blocks(dquot)) {
62af9b520   Jan Kara   quota: Convert __...
942
  #ifdef CONFIG_QUOTA_DEBUG
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
943
  			if (atomic_read(&dquot->dq_count) != 1)
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
944
945
946
  				quota_error(inode->i_sb, "Adding dquot with "
  					    "dq_count %d to dispose list",
  					    atomic_read(&dquot->dq_count));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
947
948
  #endif
  			spin_lock(&dq_list_lock);
268157ba6   Jan Kara   quota: Coding sty...
949
950
951
  			/* As dquot must have currently users it can't be on
  			 * the free list... */
  			list_add(&dquot->dq_free, tofree_head);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
952
953
954
955
956
957
958
959
  			spin_unlock(&dq_list_lock);
  			return 1;
  		}
  		else
  			dqput(dquot);   /* We have guaranteed we won't block */
  	}
  	return 0;
  }
268157ba6   Jan Kara   quota: Coding sty...
960
961
962
963
964
  /*
   * 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
965
966
967
968
969
970
  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
971
972
973
  	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...
974
975
  		/* 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
976
977
978
  		dqput(dquot);
  	}
  }
fb58b7316   Christoph Hellwig   [PATCH] move remo...
979
980
981
982
  static void remove_dquot_ref(struct super_block *sb, int type,
  		struct list_head *tofree_head)
  {
  	struct inode *inode;
7af9cce8a   Dmitry Monakhov   quota: check quot...
983
  	int reserved = 0;
fb58b7316   Christoph Hellwig   [PATCH] move remo...
984

55fa6091d   Dave Chinner   fs: move i_sb_lis...
985
  	spin_lock(&inode_sb_list_lock);
fb58b7316   Christoph Hellwig   [PATCH] move remo...
986
  	list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
aabb8fdb4   Nick Piggin   fs: avoid I_NEW i...
987
988
989
990
991
992
  		/*
  		 *  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
  		 *  (dqptr_sem).
  		 */
7af9cce8a   Dmitry Monakhov   quota: check quot...
993
994
995
  		if (!IS_NOQUOTA(inode)) {
  			if (unlikely(inode_get_rsv_space(inode) > 0))
  				reserved = 1;
fb58b7316   Christoph Hellwig   [PATCH] move remo...
996
  			remove_inode_dquot_ref(inode, type, tofree_head);
7af9cce8a   Dmitry Monakhov   quota: check quot...
997
  		}
fb58b7316   Christoph Hellwig   [PATCH] move remo...
998
  	}
55fa6091d   Dave Chinner   fs: move i_sb_lis...
999
  	spin_unlock(&inode_sb_list_lock);
7af9cce8a   Dmitry Monakhov   quota: check quot...
1000
1001
1002
1003
1004
1005
1006
1007
  #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...
1008
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1009
1010
1011
1012
  /* 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...
1013
1014
1015
1016
1017
1018
  	if (sb->dq_op) {
  		down_write(&sb_dqopt(sb)->dqptr_sem);
  		remove_dquot_ref(sb, type, &tofree_head);
  		up_write(&sb_dqopt(sb)->dqptr_sem);
  		put_dquot_list(&tofree_head);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1019
  }
12095460f   Jan Kara   quota: Increase s...
1020
  static inline void dquot_incr_inodes(struct dquot *dquot, qsize_t number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1021
1022
1023
1024
1025
1026
1027
1028
  {
  	dquot->dq_dqb.dqb_curinodes += number;
  }
  
  static inline void dquot_incr_space(struct dquot *dquot, qsize_t number)
  {
  	dquot->dq_dqb.dqb_curspace += number;
  }
f18df2289   Mingming Cao   quota: Add quota ...
1029
1030
1031
1032
  static inline void dquot_resv_space(struct dquot *dquot, qsize_t number)
  {
  	dquot->dq_dqb.dqb_rsvspace += number;
  }
740d9dcd9   Mingming Cao   quota: Add quota ...
1033
1034
1035
  /*
   * Claim reserved quota space
   */
0a5a9c725   Jan Kara   quota: Fix warnin...
1036
  static void dquot_claim_reserved_space(struct dquot *dquot, qsize_t number)
740d9dcd9   Mingming Cao   quota: Add quota ...
1037
  {
0a5a9c725   Jan Kara   quota: Fix warnin...
1038
1039
1040
1041
  	if (dquot->dq_dqb.dqb_rsvspace < number) {
  		WARN_ON_ONCE(1);
  		number = dquot->dq_dqb.dqb_rsvspace;
  	}
740d9dcd9   Mingming Cao   quota: Add quota ...
1042
1043
1044
1045
1046
1047
1048
  	dquot->dq_dqb.dqb_curspace += number;
  	dquot->dq_dqb.dqb_rsvspace -= number;
  }
  
  static inline
  void dquot_free_reserved_space(struct dquot *dquot, qsize_t number)
  {
0a5a9c725   Jan Kara   quota: Fix warnin...
1049
1050
1051
1052
1053
1054
  	if (dquot->dq_dqb.dqb_rsvspace >= number)
  		dquot->dq_dqb.dqb_rsvspace -= number;
  	else {
  		WARN_ON_ONCE(1);
  		dquot->dq_dqb.dqb_rsvspace = 0;
  	}
740d9dcd9   Mingming Cao   quota: Add quota ...
1055
  }
7a2435d87   Jan Kara   quota: Remove sup...
1056
  static void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1057
  {
db49d2df4   Jan Kara   quota: Allow nega...
1058
1059
  	if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE ||
  	    dquot->dq_dqb.dqb_curinodes >= number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1060
1061
1062
1063
1064
1065
1066
  		dquot->dq_dqb.dqb_curinodes -= number;
  	else
  		dquot->dq_dqb.dqb_curinodes = 0;
  	if (dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit)
  		dquot->dq_dqb.dqb_itime = (time_t) 0;
  	clear_bit(DQ_INODES_B, &dquot->dq_flags);
  }
7a2435d87   Jan Kara   quota: Remove sup...
1067
  static void dquot_decr_space(struct dquot *dquot, qsize_t number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1068
  {
db49d2df4   Jan Kara   quota: Allow nega...
1069
1070
  	if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE ||
  	    dquot->dq_dqb.dqb_curspace >= number)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1071
1072
1073
  		dquot->dq_dqb.dqb_curspace -= number;
  	else
  		dquot->dq_dqb.dqb_curspace = 0;
12095460f   Jan Kara   quota: Increase s...
1074
  	if (dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1075
1076
1077
  		dquot->dq_dqb.dqb_btime = (time_t) 0;
  	clear_bit(DQ_BLKS_B, &dquot->dq_flags);
  }
c525460e2   Jan Kara   Don't send quota ...
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
  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...
1089
  #ifdef CONFIG_PRINT_QUOTA_WARNING
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1090
  static int flag_print_warnings = 1;
7a2435d87   Jan Kara   quota: Remove sup...
1091
  static int need_print_warning(struct dquot *dquot)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1092
1093
1094
1095
1096
1097
  {
  	if (!flag_print_warnings)
  		return 0;
  
  	switch (dquot->dq_type) {
  		case USRQUOTA:
da9592ede   David Howells   CRED: Wrap task c...
1098
  			return current_fsuid() == dquot->dq_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1099
1100
1101
1102
1103
  		case GRPQUOTA:
  			return in_group_p(dquot->dq_id);
  	}
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1104
  /* Print warning to user which exceeded quota */
c525460e2   Jan Kara   Don't send quota ...
1105
  static void print_warning(struct dquot *dquot, const int warntype)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1106
1107
  {
  	char *msg = NULL;
24ec839c4   Peter Zijlstra   [PATCH] tty: ->si...
1108
  	struct tty_struct *tty;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1109

657d3bfa9   Jan Kara   quota: implement ...
1110
1111
1112
1113
  	if (warntype == QUOTA_NL_IHARDBELOW ||
  	    warntype == QUOTA_NL_ISOFTBELOW ||
  	    warntype == QUOTA_NL_BHARDBELOW ||
  	    warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1114
  		return;
24ec839c4   Peter Zijlstra   [PATCH] tty: ->si...
1115
1116
  	tty = get_current_tty();
  	if (!tty)
452a00d2e   Alan Cox   tty: Make get_cur...
1117
  		return;
24ec839c4   Peter Zijlstra   [PATCH] tty: ->si...
1118
  	tty_write_message(tty, dquot->dq_sb->s_id);
8e8934695   Jan Kara   quota: send messa...
1119
  	if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN)
24ec839c4   Peter Zijlstra   [PATCH] tty: ->si...
1120
  		tty_write_message(tty, ": warning, ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1121
  	else
24ec839c4   Peter Zijlstra   [PATCH] tty: ->si...
1122
1123
  		tty_write_message(tty, ": write failed, ");
  	tty_write_message(tty, quotatypes[dquot->dq_type]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1124
  	switch (warntype) {
8e8934695   Jan Kara   quota: send messa...
1125
  		case QUOTA_NL_IHARDWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1126
1127
1128
  			msg = " file limit reached.\r
  ";
  			break;
8e8934695   Jan Kara   quota: send messa...
1129
  		case QUOTA_NL_ISOFTLONGWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1130
1131
1132
  			msg = " file quota exceeded too long.\r
  ";
  			break;
8e8934695   Jan Kara   quota: send messa...
1133
  		case QUOTA_NL_ISOFTWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1134
1135
1136
  			msg = " file quota exceeded.\r
  ";
  			break;
8e8934695   Jan Kara   quota: send messa...
1137
  		case QUOTA_NL_BHARDWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1138
1139
1140
  			msg = " block limit reached.\r
  ";
  			break;
8e8934695   Jan Kara   quota: send messa...
1141
  		case QUOTA_NL_BSOFTLONGWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1142
1143
1144
  			msg = " block quota exceeded too long.\r
  ";
  			break;
8e8934695   Jan Kara   quota: send messa...
1145
  		case QUOTA_NL_BSOFTWARN:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1146
1147
1148
1149
  			msg = " block quota exceeded.\r
  ";
  			break;
  	}
24ec839c4   Peter Zijlstra   [PATCH] tty: ->si...
1150
  	tty_write_message(tty, msg);
452a00d2e   Alan Cox   tty: Make get_cur...
1151
  	tty_kref_put(tty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1152
  }
8e8934695   Jan Kara   quota: send messa...
1153
  #endif
f18df2289   Mingming Cao   quota: Add quota ...
1154
1155
1156
1157
1158
  /*
   * Write warnings to the console and send warning messages over netlink.
   *
   * Note that this function can sleep.
   */
7a2435d87   Jan Kara   quota: Remove sup...
1159
  static void flush_warnings(struct dquot *const *dquots, char *warntype)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1160
  {
86e931a35   Steven Whitehouse   VFS: Export dquot...
1161
  	struct dquot *dq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1162
  	int i;
86e931a35   Steven Whitehouse   VFS: Export dquot...
1163
1164
1165
1166
  	for (i = 0; i < MAXQUOTAS; i++) {
  		dq = dquots[i];
  		if (dq && warntype[i] != QUOTA_NL_NOWARN &&
  		    !warning_issued(dq, warntype[i])) {
8e8934695   Jan Kara   quota: send messa...
1167
  #ifdef CONFIG_PRINT_QUOTA_WARNING
86e931a35   Steven Whitehouse   VFS: Export dquot...
1168
  			print_warning(dq, warntype[i]);
8e8934695   Jan Kara   quota: send messa...
1169
  #endif
86e931a35   Steven Whitehouse   VFS: Export dquot...
1170
1171
  			quota_send_warning(dq->dq_type, dq->dq_id,
  					   dq->dq_sb->s_dev, warntype[i]);
8e8934695   Jan Kara   quota: send messa...
1172
  		}
86e931a35   Steven Whitehouse   VFS: Export dquot...
1173
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1174
  }
7a2435d87   Jan Kara   quota: Remove sup...
1175
  static int ignore_hardlimit(struct dquot *dquot)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1176
1177
1178
1179
  {
  	struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
  
  	return capable(CAP_SYS_RESOURCE) &&
268157ba6   Jan Kara   quota: Coding sty...
1180
1181
  	       (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD ||
  		!(info->dqi_flags & V1_DQF_RSQUASH));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1182
1183
1184
  }
  
  /* needs dq_data_lock */
12095460f   Jan Kara   quota: Increase s...
1185
  static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1186
  {
268157ba6   Jan Kara   quota: Coding sty...
1187
  	qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes;
8e8934695   Jan Kara   quota: send messa...
1188
  	*warntype = QUOTA_NL_NOWARN;
f55abc0fb   Jan Kara   quota: Allow to s...
1189
1190
  	if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) ||
  	    test_bit(DQ_FAKE_B, &dquot->dq_flags))
efd8f0e6f   Christoph Hellwig   quota: stop using...
1191
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1192
1193
  
  	if (dquot->dq_dqb.dqb_ihardlimit &&
268157ba6   Jan Kara   quota: Coding sty...
1194
  	    newinodes > dquot->dq_dqb.dqb_ihardlimit &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1195
              !ignore_hardlimit(dquot)) {
8e8934695   Jan Kara   quota: send messa...
1196
  		*warntype = QUOTA_NL_IHARDWARN;
efd8f0e6f   Christoph Hellwig   quota: stop using...
1197
  		return -EDQUOT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1198
1199
1200
  	}
  
  	if (dquot->dq_dqb.dqb_isoftlimit &&
268157ba6   Jan Kara   quota: Coding sty...
1201
1202
1203
  	    newinodes > dquot->dq_dqb.dqb_isoftlimit &&
  	    dquot->dq_dqb.dqb_itime &&
  	    get_seconds() >= dquot->dq_dqb.dqb_itime &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1204
              !ignore_hardlimit(dquot)) {
8e8934695   Jan Kara   quota: send messa...
1205
  		*warntype = QUOTA_NL_ISOFTLONGWARN;
efd8f0e6f   Christoph Hellwig   quota: stop using...
1206
  		return -EDQUOT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1207
1208
1209
  	}
  
  	if (dquot->dq_dqb.dqb_isoftlimit &&
268157ba6   Jan Kara   quota: Coding sty...
1210
  	    newinodes > dquot->dq_dqb.dqb_isoftlimit &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1211
  	    dquot->dq_dqb.dqb_itime == 0) {
8e8934695   Jan Kara   quota: send messa...
1212
  		*warntype = QUOTA_NL_ISOFTWARN;
268157ba6   Jan Kara   quota: Coding sty...
1213
1214
  		dquot->dq_dqb.dqb_itime = get_seconds() +
  		    sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1215
  	}
efd8f0e6f   Christoph Hellwig   quota: stop using...
1216
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1217
1218
1219
1220
1221
  }
  
  /* needs dq_data_lock */
  static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype)
  {
f18df2289   Mingming Cao   quota: Add quota ...
1222
  	qsize_t tspace;
268157ba6   Jan Kara   quota: Coding sty...
1223
  	struct super_block *sb = dquot->dq_sb;
f18df2289   Mingming Cao   quota: Add quota ...
1224

8e8934695   Jan Kara   quota: send messa...
1225
  	*warntype = QUOTA_NL_NOWARN;
268157ba6   Jan Kara   quota: Coding sty...
1226
  	if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) ||
f55abc0fb   Jan Kara   quota: Allow to s...
1227
  	    test_bit(DQ_FAKE_B, &dquot->dq_flags))
efd8f0e6f   Christoph Hellwig   quota: stop using...
1228
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1229

f18df2289   Mingming Cao   quota: Add quota ...
1230
1231
  	tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace
  		+ space;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1232
  	if (dquot->dq_dqb.dqb_bhardlimit &&
f18df2289   Mingming Cao   quota: Add quota ...
1233
  	    tspace > dquot->dq_dqb.dqb_bhardlimit &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1234
1235
              !ignore_hardlimit(dquot)) {
  		if (!prealloc)
8e8934695   Jan Kara   quota: send messa...
1236
  			*warntype = QUOTA_NL_BHARDWARN;
efd8f0e6f   Christoph Hellwig   quota: stop using...
1237
  		return -EDQUOT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1238
1239
1240
  	}
  
  	if (dquot->dq_dqb.dqb_bsoftlimit &&
f18df2289   Mingming Cao   quota: Add quota ...
1241
  	    tspace > dquot->dq_dqb.dqb_bsoftlimit &&
268157ba6   Jan Kara   quota: Coding sty...
1242
1243
  	    dquot->dq_dqb.dqb_btime &&
  	    get_seconds() >= dquot->dq_dqb.dqb_btime &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1244
1245
              !ignore_hardlimit(dquot)) {
  		if (!prealloc)
8e8934695   Jan Kara   quota: send messa...
1246
  			*warntype = QUOTA_NL_BSOFTLONGWARN;
efd8f0e6f   Christoph Hellwig   quota: stop using...
1247
  		return -EDQUOT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1248
1249
1250
  	}
  
  	if (dquot->dq_dqb.dqb_bsoftlimit &&
f18df2289   Mingming Cao   quota: Add quota ...
1251
  	    tspace > dquot->dq_dqb.dqb_bsoftlimit &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1252
1253
  	    dquot->dq_dqb.dqb_btime == 0) {
  		if (!prealloc) {
8e8934695   Jan Kara   quota: send messa...
1254
  			*warntype = QUOTA_NL_BSOFTWARN;
268157ba6   Jan Kara   quota: Coding sty...
1255
1256
  			dquot->dq_dqb.dqb_btime = get_seconds() +
  			    sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1257
1258
1259
1260
1261
1262
  		}
  		else
  			/*
  			 * We don't allow preallocation to exceed softlimit so exceeding will
  			 * be always printed
  			 */
efd8f0e6f   Christoph Hellwig   quota: stop using...
1263
  			return -EDQUOT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1264
  	}
efd8f0e6f   Christoph Hellwig   quota: stop using...
1265
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1266
  }
12095460f   Jan Kara   quota: Increase s...
1267
  static int info_idq_free(struct dquot *dquot, qsize_t inodes)
657d3bfa9   Jan Kara   quota: implement ...
1268
  {
268157ba6   Jan Kara   quota: Coding sty...
1269
  	qsize_t newinodes;
657d3bfa9   Jan Kara   quota: implement ...
1270
  	if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
f55abc0fb   Jan Kara   quota: Allow to s...
1271
1272
  	    dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit ||
  	    !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type))
657d3bfa9   Jan Kara   quota: implement ...
1273
  		return QUOTA_NL_NOWARN;
268157ba6   Jan Kara   quota: Coding sty...
1274
1275
  	newinodes = dquot->dq_dqb.dqb_curinodes - inodes;
  	if (newinodes <= dquot->dq_dqb.dqb_isoftlimit)
657d3bfa9   Jan Kara   quota: implement ...
1276
1277
  		return QUOTA_NL_ISOFTBELOW;
  	if (dquot->dq_dqb.dqb_curinodes >= dquot->dq_dqb.dqb_ihardlimit &&
268157ba6   Jan Kara   quota: Coding sty...
1278
  	    newinodes < dquot->dq_dqb.dqb_ihardlimit)
657d3bfa9   Jan Kara   quota: implement ...
1279
1280
1281
1282
1283
1284
1285
  		return QUOTA_NL_IHARDBELOW;
  	return QUOTA_NL_NOWARN;
  }
  
  static int info_bdq_free(struct dquot *dquot, qsize_t space)
  {
  	if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
12095460f   Jan Kara   quota: Increase s...
1286
  	    dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit)
657d3bfa9   Jan Kara   quota: implement ...
1287
  		return QUOTA_NL_NOWARN;
12095460f   Jan Kara   quota: Increase s...
1288
  	if (dquot->dq_dqb.dqb_curspace - space <= dquot->dq_dqb.dqb_bsoftlimit)
657d3bfa9   Jan Kara   quota: implement ...
1289
  		return QUOTA_NL_BSOFTBELOW;
12095460f   Jan Kara   quota: Increase s...
1290
1291
  	if (dquot->dq_dqb.dqb_curspace >= dquot->dq_dqb.dqb_bhardlimit &&
  	    dquot->dq_dqb.dqb_curspace - space < dquot->dq_dqb.dqb_bhardlimit)
657d3bfa9   Jan Kara   quota: implement ...
1292
1293
1294
  		return QUOTA_NL_BHARDBELOW;
  	return QUOTA_NL_NOWARN;
  }
0a5a9c725   Jan Kara   quota: Fix warnin...
1295

189eef59e   Christoph Hellwig   quota: clean up q...
1296
1297
1298
1299
1300
1301
1302
1303
  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
1304
  /*
871a29315   Christoph Hellwig   dquot: cleanup dq...
1305
1306
1307
1308
1309
1310
1311
   * Initialize quota pointers in inode
   *
   * We do things in a bit complicated way but by that we avoid calling
   * dqget() and thus filesystem callbacks under dqptr_sem.
   *
   * 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
1312
   */
871a29315   Christoph Hellwig   dquot: cleanup dq...
1313
  static void __dquot_initialize(struct inode *inode, int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1314
1315
  {
  	unsigned int id = 0;
871a29315   Christoph Hellwig   dquot: cleanup dq...
1316
  	int cnt;
ad1e6e8da   Dmitry Monakhov   quota: sb_quota s...
1317
  	struct dquot *got[MAXQUOTAS];
cc33412fb   Jan Kara   quota: Improve lo...
1318
  	struct super_block *sb = inode->i_sb;
0a5a9c725   Jan Kara   quota: Fix warnin...
1319
  	qsize_t rsv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1320

d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1321
1322
  	/* First test before acquiring mutex - solves deadlocks when we
           * re-enter the quota code and are already holding the mutex */
189eef59e   Christoph Hellwig   quota: clean up q...
1323
  	if (!dquot_active(inode))
871a29315   Christoph Hellwig   dquot: cleanup dq...
1324
  		return;
cc33412fb   Jan Kara   quota: Improve lo...
1325
1326
1327
  
  	/* First get references to structures we might need. */
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
ad1e6e8da   Dmitry Monakhov   quota: sb_quota s...
1328
  		got[cnt] = NULL;
cc33412fb   Jan Kara   quota: Improve lo...
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
  		if (type != -1 && cnt != type)
  			continue;
  		switch (cnt) {
  		case USRQUOTA:
  			id = inode->i_uid;
  			break;
  		case GRPQUOTA:
  			id = inode->i_gid;
  			break;
  		}
  		got[cnt] = dqget(sb, id, cnt);
  	}
  
  	down_write(&sb_dqopt(sb)->dqptr_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1343
1344
1345
1346
1347
  	if (IS_NOQUOTA(inode))
  		goto out_err;
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		if (type != -1 && cnt != type)
  			continue;
cc33412fb   Jan Kara   quota: Improve lo...
1348
1349
1350
  		/* Avoid races with quotaoff() */
  		if (!sb_has_quota_active(sb, cnt))
  			continue;
4408ea41c   Jan Kara   quota: Fix possib...
1351
1352
1353
  		/* We could race with quotaon or dqget() could have failed */
  		if (!got[cnt])
  			continue;
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1354
  		if (!inode->i_dquot[cnt]) {
cc33412fb   Jan Kara   quota: Improve lo...
1355
  			inode->i_dquot[cnt] = got[cnt];
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1356
  			got[cnt] = NULL;
0a5a9c725   Jan Kara   quota: Fix warnin...
1357
1358
1359
1360
1361
1362
1363
  			/*
  			 * Make quota reservation system happy if someone
  			 * did a write before quota was turned on
  			 */
  			rsv = inode_get_rsv_space(inode);
  			if (unlikely(rsv))
  				dquot_resv_space(inode->i_dquot[cnt], rsv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1364
1365
1366
  		}
  	}
  out_err:
cc33412fb   Jan Kara   quota: Improve lo...
1367
1368
  	up_write(&sb_dqopt(sb)->dqptr_sem);
  	/* Drop unused references */
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1369
  	dqput_all(got);
871a29315   Christoph Hellwig   dquot: cleanup dq...
1370
1371
1372
1373
1374
  }
  
  void dquot_initialize(struct inode *inode)
  {
  	__dquot_initialize(inode, -1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1375
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
1376
  EXPORT_SYMBOL(dquot_initialize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1377
1378
1379
  
  /*
   * 	Release all quotas referenced by inode
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1380
   */
9f7547580   Christoph Hellwig   dquot: cleanup dq...
1381
  static void __dquot_drop(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1382
1383
  {
  	int cnt;
cc33412fb   Jan Kara   quota: Improve lo...
1384
  	struct dquot *put[MAXQUOTAS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1385

cc33412fb   Jan Kara   quota: Improve lo...
1386
  	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1387
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
cc33412fb   Jan Kara   quota: Improve lo...
1388
  		put[cnt] = inode->i_dquot[cnt];
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1389
  		inode->i_dquot[cnt] = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1390
1391
  	}
  	up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1392
  	dqput_all(put);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1393
  }
9f7547580   Christoph Hellwig   dquot: cleanup dq...
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
  void dquot_drop(struct inode *inode)
  {
  	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.
  	 */
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		if (inode->i_dquot[cnt])
  			break;
  	}
  
  	if (cnt < MAXQUOTAS)
  		__dquot_drop(inode);
  }
  EXPORT_SYMBOL(dquot_drop);
b85f4b87a   Jan Kara   quota: rename quo...
1417

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1418
  /*
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
   * 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);
  }
c469070ae   Dmitry Monakhov   quota: manage res...
1429
  void inode_add_rsv_space(struct inode *inode, qsize_t number)
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1430
1431
1432
1433
1434
  {
  	spin_lock(&inode->i_lock);
  	*inode_reserved_space(inode) += number;
  	spin_unlock(&inode->i_lock);
  }
c469070ae   Dmitry Monakhov   quota: manage res...
1435
  EXPORT_SYMBOL(inode_add_rsv_space);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1436

c469070ae   Dmitry Monakhov   quota: manage res...
1437
  void inode_claim_rsv_space(struct inode *inode, qsize_t number)
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1438
1439
1440
1441
1442
1443
  {
  	spin_lock(&inode->i_lock);
  	*inode_reserved_space(inode) -= number;
  	__inode_add_bytes(inode, number);
  	spin_unlock(&inode->i_lock);
  }
c469070ae   Dmitry Monakhov   quota: manage res...
1444
  EXPORT_SYMBOL(inode_claim_rsv_space);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1445

c469070ae   Dmitry Monakhov   quota: manage res...
1446
  void inode_sub_rsv_space(struct inode *inode, qsize_t number)
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1447
1448
1449
1450
1451
  {
  	spin_lock(&inode->i_lock);
  	*inode_reserved_space(inode) -= number;
  	spin_unlock(&inode->i_lock);
  }
c469070ae   Dmitry Monakhov   quota: manage res...
1452
  EXPORT_SYMBOL(inode_sub_rsv_space);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1453
1454
1455
1456
  
  static qsize_t inode_get_rsv_space(struct inode *inode)
  {
  	qsize_t ret;
05b5d8982   Jan Kara   quota: Fix dquot_...
1457
1458
1459
  
  	if (!inode->i_sb->dq_op->get_reserved_space)
  		return 0;
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
  	spin_lock(&inode->i_lock);
  	ret = *inode_reserved_space(inode);
  	spin_unlock(&inode->i_lock);
  	return ret;
  }
  
  static void inode_incr_space(struct inode *inode, qsize_t number,
  				int reserve)
  {
  	if (reserve)
  		inode_add_rsv_space(inode, number);
  	else
  		inode_add_bytes(inode, number);
  }
  
  static void inode_decr_space(struct inode *inode, qsize_t number, int reserve)
  {
  	if (reserve)
  		inode_sub_rsv_space(inode, number);
  	else
  		inode_sub_bytes(inode, number);
  }
  
  /*
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1484
1485
1486
1487
1488
1489
1490
   * 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
1491
1492
1493
1494
1495
   */
  
  /*
   * This operation can block, but only after everything is updated
   */
56246f9ae   Eric Sandeen   quota: use flags ...
1496
  int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1497
  {
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1498
  	int cnt, ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1499
  	char warntype[MAXQUOTAS];
56246f9ae   Eric Sandeen   quota: use flags ...
1500
1501
  	int warn = flags & DQUOT_SPACE_WARN;
  	int reserve = flags & DQUOT_SPACE_RESERVE;
0e05842bc   Eric Sandeen   quota: add the op...
1502
  	int nofail = flags & DQUOT_SPACE_NOFAIL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1503

fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1504
1505
1506
1507
  	/*
  	 * First test before acquiring mutex - solves deadlocks when we
  	 * re-enter the quota code and are already holding the mutex
  	 */
189eef59e   Christoph Hellwig   quota: clean up q...
1508
  	if (!dquot_active(inode)) {
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1509
1510
1511
1512
1513
  		inode_incr_space(inode, number, reserve);
  		goto out;
  	}
  
  	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1514
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
8e8934695   Jan Kara   quota: send messa...
1515
  		warntype[cnt] = QUOTA_NL_NOWARN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1516

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1517
1518
  	spin_lock(&dq_data_lock);
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1519
  		if (!inode->i_dquot[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1520
  			continue;
efd8f0e6f   Christoph Hellwig   quota: stop using...
1521
1522
  		ret = check_bdq(inode->i_dquot[cnt], number, !warn,
  				warntype+cnt);
0e05842bc   Eric Sandeen   quota: add the op...
1523
  		if (ret && !nofail) {
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1524
1525
  			spin_unlock(&dq_data_lock);
  			goto out_flush_warn;
f18df2289   Mingming Cao   quota: Add quota ...
1526
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1527
1528
  	}
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1529
  		if (!inode->i_dquot[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1530
  			continue;
f18df2289   Mingming Cao   quota: Add quota ...
1531
1532
1533
1534
  		if (reserve)
  			dquot_resv_space(inode->i_dquot[cnt], number);
  		else
  			dquot_incr_space(inode->i_dquot[cnt], number);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1535
  	}
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1536
  	inode_incr_space(inode, number, reserve);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1537
  	spin_unlock(&dq_data_lock);
f18df2289   Mingming Cao   quota: Add quota ...
1538

fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1539
1540
  	if (reserve)
  		goto out_flush_warn;
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1541
  	mark_all_dquot_dirty(inode->i_dquot);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1542
1543
  out_flush_warn:
  	flush_warnings(inode->i_dquot, warntype);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1544
  	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
f18df2289   Mingming Cao   quota: Add quota ...
1545
1546
1547
  out:
  	return ret;
  }
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1548
  EXPORT_SYMBOL(__dquot_alloc_space);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1549
1550
1551
1552
  
  /*
   * This operation can block, but only after everything is updated
   */
63936ddaa   Christoph Hellwig   dquot: cleanup in...
1553
  int dquot_alloc_inode(const struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1554
  {
efd8f0e6f   Christoph Hellwig   quota: stop using...
1555
  	int cnt, ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1556
  	char warntype[MAXQUOTAS];
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1557
1558
  	/* First test before acquiring mutex - solves deadlocks when we
           * re-enter the quota code and are already holding the mutex */
189eef59e   Christoph Hellwig   quota: clean up q...
1559
  	if (!dquot_active(inode))
63936ddaa   Christoph Hellwig   dquot: cleanup in...
1560
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1561
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
8e8934695   Jan Kara   quota: send messa...
1562
  		warntype[cnt] = QUOTA_NL_NOWARN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1563
  	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1564
1565
  	spin_lock(&dq_data_lock);
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1566
  		if (!inode->i_dquot[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1567
  			continue;
efd8f0e6f   Christoph Hellwig   quota: stop using...
1568
1569
  		ret = check_idq(inode->i_dquot[cnt], 1, warntype + cnt);
  		if (ret)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1570
1571
1572
1573
  			goto warn_put_all;
  	}
  
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1574
  		if (!inode->i_dquot[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1575
  			continue;
63936ddaa   Christoph Hellwig   dquot: cleanup in...
1576
  		dquot_incr_inodes(inode->i_dquot[cnt], 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1577
  	}
efd8f0e6f   Christoph Hellwig   quota: stop using...
1578

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1579
1580
  warn_put_all:
  	spin_unlock(&dq_data_lock);
63936ddaa   Christoph Hellwig   dquot: cleanup in...
1581
  	if (ret == 0)
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1582
  		mark_all_dquot_dirty(inode->i_dquot);
087ee8d5b   Jan Kara   Fix compilation w...
1583
  	flush_warnings(inode->i_dquot, warntype);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1584
1585
1586
  	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
  	return ret;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
1587
  EXPORT_SYMBOL(dquot_alloc_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1588

5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1589
1590
1591
1592
  /*
   * 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 ...
1593
1594
  {
  	int cnt;
740d9dcd9   Mingming Cao   quota: Add quota ...
1595

189eef59e   Christoph Hellwig   quota: clean up q...
1596
  	if (!dquot_active(inode)) {
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1597
  		inode_claim_rsv_space(inode, number);
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1598
  		return 0;
740d9dcd9   Mingming Cao   quota: Add quota ...
1599
1600
1601
  	}
  
  	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
740d9dcd9   Mingming Cao   quota: Add quota ...
1602
1603
1604
  	spin_lock(&dq_data_lock);
  	/* Claim reserved quotas to allocated quotas */
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1605
  		if (inode->i_dquot[cnt])
740d9dcd9   Mingming Cao   quota: Add quota ...
1606
1607
1608
1609
  			dquot_claim_reserved_space(inode->i_dquot[cnt],
  							number);
  	}
  	/* Update inode bytes */
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1610
  	inode_claim_rsv_space(inode, number);
740d9dcd9   Mingming Cao   quota: Add quota ...
1611
  	spin_unlock(&dq_data_lock);
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1612
  	mark_all_dquot_dirty(inode->i_dquot);
740d9dcd9   Mingming Cao   quota: Add quota ...
1613
  	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1614
  	return 0;
740d9dcd9   Mingming Cao   quota: Add quota ...
1615
  }
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1616
  EXPORT_SYMBOL(dquot_claim_space_nodirty);
740d9dcd9   Mingming Cao   quota: Add quota ...
1617
1618
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1619
1620
   * This operation can block, but only after everything is updated
   */
56246f9ae   Eric Sandeen   quota: use flags ...
1621
  void __dquot_free_space(struct inode *inode, qsize_t number, int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1622
1623
  {
  	unsigned int cnt;
657d3bfa9   Jan Kara   quota: implement ...
1624
  	char warntype[MAXQUOTAS];
56246f9ae   Eric Sandeen   quota: use flags ...
1625
  	int reserve = flags & DQUOT_SPACE_RESERVE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1626

d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1627
1628
  	/* First test before acquiring mutex - solves deadlocks when we
           * re-enter the quota code and are already holding the mutex */
189eef59e   Christoph Hellwig   quota: clean up q...
1629
  	if (!dquot_active(inode)) {
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1630
  		inode_decr_space(inode, number, reserve);
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1631
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1632
  	}
657d3bfa9   Jan Kara   quota: implement ...
1633

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1634
  	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1635
1636
  	spin_lock(&dq_data_lock);
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1637
  		if (!inode->i_dquot[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1638
  			continue;
657d3bfa9   Jan Kara   quota: implement ...
1639
  		warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1640
1641
1642
1643
  		if (reserve)
  			dquot_free_reserved_space(inode->i_dquot[cnt], number);
  		else
  			dquot_decr_space(inode->i_dquot[cnt], number);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1644
  	}
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1645
  	inode_decr_space(inode, number, reserve);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1646
  	spin_unlock(&dq_data_lock);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1647
1648
1649
  
  	if (reserve)
  		goto out_unlock;
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1650
  	mark_all_dquot_dirty(inode->i_dquot);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1651
  out_unlock:
657d3bfa9   Jan Kara   quota: implement ...
1652
  	flush_warnings(inode->i_dquot, warntype);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1653
  	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1654
  }
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1655
  EXPORT_SYMBOL(__dquot_free_space);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1656
1657
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1658
1659
   * This operation can block, but only after everything is updated
   */
63936ddaa   Christoph Hellwig   dquot: cleanup in...
1660
  void dquot_free_inode(const struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1661
1662
  {
  	unsigned int cnt;
657d3bfa9   Jan Kara   quota: implement ...
1663
  	char warntype[MAXQUOTAS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1664

d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1665
1666
  	/* First test before acquiring mutex - solves deadlocks when we
           * re-enter the quota code and are already holding the mutex */
189eef59e   Christoph Hellwig   quota: clean up q...
1667
  	if (!dquot_active(inode))
63936ddaa   Christoph Hellwig   dquot: cleanup in...
1668
  		return;
657d3bfa9   Jan Kara   quota: implement ...
1669

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1670
  	down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1671
1672
  	spin_lock(&dq_data_lock);
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1673
  		if (!inode->i_dquot[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1674
  			continue;
63936ddaa   Christoph Hellwig   dquot: cleanup in...
1675
1676
  		warntype[cnt] = info_idq_free(inode->i_dquot[cnt], 1);
  		dquot_decr_inodes(inode->i_dquot[cnt], 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1677
1678
  	}
  	spin_unlock(&dq_data_lock);
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1679
  	mark_all_dquot_dirty(inode->i_dquot);
657d3bfa9   Jan Kara   quota: implement ...
1680
  	flush_warnings(inode->i_dquot, warntype);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1681
  	up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1682
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
1683
  EXPORT_SYMBOL(dquot_free_inode);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1684
1685
1686
  
  /*
   * Transfer the number of inode and blocks from one diskquota to an other.
bc8e5f073   Jan Kara   quota: Refactor d...
1687
1688
1689
   * 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
1690
1691
1692
   *
   * 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...
1693
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1694
   */
bc8e5f073   Jan Kara   quota: Refactor d...
1695
  int __dquot_transfer(struct inode *inode, struct dquot **transfer_to)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1696
  {
740d9dcd9   Mingming Cao   quota: Add quota ...
1697
1698
  	qsize_t space, cur_space;
  	qsize_t rsv_space = 0;
bc8e5f073   Jan Kara   quota: Refactor d...
1699
  	struct dquot *transfer_from[MAXQUOTAS] = {};
efd8f0e6f   Christoph Hellwig   quota: stop using...
1700
  	int cnt, ret = 0;
9e32784b7   Dmitry   quota: fix dquot_...
1701
  	char is_valid[MAXQUOTAS] = {};
657d3bfa9   Jan Kara   quota: implement ...
1702
1703
  	char warntype_to[MAXQUOTAS];
  	char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1704

d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1705
1706
  	/* First test before acquiring mutex - solves deadlocks when we
           * re-enter the quota code and are already holding the mutex */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1707
  	if (IS_NOQUOTA(inode))
efd8f0e6f   Christoph Hellwig   quota: stop using...
1708
  		return 0;
cc33412fb   Jan Kara   quota: Improve lo...
1709
  	/* Initialize the arrays */
bc8e5f073   Jan Kara   quota: Refactor d...
1710
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
657d3bfa9   Jan Kara   quota: implement ...
1711
  		warntype_to[cnt] = QUOTA_NL_NOWARN;
cc33412fb   Jan Kara   quota: Improve lo...
1712
  	down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
cc33412fb   Jan Kara   quota: Improve lo...
1713
1714
  	if (IS_NOQUOTA(inode)) {	/* File without quota accounting? */
  		up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
bc8e5f073   Jan Kara   quota: Refactor d...
1715
  		return 0;
cc33412fb   Jan Kara   quota: Improve lo...
1716
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1717
  	spin_lock(&dq_data_lock);
740d9dcd9   Mingming Cao   quota: Add quota ...
1718
  	cur_space = inode_get_bytes(inode);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1719
  	rsv_space = inode_get_rsv_space(inode);
740d9dcd9   Mingming Cao   quota: Add quota ...
1720
  	space = cur_space + rsv_space;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1721
1722
  	/* Build the transfer_from list and check the limits */
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
9e32784b7   Dmitry   quota: fix dquot_...
1723
1724
1725
  		/*
  		 * Skip changes for same uid or gid or for turned off quota-type.
  		 */
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1726
  		if (!transfer_to[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1727
  			continue;
9e32784b7   Dmitry   quota: fix dquot_...
1728
1729
1730
1731
  		/* Avoid races with quotaoff() */
  		if (!sb_has_quota_active(inode->i_sb, cnt))
  			continue;
  		is_valid[cnt] = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1732
  		transfer_from[cnt] = inode->i_dquot[cnt];
efd8f0e6f   Christoph Hellwig   quota: stop using...
1733
1734
1735
1736
1737
  		ret = check_idq(transfer_to[cnt], 1, warntype_to + cnt);
  		if (ret)
  			goto over_quota;
  		ret = check_bdq(transfer_to[cnt], space, 0, warntype_to + cnt);
  		if (ret)
cc33412fb   Jan Kara   quota: Improve lo...
1738
  			goto over_quota;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1739
1740
1741
1742
1743
1744
  	}
  
  	/*
  	 * Finally perform the needed transfer from transfer_from to transfer_to
  	 */
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
9e32784b7   Dmitry   quota: fix dquot_...
1745
  		if (!is_valid[cnt])
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1746
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1747
1748
  		/* Due to IO error we might not have transfer_from[] structure */
  		if (transfer_from[cnt]) {
657d3bfa9   Jan Kara   quota: implement ...
1749
1750
1751
1752
  			warntype_from_inodes[cnt] =
  				info_idq_free(transfer_from[cnt], 1);
  			warntype_from_space[cnt] =
  				info_bdq_free(transfer_from[cnt], space);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1753
  			dquot_decr_inodes(transfer_from[cnt], 1);
740d9dcd9   Mingming Cao   quota: Add quota ...
1754
1755
1756
  			dquot_decr_space(transfer_from[cnt], cur_space);
  			dquot_free_reserved_space(transfer_from[cnt],
  						  rsv_space);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1757
1758
1759
  		}
  
  		dquot_incr_inodes(transfer_to[cnt], 1);
740d9dcd9   Mingming Cao   quota: Add quota ...
1760
1761
  		dquot_incr_space(transfer_to[cnt], cur_space);
  		dquot_resv_space(transfer_to[cnt], rsv_space);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1762
1763
1764
  
  		inode->i_dquot[cnt] = transfer_to[cnt];
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1765
  	spin_unlock(&dq_data_lock);
cc33412fb   Jan Kara   quota: Improve lo...
1766
  	up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1767
1768
  	mark_all_dquot_dirty(transfer_from);
  	mark_all_dquot_dirty(transfer_to);
86f3cbec4   Jan Kara   quota: Fix issuin...
1769
1770
1771
  	flush_warnings(transfer_to, warntype_to);
  	flush_warnings(transfer_from, warntype_from_inodes);
  	flush_warnings(transfer_from, warntype_from_space);
bc8e5f073   Jan Kara   quota: Refactor d...
1772
  	/* Pass back references to put */
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1773
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
9e32784b7   Dmitry   quota: fix dquot_...
1774
1775
  		if (is_valid[cnt])
  			transfer_to[cnt] = transfer_from[cnt];
86f3cbec4   Jan Kara   quota: Fix issuin...
1776
  	return 0;
cc33412fb   Jan Kara   quota: Improve lo...
1777
1778
1779
  over_quota:
  	spin_unlock(&dq_data_lock);
  	up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
86f3cbec4   Jan Kara   quota: Fix issuin...
1780
1781
  	flush_warnings(transfer_to, warntype_to);
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1782
  }
bc8e5f073   Jan Kara   quota: Refactor d...
1783
  EXPORT_SYMBOL(__dquot_transfer);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1784

8ddd69d6d   Dmitry Monakhov   quota: generalize...
1785
1786
1787
  /* Wrapper for transferring ownership of an inode for uid/gid only
   * Called from FSXXX_setattr()
   */
b43fa8284   Christoph Hellwig   dquot: cleanup dq...
1788
  int dquot_transfer(struct inode *inode, struct iattr *iattr)
b85f4b87a   Jan Kara   quota: rename quo...
1789
  {
bc8e5f073   Jan Kara   quota: Refactor d...
1790
1791
1792
  	struct dquot *transfer_to[MAXQUOTAS] = {};
  	struct super_block *sb = inode->i_sb;
  	int ret;
8ddd69d6d   Dmitry Monakhov   quota: generalize...
1793

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

bc8e5f073   Jan Kara   quota: Refactor d...
1797
1798
1799
  	if (iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid)
  		transfer_to[USRQUOTA] = dqget(sb, iattr->ia_uid, USRQUOTA);
  	if (iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)
4dea49697   Jan Kara   quota: Fixup dquo...
1800
  		transfer_to[GRPQUOTA] = dqget(sb, iattr->ia_gid, GRPQUOTA);
bc8e5f073   Jan Kara   quota: Refactor d...
1801
1802
1803
1804
  
  	ret = __dquot_transfer(inode, transfer_to);
  	dqput_all(transfer_to);
  	return ret;
b85f4b87a   Jan Kara   quota: rename quo...
1805
  }
b43fa8284   Christoph Hellwig   dquot: cleanup dq...
1806
  EXPORT_SYMBOL(dquot_transfer);
b85f4b87a   Jan Kara   quota: rename quo...
1807

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1808
1809
1810
1811
1812
1813
1814
  /*
   * Write info of quota file to disk
   */
  int dquot_commit_info(struct super_block *sb, int type)
  {
  	int ret;
  	struct quota_info *dqopt = sb_dqopt(sb);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1815
  	mutex_lock(&dqopt->dqio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1816
  	ret = dqopt->ops[type]->write_file_info(sb, type);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1817
  	mutex_unlock(&dqopt->dqio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1818
1819
  	return ret;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
1820
  EXPORT_SYMBOL(dquot_commit_info);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1821
1822
1823
1824
  
  /*
   * Definitions of diskquota operations.
   */
61e225dc3   Alexey Dobriyan   const: make struc...
1825
  const struct dquot_operations dquot_operations = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1826
1827
1828
1829
  	.write_dquot	= dquot_commit,
  	.acquire_dquot	= dquot_acquire,
  	.release_dquot	= dquot_release,
  	.mark_dirty	= dquot_mark_dquot_dirty,
74f783af9   Jan Kara   quota: Add callba...
1830
1831
1832
  	.write_info	= dquot_commit_info,
  	.alloc_dquot	= dquot_alloc,
  	.destroy_dquot	= dquot_destroy,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1833
  };
123e9caf1   Christoph Hellwig   quota: explicitly...
1834
  EXPORT_SYMBOL(dquot_operations);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1835

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1836
  /*
907f4554e   Christoph Hellwig   dquot: move dquot...
1837
1838
1839
1840
1841
1842
1843
1844
   * 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))
871a29315   Christoph Hellwig   dquot: cleanup dq...
1845
  		dquot_initialize(inode);
907f4554e   Christoph Hellwig   dquot: move dquot...
1846
1847
1848
1849
1850
  	return error;
  }
  EXPORT_SYMBOL(dquot_file_open);
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1851
1852
   * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
   */
0f0dd62fd   Christoph Hellwig   quota: kill the v...
1853
  int dquot_disable(struct super_block *sb, int type, unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1854
  {
0ff5af834   Jan Kara   quota: quota core...
1855
  	int cnt, ret = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1856
1857
  	struct quota_info *dqopt = sb_dqopt(sb);
  	struct inode *toputinode[MAXQUOTAS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1858

f55abc0fb   Jan Kara   quota: Allow to s...
1859
1860
1861
1862
1863
1864
  	/* 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;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1865
  	/* We need to serialize quota_off() for device */
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1866
  	mutex_lock(&dqopt->dqonoff_mutex);
9377abd02   Jan Kara   quota: don't call...
1867
1868
1869
1870
1871
1872
  
  	/*
  	 * 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.
  	 */
f55abc0fb   Jan Kara   quota: Allow to s...
1873
  	if (!sb_any_quota_loaded(sb)) {
9377abd02   Jan Kara   quota: don't call...
1874
1875
1876
  		mutex_unlock(&dqopt->dqonoff_mutex);
  		return 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1877
1878
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		toputinode[cnt] = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1879
1880
  		if (type != -1 && cnt != type)
  			continue;
f55abc0fb   Jan Kara   quota: Allow to s...
1881
  		if (!sb_has_quota_loaded(sb, cnt))
0ff5af834   Jan Kara   quota: quota core...
1882
  			continue;
f55abc0fb   Jan Kara   quota: Allow to s...
1883
1884
  
  		if (flags & DQUOT_SUSPENDED) {
cc33412fb   Jan Kara   quota: Improve lo...
1885
  			spin_lock(&dq_state_lock);
f55abc0fb   Jan Kara   quota: Allow to s...
1886
1887
  			dqopt->flags |=
  				dquot_state_flag(DQUOT_SUSPENDED, cnt);
cc33412fb   Jan Kara   quota: Improve lo...
1888
  			spin_unlock(&dq_state_lock);
f55abc0fb   Jan Kara   quota: Allow to s...
1889
  		} else {
cc33412fb   Jan Kara   quota: Improve lo...
1890
  			spin_lock(&dq_state_lock);
f55abc0fb   Jan Kara   quota: Allow to s...
1891
1892
1893
1894
1895
1896
  			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...
1897
  				spin_unlock(&dq_state_lock);
f55abc0fb   Jan Kara   quota: Allow to s...
1898
1899
1900
1901
  				iput(dqopt->files[cnt]);
  				dqopt->files[cnt] = NULL;
  				continue;
  			}
cc33412fb   Jan Kara   quota: Improve lo...
1902
  			spin_unlock(&dq_state_lock);
0ff5af834   Jan Kara   quota: quota core...
1903
  		}
f55abc0fb   Jan Kara   quota: Allow to s...
1904
1905
1906
  
  		/* 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
1907
  			continue;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1908
1909
1910
1911
1912
  
  		/* Note: these are blocking operations */
  		drop_dquot_ref(sb, cnt);
  		invalidate_dquots(sb, cnt);
  		/*
268157ba6   Jan Kara   quota: Coding sty...
1913
1914
  		 * 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
1915
1916
1917
1918
1919
1920
1921
1922
  		 */
  		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);
  
  		toputinode[cnt] = dqopt->files[cnt];
f55abc0fb   Jan Kara   quota: Allow to s...
1923
  		if (!sb_has_quota_loaded(sb, cnt))
0ff5af834   Jan Kara   quota: quota core...
1924
  			dqopt->files[cnt] = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1925
1926
1927
1928
1929
  		dqopt->info[cnt].dqi_flags = 0;
  		dqopt->info[cnt].dqi_igrace = 0;
  		dqopt->info[cnt].dqi_bgrace = 0;
  		dqopt->ops[cnt] = NULL;
  	}
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1930
  	mutex_unlock(&dqopt->dqonoff_mutex);
ca785ec66   Jan Kara   quota: Introduce ...
1931
1932
1933
1934
  
  	/* 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
1935
  	/* Sync the superblock so that buffers with quota data are written to
7b7b1ace2   Al Viro   [PATCH] saner han...
1936
  	 * disk (and so userspace sees correct data afterwards). */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
  	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++)
  		if (toputinode[cnt]) {
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1947
  			mutex_lock(&dqopt->dqonoff_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1948
1949
  			/* If quota was reenabled in the meantime, we have
  			 * nothing to do */
f55abc0fb   Jan Kara   quota: Allow to s...
1950
  			if (!sb_has_quota_loaded(sb, cnt)) {
268157ba6   Jan Kara   quota: Coding sty...
1951
1952
  				mutex_lock_nested(&toputinode[cnt]->i_mutex,
  						  I_MUTEX_QUOTA);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1953
1954
  				toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
  				  S_NOATIME | S_NOQUOTA);
268157ba6   Jan Kara   quota: Coding sty...
1955
1956
  				truncate_inode_pages(&toputinode[cnt]->i_data,
  						     0);
1b1dcc1b5   Jes Sorensen   [PATCH] mutex sub...
1957
  				mutex_unlock(&toputinode[cnt]->i_mutex);
43d2932d8   Jan Kara   quota: Use mark_i...
1958
  				mark_inode_dirty_sync(toputinode[cnt]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1959
  			}
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1960
  			mutex_unlock(&dqopt->dqonoff_mutex);
ca785ec66   Jan Kara   quota: Introduce ...
1961
1962
1963
1964
1965
1966
  		}
  	if (sb->s_bdev)
  		invalidate_bdev(sb->s_bdev);
  put_inodes:
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
  		if (toputinode[cnt]) {
0ff5af834   Jan Kara   quota: quota core...
1967
  			/* On remount RO, we keep the inode pointer so that we
f55abc0fb   Jan Kara   quota: Allow to s...
1968
1969
1970
1971
1972
1973
1974
  			 * can reenable quota on the subsequent remount RW. We
  			 * have to check 'flags' variable and not use sb_has_
  			 * function because another quotaon / quotaoff could
  			 * change global state before we got here. We refuse
  			 * to suspend quotas when there is pending delete on
  			 * the quota file... */
  			if (!(flags & DQUOT_SUSPENDED))
0ff5af834   Jan Kara   quota: quota core...
1975
1976
1977
  				iput(toputinode[cnt]);
  			else if (!toputinode[cnt]->i_nlink)
  				ret = -EBUSY;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1978
  		}
0ff5af834   Jan Kara   quota: quota core...
1979
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1980
  }
0f0dd62fd   Christoph Hellwig   quota: kill the v...
1981
  EXPORT_SYMBOL(dquot_disable);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1982

287a80958   Christoph Hellwig   quota: rename def...
1983
  int dquot_quota_off(struct super_block *sb, int type)
f55abc0fb   Jan Kara   quota: Allow to s...
1984
  {
0f0dd62fd   Christoph Hellwig   quota: kill the v...
1985
1986
  	return dquot_disable(sb, type,
  			     DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
f55abc0fb   Jan Kara   quota: Allow to s...
1987
  }
287a80958   Christoph Hellwig   quota: rename def...
1988
  EXPORT_SYMBOL(dquot_quota_off);
0f0dd62fd   Christoph Hellwig   quota: kill the v...
1989

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1990
1991
1992
  /*
   *	Turn quotas on on a device
   */
f55abc0fb   Jan Kara   quota: Allow to s...
1993
1994
1995
1996
1997
1998
  /*
   * Helper function to turn quotas on when we already have the inode of
   * quota file and no quota information is loaded.
   */
  static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
  	unsigned int flags)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
  {
  	struct quota_format_type *fmt = find_quota_format(format_id);
  	struct super_block *sb = inode->i_sb;
  	struct quota_info *dqopt = sb_dqopt(sb);
  	int error;
  	int oldflags = -1;
  
  	if (!fmt)
  		return -ESRCH;
  	if (!S_ISREG(inode->i_mode)) {
  		error = -EACCES;
  		goto out_fmt;
  	}
  	if (IS_RDONLY(inode)) {
  		error = -EROFS;
  		goto out_fmt;
  	}
  	if (!sb->s_op->quota_write || !sb->s_op->quota_read) {
  		error = -EINVAL;
  		goto out_fmt;
  	}
f55abc0fb   Jan Kara   quota: Allow to s...
2020
2021
2022
2023
2024
  	/* Usage always has to be set... */
  	if (!(flags & DQUOT_USAGE_ENABLED)) {
  		error = -EINVAL;
  		goto out_fmt;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2025

ca785ec66   Jan Kara   quota: Introduce ...
2026
  	if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) {
ab94c39b6   Jan Kara   quota: Properly i...
2027
2028
2029
2030
2031
2032
2033
  		/* 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 ...
2034
2035
  		invalidate_bdev(sb->s_bdev);
  	}
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
2036
  	mutex_lock(&dqopt->dqonoff_mutex);
f55abc0fb   Jan Kara   quota: Allow to s...
2037
  	if (sb_has_quota_loaded(sb, type)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2038
2039
2040
  		error = -EBUSY;
  		goto out_lock;
  	}
ca785ec66   Jan Kara   quota: Introduce ...
2041
2042
2043
2044
2045
  
  	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. */
dee865656   Jan Kara   quota: Silence lo...
2046
  		mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
268157ba6   Jan Kara   quota: Coding sty...
2047
2048
  		oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE |
  					     S_NOQUOTA);
ca785ec66   Jan Kara   quota: Introduce ...
2049
  		inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE;
dee865656   Jan Kara   quota: Silence lo...
2050
  		mutex_unlock(&inode->i_mutex);
26245c949   Jan Kara   quota: Cleanup S_...
2051
2052
2053
2054
  		/*
  		 * When S_NOQUOTA is set, remove dquot references as no more
  		 * references can be added
  		 */
9f7547580   Christoph Hellwig   dquot: cleanup dq...
2055
  		__dquot_drop(inode);
ca785ec66   Jan Kara   quota: Introduce ...
2056
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
  
  	error = -EIO;
  	dqopt->files[type] = igrab(inode);
  	if (!dqopt->files[type])
  		goto out_lock;
  	error = -EINVAL;
  	if (!fmt->qf_ops->check_quota_file(sb, type))
  		goto out_file_init;
  
  	dqopt->ops[type] = fmt->qf_ops;
  	dqopt->info[type].dqi_format = fmt;
0ff5af834   Jan Kara   quota: quota core...
2068
  	dqopt->info[type].dqi_fmt_id = format_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2069
  	INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
2070
  	mutex_lock(&dqopt->dqio_mutex);
268157ba6   Jan Kara   quota: Coding sty...
2071
2072
  	error = dqopt->ops[type]->read_file_info(sb, type);
  	if (error < 0) {
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
2073
  		mutex_unlock(&dqopt->dqio_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2074
2075
  		goto out_file_init;
  	}
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
2076
  	mutex_unlock(&dqopt->dqio_mutex);
cc33412fb   Jan Kara   quota: Improve lo...
2077
  	spin_lock(&dq_state_lock);
f55abc0fb   Jan Kara   quota: Allow to s...
2078
  	dqopt->flags |= dquot_state_flag(flags, type);
cc33412fb   Jan Kara   quota: Improve lo...
2079
  	spin_unlock(&dq_state_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2080
2081
  
  	add_dquot_ref(sb, type);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
2082
  	mutex_unlock(&dqopt->dqonoff_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2083
2084
2085
2086
2087
2088
2089
  
  	return 0;
  
  out_file_init:
  	dqopt->files[type] = NULL;
  	iput(inode);
  out_lock:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2090
  	if (oldflags != -1) {
dee865656   Jan Kara   quota: Silence lo...
2091
  		mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2092
2093
2094
2095
  		/* Set the flags back (in the case of accidental quotaon()
  		 * on a wrong file we don't want to mess up the flags) */
  		inode->i_flags &= ~(S_NOATIME | S_NOQUOTA | S_IMMUTABLE);
  		inode->i_flags |= oldflags;
dee865656   Jan Kara   quota: Silence lo...
2096
  		mutex_unlock(&inode->i_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2097
  	}
d01730d74   Jiaying Zhang   quota: Fix possib...
2098
  	mutex_unlock(&dqopt->dqonoff_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2099
2100
2101
2102
2103
  out_fmt:
  	put_quota_format(fmt);
  
  	return error; 
  }
0ff5af834   Jan Kara   quota: quota core...
2104
  /* Reenable quotas on remount RW */
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2105
  int dquot_resume(struct super_block *sb, int type)
0ff5af834   Jan Kara   quota: quota core...
2106
2107
2108
  {
  	struct quota_info *dqopt = sb_dqopt(sb);
  	struct inode *inode;
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2109
  	int ret = 0, cnt;
f55abc0fb   Jan Kara   quota: Allow to s...
2110
  	unsigned int flags;
0ff5af834   Jan Kara   quota: quota core...
2111

0f0dd62fd   Christoph Hellwig   quota: kill the v...
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  		if (type != -1 && cnt != type)
  			continue;
  
  		mutex_lock(&dqopt->dqonoff_mutex);
  		if (!sb_has_quota_suspended(sb, cnt)) {
  			mutex_unlock(&dqopt->dqonoff_mutex);
  			continue;
  		}
  		inode = dqopt->files[cnt];
  		dqopt->files[cnt] = NULL;
  		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...
2129
  		mutex_unlock(&dqopt->dqonoff_mutex);
0ff5af834   Jan Kara   quota: quota core...
2130

0f0dd62fd   Christoph Hellwig   quota: kill the v...
2131
2132
2133
2134
2135
  		flags = dquot_generic_flag(flags, cnt);
  		ret = vfs_load_quota_inode(inode, cnt,
  				dqopt->info[cnt].dqi_fmt_id, flags);
  		iput(inode);
  	}
0ff5af834   Jan Kara   quota: quota core...
2136
2137
2138
  
  	return ret;
  }
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2139
  EXPORT_SYMBOL(dquot_resume);
0ff5af834   Jan Kara   quota: quota core...
2140

f00c9e44a   Jan Kara   quota: Fix deadlo...
2141
2142
  int dquot_quota_on(struct super_block *sb, int type, int format_id,
  		   struct path *path)
77e69dac3   Al Viro   [PATCH] fix races...
2143
2144
2145
2146
2147
  {
  	int error = security_quota_on(path->dentry);
  	if (error)
  		return error;
  	/* Quota file not on the same filesystem? */
d8c9584ea   Al Viro   vfs: prefer ->den...
2148
  	if (path->dentry->d_sb != sb)
77e69dac3   Al Viro   [PATCH] fix races...
2149
2150
  		error = -EXDEV;
  	else
f55abc0fb   Jan Kara   quota: Allow to s...
2151
2152
2153
  		error = vfs_load_quota_inode(path->dentry->d_inode, type,
  					     format_id, DQUOT_USAGE_ENABLED |
  					     DQUOT_LIMITS_ENABLED);
77e69dac3   Al Viro   [PATCH] fix races...
2154
2155
  	return error;
  }
287a80958   Christoph Hellwig   quota: rename def...
2156
  EXPORT_SYMBOL(dquot_quota_on);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2157
2158
  
  /*
f55abc0fb   Jan Kara   quota: Allow to s...
2159
2160
2161
   * More powerful function for turning on quotas allowing setting
   * of individual quota flags
   */
287a80958   Christoph Hellwig   quota: rename def...
2162
2163
  int dquot_enable(struct inode *inode, int type, int format_id,
  		 unsigned int flags)
f55abc0fb   Jan Kara   quota: Allow to s...
2164
2165
2166
2167
2168
2169
  {
  	int ret = 0;
  	struct super_block *sb = inode->i_sb;
  	struct quota_info *dqopt = sb_dqopt(sb);
  
  	/* Just unsuspend quotas? */
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2170
  	BUG_ON(flags & DQUOT_SUSPENDED);
f55abc0fb   Jan Kara   quota: Allow to s...
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
  	if (!flags)
  		return 0;
  	/* Just updating flags needed? */
  	if (sb_has_quota_loaded(sb, type)) {
  		mutex_lock(&dqopt->dqonoff_mutex);
  		/* Now do a reliable test... */
  		if (!sb_has_quota_loaded(sb, type)) {
  			mutex_unlock(&dqopt->dqonoff_mutex);
  			goto load_quota;
  		}
  		if (flags & DQUOT_USAGE_ENABLED &&
  		    sb_has_quota_usage_enabled(sb, type)) {
  			ret = -EBUSY;
  			goto out_lock;
  		}
  		if (flags & DQUOT_LIMITS_ENABLED &&
  		    sb_has_quota_limits_enabled(sb, type)) {
  			ret = -EBUSY;
  			goto out_lock;
  		}
cc33412fb   Jan Kara   quota: Improve lo...
2191
  		spin_lock(&dq_state_lock);
f55abc0fb   Jan Kara   quota: Allow to s...
2192
  		sb_dqopt(sb)->flags |= dquot_state_flag(flags, type);
cc33412fb   Jan Kara   quota: Improve lo...
2193
  		spin_unlock(&dq_state_lock);
f55abc0fb   Jan Kara   quota: Allow to s...
2194
2195
2196
2197
2198
2199
2200
2201
  out_lock:
  		mutex_unlock(&dqopt->dqonoff_mutex);
  		return ret;
  	}
  
  load_quota:
  	return vfs_load_quota_inode(inode, type, format_id, flags);
  }
287a80958   Christoph Hellwig   quota: rename def...
2202
  EXPORT_SYMBOL(dquot_enable);
f55abc0fb   Jan Kara   quota: Allow to s...
2203
2204
  
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2205
2206
2207
   * This function is used when filesystem needs to initialize quotas
   * during mount time.
   */
287a80958   Christoph Hellwig   quota: rename def...
2208
  int dquot_quota_on_mount(struct super_block *sb, char *qf_name,
84de856ed   Christoph Hellwig   [PATCH] quota: co...
2209
  		int format_id, int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2210
  {
84de856ed   Christoph Hellwig   [PATCH] quota: co...
2211
  	struct dentry *dentry;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2212
  	int error;
c56818d7d   Jan Kara   quota: Fix WARN_O...
2213
  	mutex_lock(&sb->s_root->d_inode->i_mutex);
2fa389c5e   Christoph Hellwig   [PATCH] quota: sa...
2214
  	dentry = lookup_one_len(qf_name, sb->s_root, strlen(qf_name));
c56818d7d   Jan Kara   quota: Fix WARN_O...
2215
  	mutex_unlock(&sb->s_root->d_inode->i_mutex);
84de856ed   Christoph Hellwig   [PATCH] quota: co...
2216
2217
  	if (IS_ERR(dentry))
  		return PTR_ERR(dentry);
154f484b9   Jan Kara   [PATCH] Fix oops ...
2218
2219
2220
2221
  	if (!dentry->d_inode) {
  		error = -ENOENT;
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2222
  	error = security_quota_on(dentry);
84de856ed   Christoph Hellwig   [PATCH] quota: co...
2223
  	if (!error)
f55abc0fb   Jan Kara   quota: Allow to s...
2224
2225
  		error = vfs_load_quota_inode(dentry->d_inode, type, format_id,
  				DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
84de856ed   Christoph Hellwig   [PATCH] quota: co...
2226

154f484b9   Jan Kara   [PATCH] Fix oops ...
2227
  out:
84de856ed   Christoph Hellwig   [PATCH] quota: co...
2228
2229
  	dput(dentry);
  	return error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2230
  }
287a80958   Christoph Hellwig   quota: rename def...
2231
  EXPORT_SYMBOL(dquot_quota_on_mount);
b85f4b87a   Jan Kara   quota: rename quo...
2232

12095460f   Jan Kara   quota: Increase s...
2233
2234
2235
2236
2237
2238
2239
2240
2241
  static inline qsize_t qbtos(qsize_t blocks)
  {
  	return blocks << QIF_DQBLKSIZE_BITS;
  }
  
  static inline qsize_t stoqb(qsize_t space)
  {
  	return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2242
  /* Generic routine for getting common part of quota structure */
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
2243
  static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2244
2245
  {
  	struct mem_dqblk *dm = &dquot->dq_dqb;
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
2246
2247
2248
  	memset(di, 0, sizeof(*di));
  	di->d_version = FS_DQUOT_VERSION;
  	di->d_flags = dquot->dq_type == USRQUOTA ?
ade7ce31c   Christoph Hellwig   quota: Clean up t...
2249
  			FS_USER_QUOTA : FS_GROUP_QUOTA;
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
2250
  	di->d_id = dquot->dq_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2251
  	spin_lock(&dq_data_lock);
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
2252
2253
2254
2255
2256
2257
2258
2259
  	di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit);
  	di->d_blk_softlimit = stoqb(dm->dqb_bsoftlimit);
  	di->d_ino_hardlimit = dm->dqb_ihardlimit;
  	di->d_ino_softlimit = dm->dqb_isoftlimit;
  	di->d_bcount = dm->dqb_curspace + dm->dqb_rsvspace;
  	di->d_icount = dm->dqb_curinodes;
  	di->d_btimer = dm->dqb_btime;
  	di->d_itimer = dm->dqb_itime;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2260
2261
  	spin_unlock(&dq_data_lock);
  }
287a80958   Christoph Hellwig   quota: rename def...
2262
2263
  int dquot_get_dqblk(struct super_block *sb, int type, qid_t id,
  		    struct fs_disk_quota *di)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2264
2265
  {
  	struct dquot *dquot;
cc33412fb   Jan Kara   quota: Improve lo...
2266
  	dquot = dqget(sb, id, type);
dd6f3c6d5   Jan Kara   quota: Remove NOD...
2267
  	if (!dquot)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2268
  		return -ESRCH;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2269
2270
  	do_get_dqblk(dquot, di);
  	dqput(dquot);
cc33412fb   Jan Kara   quota: Improve lo...
2271

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2272
2273
  	return 0;
  }
287a80958   Christoph Hellwig   quota: rename def...
2274
  EXPORT_SYMBOL(dquot_get_dqblk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2275

c472b4327   Christoph Hellwig   quota: unify ->se...
2276
2277
2278
2279
  #define VFS_FS_DQ_MASK \
  	(FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \
  	 FS_DQ_ICOUNT | FS_DQ_ISOFT | FS_DQ_IHARD | \
  	 FS_DQ_BTIMER | FS_DQ_ITIMER)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2280
  /* Generic routine for setting common part of quota structure */
c472b4327   Christoph Hellwig   quota: unify ->se...
2281
  static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2282
2283
2284
  {
  	struct mem_dqblk *dm = &dquot->dq_dqb;
  	int check_blim = 0, check_ilim = 0;
338bf9afd   Andrew Perepechko   quota: do not all...
2285
  	struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
c472b4327   Christoph Hellwig   quota: unify ->se...
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
  	if (di->d_fieldmask & ~VFS_FS_DQ_MASK)
  		return -EINVAL;
  
  	if (((di->d_fieldmask & FS_DQ_BSOFT) &&
  	     (di->d_blk_softlimit > dqi->dqi_maxblimit)) ||
  	    ((di->d_fieldmask & FS_DQ_BHARD) &&
  	     (di->d_blk_hardlimit > dqi->dqi_maxblimit)) ||
  	    ((di->d_fieldmask & FS_DQ_ISOFT) &&
  	     (di->d_ino_softlimit > dqi->dqi_maxilimit)) ||
  	    ((di->d_fieldmask & FS_DQ_IHARD) &&
  	     (di->d_ino_hardlimit > dqi->dqi_maxilimit)))
338bf9afd   Andrew Perepechko   quota: do not all...
2297
  		return -ERANGE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2298
2299
  
  	spin_lock(&dq_data_lock);
c472b4327   Christoph Hellwig   quota: unify ->se...
2300
2301
  	if (di->d_fieldmask & FS_DQ_BCOUNT) {
  		dm->dqb_curspace = di->d_bcount - dm->dqb_rsvspace;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2302
  		check_blim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2303
  		set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2304
  	}
c472b4327   Christoph Hellwig   quota: unify ->se...
2305
2306
2307
2308
2309
2310
  
  	if (di->d_fieldmask & FS_DQ_BSOFT)
  		dm->dqb_bsoftlimit = qbtos(di->d_blk_softlimit);
  	if (di->d_fieldmask & FS_DQ_BHARD)
  		dm->dqb_bhardlimit = qbtos(di->d_blk_hardlimit);
  	if (di->d_fieldmask & (FS_DQ_BSOFT | FS_DQ_BHARD)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2311
  		check_blim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2312
  		set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2313
  	}
c472b4327   Christoph Hellwig   quota: unify ->se...
2314
2315
2316
  
  	if (di->d_fieldmask & FS_DQ_ICOUNT) {
  		dm->dqb_curinodes = di->d_icount;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2317
  		check_ilim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2318
  		set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2319
  	}
c472b4327   Christoph Hellwig   quota: unify ->se...
2320
2321
2322
2323
2324
2325
  
  	if (di->d_fieldmask & FS_DQ_ISOFT)
  		dm->dqb_isoftlimit = di->d_ino_softlimit;
  	if (di->d_fieldmask & FS_DQ_IHARD)
  		dm->dqb_ihardlimit = di->d_ino_hardlimit;
  	if (di->d_fieldmask & (FS_DQ_ISOFT | FS_DQ_IHARD)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2326
  		check_ilim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2327
  		set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2328
  	}
c472b4327   Christoph Hellwig   quota: unify ->se...
2329
2330
2331
  
  	if (di->d_fieldmask & FS_DQ_BTIMER) {
  		dm->dqb_btime = di->d_btimer;
e04a88a92   Jan Kara   quota: don't set ...
2332
  		check_blim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2333
  		set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
4d59bce4f   Jan Kara   quota: Keep which...
2334
  	}
c472b4327   Christoph Hellwig   quota: unify ->se...
2335
2336
2337
  
  	if (di->d_fieldmask & FS_DQ_ITIMER) {
  		dm->dqb_itime = di->d_itimer;
e04a88a92   Jan Kara   quota: don't set ...
2338
  		check_ilim = 1;
08261673c   Andrew Perepechko   quota: Fix possib...
2339
  		set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
4d59bce4f   Jan Kara   quota: Keep which...
2340
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2341
2342
  
  	if (check_blim) {
268157ba6   Jan Kara   quota: Coding sty...
2343
2344
  		if (!dm->dqb_bsoftlimit ||
  		    dm->dqb_curspace < dm->dqb_bsoftlimit) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2345
2346
  			dm->dqb_btime = 0;
  			clear_bit(DQ_BLKS_B, &dquot->dq_flags);
c472b4327   Christoph Hellwig   quota: unify ->se...
2347
  		} else if (!(di->d_fieldmask & FS_DQ_BTIMER))
268157ba6   Jan Kara   quota: Coding sty...
2348
  			/* Set grace only if user hasn't provided his own... */
338bf9afd   Andrew Perepechko   quota: do not all...
2349
  			dm->dqb_btime = get_seconds() + dqi->dqi_bgrace;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2350
2351
  	}
  	if (check_ilim) {
268157ba6   Jan Kara   quota: Coding sty...
2352
2353
  		if (!dm->dqb_isoftlimit ||
  		    dm->dqb_curinodes < dm->dqb_isoftlimit) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2354
2355
  			dm->dqb_itime = 0;
  			clear_bit(DQ_INODES_B, &dquot->dq_flags);
c472b4327   Christoph Hellwig   quota: unify ->se...
2356
  		} else if (!(di->d_fieldmask & FS_DQ_ITIMER))
268157ba6   Jan Kara   quota: Coding sty...
2357
  			/* Set grace only if user hasn't provided his own... */
338bf9afd   Andrew Perepechko   quota: do not all...
2358
  			dm->dqb_itime = get_seconds() + dqi->dqi_igrace;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2359
  	}
268157ba6   Jan Kara   quota: Coding sty...
2360
2361
  	if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit ||
  	    dm->dqb_isoftlimit)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2362
2363
2364
2365
2366
  		clear_bit(DQ_FAKE_B, &dquot->dq_flags);
  	else
  		set_bit(DQ_FAKE_B, &dquot->dq_flags);
  	spin_unlock(&dq_data_lock);
  	mark_dquot_dirty(dquot);
338bf9afd   Andrew Perepechko   quota: do not all...
2367
2368
  
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2369
  }
287a80958   Christoph Hellwig   quota: rename def...
2370
  int dquot_set_dqblk(struct super_block *sb, int type, qid_t id,
c472b4327   Christoph Hellwig   quota: unify ->se...
2371
  		  struct fs_disk_quota *di)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2372
2373
  {
  	struct dquot *dquot;
338bf9afd   Andrew Perepechko   quota: do not all...
2374
  	int rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2375

f55abc0fb   Jan Kara   quota: Allow to s...
2376
2377
2378
2379
  	dquot = dqget(sb, id, type);
  	if (!dquot) {
  		rc = -ESRCH;
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2380
  	}
338bf9afd   Andrew Perepechko   quota: do not all...
2381
  	rc = do_set_dqblk(dquot, di);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2382
  	dqput(dquot);
f55abc0fb   Jan Kara   quota: Allow to s...
2383
  out:
338bf9afd   Andrew Perepechko   quota: do not all...
2384
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2385
  }
287a80958   Christoph Hellwig   quota: rename def...
2386
  EXPORT_SYMBOL(dquot_set_dqblk);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2387
2388
  
  /* Generic routine for getting common part of quota file information */
287a80958   Christoph Hellwig   quota: rename def...
2389
  int dquot_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2390
2391
2392
  {
  	struct mem_dqinfo *mi;
    
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
2393
  	mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
f55abc0fb   Jan Kara   quota: Allow to s...
2394
  	if (!sb_has_quota_active(sb, type)) {
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
2395
  		mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2396
2397
2398
2399
2400
2401
2402
2403
2404
  		return -ESRCH;
  	}
  	mi = sb_dqopt(sb)->info + type;
  	spin_lock(&dq_data_lock);
  	ii->dqi_bgrace = mi->dqi_bgrace;
  	ii->dqi_igrace = mi->dqi_igrace;
  	ii->dqi_flags = mi->dqi_flags & DQF_MASK;
  	ii->dqi_valid = IIF_ALL;
  	spin_unlock(&dq_data_lock);
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
2405
  	mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2406
2407
  	return 0;
  }
287a80958   Christoph Hellwig   quota: rename def...
2408
  EXPORT_SYMBOL(dquot_get_dqinfo);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2409
2410
  
  /* Generic routine for setting common part of quota file information */
287a80958   Christoph Hellwig   quota: rename def...
2411
  int dquot_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2412
2413
  {
  	struct mem_dqinfo *mi;
f55abc0fb   Jan Kara   quota: Allow to s...
2414
  	int err = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2415

d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
2416
  	mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
f55abc0fb   Jan Kara   quota: Allow to s...
2417
2418
2419
  	if (!sb_has_quota_active(sb, type)) {
  		err = -ESRCH;
  		goto out;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2420
2421
2422
2423
2424
2425
2426
2427
  	}
  	mi = sb_dqopt(sb)->info + type;
  	spin_lock(&dq_data_lock);
  	if (ii->dqi_valid & IIF_BGRACE)
  		mi->dqi_bgrace = ii->dqi_bgrace;
  	if (ii->dqi_valid & IIF_IGRACE)
  		mi->dqi_igrace = ii->dqi_igrace;
  	if (ii->dqi_valid & IIF_FLAGS)
268157ba6   Jan Kara   quota: Coding sty...
2428
2429
  		mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) |
  				(ii->dqi_flags & DQF_MASK);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2430
2431
2432
2433
  	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...
2434
  out:
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
2435
  	mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
f55abc0fb   Jan Kara   quota: Allow to s...
2436
  	return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2437
  }
287a80958   Christoph Hellwig   quota: rename def...
2438
  EXPORT_SYMBOL(dquot_set_dqinfo);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2439

287a80958   Christoph Hellwig   quota: rename def...
2440
2441
2442
2443
2444
2445
2446
2447
  const struct quotactl_ops dquot_quotactl_ops = {
  	.quota_on	= dquot_quota_on,
  	.quota_off	= dquot_quota_off,
  	.quota_sync	= dquot_quota_sync,
  	.get_info	= dquot_get_dqinfo,
  	.set_info	= dquot_set_dqinfo,
  	.get_dqblk	= dquot_get_dqblk,
  	.set_dqblk	= dquot_set_dqblk
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2448
  };
287a80958   Christoph Hellwig   quota: rename def...
2449
  EXPORT_SYMBOL(dquot_quotactl_ops);
dde958885   Dmitry Monakhov   quota: Make quota...
2450
2451
2452
2453
  
  static int do_proc_dqstats(struct ctl_table *table, int write,
  		     void __user *buffer, size_t *lenp, loff_t *ppos)
  {
dde958885   Dmitry Monakhov   quota: Make quota...
2454
  	unsigned int type = (int *)table->data - dqstats.stat;
f32764bd2   Dmitry Monakhov   quota: Convert qu...
2455
2456
2457
2458
  
  	/* Update global table */
  	dqstats.stat[type] =
  			percpu_counter_sum_positive(&dqstats.counter[type]);
dde958885   Dmitry Monakhov   quota: Make quota...
2459
2460
  	return proc_dointvec(table, write, buffer, lenp, ppos);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2461
2462
  static ctl_table fs_dqstats_table[] = {
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2463
  		.procname	= "lookups",
dde958885   Dmitry Monakhov   quota: Make quota...
2464
  		.data		= &dqstats.stat[DQST_LOOKUPS],
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2465
2466
  		.maxlen		= sizeof(int),
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2467
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2468
2469
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2470
  		.procname	= "drops",
dde958885   Dmitry Monakhov   quota: Make quota...
2471
  		.data		= &dqstats.stat[DQST_DROPS],
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2472
2473
  		.maxlen		= sizeof(int),
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2474
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2475
2476
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2477
  		.procname	= "reads",
dde958885   Dmitry Monakhov   quota: Make quota...
2478
  		.data		= &dqstats.stat[DQST_READS],
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2479
2480
  		.maxlen		= sizeof(int),
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2481
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2482
2483
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2484
  		.procname	= "writes",
dde958885   Dmitry Monakhov   quota: Make quota...
2485
  		.data		= &dqstats.stat[DQST_WRITES],
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2486
2487
  		.maxlen		= sizeof(int),
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2488
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2489
2490
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2491
  		.procname	= "cache_hits",
dde958885   Dmitry Monakhov   quota: Make quota...
2492
  		.data		= &dqstats.stat[DQST_CACHE_HITS],
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2493
2494
  		.maxlen		= sizeof(int),
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2495
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2496
2497
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2498
  		.procname	= "allocated_dquots",
dde958885   Dmitry Monakhov   quota: Make quota...
2499
  		.data		= &dqstats.stat[DQST_ALLOC_DQUOTS],
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2500
2501
  		.maxlen		= sizeof(int),
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2502
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2503
2504
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2505
  		.procname	= "free_dquots",
dde958885   Dmitry Monakhov   quota: Make quota...
2506
  		.data		= &dqstats.stat[DQST_FREE_DQUOTS],
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2507
2508
  		.maxlen		= sizeof(int),
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2509
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2510
2511
  	},
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2512
  		.procname	= "syncs",
dde958885   Dmitry Monakhov   quota: Make quota...
2513
  		.data		= &dqstats.stat[DQST_SYNCS],
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2514
2515
  		.maxlen		= sizeof(int),
  		.mode		= 0444,
dde958885   Dmitry Monakhov   quota: Make quota...
2516
  		.proc_handler	= do_proc_dqstats,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2517
  	},
8e8934695   Jan Kara   quota: send messa...
2518
  #ifdef CONFIG_PRINT_QUOTA_WARNING
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2519
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2520
2521
2522
2523
  		.procname	= "warnings",
  		.data		= &flag_print_warnings,
  		.maxlen		= sizeof(int),
  		.mode		= 0644,
6d4561110   Eric W. Biederman   sysctl: Drop & in...
2524
  		.proc_handler	= proc_dointvec,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2525
  	},
8e8934695   Jan Kara   quota: send messa...
2526
  #endif
ab09203e3   Eric W. Biederman   sysctl fs: Remove...
2527
  	{ },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2528
2529
2530
2531
  };
  
  static ctl_table fs_table[] = {
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2532
2533
2534
2535
  		.procname	= "quota",
  		.mode		= 0555,
  		.child		= fs_dqstats_table,
  	},
ab09203e3   Eric W. Biederman   sysctl fs: Remove...
2536
  	{ },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2537
2538
2539
2540
  };
  
  static ctl_table sys_table[] = {
  	{
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2541
2542
2543
2544
  		.procname	= "fs",
  		.mode		= 0555,
  		.child		= fs_table,
  	},
ab09203e3   Eric W. Biederman   sysctl fs: Remove...
2545
  	{ },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2546
2547
2548
2549
  };
  
  static int __init dquot_init(void)
  {
f32764bd2   Dmitry Monakhov   quota: Convert qu...
2550
  	int i, ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2551
2552
2553
2554
  	unsigned long nr_hash, order;
  
  	printk(KERN_NOTICE "VFS: Disk quotas %s
  ", __DQUOT_VERSION__);
0b4d41471   Eric W. Biederman   [PATCH] sysctl: r...
2555
  	register_sysctl_table(sys_table);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2556

20c2df83d   Paul Mundt   mm: Remove slab d...
2557
  	dquot_cachep = kmem_cache_create("dquot",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2558
  			sizeof(struct dquot), sizeof(unsigned long) * 4,
fffb60f93   Paul Jackson   [PATCH] cpuset me...
2559
2560
  			(SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
  				SLAB_MEM_SPREAD|SLAB_PANIC),
20c2df83d   Paul Mundt   mm: Remove slab d...
2561
  			NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2562
2563
2564
2565
2566
  
  	order = 0;
  	dquot_hash = (struct hlist_head *)__get_free_pages(GFP_ATOMIC, order);
  	if (!dquot_hash)
  		panic("Cannot create dquot hash table");
f32764bd2   Dmitry Monakhov   quota: Convert qu...
2567
2568
2569
2570
2571
  	for (i = 0; i < _DQST_DQSTAT_LAST; i++) {
  		ret = percpu_counter_init(&dqstats.counter[i], 0);
  		if (ret)
  			panic("Cannot create dquot stat counters");
  	}
dde958885   Dmitry Monakhov   quota: Make quota...
2572

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
  	/* Find power-of-two hlist_heads which can fit into allocation */
  	nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct hlist_head);
  	dq_hash_bits = 0;
  	do {
  		dq_hash_bits++;
  	} while (nr_hash >> dq_hash_bits);
  	dq_hash_bits--;
  
  	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);
  
  	printk("Dquot-cache hash table entries: %ld (order %ld, %ld bytes)
  ",
  			nr_hash, order, (PAGE_SIZE << order));
8e1f936b7   Rusty Russell   mm: clean up and ...
2589
  	register_shrinker(&dqcache_shrinker);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2590
2591
2592
2593
  
  	return 0;
  }
  module_init(dquot_init);