The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/dquot.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    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  *              Used struct list_head instead of own list struct
   38  *              Invalidation of referenced dquots is no longer possible
   39  *              Improved free_dquots list management
   40  *              Quota and i_blocks are now updated in one place to avoid races
   41  *              Warnings are now delayed so we won't block in critical section
   42  *              Write updated not to require dquot lock
   43  *              Jan Kara, <jack@suse.cz>, 9/2000
   44  *
   45  *              Added dynamic quota structure allocation
   46  *              Jan Kara <jack@suse.cz> 12/2000
   47  *
   48  *              Rewritten quota interface. Implemented new quota format and
   49  *              formats registering.
   50  *              Jan Kara, <jack@suse.cz>, 2001,2002
   51  *
   52  * (C) Copyright 1994 - 1997 Marco van Wieringen 
   53  */
   54 
   55 #include <linux/errno.h>
   56 #include <linux/kernel.h>
   57 #include <linux/fs.h>
   58 #include <linux/sched.h>
   59 #include <linux/types.h>
   60 #include <linux/string.h>
   61 #include <linux/fcntl.h>
   62 #include <linux/stat.h>
   63 #include <linux/tty.h>
   64 #include <linux/file.h>
   65 #include <linux/slab.h>
   66 #include <linux/sysctl.h>
   67 #include <linux/smp_lock.h>
   68 #include <linux/init.h>
   69 #include <linux/module.h>
   70 #include <linux/proc_fs.h>
   71 
   72 #include <asm/uaccess.h>
   73 
   74 static char *quotatypes[] = INITQFNAMES;
   75 static struct quota_format_type *quota_formats; /* List of registered formats */
   76 
   77 int register_quota_format(struct quota_format_type *fmt)
   78 {
   79         lock_kernel();
   80         fmt->qf_next = quota_formats;
   81         quota_formats = fmt;
   82         unlock_kernel();
   83         return 0;
   84 }
   85 
   86 void unregister_quota_format(struct quota_format_type *fmt)
   87 {
   88         struct quota_format_type **actqf;
   89 
   90         lock_kernel();
   91         for (actqf = &quota_formats; *actqf && *actqf != fmt; actqf = &(*actqf)->qf_next);
   92         if (*actqf)
   93                 *actqf = (*actqf)->qf_next;
   94         unlock_kernel();
   95 }
   96 
   97 static struct quota_format_type *find_quota_format(int id)
   98 {
   99         struct quota_format_type *actqf;
  100 
  101         lock_kernel();
  102         for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next);
  103         if (actqf && !try_inc_mod_count(actqf->qf_owner))
  104                 actqf = NULL;
  105         unlock_kernel();
  106         return actqf;
  107 }
  108 
  109 static void put_quota_format(struct quota_format_type *fmt)
  110 {
  111         if (fmt->qf_owner)
  112                 __MOD_DEC_USE_COUNT(fmt->qf_owner);
  113 }
  114 
  115 /*
  116  * Dquot List Management:
  117  * The quota code uses three lists for dquot management: the inuse_list,
  118  * free_dquots, and dquot_hash[] array. A single dquot structure may be
  119  * on all three lists, depending on its current state.
  120  *
  121  * All dquots are placed to the end of inuse_list when first created, and this
  122  * list is used for the sync and invalidate operations, which must look
  123  * at every dquot.
  124  *
  125  * Unused dquots (dq_count == 0) are added to the free_dquots list when freed,
  126  * and this list is searched whenever we need an available dquot.  Dquots are
  127  * removed from the list as soon as they are used again, and
  128  * dqstats.free_dquots gives the number of dquots on the list. When
  129  * dquot is invalidated it's completely released from memory.
  130  *
  131  * Dquots with a specific identity (device, type and id) are placed on
  132  * one of the dquot_hash[] hash chains. The provides an efficient search
  133  * mechanism to locate a specific dquot.
  134  */
  135 
  136 /*
  137  * Note that any operation which operates on dquot data (ie. dq_dqb) mustn't
  138  * block while it's updating/reading it. Otherwise races would occur.
  139  *
  140  * Locked dquots might not be referenced in inodes - operations like
  141  * add_dquot_space() does dqduplicate() and would complain. Currently
  142  * dquot it locked only once in its existence - when it's being read
  143  * to memory on first dqget() and at that time it can't be referenced
  144  * from inode. Write operations on dquots don't hold dquot lock as they
  145  * copy data to internal buffers before writing anyway and copying as well
  146  * as any data update should be atomic. Also nobody can change used
  147  * entries in dquot structure as this is done only when quota is destroyed
  148  * and invalidate_dquots() waits for dquot to have dq_count == 0.
  149  */
  150 
  151 static LIST_HEAD(inuse_list);
  152 static LIST_HEAD(free_dquots);
  153 static struct list_head dquot_hash[NR_DQHASH];
  154 
  155 static void dqput(struct dquot *);
  156 static struct dquot *dqduplicate(struct dquot *);
  157 
  158 static inline void get_dquot_ref(struct dquot *dquot)
  159 {
  160         dquot->dq_count++;
  161 }
  162 
  163 static inline void put_dquot_ref(struct dquot *dquot)
  164 {
  165         dquot->dq_count--;
  166 }
  167 
  168 static inline void get_dquot_dup_ref(struct dquot *dquot)
  169 {
  170         dquot->dq_dup_ref++;
  171 }
  172 
  173 static inline void put_dquot_dup_ref(struct dquot *dquot)
  174 {
  175         dquot->dq_dup_ref--;
  176 }
  177 
  178 static inline int const hashfn(struct super_block *sb, unsigned int id, int type)
  179 {
  180         return((HASHDEV(sb->s_dev) ^ id) * (MAXQUOTAS - type)) % NR_DQHASH;
  181 }
  182 
  183 static inline void insert_dquot_hash(struct dquot *dquot)
  184 {
  185         struct list_head *head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
  186         list_add(&dquot->dq_hash, head);
  187 }
  188 
  189 static inline void remove_dquot_hash(struct dquot *dquot)
  190 {
  191         list_del(&dquot->dq_hash);
  192         INIT_LIST_HEAD(&dquot->dq_hash);
  193 }
  194 
  195 static inline struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, unsigned int id, int type)
  196 {
  197         struct list_head *head;
  198         struct dquot *dquot;
  199 
  200         for (head = dquot_hash[hashent].next; head != dquot_hash+hashent; head = head->next) {
  201                 dquot = list_entry(head, struct dquot, dq_hash);
  202                 if (dquot->dq_sb == sb && dquot->dq_id == id && dquot->dq_type == type)
  203                         return dquot;
  204         }
  205         return NODQUOT;
  206 }
  207 
  208 /* Add a dquot to the head of the free list */
  209 static inline void put_dquot_head(struct dquot *dquot)
  210 {
  211         list_add(&dquot->dq_free, &free_dquots);
  212         dqstats.free_dquots++;
  213 }
  214 
  215 /* Add a dquot to the tail of the free list */
  216 static inline void put_dquot_last(struct dquot *dquot)
  217 {
  218         list_add(&dquot->dq_free, free_dquots.prev);
  219         dqstats.free_dquots++;
  220 }
  221 
  222 /* Move dquot to the head of free list (it must be already on it) */
  223 static inline void move_dquot_head(struct dquot *dquot)
  224 {
  225         list_del(&dquot->dq_free);
  226         list_add(&dquot->dq_free, &free_dquots);
  227 }
  228 
  229 static inline void remove_free_dquot(struct dquot *dquot)
  230 {
  231         if (list_empty(&dquot->dq_free))
  232                 return;
  233         list_del(&dquot->dq_free);
  234         INIT_LIST_HEAD(&dquot->dq_free);
  235         dqstats.free_dquots--;
  236 }
  237 
  238 static inline void put_inuse(struct dquot *dquot)
  239 {
  240         /* We add to the back of inuse list so we don't have to restart
  241          * when traversing this list and we block */
  242         list_add(&dquot->dq_inuse, inuse_list.prev);
  243         dqstats.allocated_dquots++;
  244 }
  245 
  246 static inline void remove_inuse(struct dquot *dquot)
  247 {
  248         dqstats.allocated_dquots--;
  249         list_del(&dquot->dq_inuse);
  250 }
  251 
  252 static void __wait_on_dquot(struct dquot *dquot)
  253 {
  254         DECLARE_WAITQUEUE(wait, current);
  255 
  256         add_wait_queue(&dquot->dq_wait_lock, &wait);
  257 repeat:
  258         set_current_state(TASK_UNINTERRUPTIBLE);
  259         if (dquot->dq_flags & DQ_LOCKED) {
  260                 schedule();
  261                 goto repeat;
  262         }
  263         remove_wait_queue(&dquot->dq_wait_lock, &wait);
  264         current->state = TASK_RUNNING;
  265 }
  266 
  267 static inline void wait_on_dquot(struct dquot *dquot)
  268 {
  269         if (dquot->dq_flags & DQ_LOCKED)
  270                 __wait_on_dquot(dquot);
  271 }
  272 
  273 static inline void lock_dquot(struct dquot *dquot)
  274 {
  275         wait_on_dquot(dquot);
  276         dquot->dq_flags |= DQ_LOCKED;
  277 }
  278 
  279 static inline void unlock_dquot(struct dquot *dquot)
  280 {
  281         dquot->dq_flags &= ~DQ_LOCKED;
  282         wake_up(&dquot->dq_wait_lock);
  283 }
  284 
  285 /* Wait for dquot to be unused */
  286 static void __wait_dquot_unused(struct dquot *dquot)
  287 {
  288         DECLARE_WAITQUEUE(wait, current);
  289 
  290         add_wait_queue(&dquot->dq_wait_free, &wait);
  291 repeat:
  292         set_current_state(TASK_UNINTERRUPTIBLE);
  293         if (dquot->dq_count) {
  294                 schedule();
  295                 goto repeat;
  296         }
  297         remove_wait_queue(&dquot->dq_wait_free, &wait);
  298         current->state = TASK_RUNNING;
  299 }
  300 
  301 /* Wait for all duplicated dquot references to be dropped */
  302 static void __wait_dup_drop(struct dquot *dquot)
  303 {
  304         DECLARE_WAITQUEUE(wait, current);
  305 
  306         add_wait_queue(&dquot->dq_wait_free, &wait);
  307 repeat:
  308         set_current_state(TASK_UNINTERRUPTIBLE);
  309         if (dquot->dq_dup_ref) {
  310                 schedule();
  311                 goto repeat;
  312         }
  313         remove_wait_queue(&dquot->dq_wait_free, &wait);
  314         current->state = TASK_RUNNING;
  315 }
  316 
  317 static int read_dqblk(struct dquot *dquot)
  318 {
  319         int ret;
  320         struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
  321 
  322         lock_dquot(dquot);
  323         down(&dqopt->dqio_sem);
  324         ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot);
  325         up(&dqopt->dqio_sem);
  326         unlock_dquot(dquot);
  327         return ret;
  328 }
  329 
  330 static int commit_dqblk(struct dquot *dquot)
  331 {
  332         int ret;
  333         struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
  334 
  335         down(&dqopt->dqio_sem);
  336         ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
  337         up(&dqopt->dqio_sem);
  338         return ret;
  339 }
  340 
  341 /* Invalidate all dquots on the list, wait for all users. Note that this function is called
  342  * after quota is disabled so no new quota might be created. As we only insert to the end of
  343  * inuse list, we don't have to restart searching... */
  344 static void invalidate_dquots(struct super_block *sb, int type)
  345 {
  346         struct dquot *dquot;
  347         struct list_head *head;
  348 
  349 restart:
  350         list_for_each(head, &inuse_list) {
  351                 dquot = list_entry(head, struct dquot, dq_inuse);
  352                 if (dquot->dq_sb != sb)
  353                         continue;
  354                 if (dquot->dq_type != type)
  355                         continue;
  356                 dquot->dq_flags |= DQ_INVAL;
  357                 if (dquot->dq_count)
  358                         /*
  359                          *  Wait for any users of quota. As we have already cleared the flags in
  360                          *  superblock and cleared all pointers from inodes we are assured
  361                          *  that there will be no new users of this quota.
  362                          */
  363                         __wait_dquot_unused(dquot);
  364                 /* Quota now have no users and it has been written on last dqput() */
  365                 remove_dquot_hash(dquot);
  366                 remove_free_dquot(dquot);
  367                 remove_inuse(dquot);
  368                 kmem_cache_free(dquot_cachep, dquot);
  369                 goto restart;
  370         }
  371 }
  372 
  373 static int vfs_quota_sync(struct super_block *sb, int type)
  374 {
  375         struct list_head *head;
  376         struct dquot *dquot;
  377         struct quota_info *dqopt = sb_dqopt(sb);
  378         int cnt;
  379 
  380 restart:
  381         list_for_each(head, &inuse_list) {
  382                 dquot = list_entry(head, struct dquot, dq_inuse);
  383                 if (sb && dquot->dq_sb != sb)
  384                         continue;
  385                 if (type != -1 && dquot->dq_type != type)
  386                         continue;
  387                 if (!dquot->dq_sb)      /* Invalidated? */
  388                         continue;
  389                 if (!dquot_dirty(dquot) && !(dquot->dq_flags & DQ_LOCKED))
  390                         continue;
  391                 /* Get reference to quota so it won't be invalidated. get_dquot_ref()
  392                  * is enough since if dquot is locked/modified it can't be
  393                  * on the free list */
  394                 get_dquot_ref(dquot);
  395                 if (dquot->dq_flags & DQ_LOCKED)
  396                         wait_on_dquot(dquot);
  397                 if (dquot_dirty(dquot))
  398                         sb->dq_op->sync_dquot(dquot);
  399                 dqput(dquot);
  400                 goto restart;
  401         }
  402         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
  403                 if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt))
  404                         dqopt->info[cnt].dqi_flags &= ~DQF_ANY_DQUOT_DIRTY;
  405         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
  406                 if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt) && info_dirty(&dqopt->info[cnt]))
  407                         dqopt->ops[cnt]->write_file_info(sb, cnt);
  408         dqstats.syncs++;
  409 
  410         return 0;
  411 }
  412 
  413 static struct super_block *get_super_to_sync(int type)
  414 {
  415         struct list_head *head;
  416         int cnt, dirty;
  417 
  418 restart:
  419         spin_lock(&sb_lock);
  420         list_for_each(head, &super_blocks) {
  421                 struct super_block *sb = list_entry(head, struct super_block, s_list);
  422 
  423                 for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
  424                         if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
  425                             && sb_dqopt(sb)->info[cnt].dqi_flags & DQF_ANY_DQUOT_DIRTY)
  426                                 dirty = 1;
  427                 if (!dirty)
  428                         continue;
  429                 sb->s_count++;
  430                 spin_unlock(&sb_lock);
  431                 down_read(&sb->s_umount);
  432                 if (!sb->s_root) {
  433                         drop_super(sb);
  434                         goto restart;
  435                 }
  436                 return sb;
  437         }
  438         spin_unlock(&sb_lock);
  439         return NULL;
  440 }
  441 
  442 void sync_dquots_dev(kdev_t dev, int type)
  443 {
  444         struct super_block *sb;
  445 
  446         if (dev) {
  447                 if ((sb = get_super(dev))) {
  448                         lock_kernel();
  449                         if (sb->s_qcop->quota_sync)
  450                                 sb->s_qcop->quota_sync(sb, type);
  451                         unlock_kernel();
  452                         drop_super(sb);
  453                 }
  454         }
  455         else {
  456                 while ((sb = get_super_to_sync(type))) {
  457                         lock_kernel();
  458                         if (sb->s_qcop->quota_sync)
  459                                 sb->s_qcop->quota_sync(sb, type);
  460                         unlock_kernel();
  461                         drop_super(sb);
  462                 }
  463         }
  464 }
  465 
  466 void sync_dquots_sb(struct super_block *sb, int type)
  467 {
  468         lock_kernel();
  469         if (sb->s_qcop->quota_sync)
  470                 sb->s_qcop->quota_sync(sb, type);
  471         unlock_kernel();
  472 }
  473 
  474 /* Free unused dquots from cache */
  475 static void prune_dqcache(int count)
  476 {
  477         struct list_head *head;
  478         struct dquot *dquot;
  479 
  480         head = free_dquots.prev;
  481         while (head != &free_dquots && count) {
  482                 dquot = list_entry(head, struct dquot, dq_free);
  483                 remove_dquot_hash(dquot);
  484                 remove_free_dquot(dquot);
  485                 remove_inuse(dquot);
  486                 kmem_cache_free(dquot_cachep, dquot);
  487                 count--;
  488                 head = free_dquots.prev;
  489         }
  490 }
  491 
  492 /*
  493  * This is called from kswapd when we think we need some
  494  * more memory, but aren't really sure how much. So we
  495  * carefully try to free a _bit_ of our dqcache, but not
  496  * too much.
  497  *
  498  * Priority:
  499  *   1 - very urgent: shrink everything
  500  *   ...
  501  *   6 - base-level: try to shrink a bit.
  502  */
  503 
  504 int shrink_dqcache_memory(int priority, unsigned int gfp_mask)
  505 {
  506         int count = 0;
  507 
  508         lock_kernel();
  509         count = dqstats.free_dquots / priority;
  510         prune_dqcache(count);
  511         unlock_kernel();
  512         return kmem_cache_shrink(dquot_cachep);
  513 }
  514 
  515 /*
  516  * Put reference to dquot
  517  * NOTE: If you change this function please check whether dqput_blocks() works right...
  518  */
  519 static void dqput(struct dquot *dquot)
  520 {
  521         if (!dquot)
  522                 return;
  523 #ifdef __DQUOT_PARANOIA
  524         if (!dquot->dq_count) {
  525                 printk("VFS: dqput: trying to free free dquot\n");
  526                 printk("VFS: device %s, dquot of %s %d\n",
  527                         kdevname(dquot->dq_dev), quotatypes[dquot->dq_type],
  528                         dquot->dq_id);
  529                 return;
  530         }
  531 #endif
  532 
  533         dqstats.drops++;
  534 we_slept:
  535         if (dquot->dq_dup_ref && dquot->dq_count - dquot->dq_dup_ref <= 1) {    /* Last unduplicated reference? */
  536                 __wait_dup_drop(dquot);
  537                 goto we_slept;
  538         }
  539         if (dquot->dq_count > 1) {
  540                 /* We have more than one user... We can simply decrement use count */
  541                 put_dquot_ref(dquot);
  542                 return;
  543         }
  544         if (dquot_dirty(dquot)) {
  545                 commit_dqblk(dquot);
  546                 goto we_slept;
  547         }
  548 
  549         /* sanity check */
  550         if (!list_empty(&dquot->dq_free)) {
  551                 printk(KERN_ERR "dqput: dquot already on free list??\n");
  552                 put_dquot_ref(dquot);
  553                 return;
  554         }
  555         put_dquot_ref(dquot);
  556         /* If dquot is going to be invalidated invalidate_dquots() is going to free it so */
  557         if (!(dquot->dq_flags & DQ_INVAL))
  558                 put_dquot_last(dquot);  /* Place at end of LRU free queue */
  559         wake_up(&dquot->dq_wait_free);
  560 }
  561 
  562 static struct dquot *get_empty_dquot(struct super_block *sb, int type)
  563 {
  564         struct dquot *dquot;
  565 
  566         dquot = kmem_cache_alloc(dquot_cachep, SLAB_KERNEL);
  567         if(!dquot)
  568                 return NODQUOT;
  569 
  570         memset((caddr_t)dquot, 0, sizeof(struct dquot));
  571         init_waitqueue_head(&dquot->dq_wait_free);
  572         init_waitqueue_head(&dquot->dq_wait_lock);
  573         INIT_LIST_HEAD(&dquot->dq_free);
  574         INIT_LIST_HEAD(&dquot->dq_inuse);
  575         INIT_LIST_HEAD(&dquot->dq_hash);
  576         dquot->dq_sb = sb;
  577         dquot->dq_dev = sb->s_dev;
  578         dquot->dq_type = type;
  579         dquot->dq_count = 1;
  580         /* all dquots go on the inuse_list */
  581         put_inuse(dquot);
  582 
  583         return dquot;
  584 }
  585 
  586 static struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
  587 {
  588         unsigned int hashent = hashfn(sb, id, type);
  589         struct dquot *dquot, *empty = NODQUOT;
  590         struct quota_info *dqopt = sb_dqopt(sb);
  591 
  592 we_slept:
  593         if (!is_enabled(dqopt, type)) {
  594                 if (empty)
  595                         dqput(empty);
  596                 return NODQUOT;
  597         }
  598 
  599         if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) {
  600                 if (empty == NODQUOT) {
  601                         if ((empty = get_empty_dquot(sb, type)) == NODQUOT)
  602                                 schedule();     /* Try to wait for a moment... */
  603                         goto we_slept;
  604                 }
  605                 dquot = empty;
  606                 dquot->dq_id = id;
  607                 /* hash it first so it can be found */
  608                 insert_dquot_hash(dquot);
  609                 read_dqblk(dquot);
  610         } else {
  611                 if (!dquot->dq_count)
  612                         remove_free_dquot(dquot);
  613                 get_dquot_ref(dquot);
  614                 dqstats.cache_hits++;
  615                 wait_on_dquot(dquot);
  616                 if (empty)
  617                         dqput(empty);
  618         }
  619 
  620         if (!dquot->dq_sb) {    /* Has somebody invalidated entry under us? */
  621                 printk(KERN_ERR "VFS: dqget(): Quota invalidated in dqget()!\n");
  622                 dqput(dquot);
  623                 return NODQUOT;
  624         }
  625         ++dquot->dq_referenced;
  626         dqstats.lookups++;
  627 
  628         return dquot;
  629 }
  630 
  631 /* Duplicate reference to dquot got from inode */
  632 static struct dquot *dqduplicate(struct dquot *dquot)
  633 {
  634         if (dquot == NODQUOT)
  635                 return NODQUOT;
  636         get_dquot_ref(dquot);
  637         if (!dquot->dq_sb) {
  638                 printk(KERN_ERR "VFS: dqduplicate(): Invalidated quota to be duplicated!\n");
  639                 put_dquot_ref(dquot);
  640                 return NODQUOT;
  641         }
  642         if (dquot->dq_flags & DQ_LOCKED)
  643                 printk(KERN_ERR "VFS: dqduplicate(): Locked quota to be duplicated!\n");
  644         get_dquot_dup_ref(dquot);
  645         dquot->dq_referenced++;
  646         dqstats.lookups++;
  647 
  648         return dquot;
  649 }
  650 
  651 /* Put duplicated reference */
  652 static void dqputduplicate(struct dquot *dquot)
  653 {
  654         if (!dquot->dq_dup_ref) {
  655                 printk(KERN_ERR "VFS: dqputduplicate(): Duplicated dquot put without duplicate reference.\n");
  656                 return;
  657         }
  658         put_dquot_dup_ref(dquot);
  659         if (!dquot->dq_dup_ref)
  660                 wake_up(&dquot->dq_wait_free);
  661         put_dquot_ref(dquot);
  662         dqstats.drops++;
  663 }
  664 
  665 static int dqinit_needed(struct inode *inode, int type)
  666 {
  667         int cnt;
  668 
  669         if (IS_NOQUOTA(inode))
  670                 return 0;
  671         if (type != -1)
  672                 return inode->i_dquot[type] == NODQUOT;
  673         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
  674                 if (inode->i_dquot[cnt] == NODQUOT)
  675                         return 1;
  676         return 0;
  677 }
  678 
  679 static void add_dquot_ref(struct super_block *sb, int type)
  680 {
  681         struct list_head *p;
  682 
  683 restart:
  684         file_list_lock();
  685         list_for_each(p, &sb->s_files) {
  686                 struct file *filp = list_entry(p, struct file, f_list);
  687                 struct inode *inode = filp->f_dentry->d_inode;
  688                 if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
  689                         struct vfsmount *mnt = mntget(filp->f_vfsmnt);
  690                         struct dentry *dentry = dget(filp->f_dentry);
  691                         file_list_unlock();
  692                         sb->dq_op->initialize(inode, type);
  693                         dput(dentry);
  694                         mntput(mnt);
  695                         /* As we may have blocked we had better restart... */
  696                         goto restart;
  697                 }
  698         }
  699         file_list_unlock();
  700 }
  701 
  702 /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */
  703 static inline int dqput_blocks(struct dquot *dquot)
  704 {
  705         if (dquot->dq_dup_ref && dquot->dq_count - dquot->dq_dup_ref <= 1)
  706                 return 1;
  707         if (dquot->dq_count <= 1 && dquot->dq_flags & DQ_MOD)
  708                 return 1;
  709         return 0;
  710 }
  711 
  712 /* Remove references to dquots from inode - add dquot to list for freeing if needed */
  713 int remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head)
  714 {
  715         struct dquot *dquot = inode->i_dquot[type];
  716         int cnt;
  717 
  718         inode->i_dquot[type] = NODQUOT;
  719         /* any other quota in use? */
  720         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  721                 if (inode->i_dquot[cnt] != NODQUOT)
  722                         goto put_it;
  723         }
  724         inode->i_flags &= ~S_QUOTA;
  725 put_it:
  726         if (dquot != NODQUOT) {
  727                 if (dqput_blocks(dquot)) {
  728                         if (dquot->dq_count != 1)
  729                                 printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", dquot->dq_count);
  730                         list_add(&dquot->dq_free, tofree_head); /* As dquot must have currently users it can't be on the free list... */
  731                         return 1;
  732                 }
  733                 else
  734                         dqput(dquot);   /* We have guaranteed we won't block */
  735         }
  736         return 0;
  737 }
  738 
  739 /* Free list of dquots - called from inode.c */
  740 void put_dquot_list(struct list_head *tofree_head)
  741 {
  742         struct list_head *act_head;
  743         struct dquot *dquot;
  744 
  745         lock_kernel();
  746         act_head = tofree_head->next;
  747         /* So now we have dquots on the list... Just free them */
  748         while (act_head != tofree_head) {
  749                 dquot = list_entry(act_head, struct dquot, dq_free);
  750                 act_head = act_head->next;
  751                 list_del(&dquot->dq_free);      /* Remove dquot from the list so we won't have problems... */
  752                 INIT_LIST_HEAD(&dquot->dq_free);
  753                 dqput(dquot);
  754         }
  755         unlock_kernel();
  756 }
  757 
  758 static inline void dquot_incr_inodes(struct dquot *dquot, unsigned long number)
  759 {
  760         dquot->dq_dqb.dqb_curinodes += number;
  761         mark_dquot_dirty(dquot);
  762 }
  763 
  764 static inline void dquot_incr_space(struct dquot *dquot, qsize_t number)
  765 {
  766         dquot->dq_dqb.dqb_curspace += number;
  767         mark_dquot_dirty(dquot);
  768 }
  769 
  770 static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number)
  771 {
  772         if (dquot->dq_dqb.dqb_curinodes > number)
  773                 dquot->dq_dqb.dqb_curinodes -= number;
  774         else
  775                 dquot->dq_dqb.dqb_curinodes = 0;
  776         if (dquot->dq_dqb.dqb_curinodes < dquot->dq_dqb.dqb_isoftlimit)
  777                 dquot->dq_dqb.dqb_itime = (time_t) 0;
  778         dquot->dq_flags &= ~DQ_INODES;
  779         mark_dquot_dirty(dquot);
  780 }
  781 
  782 static inline void dquot_decr_space(struct dquot *dquot, qsize_t number)
  783 {
  784         if (dquot->dq_dqb.dqb_curspace > number)
  785                 dquot->dq_dqb.dqb_curspace -= number;
  786         else
  787                 dquot->dq_dqb.dqb_curspace = 0;
  788         if (toqb(dquot->dq_dqb.dqb_curspace) < dquot->dq_dqb.dqb_bsoftlimit)
  789                 dquot->dq_dqb.dqb_btime = (time_t) 0;
  790         dquot->dq_flags &= ~DQ_BLKS;
  791         mark_dquot_dirty(dquot);
  792 }
  793 
  794 static inline int need_print_warning(struct dquot *dquot, int flag)
  795 {
  796         switch (dquot->dq_type) {
  797                 case USRQUOTA:
  798                         return current->fsuid == dquot->dq_id && !(dquot->dq_flags & flag);
  799                 case GRPQUOTA:
  800                         return in_group_p(dquot->dq_id) && !(dquot->dq_flags & flag);
  801         }
  802         return 0;
  803 }
  804 
  805 /* Values of warnings */
  806 #define NOWARN 0
  807 #define IHARDWARN 1
  808 #define ISOFTLONGWARN 2
  809 #define ISOFTWARN 3
  810 #define BHARDWARN 4
  811 #define BSOFTLONGWARN 5
  812 #define BSOFTWARN 6
  813 
  814 /* Print warning to user which exceeded quota */
  815 static void print_warning(struct dquot *dquot, const char warntype)
  816 {
  817         char *msg = NULL;
  818         int flag = (warntype == BHARDWARN || warntype == BSOFTLONGWARN) ? DQ_BLKS :
  819           ((warntype == IHARDWARN || warntype == ISOFTLONGWARN) ? DQ_INODES : 0);
  820 
  821         if (!need_print_warning(dquot, flag))
  822                 return;
  823         dquot->dq_flags |= flag;
  824         tty_write_message(current->tty, (char *)bdevname(dquot->dq_sb->s_dev));
  825         if (warntype == ISOFTWARN || warntype == BSOFTWARN)
  826                 tty_write_message(current->tty, ": warning, ");
  827         else
  828                 tty_write_message(current->tty, ": write failed, ");
  829         tty_write_message(current->tty, quotatypes[dquot->dq_type]);
  830         switch (warntype) {
  831                 case IHARDWARN:
  832                         msg = " file limit reached.\r\n";
  833                         break;
  834                 case ISOFTLONGWARN:
  835                         msg = " file quota exceeded too long.\r\n";
  836                         break;
  837                 case ISOFTWARN:
  838                         msg = " file quota exceeded.\r\n";
  839                         break;
  840                 case BHARDWARN:
  841                         msg = " block limit reached.\r\n";
  842                         break;
  843                 case BSOFTLONGWARN:
  844                         msg = " block quota exceeded too long.\r\n";
  845                         break;
  846                 case BSOFTWARN:
  847                         msg = " block quota exceeded.\r\n";
  848                         break;
  849         }
  850         tty_write_message(current->tty, msg);
  851 }
  852 
  853 static inline void flush_warnings(struct dquot **dquots, char *warntype)
  854 {
  855         int i;
  856 
  857         for (i = 0; i < MAXQUOTAS; i++)
  858                 if (dquots[i] != NODQUOT && warntype[i] != NOWARN)
  859                         print_warning(dquots[i], warntype[i]);
  860 }
  861 
  862 static inline char ignore_hardlimit(struct dquot *dquot)
  863 {
  864         struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
  865 
  866         return capable(CAP_SYS_RESOURCE) &&
  867             (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || !(info->dqi_flags & V1_DQF_RSQUASH));
  868 }
  869 
  870 static int check_idq(struct dquot *dquot, ulong inodes, char *warntype)
  871 {
  872         *warntype = NOWARN;
  873         if (inodes <= 0 || dquot->dq_flags & DQ_FAKE)
  874                 return QUOTA_OK;
  875 
  876         if (dquot->dq_dqb.dqb_ihardlimit &&
  877            (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_ihardlimit &&
  878             !ignore_hardlimit(dquot)) {
  879                 *warntype = IHARDWARN;
  880                 return NO_QUOTA;
  881         }
  882 
  883         if (dquot->dq_dqb.dqb_isoftlimit &&
  884            (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
  885             dquot->dq_dqb.dqb_itime && CURRENT_TIME >= dquot->dq_dqb.dqb_itime &&
  886             !ignore_hardlimit(dquot)) {
  887                 *warntype = ISOFTLONGWARN;
  888                 return NO_QUOTA;
  889         }
  890 
  891         if (dquot->dq_dqb.dqb_isoftlimit &&
  892            (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
  893             dquot->dq_dqb.dqb_itime == 0) {
  894                 *warntype = ISOFTWARN;
  895                 dquot->dq_dqb.dqb_itime = CURRENT_TIME + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
  896         }
  897 
  898         return QUOTA_OK;
  899 }
  900 
  901 static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype)
  902 {
  903         *warntype = 0;
  904         if (space <= 0 || dquot->dq_flags & DQ_FAKE)
  905                 return QUOTA_OK;
  906 
  907         if (dquot->dq_dqb.dqb_bhardlimit &&
  908            toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bhardlimit &&
  909             !ignore_hardlimit(dquot)) {
  910                 if (!prealloc)
  911                         *warntype = BHARDWARN;
  912                 return NO_QUOTA;
  913         }
  914 
  915         if (dquot->dq_dqb.dqb_bsoftlimit &&
  916            toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit &&
  917             dquot->dq_dqb.dqb_btime && CURRENT_TIME >= dquot->dq_dqb.dqb_btime &&
  918             !ignore_hardlimit(dquot)) {
  919                 if (!prealloc)
  920                         *warntype = BSOFTLONGWARN;
  921                 return NO_QUOTA;
  922         }
  923 
  924         if (dquot->dq_dqb.dqb_bsoftlimit &&
  925            toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit &&
  926             dquot->dq_dqb.dqb_btime == 0) {
  927                 if (!prealloc) {
  928                         *warntype = BSOFTWARN;
  929                         dquot->dq_dqb.dqb_btime = CURRENT_TIME + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
  930                 }
  931                 else
  932                         /*
  933                          * We don't allow preallocation to exceed softlimit so exceeding will
  934                          * be always printed
  935                          */
  936                         return NO_QUOTA;
  937         }
  938 
  939         return QUOTA_OK;
  940 }
  941 
  942 /*
  943  * Externally referenced functions through dquot_operations in inode.
  944  *
  945  * Note: this is a blocking operation.
  946  */
  947 void dquot_initialize(struct inode *inode, int type)
  948 {
  949         struct dquot *dquot[MAXQUOTAS];
  950         unsigned int id = 0;
  951         int cnt;
  952 
  953         if (IS_NOQUOTA(inode))
  954                 return;
  955         /* Build list of quotas to initialize... We can block here */
  956         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  957                 dquot[cnt] = NODQUOT;
  958                 if (type != -1 && cnt != type)
  959                         continue;
  960                 if (!sb_has_quota_enabled(inode->i_sb, cnt))
  961                         continue;
  962                 if (inode->i_dquot[cnt] == NODQUOT) {
  963                         switch (cnt) {
  964                                 case USRQUOTA:
  965                                         id = inode->i_uid;
  966                                         break;
  967                                 case GRPQUOTA:
  968                                         id = inode->i_gid;
  969                                         break;
  970                         }
  971                         dquot[cnt] = dqget(inode->i_sb, id, cnt);
  972                 }
  973         }
  974         /* NOBLOCK START: Here we shouldn't block */
  975         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
  976                 if (dquot[cnt] == NODQUOT || !sb_has_quota_enabled(inode->i_sb, cnt) || inode->i_dquot[cnt] != NODQUOT)
  977                         continue;
  978                 inode->i_dquot[cnt] = dquot[cnt];
  979                 dquot[cnt] = NODQUOT;
  980                 inode->i_flags |= S_QUOTA;
  981         }
  982         /* NOBLOCK END */
  983         /* Put quotas which we didn't use */
  984         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
  985                 if (dquot[cnt] != NODQUOT)
  986                         dqput(dquot[cnt]);
  987 }
  988 
  989 /*
  990  * Release all quota for the specified inode.
  991  *
  992  * Note: this is a blocking operation.
  993  */
  994 void dquot_drop(struct inode *inode)
  995 {
  996         struct dquot *dquot;
  997         int cnt;
  998 
  999         inode->i_flags &= ~S_QUOTA;
 1000         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1001                 if (inode->i_dquot[cnt] == NODQUOT)
 1002                         continue;
 1003                 dquot = inode->i_dquot[cnt];
 1004                 inode->i_dquot[cnt] = NODQUOT;
 1005                 dqput(dquot);
 1006         }
 1007 }
 1008 
 1009 /*
 1010  * This operation can block, but only after everything is updated
 1011  */
 1012 int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
 1013 {
 1014         int cnt, ret = NO_QUOTA;
 1015         struct dquot *dquot[MAXQUOTAS];
 1016         char warntype[MAXQUOTAS];
 1017 
 1018         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1019                 dquot[cnt] = NODQUOT;
 1020                 warntype[cnt] = NOWARN;
 1021         }
 1022         /* NOBLOCK Start */
 1023         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1024                 dquot[cnt] = dqduplicate(inode->i_dquot[cnt]);
 1025                 if (dquot[cnt] == NODQUOT)
 1026                         continue;
 1027                 if (check_bdq(dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA)
 1028                         goto warn_put_all;
 1029         }
 1030         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1031                 if (dquot[cnt] == NODQUOT)
 1032                         continue;
 1033                 dquot_incr_space(dquot[cnt], number);
 1034         }
 1035         inode_add_bytes(inode, number);
 1036         /* NOBLOCK End */
 1037         ret = QUOTA_OK;
 1038 warn_put_all:
 1039         flush_warnings(dquot, warntype);
 1040         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 1041                 if (dquot[cnt] != NODQUOT)
 1042                         dqputduplicate(dquot[cnt]);
 1043         return ret;
 1044 }
 1045 
 1046 /*
 1047  * This operation can block, but only after everything is updated
 1048  */
 1049 int dquot_alloc_inode(const struct inode *inode, unsigned long number)
 1050 {
 1051         int cnt, ret = NO_QUOTA;
 1052         struct dquot *dquot[MAXQUOTAS];
 1053         char warntype[MAXQUOTAS];
 1054 
 1055         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1056                 dquot[cnt] = NODQUOT;
 1057                 warntype[cnt] = NOWARN;
 1058         }
 1059         /* NOBLOCK Start */
 1060         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1061                 dquot[cnt] = dqduplicate(inode -> i_dquot[cnt]);
 1062                 if (dquot[cnt] == NODQUOT)
 1063                         continue;
 1064                 if (check_idq(dquot[cnt], number, warntype+cnt) == NO_QUOTA)
 1065                         goto warn_put_all;
 1066         }
 1067 
 1068         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1069                 if (dquot[cnt] == NODQUOT)
 1070                         continue;
 1071                 dquot_incr_inodes(dquot[cnt], number);
 1072         }
 1073         /* NOBLOCK End */
 1074         ret = QUOTA_OK;
 1075 warn_put_all:
 1076         flush_warnings(dquot, warntype);
 1077         for (cnt = 0; cnt < MAXQUOTAS; cnt++)
 1078                 if (dquot[cnt] != NODQUOT)
 1079                         dqputduplicate(dquot[cnt]);
 1080         return ret;
 1081 }
 1082 
 1083 /*
 1084  * This is a non-blocking operation.
 1085  */
 1086 void dquot_free_space(struct inode *inode, qsize_t number)
 1087 {
 1088         unsigned int cnt;
 1089         struct dquot *dquot;
 1090 
 1091         /* NOBLOCK Start */
 1092         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1093                 dquot = dqduplicate(inode->i_dquot[cnt]);
 1094                 if (dquot == NODQUOT)
 1095                         continue;
 1096                 dquot_decr_space(dquot, number);
 1097                 dqputduplicate(dquot);
 1098         }
 1099         inode_sub_bytes(inode, number);
 1100         /* NOBLOCK End */
 1101 }
 1102 
 1103 /*
 1104  * This is a non-blocking operation.
 1105  */
 1106 void dquot_free_inode(const struct inode *inode, unsigned long number)
 1107 {
 1108         unsigned int cnt;
 1109         struct dquot *dquot;
 1110 
 1111         /* NOBLOCK Start */
 1112         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1113                 dquot = dqduplicate(inode->i_dquot[cnt]);
 1114                 if (dquot == NODQUOT)
 1115                         continue;
 1116                 dquot_decr_inodes(dquot, number);
 1117                 dqputduplicate(dquot);
 1118         }
 1119         /* NOBLOCK End */
 1120 }
 1121 
 1122 /*
 1123  * Transfer the number of inode and blocks from one diskquota to an other.
 1124  *
 1125  * This operation can block, but only after everything is updated
 1126  */
 1127 int dquot_transfer(struct inode *inode, struct iattr *iattr)
 1128 {
 1129         qsize_t space;
 1130         struct dquot *transfer_from[MAXQUOTAS];
 1131         struct dquot *transfer_to[MAXQUOTAS];
 1132         int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid,
 1133             chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid;
 1134         char warntype[MAXQUOTAS];
 1135 
 1136         /* Clear the arrays */
 1137         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1138                 transfer_to[cnt] = transfer_from[cnt] = NODQUOT;
 1139                 warntype[cnt] = NOWARN;
 1140         }
 1141         /* First build the transfer_to list - here we can block on reading of dquots... */
 1142         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1143                 if (!sb_has_quota_enabled(inode->i_sb, cnt))
 1144                         continue;
 1145                 switch (cnt) {
 1146                         case USRQUOTA:
 1147                                 if (!chuid)
 1148                                         continue;
 1149                                 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
 1150                                 break;
 1151                         case GRPQUOTA:
 1152                                 if (!chgid)
 1153                                         continue;
 1154                                 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
 1155                                 break;
 1156                 }
 1157         }
 1158         /* NOBLOCK START: From now on we shouldn't block */
 1159         space = inode_get_bytes(inode);
 1160         /* Build the transfer_from list and check the limits */
 1161         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1162                 /* The second test can fail when quotaoff is in progress... */
 1163                 if (transfer_to[cnt] == NODQUOT || !sb_has_quota_enabled(inode->i_sb, cnt))
 1164                         continue;
 1165                 transfer_from[cnt] = dqduplicate(inode->i_dquot[cnt]);
 1166                 if (transfer_from[cnt] == NODQUOT)      /* Can happen on quotafiles (quota isn't initialized on them)... */
 1167                         continue;
 1168                 if (check_idq(transfer_to[cnt], 1, warntype+cnt) == NO_QUOTA ||
 1169                     check_bdq(transfer_to[cnt], space, 0, warntype+cnt) == NO_QUOTA)
 1170                         goto warn_put_all;
 1171         }
 1172 
 1173         /*
 1174          * Finally perform the needed transfer from transfer_from to transfer_to
 1175          */
 1176         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1177                 /*
 1178                  * Skip changes for same uid or gid or for non-existing quota-type.
 1179                  */
 1180                 if (transfer_from[cnt] == NODQUOT || transfer_to[cnt] == NODQUOT)
 1181                         continue;
 1182 
 1183                 dquot_decr_inodes(transfer_from[cnt], 1);
 1184                 dquot_decr_space(transfer_from[cnt], space);
 1185 
 1186                 dquot_incr_inodes(transfer_to[cnt], 1);
 1187                 dquot_incr_space(transfer_to[cnt], space);
 1188 
 1189                 if (inode->i_dquot[cnt] == NODQUOT)
 1190                         BUG();
 1191                 inode->i_dquot[cnt] = transfer_to[cnt];
 1192                 /*
 1193                  * We've got to release transfer_from[] twice - once for dquot_transfer() and
 1194                  * once for inode. We don't want to release transfer_to[] as it's now placed in inode
 1195                  */
 1196                 transfer_to[cnt] = transfer_from[cnt];
 1197         }
 1198         /* NOBLOCK END. From now on we can block as we wish */
 1199         ret = QUOTA_OK;
 1200 warn_put_all:
 1201         flush_warnings(transfer_to, warntype);
 1202         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1203                 /* First we must put duplicate - otherwise we might deadlock */
 1204                 if (transfer_from[cnt] != NODQUOT)
 1205                         dqputduplicate(transfer_from[cnt]);
 1206                 if (transfer_to[cnt] != NODQUOT)
 1207                         dqput(transfer_to[cnt]);
 1208         }
 1209         return ret;
 1210 }
 1211 
 1212 /*
 1213  * Definitions of diskquota operations.
 1214  */
 1215 struct dquot_operations dquot_operations = {
 1216         initialize:     dquot_initialize,               /* mandatory */
 1217         drop:           dquot_drop,                     /* mandatory */
 1218         alloc_space:    dquot_alloc_space,
 1219         alloc_inode:    dquot_alloc_inode,
 1220         free_space:     dquot_free_space,
 1221         free_inode:     dquot_free_inode,
 1222         transfer:       dquot_transfer,
 1223         sync_dquot:     commit_dqblk
 1224 };
 1225 
 1226 /* Function used by filesystems for initializing the dquot_operations structure */
 1227 void init_dquot_operations(struct dquot_operations *fsdqops)
 1228 {
 1229         memcpy(fsdqops, &dquot_operations, sizeof(dquot_operations));
 1230 }
 1231 
 1232 static inline void set_enable_flags(struct quota_info *dqopt, int type)
 1233 {
 1234         switch (type) {
 1235                 case USRQUOTA:
 1236                         dqopt->flags |= DQUOT_USR_ENABLED;
 1237                         break;
 1238                 case GRPQUOTA:
 1239                         dqopt->flags |= DQUOT_GRP_ENABLED;
 1240                         break;
 1241         }
 1242 }
 1243 
 1244 static inline void reset_enable_flags(struct quota_info *dqopt, int type)
 1245 {
 1246         switch (type) {
 1247                 case USRQUOTA:
 1248                         dqopt->flags &= ~DQUOT_USR_ENABLED;
 1249                         break;
 1250                 case GRPQUOTA:
 1251                         dqopt->flags &= ~DQUOT_GRP_ENABLED;
 1252                         break;
 1253         }
 1254 }
 1255 
 1256 /* Function in inode.c - remove pointers to dquots in icache */
 1257 extern void remove_dquot_ref(struct super_block *, int);
 1258 
 1259 /*
 1260  * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
 1261  */
 1262 int vfs_quota_off(struct super_block *sb, int type)
 1263 {
 1264         int cnt;
 1265         struct quota_info *dqopt = sb_dqopt(sb);
 1266 
 1267         lock_kernel();
 1268         if (!sb)
 1269                 goto out;
 1270 
 1271         /* We need to serialize quota_off() for device */
 1272         down(&dqopt->dqoff_sem);
 1273         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
 1274                 if (type != -1 && cnt != type)
 1275                         continue;
 1276                 if (!is_enabled(dqopt, cnt))
 1277                         continue;
 1278                 reset_enable_flags(dqopt, cnt);
 1279 
 1280                 /* Note: these are blocking operations */
 1281                 remove_dquot_ref(sb, cnt);
 1282                 invalidate_dquots(sb, cnt);
 1283                 if (info_dirty(&dqopt->info[cnt]))
 1284                         dqopt->ops[cnt]->write_file_info(sb, cnt);
 1285                 if (dqopt->ops[cnt]->free_file_info)
 1286                         dqopt->ops[cnt]->free_file_info(sb, cnt);
 1287                 put_quota_format(dqopt->info[cnt].dqi_format);
 1288 
 1289                 fput(dqopt->files[cnt]);
 1290                 dqopt->files[cnt] = (struct file *)NULL;
 1291                 dqopt->info[cnt].dqi_flags = 0;
 1292                 dqopt->info[cnt].dqi_igrace = 0;
 1293                 dqopt->info[cnt].dqi_bgrace = 0;
 1294                 dqopt->ops[cnt] = NULL;
 1295         }
 1296         up(&dqopt->dqoff_sem);
 1297 out:
 1298         unlock_kernel();
 1299         return 0;
 1300 }
 1301 
 1302 int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
 1303 {
 1304         struct file *f = NULL;
 1305         struct inode *inode;
 1306         struct quota_info *dqopt = sb_dqopt(sb);
 1307         struct quota_format_type *fmt = find_quota_format(format_id);
 1308         int error;
 1309 
 1310         if (!fmt)
 1311                 return -ESRCH;
 1312         if (is_enabled(dqopt, type)) {
 1313                 error = -EBUSY;
 1314                 goto out_fmt;
 1315         }
 1316 
 1317         down(&dqopt->dqoff_sem);
 1318 
 1319         f = filp_open(path, O_RDWR, 0600);
 1320 
 1321         error = PTR_ERR(f);
 1322         if (IS_ERR(f))
 1323                 goto out_lock;
 1324         dqopt->files[type] = f;
 1325         error = -EIO;
 1326         if (!f->f_op || !f->f_op->read || !f->f_op->write)
 1327                 goto out_f;
 1328         inode = f->f_dentry->d_inode;
 1329         error = -EACCES;
 1330         if (!S_ISREG(inode->i_mode))
 1331                 goto out_f;
 1332         error = -EINVAL;
 1333         if (!fmt->qf_ops->check_quota_file(sb, type))
 1334                 goto out_f;
 1335         /* We don't want quota on quota files */
 1336         dquot_drop(inode);
 1337         inode->i_flags |= S_NOQUOTA;
 1338 
 1339         dqopt->ops[type] = fmt->qf_ops;
 1340         dqopt->info[type].dqi_format = fmt;
 1341         if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0)
 1342                 goto out_f;
 1343         set_enable_flags(dqopt, type);
 1344 
 1345         add_dquot_ref(sb, type);
 1346 
 1347         up(&dqopt->dqoff_sem);
 1348         return 0;
 1349 
 1350 out_f:
 1351         if (f)
 1352                 filp_close(f, NULL);
 1353         dqopt->files[type] = NULL;
 1354 out_lock:
 1355         up(&dqopt->dqoff_sem);
 1356 out_fmt:
 1357         put_quota_format(fmt);
 1358 
 1359         return error; 
 1360 }
 1361 
 1362 /* Generic routine for getting common part of quota structure */
 1363 static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
 1364 {
 1365         struct mem_dqblk *dm = &dquot->dq_dqb;
 1366 
 1367         di->dqb_bhardlimit = dm->dqb_bhardlimit;
 1368         di->dqb_bsoftlimit = dm->dqb_bsoftlimit;
 1369         di->dqb_curspace = dm->dqb_curspace;
 1370         di->dqb_ihardlimit = dm->dqb_ihardlimit;
 1371         di->dqb_isoftlimit = dm->dqb_isoftlimit;
 1372         di->dqb_curinodes = dm->dqb_curinodes;
 1373         di->dqb_btime = dm->dqb_btime;
 1374         di->dqb_itime = dm->dqb_itime;
 1375         di->dqb_valid = QIF_ALL;
 1376 }
 1377 
 1378 int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
 1379 {
 1380         struct dquot *dquot = dqget(sb, id, type);
 1381 
 1382         if (!dquot)
 1383                 return -EINVAL;
 1384         do_get_dqblk(dquot, di);
 1385         dqput(dquot);
 1386         return 0;
 1387 }
 1388 
 1389 /* Generic routine for setting common part of quota structure */
 1390 static void do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
 1391 {
 1392         struct mem_dqblk *dm = &dquot->dq_dqb;
 1393         int check_blim = 0, check_ilim = 0;
 1394 
 1395         if (di->dqb_valid & QIF_SPACE) {
 1396                 dm->dqb_curspace = di->dqb_curspace;
 1397                 check_blim = 1;
 1398         }
 1399         if (di->dqb_valid & QIF_BLIMITS) {
 1400                 dm->dqb_bsoftlimit = di->dqb_bsoftlimit;
 1401                 dm->dqb_bhardlimit = di->dqb_bhardlimit;
 1402                 check_blim = 1;
 1403         }
 1404         if (di->dqb_valid & QIF_INODES) {
 1405                 dm->dqb_curinodes = di->dqb_curinodes;
 1406                 check_ilim = 1;
 1407         }
 1408         if (di->dqb_valid & QIF_ILIMITS) {
 1409                 dm->dqb_isoftlimit = di->dqb_isoftlimit;
 1410                 dm->dqb_ihardlimit = di->dqb_ihardlimit;
 1411                 check_ilim = 1;
 1412         }
 1413         if (di->dqb_valid & QIF_BTIME)
 1414                 dm->dqb_btime = di->dqb_btime;
 1415         if (di->dqb_valid & QIF_ITIME)
 1416                 dm->dqb_itime = di->dqb_itime;
 1417 
 1418         if (check_blim) {
 1419                 if (!dm->dqb_bsoftlimit || toqb(dm->dqb_curspace) < dm->dqb_bsoftlimit) {
 1420                         dm->dqb_btime = 0;
 1421                         dquot->dq_flags &= ~DQ_BLKS;
 1422                 }
 1423                 else if (!(di->dqb_valid & QIF_BTIME))  /* Set grace only if user hasn't provided his own... */
 1424                         dm->dqb_btime = CURRENT_TIME + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
 1425         }
 1426         if (check_ilim) {
 1427                 if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) {
 1428                         dm->dqb_itime = 0;
 1429                         dquot->dq_flags &= ~DQ_INODES;
 1430                 }
 1431                 else if (!(di->dqb_valid & QIF_ITIME))  /* Set grace only if user hasn't provided his own... */
 1432                         dm->dqb_itime = CURRENT_TIME + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
 1433         }
 1434         if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit)
 1435                 dquot->dq_flags &= ~DQ_FAKE;
 1436         else
 1437                 dquot->dq_flags |= DQ_FAKE;
 1438         dquot->dq_flags |= DQ_MOD;
 1439 }
 1440 
 1441 int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
 1442 {
 1443         struct dquot *dquot = dqget(sb, id, type);
 1444 
 1445         if (!dquot)
 1446                 return -EINVAL;
 1447         do_set_dqblk(dquot, di);
 1448         dqput(dquot);
 1449         return 0;
 1450 }
 1451 
 1452 /* Generic routine for getting common part of quota file information */
 1453 int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
 1454 {
 1455         struct mem_dqinfo *mi = sb_dqopt(sb)->info + type;
 1456 
 1457         ii->dqi_bgrace = mi->dqi_bgrace;
 1458         ii->dqi_igrace = mi->dqi_igrace;
 1459         ii->dqi_flags = mi->dqi_flags & DQF_MASK;
 1460         ii->dqi_valid = IIF_ALL;
 1461         return 0;
 1462 }
 1463 
 1464 /* Generic routine for setting common part of quota file information */
 1465 int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
 1466 {
 1467         struct mem_dqinfo *mi = sb_dqopt(sb)->info + type;
 1468 
 1469         if (ii->dqi_valid & IIF_BGRACE)
 1470                 mi->dqi_bgrace = ii->dqi_bgrace;
 1471         if (ii->dqi_valid & IIF_IGRACE)
 1472                 mi->dqi_igrace = ii->dqi_igrace;
 1473         if (ii->dqi_valid & IIF_FLAGS)
 1474                 mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK);
 1475         mark_info_dirty(mi);
 1476         return 0;
 1477 }
 1478 
 1479 struct quotactl_ops vfs_quotactl_ops = {
 1480         quota_on:       vfs_quota_on,
 1481         quota_off:      vfs_quota_off,
 1482         quota_sync:     vfs_quota_sync,
 1483         get_info:       vfs_get_dqinfo,
 1484         set_info:       vfs_set_dqinfo,
 1485         get_dqblk:      vfs_get_dqblk,
 1486         set_dqblk:      vfs_set_dqblk
 1487 };
 1488 
 1489 static ctl_table fs_dqstats_table[] = {
 1490         {FS_DQ_LOOKUPS, "lookups", &dqstats.lookups, sizeof(int), 0444, NULL, &proc_dointvec},
 1491         {FS_DQ_DROPS, "drops", &dqstats.drops, sizeof(int), 0444, NULL, &proc_dointvec},
 1492         {FS_DQ_READS, "reads", &dqstats.reads, sizeof(int), 0444, NULL, &proc_dointvec},
 1493         {FS_DQ_WRITES, "writes", &dqstats.writes, sizeof(int), 0444, NULL, &proc_dointvec},
 1494         {FS_DQ_CACHE_HITS, "cache_hits", &dqstats.cache_hits, sizeof(int), 0444, NULL, &proc_dointvec},
 1495         {FS_DQ_ALLOCATED, "allocated_dquots", &dqstats.allocated_dquots, sizeof(int), 0444, NULL, &proc_dointvec},
 1496         {FS_DQ_FREE, "free_dquots", &dqstats.free_dquots, sizeof(int), 0444, NULL, &proc_dointvec},
 1497         {FS_DQ_SYNCS, "syncs", &dqstats.syncs, sizeof(int), 0444, NULL, &proc_dointvec},
 1498         {},
 1499 };
 1500 
 1501 static ctl_table fs_table[] = {
 1502         {FS_DQSTATS, "quota", NULL, 0, 0555, fs_dqstats_table},
 1503         {},
 1504 };
 1505 
 1506 static ctl_table sys_table[] = {
 1507         {CTL_FS, "fs", NULL, 0, 0555, fs_table},
 1508         {},
 1509 };
 1510 
 1511 static int __init dquot_init(void)
 1512 {
 1513         int i;
 1514 
 1515         register_sysctl_table(sys_table, 0);
 1516         for (i = 0; i < NR_DQHASH; i++)
 1517                 INIT_LIST_HEAD(dquot_hash + i);
 1518         printk(KERN_NOTICE "VFS: Disk quotas v%s\n", __DQUOT_VERSION__);
 1519 
 1520         return 0;
 1521 }
 1522 __initcall(dquot_init);
 1523 
 1524 EXPORT_SYMBOL(register_quota_format);
 1525 EXPORT_SYMBOL(unregister_quota_format);
 1526 EXPORT_SYMBOL(dqstats);
 1527 EXPORT_SYMBOL(init_dquot_operations);

Cache object: b5c2cd86ad8cbc40cfd355635008bdb1


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.