~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/dquot.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Implementation of the diskquota system for the LINUX operating
  3  * system. QUOTA is implemented using the BSD system call interface as
  4  * the means of communication with the user level. Currently only the
  5  * ext2 filesystem has support for disk quotas. Other filesystems may
  6  * be added in the future. This file contains the generic routines
  7  * called by the different filesystems on allocation of an inode or
  8  * block. These routines take care of the administration needed to
  9  * have a consistent diskquota tracking system. The ideas of both
 10  * user and group quotas are based on the Melbourne quota system as
 11  * used on BSD derived systems. The internal implementation is 
 12  * based on one of the several variants of the LINUX inode-subsystem
 13  * with added complexity of the diskquota system.
 14  * 
 15  * Version: $Id: dquot.c,v 6.3 1996/11/17 18:35:34 mvw Exp mvw $
 16  * 
 17  * Author:      Marco van Wieringen <mvw@planets.elm.net>
 18  *
 19  * Fixes:   Dmitry Gorodchanin <pgmdsg@ibi.com>, 11 Feb 96
 20  *
 21  *              Revised list management to avoid races
 22  *              -- Bill Hawes, <whawes@star.net>, 9/98
 23  *
 24  *              Fixed races in dquot_transfer(), dqget() and dquot_alloc_...().
 25  *              As the consequence the locking was moved from dquot_decr_...(),
 26  *              dquot_incr_...() to calling functions.
 27  *              invalidate_dquots() now writes modified dquots.
 28  *              Serialized quota_off() and quota_on() for mount point.
 29  *              Fixed a few bugs in grow_dquots.
 30  *              Fixed deadlock in write_dquot() - we no longer account quotas on
 31  *              quota files
 32  *              remove_dquot_ref() moved to inode.c - it now traverses through inodes
 33  *              add_dquot_ref() restarts after blocking
 34  *              Added check for bogus uid and fixed check for group in quotactl.
 35  *              Jan Kara, <jack@suse.cz>, sponsored by SuSE CR, 10-11/99
 36  *
 37  * (C) Copyright 1994 - 1997 Marco van Wieringen 
 38  */
 39 
 40 #include <linux/errno.h>
 41 #include <linux/kernel.h>
 42 #include <linux/sched.h>
 43 
 44 #include <linux/types.h>
 45 #include <linux/string.h>
 46 #include <linux/fcntl.h>
 47 #include <linux/stat.h>
 48 #include <linux/tty.h>
 49 #include <linux/file.h>
 50 #include <linux/malloc.h>
 51 #include <linux/mount.h>
 52 #include <linux/smp.h>
 53 #include <linux/smp_lock.h>
 54 #include <linux/init.h>
 55 #include <linux/slab.h>
 56 
 57 #include <asm/uaccess.h>
 58 
 59 #define __DQUOT_VERSION__       "dquot_6.4.0"
 60 
 61 int nr_dquots, nr_free_dquots;
 62 int max_dquots = NR_DQUOTS;
 63 
 64 static char quotamessage[MAX_QUOTA_MESSAGE];
 65 static char *quotatypes[] = INITQFNAMES;
 66 
 67 static inline struct quota_mount_options *sb_dqopt(struct super_block *sb)
 68 {
 69         return &sb->s_dquot;
 70 }
 71 
 72 /*
 73  * Dquot List Management:
 74  * The quota code uses three lists for dquot management: the inuse_list,
 75  * free_dquots, and dquot_hash[] array. A single dquot structure may be
 76  * on all three lists, depending on its current state.
 77  *
 78  * All dquots are placed on the inuse_list when first created, and this
 79  * list is used for the sync and invalidate operations, which must look
 80  * at every dquot.
 81  *
 82  * Unused dquots (dq_count == 0) are added to the free_dquots list when
 83  * freed, and this list is searched whenever we need an available dquot.
 84  * Dquots are removed from the list as soon as they are used again, and
 85  * nr_free_dquots gives the number of dquots on the list.
 86  *
 87  * Dquots with a specific identity (device, type and id) are placed on
 88  * one of the dquot_hash[] hash chains. The provides an efficient search
 89  * mechanism to lcoate a specific dquot.
 90  */
 91 
 92 static struct dquot *inuse_list;
 93 static LIST_HEAD(free_dquots);
 94 static struct dquot *dquot_hash[NR_DQHASH];
 95 static int dquot_updating[NR_DQHASH];
 96 
 97 static struct dqstats dqstats;
 98 static DECLARE_WAIT_QUEUE_HEAD(dquot_wait);
 99 static DECLARE_WAIT_QUEUE_HEAD(update_wait);
100 
101 static void dqput(struct dquot *);
102 static struct dquot *dqduplicate(struct dquot *);
103 
104 static inline char is_enabled(struct quota_mount_options *dqopt, short type)
105 {
106         switch (type) {
107                 case USRQUOTA:
108                         return((dqopt->flags & DQUOT_USR_ENABLED) != 0);
109                 case GRPQUOTA:
110                         return((dqopt->flags & DQUOT_GRP_ENABLED) != 0);
111         }
112         return(0);
113 }
114 
115 static inline char sb_has_quota_enabled(struct super_block *sb, short type)
116 {
117         return is_enabled(sb_dqopt(sb), type);
118 }
119 
120 static inline int const hashfn(kdev_t dev, unsigned int id, short type)
121 {
122         return((HASHDEV(dev) ^ id) * (MAXQUOTAS - type)) % NR_DQHASH;
123 }
124 
125 static inline void insert_dquot_hash(struct dquot *dquot)
126 {
127         struct dquot **htable;
128 
129         htable = &dquot_hash[hashfn(dquot->dq_dev, dquot->dq_id, dquot->dq_type)];
130         if ((dquot->dq_hash_next = *htable) != NULL)
131                 (*htable)->dq_hash_pprev = &dquot->dq_hash_next;
132         *htable = dquot;
133         dquot->dq_hash_pprev = htable;
134 }
135 
136 static inline void hash_dquot(struct dquot *dquot)
137 {
138         insert_dquot_hash(dquot);
139 }
140 
141 static inline void unhash_dquot(struct dquot *dquot)
142 {
143         if (dquot->dq_hash_pprev) {
144                 if (dquot->dq_hash_next)
145                         dquot->dq_hash_next->dq_hash_pprev = dquot->dq_hash_pprev;
146                 *(dquot->dq_hash_pprev) = dquot->dq_hash_next;
147                 dquot->dq_hash_pprev = NULL;
148         }
149 }
150 
151 static inline struct dquot *find_dquot(unsigned int hashent, kdev_t dev, unsigned int id, short type)
152 {
153         struct dquot *dquot;
154 
155         for (dquot = dquot_hash[hashent]; dquot; dquot = dquot->dq_hash_next)
156                 if (dquot->dq_dev == dev && dquot->dq_id == id && dquot->dq_type == type)
157                         break;
158         return dquot;
159 }
160 
161 /* Add a dquot to the head of the free list */
162 static inline void put_dquot_head(struct dquot *dquot)
163 {
164         list_add(&dquot->dq_free, &free_dquots);
165         nr_free_dquots++;
166 }
167 
168 /* Add a dquot to the tail of the free list */
169 static inline void put_dquot_last(struct dquot *dquot)
170 {
171         list_add(&dquot->dq_free, free_dquots.prev);
172         nr_free_dquots++;
173 }
174 
175 static inline void remove_free_dquot(struct dquot *dquot)
176 {
177         /* sanity check */
178         if (list_empty(&dquot->dq_free)) {
179                 printk("remove_free_dquot: dquot not on the free list??\n");
180                 return;         /* J.K. Just don't do anything */
181         }
182         list_del(&dquot->dq_free);
183         INIT_LIST_HEAD(&dquot->dq_free);
184         nr_free_dquots--;
185 }
186 
187 static inline void put_inuse(struct dquot *dquot)
188 {
189         if ((dquot->dq_next = inuse_list) != NULL)
190                 inuse_list->dq_pprev = &dquot->dq_next;
191         inuse_list = dquot;
192         dquot->dq_pprev = &inuse_list;
193 }
194 
195 #if 0   /* currently not needed */
196 static inline void remove_inuse(struct dquot *dquot)
197 {
198         if (dquot->dq_pprev) {
199                 if (dquot->dq_next)
200                         dquot->dq_next->dq_pprev = dquot->dq_pprev;
201                 *dquot->dq_pprev = dquot->dq_next;
202                 dquot->dq_pprev = NULL;
203         }
204 }
205 #endif
206 
207 static void __wait_on_dquot(struct dquot *dquot)
208 {
209         DECLARE_WAITQUEUE(wait, current);
210 
211         add_wait_queue(&dquot->dq_wait, &wait);
212 repeat:
213         set_current_state(TASK_UNINTERRUPTIBLE);
214         if (dquot->dq_flags & DQ_LOCKED) {
215                 schedule();
216                 goto repeat;
217         }
218         remove_wait_queue(&dquot->dq_wait, &wait);
219         current->state = TASK_RUNNING;
220 }
221 
222 static inline void wait_on_dquot(struct dquot *dquot)
223 {
224         if (dquot->dq_flags & DQ_LOCKED)
225                 __wait_on_dquot(dquot);
226 }
227 
228 static inline void lock_dquot(struct dquot *dquot)
229 {
230         wait_on_dquot(dquot);
231         dquot->dq_flags |= DQ_LOCKED;
232 }
233 
234 static inline void unlock_dquot(struct dquot *dquot)
235 {
236         dquot->dq_flags &= ~DQ_LOCKED;
237         wake_up(&dquot->dq_wait);
238 }
239 
240 /*
241  *      We don't have to be afraid of deadlocks as we never have quotas on quota files...
242  */
243 static void write_dquot(struct dquot *dquot)
244 {
245         short type = dquot->dq_type;
246         struct file *filp;
247         mm_segment_t fs;
248         loff_t offset;
249         ssize_t ret;
250         struct semaphore *sem = &dquot->dq_sb->s_dquot.dqio_sem;
251 
252         lock_dquot(dquot);
253         if (!dquot->dq_sb) {    /* Invalidated quota? */
254                 unlock_dquot(dquot);
255                 return;
256         }
257         down(sem);
258         filp = dquot->dq_sb->s_dquot.files[type];
259         offset = dqoff(dquot->dq_id);
260         fs = get_fs();
261         set_fs(KERNEL_DS);
262 
263         /*
264          * Note: clear the DQ_MOD flag unconditionally,
265          * so we don't loop forever on failure.
266          */
267         dquot->dq_flags &= ~DQ_MOD;
268         ret = 0;
269         if (filp)
270                 ret = filp->f_op->write(filp, (char *)&dquot->dq_dqb, 
271                                         sizeof(struct dqblk), &offset);
272         if (ret != sizeof(struct dqblk))
273                 printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
274                         kdevname(dquot->dq_dev));
275 
276         set_fs(fs);
277         up(sem);
278         unlock_dquot(dquot);
279 
280         dqstats.writes++;
281 }
282 
283 static void read_dquot(struct dquot *dquot)
284 {
285         short type = dquot->dq_type;
286         struct file *filp;
287         mm_segment_t fs;
288         loff_t offset;
289 
290         filp = dquot->dq_sb->s_dquot.files[type];
291         if (filp == (struct file *)NULL)
292                 return;
293 
294         lock_dquot(dquot);
295         if (!dquot->dq_sb)      /* Invalidated quota? */
296                 goto out_lock;
297         /* Now we are sure filp is valid - the dquot isn't invalidated */
298         down(&dquot->dq_sb->s_dquot.dqio_sem);
299         offset = dqoff(dquot->dq_id);
300         fs = get_fs();
301         set_fs(KERNEL_DS);
302         filp->f_op->read(filp, (char *)&dquot->dq_dqb, sizeof(struct dqblk), &offset);
303         up(&dquot->dq_sb->s_dquot.dqio_sem);
304         set_fs(fs);
305 
306         if (dquot->dq_bhardlimit == 0 && dquot->dq_bsoftlimit == 0 &&
307             dquot->dq_ihardlimit == 0 && dquot->dq_isoftlimit == 0)
308                 dquot->dq_flags |= DQ_FAKE;
309         dqstats.reads++;
310 out_lock:
311         unlock_dquot(dquot);
312 }
313 
314 /*
315  * Unhash and selectively clear the dquot structure,
316  * but preserve the use count, list pointers, and
317  * wait queue.
318  */
319 void clear_dquot(struct dquot *dquot)
320 {
321         /* unhash it first */
322         unhash_dquot(dquot);
323         dquot->dq_sb = NULL;
324         dquot->dq_flags = 0;
325         dquot->dq_referenced = 0;
326         memset(&dquot->dq_dqb, 0, sizeof(struct dqblk));
327 }
328 
329 void invalidate_dquots(kdev_t dev, short type)
330 {
331         struct dquot *dquot, *next;
332         int need_restart;
333 
334 restart:
335         next = inuse_list;      /* Here it is better. Otherwise the restart doesn't have any sense ;-) */
336         need_restart = 0;
337         while ((dquot = next) != NULL) {
338                 next = dquot->dq_next;
339                 if (dquot->dq_dev != dev)
340                         continue;
341                 if (dquot->dq_type != type)
342                         continue;
343                 if (!dquot->dq_sb)      /* Already invalidated entry? */
344                         continue;
345                 if (dquot->dq_flags & DQ_LOCKED) {
346                         __wait_on_dquot(dquot);
347 
348                         /* Set the flag for another pass. */
349                         need_restart = 1;
350                         /*
351                          * Make sure it's still the same dquot.
352                          */
353                         if (dquot->dq_dev != dev)
354                                 continue;
355                         if (dquot->dq_type != type)
356                                 continue;
357                         if (!dquot->dq_sb)
358                                 continue;
359                 }
360                 /*
361                  *  Because inodes needn't to be the only holders of dquot
362                  *  the quota needn't to be written to disk. So we write it
363                  *  ourselves before discarding the data just for sure...
364                  */
365                 if (dquot->dq_flags & DQ_MOD && dquot->dq_sb)
366                 {
367                         write_dquot(dquot);
368                         need_restart = 1;       /* We slept on IO */
369                 }
370                 clear_dquot(dquot);
371         }
372         /*
373          * If anything blocked, restart the operation
374          * to ensure we don't miss any dquots.
375          */ 
376         if (need_restart)
377                 goto restart;
378 }
379 
380 int sync_dquots(kdev_t dev, short type)
381 {
382         struct dquot *dquot, *next, *ddquot;
383         int need_restart;
384 
385 restart:
386         next = inuse_list;
387         need_restart = 0;
388         while ((dquot = next) != NULL) {
389                 next = dquot->dq_next;
390                 if (dev && dquot->dq_dev != dev)
391                         continue;
392                 if (type != -1 && dquot->dq_type != type)
393                         continue;
394                 if (!dquot->dq_sb)      /* Invalidated? */
395                         continue;
396                 if (!(dquot->dq_flags & (DQ_LOCKED | DQ_MOD)))
397                         continue;
398 
399                 if ((ddquot = dqduplicate(dquot)) == NODQUOT)
400                         continue;
401                 if (ddquot->dq_flags & DQ_MOD)
402                         write_dquot(ddquot);
403                 dqput(ddquot);
404                 /* Set the flag for another pass. */
405                 need_restart = 1;
406         }
407         /*
408          * If anything blocked, restart the operation
409          * to ensure we don't miss any dquots.
410          */ 
411         if (need_restart)
412                 goto restart;
413 
414         dqstats.syncs++;
415         return(0);
416 }
417 
418 /* NOTE: If you change this function please check whether dqput_blocks() works right... */
419 static void dqput(struct dquot *dquot)
420 {
421         if (!dquot)
422                 return;
423         if (!dquot->dq_count) {
424                 printk("VFS: dqput: trying to free free dquot\n");
425                 printk("VFS: device %s, dquot of %s %d\n",
426                         kdevname(dquot->dq_dev), quotatypes[dquot->dq_type],
427                         dquot->dq_id);
428                 return;
429         }
430 
431         /*
432          * If the dq_sb pointer isn't initialized this entry needs no
433          * checking and doesn't need to be written. It's just an empty
434          * dquot that is put back on to the freelist.
435          */
436         if (dquot->dq_sb)
437                 dqstats.drops++;
438 we_slept:
439         if (dquot->dq_count > 1) {
440                 /* We have more than one user... We can simply decrement use count */
441                 dquot->dq_count--;
442                 return;
443         }
444         if (dquot->dq_flags & DQ_LOCKED) {
445                 printk(KERN_ERR "VFS: Locked quota to be put on the free list.\n");
446                 dquot->dq_flags &= ~DQ_LOCKED;
447         }
448         if (dquot->dq_sb && dquot->dq_flags & DQ_MOD) {
449                 write_dquot(dquot);
450                 goto we_slept;
451         }
452 
453         /* sanity check */
454         if (!list_empty(&dquot->dq_free)) {
455                 printk(KERN_ERR "dqput: dquot already on free list??\n");
456                 dquot->dq_count--;      /* J.K. Just decrementing use count seems safer... */
457                 return;
458         }
459         dquot->dq_count--;
460         dquot->dq_flags &= ~DQ_MOD;     /* Modified flag has no sense on free list */
461         /* Place at end of LRU free queue */
462         put_dquot_last(dquot);
463         wake_up(&dquot_wait);
464 }
465 
466 static int grow_dquots(void)
467 {
468         struct dquot *dquot;
469         int cnt = 0;
470 
471         while (cnt < 32) {
472                 dquot = kmem_cache_alloc(dquot_cachep, SLAB_KERNEL);
473                 if(!dquot)
474                         return cnt;
475 
476                 nr_dquots++;
477                 memset((caddr_t)dquot, 0, sizeof(struct dquot));
478                 init_waitqueue_head(&dquot->dq_wait);
479                 /* all dquots go on the inuse_list */
480                 put_inuse(dquot);
481                 put_dquot_head(dquot);
482                 cnt++;
483         }
484         return cnt;
485 }
486 
487 static struct dquot *find_best_candidate_weighted(void)
488 {
489         struct list_head *tmp = &free_dquots;
490         struct dquot *dquot, *best = NULL;
491         unsigned long myscore, bestscore = ~0U;
492         int limit = (nr_free_dquots > 128) ? nr_free_dquots >> 2 : 32;
493 
494         while ((tmp = tmp->next) != &free_dquots && --limit) {
495                 dquot = list_entry(tmp, struct dquot, dq_free);
496                 /* This should never happen... */
497                 if (dquot->dq_flags & (DQ_LOCKED | DQ_MOD))
498                         continue;
499                 myscore = dquot->dq_referenced;
500                 if (myscore < bestscore) {
501                         bestscore = myscore;
502                         best = dquot;
503                 }
504         }
505         return best;
506 }
507 
508 static inline struct dquot *find_best_free(void)
509 {
510         struct list_head *tmp = &free_dquots;
511         struct dquot *dquot;
512         int limit = (nr_free_dquots > 1024) ? nr_free_dquots >> 5 : 32;
513 
514         while ((tmp = tmp->next) != &free_dquots && --limit) {
515                 dquot = list_entry(tmp, struct dquot, dq_free);
516                 if (dquot->dq_referenced == 0)
517                         return dquot;
518         }
519         return NULL;
520 }
521 
522 struct dquot *get_empty_dquot(void)
523 {
524         struct dquot *dquot;
525         int shrink = 8; /* Number of times we should try to shrink dcache and icache */
526 
527 repeat:
528         dquot = find_best_free();
529         if (!dquot)
530                 goto pressure;
531 got_it:
532         /* Sanity checks */
533         if (dquot->dq_flags & DQ_LOCKED)
534                 printk(KERN_ERR "VFS: Locked dquot on the free list\n");
535         if (dquot->dq_count != 0)
536                 printk(KERN_ERR "VFS: free dquot count=%d\n", dquot->dq_count);
537 
538         remove_free_dquot(dquot);
539         dquot->dq_count = 1;
540         /* unhash and selectively clear the structure */
541         clear_dquot(dquot);
542         return dquot;
543 
544 pressure:
545         if (nr_dquots < max_dquots)
546                 if (grow_dquots())
547                         goto repeat;
548 
549         dquot = find_best_candidate_weighted();
550         if (dquot)
551                 goto got_it;
552         /*
553          * Try pruning the dcache to free up some dquots ...
554          */
555         if (shrink) {
556                 printk(KERN_DEBUG "get_empty_dquot: pruning dcache and icache\n");
557                 prune_dcache(128);
558                 prune_icache(128);
559                 shrink--;
560                 goto repeat;
561         }
562 
563         printk("VFS: No free dquots, contact mvw@planets.elm.net\n");
564         sleep_on(&dquot_wait);
565         goto repeat;
566 }
567 
568 static struct dquot *dqget(struct super_block *sb, unsigned int id, short type)
569 {
570         unsigned int hashent = hashfn(sb->s_dev, id, type);
571         struct dquot *dquot, *empty = NULL;
572         struct quota_mount_options *dqopt = sb_dqopt(sb);
573 
574         if (!is_enabled(dqopt, type))
575                 return(NODQUOT);
576 
577 we_slept:
578         if ((dquot = find_dquot(hashent, sb->s_dev, id, type)) == NULL) {
579                 if (empty == NULL) {
580                         dquot_updating[hashent]++;
581                         empty = get_empty_dquot();
582                         if (!--dquot_updating[hashent])
583                                 wake_up(&update_wait);
584                         goto we_slept;
585                 }
586                 dquot = empty;
587                 dquot->dq_id = id;
588                 dquot->dq_type = type;
589                 dquot->dq_dev = sb->s_dev;
590                 dquot->dq_sb = sb;
591                 /* hash it first so it can be found */
592                 hash_dquot(dquot);
593                 read_dquot(dquot);
594         } else {
595                 if (!dquot->dq_count++) {
596                         remove_free_dquot(dquot);
597                 } else
598                         dqstats.cache_hits++;
599                 wait_on_dquot(dquot);
600                 if (empty)
601                         dqput(empty);
602         }
603 
604         while (dquot_updating[hashent])
605                 sleep_on(&update_wait);
606 
607         if (!dquot->dq_sb) {    /* Has somebody invalidated entry under us? */
608                 /*
609                  *  Do it as if the quota was invalidated before we started
610                  */
611                 dqput(dquot);
612                 return NODQUOT;
613         }
614         dquot->dq_referenced++;
615         dqstats.lookups++;
616 
617         return dquot;
618 }
619 
620 static struct dquot *dqduplicate(struct dquot *dquot)
621 {
622         if (dquot == NODQUOT || !dquot->dq_sb)
623                 return NODQUOT;
624         dquot->dq_count++;
625         wait_on_dquot(dquot);
626         if (!dquot->dq_sb) {
627                 dquot->dq_count--;
628                 return NODQUOT;
629         }
630         dquot->dq_referenced++;
631         dqstats.lookups++;
632         return dquot;
633 }
634 
635 /* Check whether this inode is quota file */
636 static inline int is_quotafile(struct inode *inode)
637 {
638         int cnt;
639         struct quota_mount_options *dqopt = sb_dqopt(inode->i_sb);
640         struct file **files;
641 
642         if (!dqopt)
643                 return 0;
644         files = dqopt->files;
645         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
646                 if (files[cnt] && files[cnt]->f_dentry->d_inode == inode)
647                         return 1;
648         return 0;
649 }
650 
651 static int dqinit_needed(struct inode *inode, short type)
652 {
653         int cnt;
654 
655         if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
656                 return 0;
657         if (is_quotafile(inode))
658                 return 0;
659         if (type != -1)
660                 return inode->i_dquot[type] == NODQUOT;
661         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
662                 if (inode->i_dquot[cnt] == NODQUOT)
663                         return 1;
664         return 0;
665 }
666 
667 static void add_dquot_ref(struct super_block *sb, short type)
668 {
669         struct list_head *p;
670         struct inode *inode;
671 
672         if (!sb->dq_op)
673                 return; /* nothing to do */
674 
675 restart:
676         file_list_lock();
677         for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
678                 struct file *filp = list_entry(p, struct file, f_list);
679                 if (!filp->f_dentry)
680                         continue;
681                 inode = filp->f_dentry->d_inode;
682                 if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
683                         file_list_unlock();
684                         sb->dq_op->initialize(inode, type);
685                         inode->i_flags |= S_QUOTA;
686                         /* As we may have blocked we had better restart... */
687                         goto restart;
688                 }
689         }
690         file_list_unlock();
691 }
692 
693 /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */
694 static inline int dqput_blocks(struct dquot *dquot)
695 {
696         if (dquot->dq_count == 1)
697                 return 1;
698         return 0;
699 }
700 
701 /* Remove references to dquots from inode - add dquot to list for freeing if needed */
702 int remove_inode_dquot_ref(struct inode *inode, short type, struct list_head *tofree_head)
703 {
704         struct dquot *dquot = inode->i_dquot[type];
705         int cnt;
706 
707         inode->i_dquot[type] = NODQUOT;
708         /* any other quota in use? */
709         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
710                 if (inode->i_dquot[cnt] != NODQUOT)
711                         goto put_it;
712         }
713         inode->i_flags &= ~S_QUOTA;
714 put_it:
715         if (dquot != NODQUOT) {
716                 if (dqput_blocks(dquot)) {
717                         if (dquot->dq_count != 1)
718                                 printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", dquot->dq_count);
719                         list_add(&dquot->dq_free, tofree_head); /* As dquot must have currently users it can't be on the free list... */
720                         return 1;
721                 } else {
722                         dqput(dquot);   /* We have guaranteed we won't block */
723                 }
724         }
725         return 0;
726 }
727 
728 /* Free list of dquots - called from inode.c */
729 void put_dquot_list(struct list_head *tofree_head)
730 {
731         struct list_head *act_head = tofree_head->next;
732         struct dquot *dquot;
733 
734         /* So now we have dquots on the list... Just free them */
735         while (act_head != tofree_head) {
736                 dquot = list_entry(act_head, struct dquot, dq_free);
737                 act_head = act_head->next;
738                 list_del(&dquot->dq_free);      /* Remove dquot from the list so we won't have problems... */
739                 INIT_LIST_HEAD(&dquot->dq_free);
740                 dqput(dquot);
741         }
742 }
743 
744 static inline void dquot_incr_inodes(struct dquot *dquot, unsigned long number)
745 {
746         dquot->dq_curinodes += number;
747         dquot->dq_flags |= DQ_MOD;
748 }
749 
750 static inline void dquot_incr_blocks(struct dquot *dquot, unsigned long number)
751 {
752         dquot->dq_curblocks += number;
753         dquot->dq_flags |= DQ_MOD;
754 }
755 
756 static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number)
757 {
758         if (dquot->dq_curinodes > number)
759                 dquot->dq_curinodes -= number;
760         else
761                 dquot->dq_curinodes = 0;
762         if (dquot->dq_curinodes < dquot->dq_isoftlimit)
763                 dquot->dq_itime = (time_t) 0;
764         dquot->dq_flags &= ~DQ_INODES;
765         dquot->dq_flags |= DQ_MOD;
766 }
767 
768 static inline void dquot_decr_blocks(struct dquot *dquot, unsigned long number)
769 {
770         if (dquot->dq_curblocks > number)
771                 dquot->dq_curblocks -= number;
772         else
773                 dquot->dq_curblocks = 0;
774         if (dquot->dq_curblocks < dquot->dq_bsoftlimit)
775                 dquot->dq_btime = (time_t) 0;
776         dquot->dq_flags &= ~DQ_BLKS;
777         dquot->dq_flags |= DQ_MOD;
778 }
779 
780 static inline int need_print_warning(struct dquot *dquot, int flag)
781 {
782         switch (dquot->dq_type) {
783                 case USRQUOTA:
784                         return current->fsuid == dquot->dq_id && !(dquot->dq_flags & flag);
785                 case GRPQUOTA:
786                         return in_group_p(dquot->dq_id) && !(dquot->dq_flags & flag);
787         }
788         return 0;
789 }
790 
791 static void print_warning(struct dquot *dquot, int flag, const char *fmtstr)
792 {
793         if (!need_print_warning(dquot, flag))
794                 return;
795         sprintf(quotamessage, fmtstr,
796                 bdevname(dquot->dq_sb->s_dev), quotatypes[dquot->dq_type]);
797         tty_write_message(current->tty, quotamessage);
798         dquot->dq_flags |= flag;
799 }
800 
801 static inline char ignore_hardlimit(struct dquot *dquot)
802 {
803         return capable(CAP_SYS_RESOURCE) && !dquot->dq_sb->s_dquot.rsquash[dquot->dq_type];
804 }
805 
806 static int check_idq(struct dquot *dquot, u_long inodes)
807 {
808         if (inodes <= 0 || dquot->dq_flags & DQ_FAKE)
809                 return QUOTA_OK;
810 
811         if (dquot->dq_ihardlimit &&
812            (dquot->dq_curinodes + inodes) > dquot->dq_ihardlimit &&
813             !ignore_hardlimit(dquot)) {
814                 print_warning(dquot, DQ_INODES, "%s: write failed, %s file limit reached\n");
815                 return NO_QUOTA;
816         }
817 
818         if (dquot->dq_isoftlimit &&
819            (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
820             dquot->dq_itime && CURRENT_TIME >= dquot->dq_itime &&
821             !ignore_hardlimit(dquot)) {
822                 print_warning(dquot, DQ_INODES, "%s: warning, %s file quota exceeded too long.\n");
823                 return NO_QUOTA;
824         }
825 
826         if (dquot->dq_isoftlimit &&
827            (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
828             dquot->dq_itime == 0) {
829                 print_warning(dquot, 0, "%s: warning, %s file quota exceeded\n");
830                 dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[dquot->dq_type];
831         }
832 
833         return QUOTA_OK;
834 }
835 
836 static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc)
837 {
838         if (blocks <= 0 || dquot->dq_flags & DQ_FAKE)
839                 return QUOTA_OK;
840 
841         if (dquot->dq_bhardlimit &&
842            (dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit &&
843             !ignore_hardlimit(dquot)) {
844                 if (!prealloc)
845                         print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk limit reached.\n");
846                 return NO_QUOTA;
847         }
848 
849         if (dquot->dq_bsoftlimit &&
850            (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
851             dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime &&
852             !ignore_hardlimit(dquot)) {
853                 if (!prealloc)
854                         print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk quota exceeded too long.\n");
855                 return NO_QUOTA;
856         }
857 
858         if (dquot->dq_bsoftlimit &&
859            (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
860             dquot->dq_btime == 0) {
861                 if (!prealloc) {
862                         print_warning(dquot, 0, "%s: warning, %s disk quota exceeded\n");
863                         dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[dquot->dq_type];
864                 }
865                 else
866                         /*
867                          * We don't allow preallocation to exceed softlimit so exceeding will
868                          * be always printed
869                          */
870                         return NO_QUOTA;
871         }
872 
873         return QUOTA_OK;
874 }
875 
876 /*
877  * Initialize a dquot-struct with new quota info. This is used by the
878  * system call interface functions.
879  */ 
880 static int set_dqblk(struct super_block *sb, int id, short type, int flags, struct dqblk *dqblk)
881 {
882         struct dquot *dquot;
883         int error = -EFAULT;
884         struct dqblk dq_dqblk;
885 
886         if (dqblk == (struct dqblk *)NULL)
887                 return error;
888 
889         if (flags & QUOTA_SYSCALL) {
890                 if (copy_from_user(&dq_dqblk, dqblk, sizeof(struct dqblk)))
891                         return(error);
892         } else
893                 memcpy((caddr_t)&dq_dqblk, (caddr_t)dqblk, sizeof(struct dqblk));
894 
895         if (sb && (dquot = dqget(sb, id, type)) != NODQUOT) {
896                 lock_dquot(dquot);
897 
898                 if (id > 0 && ((flags & SET_QUOTA) || (flags & SET_QLIMIT))) {
899                         dquot->dq_bhardlimit = dq_dqblk.dqb_bhardlimit;
900                         dquot->dq_bsoftlimit = dq_dqblk.dqb_bsoftlimit;
901                         dquot->dq_ihardlimit = dq_dqblk.dqb_ihardlimit;
902                         dquot->dq_isoftlimit = dq_dqblk.dqb_isoftlimit;
903                 }
904 
905                 if ((flags & SET_QUOTA) || (flags & SET_USE)) {
906                         if (dquot->dq_isoftlimit &&
907                             dquot->dq_curinodes < dquot->dq_isoftlimit &&
908                             dq_dqblk.dqb_curinodes >= dquot->dq_isoftlimit)
909                                 dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[type];
910                         dquot->dq_curinodes = dq_dqblk.dqb_curinodes;
911                         if (dquot->dq_curinodes < dquot->dq_isoftlimit)
912                                 dquot->dq_flags &= ~DQ_INODES;
913                         if (dquot->dq_bsoftlimit &&
914                             dquot->dq_curblocks < dquot->dq_bsoftlimit &&
915                             dq_dqblk.dqb_curblocks >= dquot->dq_bsoftlimit)
916                                 dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[type];
917                         dquot->dq_curblocks = dq_dqblk.dqb_curblocks;
918                         if (dquot->dq_curblocks < dquot->dq_bsoftlimit)
919                                 dquot->dq_flags &= ~DQ_BLKS;
920                 }
921 
922                 if (id == 0) {
923                         dquot->dq_sb->s_dquot.block_expire[type] = dquot->dq_btime = dq_dqblk.dqb_btime;
924                         dquot->dq_sb->s_dquot.inode_expire[type] = dquot->dq_itime = dq_dqblk.dqb_itime;
925                 }
926 
927                 if (dq_dqblk.dqb_bhardlimit == 0 && dq_dqblk.dqb_bsoftlimit == 0 &&
928                     dq_dqblk.dqb_ihardlimit == 0 && dq_dqblk.dqb_isoftlimit == 0)
929                         dquot->dq_flags |= DQ_FAKE;
930                 else
931                         dquot->dq_flags &= ~DQ_FAKE;
932 
933                 dquot->dq_flags |= DQ_MOD;
934                 unlock_dquot(dquot);
935                 dqput(dquot);
936         }
937         return(0);
938 }
939 
940 static int get_quota(struct super_block *sb, int id, short type, struct dqblk *dqblk)
941 {
942         struct dquot *dquot;
943         int error = -ESRCH;
944 
945         if (!sb || !sb_has_quota_enabled(sb, type))
946                 goto out;
947         dquot = dqget(sb, id, type);
948         if (dquot == NODQUOT)
949                 goto out;
950 
951         lock_dquot(dquot);      /* We must protect against invalidating the quota */
952         error = -EFAULT;
953         if (dqblk && !copy_to_user(dqblk, &dquot->dq_dqb, sizeof(struct dqblk)))
954                 error = 0;
955         unlock_dquot(dquot);
956         dqput(dquot);
957 out:
958         return error;
959 }
960 
961 static int get_stats(caddr_t addr)
962 {
963         int error = -EFAULT;
964         struct dqstats stats;
965 
966         dqstats.allocated_dquots = nr_dquots;
967         dqstats.free_dquots = nr_free_dquots;
968 
969         /* make a copy, in case we page-fault in user space */
970         memcpy(&stats, &dqstats, sizeof(struct dqstats));
971         if (!copy_to_user(addr, &stats, sizeof(struct dqstats)))
972                 error = 0;
973         return error;
974 }
975 
976 static int quota_root_squash(struct super_block *sb, short type, int *addr)
977 {
978         int new_value, error;
979 
980         if (!sb)
981                 return(-ENODEV);
982 
983         error = -EFAULT;
984         if (!copy_from_user(&new_value, addr, sizeof(int))) {
985                 sb_dqopt(sb)->rsquash[type] = new_value;
986                 error = 0;
987         }
988         return error;
989 }
990 
991 /*
992  * This is a simple algorithm that calculates the size of a file in blocks.
993  * This is only used on filesystems that do not have an i_blocks count.
994  */
995 static u_long isize_to_blocks(loff_t isize, size_t blksize_bits)
996 {
997         u_long blocks;
998         u_long indirect;
999 
1000         if (!blksize_bits)
1001                 blksize_bits = BLOCK_SIZE_BITS;
1002         blocks = (isize >> blksize_bits) + ((isize & ~((1 << blksize_bits)-1)) ? 1 : 0);
1003         if (blocks > 10) {
1004                 indirect = ((blocks - 11) >> 8) + 1; /* single indirect blocks */
1005                 if (blocks > (10 + 256)) {
1006                         indirect += ((blocks - 267) >> 16) + 1; /* double indirect blocks */
1007                         if (blocks > (10 + 256 + (256 << 8)))
1008                                 indirect++; /* triple indirect blocks */
1009                 }
1010                 blocks += indirect;
1011         }
1012         return blocks;
1013 }
1014 
1015 /*
1016  * Externally referenced functions through dquot_operations in inode.
1017  *
1018  * Note: this is a blocking operation.
1019  */
1020 void dquot_initialize(struct inode *inode, short type)
1021 {
1022         struct dquot *dquot;
1023         unsigned int id = 0;
1024         short cnt;
1025 
1026         if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) &&
1027             !S_ISLNK(inode->i_mode))
1028                 return;
1029         lock_kernel();
1030         /* We don't want to have quotas on quota files - nasty deadlocks possible */
1031         if (is_quotafile(inode)) {
1032                 unlock_kernel();
1033                 return;
1034         }
1035         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1036                 if (type != -1 && cnt != type)
1037                         continue;
1038 
1039                 if (!sb_has_quota_enabled(inode->i_sb, cnt))
1040                         continue;
1041 
1042                 if (inode->i_dquot[cnt] == NODQUOT) {
1043                         switch (cnt) {
1044                                 case USRQUOTA:
1045                                         id = inode->i_uid;
1046                                         break;
1047                                 case GRPQUOTA:
1048                                         id = inode->i_gid;
1049                                         break;
1050                         }
1051                         dquot = dqget(inode->i_sb, id, cnt);
1052                         if (dquot == NODQUOT)
1053                                 continue;
1054                         if (inode->i_dquot[cnt] != NODQUOT) {
1055                                 dqput(dquot);
1056                                 continue;
1057                         } 
1058                         inode->i_dquot[cnt] = dquot;
1059                         inode->i_flags |= S_QUOTA;
1060                 }
1061         }
1062         unlock_kernel();
1063 }
1064 
1065 /*
1066  * Release all quota for the specified inode.
1067  *
1068  * Note: this is a blocking operation.
1069  */
1070 void dquot_drop(struct inode *inode)
1071 {
1072         struct dquot *dquot;
1073         short cnt;
1074 
1075         lock_kernel();
1076         inode->i_flags &= ~S_QUOTA;
1077         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1078                 if (inode->i_dquot[cnt] == NODQUOT)
1079                         continue;
1080                 dquot = inode->i_dquot[cnt];
1081                 inode->i_dquot[cnt] = NODQUOT;
1082                 dqput(dquot);
1083         }
1084         unlock_kernel();
1085 }
1086 
1087 /*
1088  * Note: this is a blocking operation.
1089  */
1090 int dquot_alloc_block(const struct inode *inode, unsigned long number, char warn)
1091 {
1092         int cnt;
1093         struct dquot *dquot[MAXQUOTAS];
1094 
1095         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1096                 dquot[cnt] = dqduplicate(inode->i_dquot[cnt]);
1097                 if (dquot[cnt] == NODQUOT)
1098                         continue;
1099                 lock_dquot(dquot[cnt]);
1100                 if (check_bdq(dquot[cnt], number, warn))
1101                         goto put_all;
1102         }
1103 
1104         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1105                 if (dquot[cnt] == NODQUOT)
1106                         continue;
1107                 dquot_incr_blocks(dquot[cnt], number);
1108                 unlock_dquot(dquot[cnt]);
1109                 dqput(dquot[cnt]);
1110         }
1111 
1112         return QUOTA_OK;
1113 put_all:
1114         for (; cnt >= 0; cnt--) {
1115                 if (dquot[cnt] == NODQUOT)
1116                         continue;
1117                 unlock_dquot(dquot[cnt]);
1118                 dqput(dquot[cnt]);
1119         }
1120         return NO_QUOTA;
1121 }
1122 
1123 /*
1124  * Note: this is a blocking operation.
1125  */
1126 int dquot_alloc_inode(const struct inode *inode, unsigned long number)
1127 {
1128         int cnt;
1129         struct dquot *dquot[MAXQUOTAS];
1130 
1131         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1132                 dquot[cnt] = dqduplicate(inode -> i_dquot[cnt]);
1133                 if (dquot[cnt] == NODQUOT)
1134                         continue;
1135                 lock_dquot(dquot[cnt]);
1136                 if (check_idq(dquot[cnt], number))
1137                         goto put_all;
1138         }
1139 
1140         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1141                 if (dquot[cnt] == NODQUOT)
1142                         continue;
1143                 dquot_incr_inodes(dquot[cnt], number);
1144                 unlock_dquot(dquot[cnt]);
1145                 dqput(dquot[cnt]);
1146         }
1147 
1148         return QUOTA_OK;
1149 put_all:
1150         for (; cnt >= 0; cnt--) {
1151                 if (dquot[cnt] == NODQUOT)
1152                         continue;
1153                 unlock_dquot(dquot[cnt]);
1154                 dqput(dquot[cnt]);
1155         }
1156         return NO_QUOTA;
1157 }
1158 
1159 /*
1160  * Note: this is a blocking operation.
1161  */
1162 void dquot_free_block(const struct inode *inode, unsigned long number)
1163 {
1164         unsigned short cnt;
1165         struct dquot *dquot;
1166 
1167         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1168                 dquot = inode->i_dquot[cnt];
1169                 if (dquot == NODQUOT)
1170                         continue;
1171                 wait_on_dquot(dquot);
1172                 dquot_decr_blocks(dquot, number);
1173         }
1174 }
1175 
1176 /*
1177  * Note: this is a blocking operation.
1178  */
1179 void dquot_free_inode(const struct inode *inode, unsigned long number)
1180 {
1181         unsigned short cnt;
1182         struct dquot *dquot;
1183 
1184         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1185                 dquot = inode->i_dquot[cnt];
1186                 if (dquot == NODQUOT)
1187                         continue;
1188                 wait_on_dquot(dquot);
1189                 dquot_decr_inodes(dquot, number);
1190         }
1191 }
1192 
1193 /*
1194  * Transfer the number of inode and blocks from one diskquota to an other.
1195  *
1196  * Note: this is a blocking operation.
1197  */
1198 int dquot_transfer(struct dentry *dentry, struct iattr *iattr)
1199 {
1200         struct inode *inode = dentry -> d_inode;
1201         unsigned long blocks;
1202         struct dquot *transfer_from[MAXQUOTAS];
1203         struct dquot *transfer_to[MAXQUOTAS];
1204         short cnt, disc;
1205         int error = -EDQUOT;
1206 
1207         if (!inode)
1208                 return -ENOENT;
1209         /* Arguably we could consider that as error, but... no fs - no quota */
1210         if (!inode->i_sb)
1211                 return 0;
1212 
1213         lock_kernel();
1214         /*
1215          * Build the transfer_from and transfer_to lists and check quotas to see
1216          * if operation is permitted.
1217          */
1218         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1219                 transfer_from[cnt] = NODQUOT;
1220                 transfer_to[cnt] = NODQUOT;
1221 
1222                 if (!sb_has_quota_enabled(inode->i_sb, cnt))
1223                         continue;
1224 
1225                 switch (cnt) {
1226                         case USRQUOTA:
1227                                 if (inode->i_uid == iattr->ia_uid)
1228                                         continue;
1229                                 /* We can get transfer_from from inode, can't we? */
1230                                 transfer_from[cnt] = dqget(inode->i_sb, inode->i_uid, cnt);
1231                                 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
1232                                 break;
1233                         case GRPQUOTA:
1234                                 if (inode->i_gid == iattr->ia_gid)
1235                                         continue;
1236                                 transfer_from[cnt] = dqget(inode->i_sb, inode->i_gid, cnt);
1237                                 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
1238                                 break;
1239                 }
1240 
1241                 /* Something bad (eg. quotaoff) happened while we were sleeping? */
1242                 if (transfer_from[cnt] == NODQUOT || transfer_to[cnt] == NODQUOT)
1243                 {
1244                         if (transfer_from[cnt] != NODQUOT) {
1245                                 dqput(transfer_from[cnt]);
1246                                 transfer_from[cnt] = NODQUOT;
1247                         }
1248                         if (transfer_to[cnt] != NODQUOT) {
1249                                 dqput(transfer_to[cnt]);
1250                                 transfer_to[cnt] = NODQUOT;
1251                         }
1252                         continue;
1253                 }
1254                 /*
1255                  *  We have to lock the quotas to prevent races...
1256                  */
1257                 if (transfer_from[cnt] < transfer_to[cnt])
1258                 {
1259                         lock_dquot(transfer_from[cnt]);
1260                         lock_dquot(transfer_to[cnt]);
1261                 }
1262                 else
1263                 {
1264                         lock_dquot(transfer_to[cnt]);
1265                         lock_dquot(transfer_from[cnt]);
1266                 }
1267 
1268                 /*
1269                  * The entries might got invalidated while locking. The second
1270                  * dqget() could block and so the first structure might got
1271                  * invalidated or locked...
1272                  */
1273                 if (!transfer_to[cnt]->dq_sb || !transfer_from[cnt]->dq_sb) {
1274                         cnt++;
1275                         goto put_all;
1276                 }
1277         }
1278 
1279         /*
1280          * Find out if this filesystem uses i_blocks.
1281          */
1282         if (!inode->i_sb->s_blocksize)
1283                 blocks = isize_to_blocks(inode->i_size, BLOCK_SIZE_BITS);
1284         else
1285                 blocks = (inode->i_blocks >> 1);
1286         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1287                 if (!transfer_to[cnt])
1288                         continue;
1289                 if (check_idq(transfer_to[cnt], 1) == NO_QUOTA ||
1290                     check_bdq(transfer_to[cnt], blocks, 0) == NO_QUOTA) {
1291                         cnt = MAXQUOTAS;
1292                         goto put_all;
1293                 }
1294         }
1295 
1296         if ((error = notify_change(dentry, iattr)))
1297                 goto put_all; 
1298         /*
1299          * Finally perform the needed transfer from transfer_from to transfer_to,
1300          * and release any pointers to dquots not needed anymore.
1301          */
1302         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1303                 /*
1304                  * Skip changes for same uid or gid or for non-existing quota-type.
1305                  */
1306                 if (transfer_from[cnt] == NODQUOT && transfer_to[cnt] == NODQUOT)
1307                         continue;
1308 
1309                 dquot_decr_inodes(transfer_from[cnt], 1);
1310                 dquot_decr_blocks(transfer_from[cnt], blocks);
1311 
1312                 dquot_incr_inodes(transfer_to[cnt], 1);
1313                 dquot_incr_blocks(transfer_to[cnt], blocks);
1314 
1315                 unlock_dquot(transfer_from[cnt]);
1316                 dqput(transfer_from[cnt]);
1317                 if (inode->i_dquot[cnt] != NODQUOT) {
1318                         struct dquot *temp = inode->i_dquot[cnt];
1319                         inode->i_dquot[cnt] = transfer_to[cnt];
1320                         unlock_dquot(transfer_to[cnt]);
1321                         dqput(temp);
1322                 } else {
1323                         unlock_dquot(transfer_to[cnt]);
1324                         dqput(transfer_to[cnt]);
1325                 }
1326         }
1327 
1328         unlock_kernel();
1329         return 0;
1330 put_all:
1331         for (disc = 0; disc < cnt; disc++) {
1332                 /* There should be none or both pointers set but... */
1333                 if (transfer_to[disc] != NODQUOT) {
1334                         unlock_dquot(transfer_to[disc]);
1335                         dqput(transfer_to[disc]);
1336                 }
1337                 if (transfer_from[disc] != NODQUOT) {
1338                         unlock_dquot(transfer_from[disc]);
1339                         dqput(transfer_from[disc]);
1340                 }
1341         }
1342         unlock_kernel();
1343         return error;
1344 }
1345 
1346 
1347 void __init dquot_init_hash(void)
1348 {
1349         printk(KERN_NOTICE "VFS: Diskquotas version %s initialized\n", __DQUOT_VERSION__);
1350 
1351         memset(dquot_hash, 0, sizeof(dquot_hash));
1352         memset((caddr_t)&dqstats, 0, sizeof(dqstats));
1353 }
1354 
1355 /*
1356  * Definitions of diskquota operations.
1357  */
1358 struct dquot_operations dquot_operations = {
1359         dquot_initialize,               /* mandatory */
1360         dquot_drop,                     /* mandatory */
1361         dquot_alloc_block,
1362         dquot_alloc_inode,
1363         dquot_free_block,
1364         dquot_free_inode,
1365         dquot_transfer
1366 };
1367 
1368 static inline void set_enable_flags(struct quota_mount_options *dqopt, short type)
1369 {
1370         switch (type) {
1371                 case USRQUOTA:
1372                         dqopt->flags |= DQUOT_USR_ENABLED;
1373                         break;
1374                 case GRPQUOTA:
1375                         dqopt->flags |= DQUOT_GRP_ENABLED;
1376                         break;
1377         }
1378 }
1379 
1380 static inline void reset_enable_flags(struct quota_mount_options *dqopt, short type)
1381 {
1382         switch (type) {
1383                 case USRQUOTA:
1384                         dqopt->flags &= ~DQUOT_USR_ENABLED;
1385                         break;
1386                 case GRPQUOTA:
1387                         dqopt->flags &= ~DQUOT_GRP_ENABLED;
1388                         break;
1389         }
1390 }
1391 
1392 /* Function in inode.c - remove pointers to dquots in icache */
1393 extern void remove_dquot_ref(kdev_t, short);
1394 
1395 /*
1396  * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
1397  */
1398 int quota_off(struct super_block *sb, short type)
1399 {
1400         struct file *filp;
1401         short cnt;
1402         int enabled = 0;
1403         struct quota_mount_options *dqopt = sb_dqopt(sb);
1404 
1405         if (!sb)
1406                 goto out;
1407 
1408         /* We need to serialize quota_off() for device */
1409         down(&dqopt->dqoff_sem);
1410         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1411                 if (type != -1 && cnt != type)
1412                         continue;
1413                 if (!is_enabled(dqopt, cnt))
1414                         continue;
1415                 reset_enable_flags(dqopt, cnt);
1416 
1417                 /* Note: these are blocking operations */
1418                 remove_dquot_ref(sb->s_dev, cnt);
1419                 invalidate_dquots(sb->s_dev, cnt);
1420 
1421                 /* Wait for any pending IO - remove me as soon as invalidate is more polite */
1422                 down(&dqopt->dqio_sem);
1423                 filp = dqopt->files[cnt];
1424                 dqopt->files[cnt] = (struct file *)NULL;
1425                 dqopt->inode_expire[cnt] = 0;
1426                 dqopt->block_expire[cnt] = 0;
1427                 up(&dqopt->dqio_sem);
1428                 fput(filp);
1429         }       
1430 
1431         /*
1432          * Check whether any quota is still enabled,
1433          * and if not clear the dq_op pointer.
1434          */
1435         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1436                 enabled |= is_enabled(dqopt, cnt);
1437         if (!enabled)
1438                 sb->dq_op = NULL;
1439         up(&dqopt->dqoff_sem);
1440 out:
1441         return(0);
1442 }
1443 
1444 static inline int check_quotafile_size(loff_t size)
1445 {
1446         ulong blocks = size >> BLOCK_SIZE_BITS;
1447         size_t off = size & (BLOCK_SIZE - 1);
1448 
1449         return !(((blocks % sizeof(struct dqblk)) * BLOCK_SIZE + off % sizeof(struct dqblk)) % sizeof(struct dqblk));
1450 }
1451 
1452 static int quota_on(struct super_block *sb, short type, char *path)
1453 {
1454         struct file *f;
1455         struct inode *inode;
1456         struct dquot *dquot;
1457         struct quota_mount_options *dqopt = sb_dqopt(sb);
1458         char *tmp;
1459         int error;
1460 
1461         if (is_enabled(dqopt, type))
1462                 return -EBUSY;
1463 
1464         down(&dqopt->dqoff_sem);
1465         tmp = getname(path);
1466         error = PTR_ERR(tmp);
1467         if (IS_ERR(tmp))
1468                 goto out_lock;
1469 
1470         f = filp_open(tmp, O_RDWR, 0600);
1471         putname(tmp);
1472 
1473         error = PTR_ERR(f);
1474         if (IS_ERR(f))
1475                 goto out_lock;
1476         error = -EIO;
1477         if (!f->f_op || (!f->f_op->read && !f->f_op->write))
1478                 goto out_f;
1479         inode = f->f_dentry->d_inode;
1480         error = -EACCES;
1481         if (!S_ISREG(inode->i_mode))
1482                 goto out_f;
1483         error = -EINVAL;
1484         if (inode->i_size == 0 || !check_quotafile_size(inode->i_size))
1485                 goto out_f;
1486         dquot_drop(inode);      /* We don't want quota on quota files */
1487 
1488         set_enable_flags(dqopt, type);
1489         dqopt->files[type] = f;
1490 
1491         dquot = dqget(sb, 0, type);
1492         dqopt->inode_expire[type] = (dquot != NODQUOT) ? dquot->dq_itime : MAX_IQ_TIME;
1493         dqopt->block_expire[type] = (dquot != NODQUOT) ? dquot->dq_btime : MAX_DQ_TIME;
1494         dqput(dquot);
1495 
1496         sb->dq_op = &dquot_operations;
1497         add_dquot_ref(sb, type);
1498 
1499         up(&dqopt->dqoff_sem);
1500         return 0;
1501 
1502 out_f:
1503         filp_close(f, NULL);
1504 out_lock:
1505         up(&dqopt->dqoff_sem);
1506 
1507         return error; 
1508 }
1509 
1510 /*
1511  * This is the system call interface. This communicates with
1512  * the user-level programs. Currently this only supports diskquota
1513  * calls. Maybe we need to add the process quotas etc. in the future,
1514  * but we probably should use rlimits for that.
1515  */
1516 asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
1517 {
1518         int cmds = 0, type = 0, flags = 0;
1519         kdev_t dev;
1520         struct super_block *sb = NULL;
1521         int ret = -EINVAL;
1522 
1523         lock_kernel();
1524         cmds = cmd >> SUBCMDSHIFT;
1525         type = cmd & SUBCMDMASK;
1526 
1527         if ((u_int) type >= MAXQUOTAS)
1528                 goto out;
1529         if (id & ~0xFFFF)
1530                 goto out;
1531 
1532         ret = -EPERM;
1533         switch (cmds) {
1534                 case Q_SYNC:
1535                 case Q_GETSTATS:
1536                         break;
1537                 case Q_GETQUOTA:
1538                         if (((type == USRQUOTA && current->euid != id) ||
1539                              (type == GRPQUOTA && in_egroup_p(id))) &&
1540                             !capable(CAP_SYS_RESOURCE))
1541                                 goto out;
1542                         break;
1543                 default:
1544                         if (!capable(CAP_SYS_RESOURCE))
1545                                 goto out;
1546         }
1547 
1548         ret = -EINVAL;
1549         dev = NODEV;
1550         if (special != NULL || (cmds != Q_SYNC && cmds != Q_GETSTATS)) {
1551                 mode_t mode;
1552                 struct nameidata nd;
1553 
1554                 ret = user_path_walk(special, &nd);
1555                 if (ret)
1556                         goto out;
1557 
1558                 dev = nd.dentry->d_inode->i_rdev;
1559                 mode = nd.dentry->d_inode->i_mode;
1560                 path_release(&nd);
1561 
1562                 ret = -ENOTBLK;
1563                 if (!S_ISBLK(mode))
1564                         goto out;
1565                 sb = get_super(dev);
1566         }
1567 
1568         ret = -EINVAL;
1569         switch (cmds) {
1570                 case Q_QUOTAON:
1571                         ret = sb ? quota_on(sb, type, (char *) addr) : -ENODEV;
1572                         goto out;
1573                 case Q_QUOTAOFF:
1574                         ret = quota_off(sb, type);
1575                         goto out;
1576                 case Q_GETQUOTA:
1577                         ret = get_quota(sb, id, type, (struct dqblk *) addr);
1578                         goto out;
1579                 case Q_SETQUOTA:
1580                         flags |= SET_QUOTA;
1581                         break;
1582                 case Q_SETUSE:
1583                         flags |= SET_USE;
1584                         break;
1585                 case Q_SETQLIM:
1586                         flags |= SET_QLIMIT;
1587                         break;
1588                 case Q_SYNC:
1589                         ret = sync_dquots(dev, type);
1590                         goto out;
1591                 case Q_GETSTATS:
1592                         ret = get_stats(addr);
1593                         goto out;
1594                 case Q_RSQUASH:
1595                         ret = quota_root_squash(sb, type, (int *) addr);
1596                         goto out;
1597                 default:
1598                         goto out;
1599         }
1600 
1601         flags |= QUOTA_SYSCALL;
1602 
1603         ret = -ESRCH;
1604         if (sb && sb_has_quota_enabled(sb, type))
1605                 ret = set_dqblk(sb, id, type, flags, (struct dqblk *) addr);
1606 out:
1607         unlock_kernel();
1608         return ret;
1609 }
1610 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.