Blame view

fs/quota/dquot.c 71.8 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
76
  #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>
  #include <linux/buffer_head.h>
16f7e0fe2   Randy Dunlap   [PATCH] capable/c...
77
  #include <linux/capability.h>
be586bab8   Adrian Bunk   [PATCH] quota: sm...
78
  #include <linux/quotaops.h>
55fa6091d   Dave Chinner   fs: move i_sb_lis...
79
  #include "../internal.h" /* ugh */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
81
  
  #include <asm/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
  /*
cc33412fb   Jan Kara   quota: Improve lo...
83
   * There are three quota SMP locks. dq_list_lock protects all lists with quotas
dde958885   Dmitry Monakhov   quota: Make quota...
84
   * and quota formats.
cc33412fb   Jan Kara   quota: Improve lo...
85
86
   * 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
87
   * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly
cc33412fb   Jan Kara   quota: Improve lo...
88
89
90
   * 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
91
   *
cc33412fb   Jan Kara   quota: Improve lo...
92
93
   * 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
94
95
96
97
98
99
   *
   * 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_...
100
101
102
103
104
105
106
   * 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
107
   *
d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
108
   * Each dquot has its dq_lock mutex. Locked dquots might not be referenced
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
109
110
111
112
113
114
115
116
117
   * 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...
118
119
   *   i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock >
   *   dqio_mutex
cc33412fb   Jan Kara   quota: Improve lo...
120
121
122
123
124
125
   * 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...
126
   * i_mutex on quota files is special (it's below dqio_mutex)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
   */
c516610cf   Jan Kara   quota: Make globa...
128
129
130
  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...
131
  EXPORT_SYMBOL(dq_data_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132

fb5ffb0e1   Jiaying Zhang   quota: Change quo...
133
  void __quota_error(struct super_block *sb, const char *func,
055adcbd7   Joe Perches   quota: Use %pV an...
134
  		   const char *fmt, ...)
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
135
  {
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
136
  	if (printk_ratelimit()) {
055adcbd7   Joe Perches   quota: Use %pV an...
137
138
  		va_list args;
  		struct va_format vaf;
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
139
  		va_start(args, fmt);
055adcbd7   Joe Perches   quota: Use %pV an...
140
141
142
143
144
145
146
  
  		vaf.fmt = fmt;
  		vaf.va = &args;
  
  		printk(KERN_ERR "Quota error (device %s): %s: %pV
  ",
  		       sb->s_id, func, &vaf);
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
147
148
149
150
  		va_end(args);
  	}
  }
  EXPORT_SYMBOL(__quota_error);
da8d1ba22   Sergey Senozhatsky   suppress warning:...
151
  #if defined(CONFIG_QUOTA_DEBUG) || defined(CONFIG_PRINT_QUOTA_WARNING)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
152
  static char *quotatypes[] = INITQFNAMES;
da8d1ba22   Sergey Senozhatsky   suppress warning:...
153
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
154
155
156
157
  static struct quota_format_type *quota_formats;	/* List of registered formats */
  static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES;
  
  /* SLAB cache for dquot structures */
e18b890bb   Christoph Lameter   [PATCH] slab: rem...
158
  static struct kmem_cache *dquot_cachep;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
160
161
162
163
164
165
166
167
  
  int register_quota_format(struct quota_format_type *fmt)
  {
  	spin_lock(&dq_list_lock);
  	fmt->qf_next = quota_formats;
  	quota_formats = fmt;
  	spin_unlock(&dq_list_lock);
  	return 0;
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
168
  EXPORT_SYMBOL(register_quota_format);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
170
171
172
173
174
  
  void unregister_quota_format(struct quota_format_type *fmt)
  {
  	struct quota_format_type **actqf;
  
  	spin_lock(&dq_list_lock);
268157ba6   Jan Kara   quota: Coding sty...
175
176
177
  	for (actqf = &quota_formats; *actqf && *actqf != fmt;
  	     actqf = &(*actqf)->qf_next)
  		;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
180
181
  	if (*actqf)
  		*actqf = (*actqf)->qf_next;
  	spin_unlock(&dq_list_lock);
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
182
  EXPORT_SYMBOL(unregister_quota_format);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
184
185
186
187
188
  
  static struct quota_format_type *find_quota_format(int id)
  {
  	struct quota_format_type *actqf;
  
  	spin_lock(&dq_list_lock);
268157ba6   Jan Kara   quota: Coding sty...
189
190
191
  	for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id;
  	     actqf = actqf->qf_next)
  		;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
195
196
  	if (!actqf || !try_module_get(actqf->qf_owner)) {
  		int qm;
  
  		spin_unlock(&dq_list_lock);
  		
268157ba6   Jan Kara   quota: Coding sty...
197
198
199
200
201
  		for (qm = 0; module_names[qm].qm_fmt_id &&
  			     module_names[qm].qm_fmt_id != id; qm++)
  			;
  		if (!module_names[qm].qm_fmt_id ||
  		    request_module(module_names[qm].qm_mod_name))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202
203
204
  			return NULL;
  
  		spin_lock(&dq_list_lock);
268157ba6   Jan Kara   quota: Coding sty...
205
206
207
  		for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id;
  		     actqf = actqf->qf_next)
  			;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
  		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...
246
  EXPORT_SYMBOL(dqstats);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247

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

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

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

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

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

6362e4d4e   Jan Kara   [PATCH] Fix oops ...
507
  restart:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
508
  	spin_lock(&dq_list_lock);
c33ed2712   Domen Puncer   [PATCH] list_for_...
509
  	list_for_each_entry_safe(dquot, tmp, &inuse_list, dq_inuse) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
511
512
513
  		if (dquot->dq_sb != sb)
  			continue;
  		if (dquot->dq_type != type)
  			continue;
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
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
541
  		/* 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
542
543
544
  		remove_dquot_hash(dquot);
  		remove_free_dquot(dquot);
  		remove_inuse(dquot);
74f783af9   Jan Kara   quota: Add callba...
545
  		do_destroy_dquot(dquot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
546
547
548
  	}
  	spin_unlock(&dq_list_lock);
  }
12c77527e   Jan Kara   quota: Implement ...
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
  /* 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 ...
566
  		spin_unlock(&dq_list_lock);
dde958885   Dmitry Monakhov   quota: Make quota...
567
  		dqstats_inc(DQST_LOOKUPS);
12c77527e   Jan Kara   quota: Implement ...
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
  		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...
583
  EXPORT_SYMBOL(dquot_scan_active);
12c77527e   Jan Kara   quota: Implement ...
584

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

5fb324ad2   Christoph Hellwig   quota: move code ...
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
652
  	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
653
654
  	return 0;
  }
287a80958   Christoph Hellwig   quota: rename def...
655
  EXPORT_SYMBOL(dquot_quota_sync);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
656
657
658
659
660
661
662
663
664
665
666
667
668
  
  /* 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...
669
  		do_destroy_dquot(dquot);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
670
671
672
673
674
675
676
677
678
  		count--;
  		head = free_dquots.prev;
  	}
  }
  
  /*
   * This is called from kswapd when we think we need some
   * more memory
   */
1495f230f   Ying Han   vmscan: change sh...
679
680
  static int shrink_dqcache_memory(struct shrinker *shrink,
  				 struct shrink_control *sc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
681
  {
1495f230f   Ying Han   vmscan: change sh...
682
  	int nr = sc->nr_to_scan;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
683
684
685
686
687
  	if (nr) {
  		spin_lock(&dq_list_lock);
  		prune_dqcache(nr);
  		spin_unlock(&dq_list_lock);
  	}
f32764bd2   Dmitry Monakhov   quota: Convert qu...
688
689
690
  	return ((unsigned)
  		percpu_counter_read_positive(&dqstats.counter[DQST_FREE_DQUOTS])
  		/100) * sysctl_vfs_cache_pressure;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
691
  }
8e1f936b7   Rusty Russell   mm: clean up and ...
692
693
694
695
  static struct shrinker dqcache_shrinker = {
  	.shrink = shrink_dqcache_memory,
  	.seeks = DEFAULT_SEEKS,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
696
697
698
  /*
   * 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
699
   */
3d9ea253a   Jan Kara   quota: Add helper...
700
  void dqput(struct dquot *dquot)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
701
  {
b48d38054   Jan Kara   quota: fix possib...
702
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703
704
  	if (!dquot)
  		return;
62af9b520   Jan Kara   quota: Convert __...
705
  #ifdef CONFIG_QUOTA_DEBUG
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
706
  	if (!atomic_read(&dquot->dq_count)) {
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
707
708
  		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
709
710
711
  		BUG();
  	}
  #endif
dde958885   Dmitry Monakhov   quota: Make quota...
712
  	dqstats_inc(DQST_DROPS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
713
714
715
716
717
  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 ...
718
  		/* Releasing dquot during quotaoff phase? */
f55abc0fb   Jan Kara   quota: Allow to s...
719
  		if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_type) &&
6362e4d4e   Jan Kara   [PATCH] Fix oops ...
720
721
  		    atomic_read(&dquot->dq_count) == 1)
  			wake_up(&dquot->dq_wait_unused);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
722
723
724
725
726
727
728
  		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...
729
730
  		ret = dquot->dq_sb->dq_op->write_dquot(dquot);
  		if (ret < 0) {
fb5ffb0e1   Jiaying Zhang   quota: Change quo...
731
732
733
  			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...
734
735
736
737
738
739
740
741
  			/*
  			 * 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
742
743
744
745
746
747
748
749
750
751
  		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 __...
752
  #ifdef CONFIG_QUOTA_DEBUG
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
753
  	/* sanity check */
8abf6a470   Eric Sesterhenn   BUG_ON() Conversi...
754
  	BUG_ON(!list_empty(&dquot->dq_free));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
755
756
757
758
  #endif
  	put_dquot_last(dquot);
  	spin_unlock(&dq_list_lock);
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
759
  EXPORT_SYMBOL(dqput);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
760

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

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

d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
774
  	mutex_init(&dquot->dq_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775
776
777
778
  	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 ...
779
  	init_waitqueue_head(&dquot->dq_wait_unused);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
780
781
782
783
784
785
786
787
788
  	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...
789
790
791
792
793
   *
   * 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
794
   */
3d9ea253a   Jan Kara   quota: Add helper...
795
  struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
797
  {
  	unsigned int hashent = hashfn(sb, id, type);
dd6f3c6d5   Jan Kara   quota: Remove NOD...
798
  	struct dquot *dquot = NULL, *empty = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
799

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

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

941d2380e   Jan Kara   quota: improve in...
896
  		iput(old_inode);
871a29315   Christoph Hellwig   dquot: cleanup dq...
897
  		__dquot_initialize(inode, type);
55fa6091d   Dave Chinner   fs: move i_sb_lis...
898
899
900
901
902
903
904
905
906
  
  		/*
  		 * 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...
907
  		old_inode = inode;
55fa6091d   Dave Chinner   fs: move i_sb_lis...
908
  		spin_lock(&inode_sb_list_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
909
  	}
55fa6091d   Dave Chinner   fs: move i_sb_lis...
910
  	spin_unlock(&inode_sb_list_lock);
941d2380e   Jan Kara   quota: improve in...
911
  	iput(old_inode);
0a5a9c725   Jan Kara   quota: Fix warnin...
912

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

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

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

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

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

189eef59e   Christoph Hellwig   quota: clean up q...
1297
1298
1299
1300
1301
1302
1303
1304
  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
1305
  /*
871a29315   Christoph Hellwig   dquot: cleanup dq...
1306
1307
1308
1309
1310
1311
1312
   * 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
1313
   */
871a29315   Christoph Hellwig   dquot: cleanup dq...
1314
  static void __dquot_initialize(struct inode *inode, int type)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1315
1316
  {
  	unsigned int id = 0;
871a29315   Christoph Hellwig   dquot: cleanup dq...
1317
  	int cnt;
ad1e6e8da   Dmitry Monakhov   quota: sb_quota s...
1318
  	struct dquot *got[MAXQUOTAS];
cc33412fb   Jan Kara   quota: Improve lo...
1319
  	struct super_block *sb = inode->i_sb;
0a5a9c725   Jan Kara   quota: Fix warnin...
1320
  	qsize_t rsv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1321

d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1322
1323
  	/* 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...
1324
  	if (!dquot_active(inode))
871a29315   Christoph Hellwig   dquot: cleanup dq...
1325
  		return;
cc33412fb   Jan Kara   quota: Improve lo...
1326
1327
1328
  
  	/* First get references to structures we might need. */
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
ad1e6e8da   Dmitry Monakhov   quota: sb_quota s...
1329
  		got[cnt] = NULL;
cc33412fb   Jan Kara   quota: Improve lo...
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
  		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
1344
1345
1346
1347
1348
  	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...
1349
1350
1351
  		/* Avoid races with quotaoff() */
  		if (!sb_has_quota_active(sb, cnt))
  			continue;
4408ea41c   Jan Kara   quota: Fix possib...
1352
1353
1354
  		/* We could race with quotaon or dqget() could have failed */
  		if (!got[cnt])
  			continue;
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1355
  		if (!inode->i_dquot[cnt]) {
cc33412fb   Jan Kara   quota: Improve lo...
1356
  			inode->i_dquot[cnt] = got[cnt];
dd6f3c6d5   Jan Kara   quota: Remove NOD...
1357
  			got[cnt] = NULL;
0a5a9c725   Jan Kara   quota: Fix warnin...
1358
1359
1360
1361
1362
1363
1364
  			/*
  			 * 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
1365
1366
1367
  		}
  	}
  out_err:
cc33412fb   Jan Kara   quota: Improve lo...
1368
1369
  	up_write(&sb_dqopt(sb)->dqptr_sem);
  	/* Drop unused references */
dc52dd3a3   Dmitry Monakhov   quota: Move dupli...
1370
  	dqput_all(got);
871a29315   Christoph Hellwig   dquot: cleanup dq...
1371
1372
1373
1374
1375
  }
  
  void dquot_initialize(struct inode *inode)
  {
  	__dquot_initialize(inode, -1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1376
  }
08d0350ce   Mingming Cao   quota: Move EXPOR...
1377
  EXPORT_SYMBOL(dquot_initialize);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1378
1379
1380
  
  /*
   * 	Release all quotas referenced by inode
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1381
   */
9f7547580   Christoph Hellwig   dquot: cleanup dq...
1382
  static void __dquot_drop(struct inode *inode)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1383
1384
  {
  	int cnt;
cc33412fb   Jan Kara   quota: Improve lo...
1385
  	struct dquot *put[MAXQUOTAS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1386

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

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

c469070ae   Dmitry Monakhov   quota: manage res...
1438
  void inode_claim_rsv_space(struct inode *inode, qsize_t number)
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1439
1440
1441
1442
1443
1444
  {
  	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...
1445
  EXPORT_SYMBOL(inode_claim_rsv_space);
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1446

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

fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1505
1506
1507
1508
  	/*
  	 * 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...
1509
  	if (!dquot_active(inode)) {
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1510
1511
1512
1513
1514
  		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
1515
  	for (cnt = 0; cnt < MAXQUOTAS; cnt++)
8e8934695   Jan Kara   quota: send messa...
1516
  		warntype[cnt] = QUOTA_NL_NOWARN;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1517

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

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

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

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

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

d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1628
1629
  	/* 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...
1630
  	if (!dquot_active(inode)) {
fd8fbfc17   Dmitry Monakhov   quota: decouple f...
1631
  		inode_decr_space(inode, number, reserve);
5dd4056db   Christoph Hellwig   dquot: cleanup sp...
1632
  		return;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1633
  	}
657d3bfa9   Jan Kara   quota: implement ...
1634

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

d3be915fc   Ingo Molnar   [PATCH] sem2mutex...
1666
1667
  	/* 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...
1668
  	if (!dquot_active(inode))
63936ddaa   Christoph Hellwig   dquot: cleanup in...
1669
  		return;
657d3bfa9   Jan Kara   quota: implement ...
1670

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

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

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

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

bc8e5f073   Jan Kara   quota: Refactor d...
1798
1799
1800
  	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...
1801
  		transfer_to[GRPQUOTA] = dqget(sb, iattr->ia_gid, GRPQUOTA);
bc8e5f073   Jan Kara   quota: Refactor d...
1802
1803
1804
1805
  
  	ret = __dquot_transfer(inode, transfer_to);
  	dqput_all(transfer_to);
  	return ret;
b85f4b87a   Jan Kara   quota: rename quo...
1806
  }
b43fa8284   Christoph Hellwig   dquot: cleanup dq...
1807
  EXPORT_SYMBOL(dquot_transfer);
b85f4b87a   Jan Kara   quota: rename quo...
1808

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

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

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1991
1992
1993
  /*
   *	Turn quotas on on a device
   */
f55abc0fb   Jan Kara   quota: Allow to s...
1994
1995
1996
1997
1998
1999
  /*
   * 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
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
  {
  	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...
2021
2022
2023
2024
2025
  	/* Usage always has to be set... */
  	if (!(flags & DQUOT_USAGE_ENABLED)) {
  		error = -EINVAL;
  		goto out_fmt;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2026

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

0f0dd62fd   Christoph Hellwig   quota: kill the v...
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
  	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...
2130
  		mutex_unlock(&dqopt->dqonoff_mutex);
0ff5af834   Jan Kara   quota: quota core...
2131

0f0dd62fd   Christoph Hellwig   quota: kill the v...
2132
2133
2134
2135
2136
  		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...
2137
2138
2139
  
  	return ret;
  }
0f0dd62fd   Christoph Hellwig   quota: kill the v...
2140
  EXPORT_SYMBOL(dquot_resume);
0ff5af834   Jan Kara   quota: quota core...
2141

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

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

12095460f   Jan Kara   quota: Increase s...
2234
2235
2236
2237
2238
2239
2240
2241
2242
  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
2243
  /* Generic routine for getting common part of quota structure */
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
2244
  static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2245
2246
  {
  	struct mem_dqblk *dm = &dquot->dq_dqb;
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
2247
2248
2249
  	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...
2250
  			FS_USER_QUOTA : FS_GROUP_QUOTA;
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
2251
  	di->d_id = dquot->dq_id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2252
  	spin_lock(&dq_data_lock);
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
2253
2254
2255
2256
2257
2258
2259
2260
  	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
2261
2262
  	spin_unlock(&dq_data_lock);
  }
287a80958   Christoph Hellwig   quota: rename def...
2263
2264
  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
2265
2266
  {
  	struct dquot *dquot;
cc33412fb   Jan Kara   quota: Improve lo...
2267
  	dquot = dqget(sb, id, type);
dd6f3c6d5   Jan Kara   quota: Remove NOD...
2268
  	if (!dquot)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2269
  		return -ESRCH;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2270
2271
  	do_get_dqblk(dquot, di);
  	dqput(dquot);
cc33412fb   Jan Kara   quota: Improve lo...
2272

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

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

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

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

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

20c2df83d   Paul Mundt   mm: Remove slab d...
2558
  	dquot_cachep = kmem_cache_create("dquot",
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2559
  			sizeof(struct dquot), sizeof(unsigned long) * 4,
fffb60f93   Paul Jackson   [PATCH] cpuset me...
2560
2561
  			(SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT|
  				SLAB_MEM_SPREAD|SLAB_PANIC),
20c2df83d   Paul Mundt   mm: Remove slab d...
2562
  			NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2563
2564
2565
2566
2567
  
  	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...
2568
2569
2570
2571
2572
  	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...
2573

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
  	/* 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 ...
2590
  	register_shrinker(&dqcache_shrinker);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2591
2592
2593
2594
  
  	return 0;
  }
  module_init(dquot_init);