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