vserver 1.9.3
[linux-2.6.git] / fs / jfs / jfs_dtree.c
index 3c3140d..29930b6 100644 (file)
  */
 
 #include <linux/fs.h>
+#include <linux/quotaops.h>
 #include "jfs_incore.h"
 #include "jfs_superblock.h"
 #include "jfs_filsys.h"
@@ -259,19 +260,19 @@ static struct dir_table_slot *find_index(struct inode *ip, u32 index,
                        jfs_warn("find_entry called with index = %d", index);
                        maxWarnings--;
                }
-               return 0;
+               return NULL;
        }
 
        if (index >= jfs_ip->next_index) {
                jfs_warn("find_entry called with index >= next_index");
-               return 0;
+               return NULL;
        }
 
        if (jfs_ip->next_index <= (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
                /*
                 * Inline directory table
                 */
-               *mp = 0;
+               *mp = NULL;
                slot = &jfs_ip->i_dirtable[index - 2];
        } else {
                offset = (index - 2) * sizeof(struct dir_table_slot);
@@ -281,7 +282,7 @@ static struct dir_table_slot *find_index(struct inode *ip, u32 index,
 
                if (*mp && (*lblock != blkno)) {
                        release_metapage(*mp);
-                       *mp = 0;
+                       *mp = NULL;
                }
                if (*mp == 0) {
                        *lblock = blkno;
@@ -289,7 +290,7 @@ static struct dir_table_slot *find_index(struct inode *ip, u32 index,
                }
                if (*mp == 0) {
                        jfs_err("free_index: error reading directory table");
-                       return 0;
+                       return NULL;
                }
 
                slot =
@@ -374,18 +375,20 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
                return index;
        }
        if (index == (MAX_INLINE_DIRTABLE_ENTRY + 1)) {
+               struct dir_table_slot temp_table[12];
+
                /*
                 * It's time to move the inline table to an external
                 * page and begin to build the xtree
                 */
-               if (dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
+               if (DQUOT_ALLOC_BLOCK(ip, sbi->nbperpage) ||
+                   dbAlloc(ip, 0, sbi->nbperpage, &xaddr))
                        goto clean_up;  /* No space */
 
                /*
                 * Save the table, we're going to overwrite it with the
                 * xtree root
                 */
-               struct dir_table_slot temp_table[12];
                memcpy(temp_table, &jfs_ip->i_dirtable, sizeof(temp_table));
 
                /*
@@ -404,7 +407,6 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
                        goto clean_up;
                }
                ip->i_size = PSIZE;
-               ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage);
 
                if ((mp = get_index_page(ip, 0)) == 0) {
                        jfs_err("add_index: get_metapage failed!");
@@ -446,7 +448,6 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
                        goto clean_up;
                }
                ip->i_size += PSIZE;
-               ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage);
 
                if ((mp = get_index_page(ip, blkno)))
                        memset(mp->data, 0, PSIZE);     /* Just looks better */
@@ -489,7 +490,7 @@ static void free_index(tid_t tid, struct inode *ip, u32 index, u32 next)
 {
        struct dir_table_slot *dirtab_slot;
        s64 lblock;
-       struct metapage *mp = 0;
+       struct metapage *mp = NULL;
 
        dirtab_slot = find_index(ip, index, &mp, &lblock);
 
@@ -542,7 +543,7 @@ static int read_index(struct inode *ip, u32 index,
                     struct dir_table_slot * dirtab_slot)
 {
        s64 lblock;
-       struct metapage *mp = 0;
+       struct metapage *mp = NULL;
        struct dir_table_slot *slot;
 
        slot = find_index(ip, index, &mp, &lblock);
@@ -849,7 +850,7 @@ int dtInsert(tid_t tid, struct inode *ip,
                data.leaf.ip = ip;
        } else {
                n = NDTLEAF_LEGACY(name->namlen);
-               data.leaf.ip = 0;       /* signifies legacy directory format */
+               data.leaf.ip = NULL;    /* signifies legacy directory format */
        }
        data.leaf.ino = cpu_to_le32(*fsn);
 
@@ -939,12 +940,13 @@ static int dtSplitUp(tid_t tid,
        int xlen, xsize;
        struct pxdlist pxdlist;
        pxd_t *pxd;
-       struct component_name key = { 0, 0 };
+       struct component_name key = { 0, NULL };
        ddata_t *data = split->data;
        int n;
        struct dt_lock *dtlck;
        struct tlock *tlck;
        struct lv *lv;
+       int quota_allocation = 0;
 
        /* get split page */
        smp = split->mp;
@@ -991,7 +993,9 @@ static int dtSplitUp(tid_t tid,
                split->pxdlist = &pxdlist;
                rc = dtSplitRoot(tid, ip, split, &rmp);
 
-               if (!rc)
+               if (rc)
+                       dbFree(ip, xaddr, xlen);
+               else
                        DT_PUTPAGE(rmp);
 
                DT_PUTPAGE(smp);
@@ -1016,6 +1020,14 @@ static int dtSplitUp(tid_t tid,
                        n = xlen + (xlen << 1);
                else
                        n = xlen;
+
+               /* Allocate blocks to quota. */
+               if (DQUOT_ALLOC_BLOCK(ip, n)) {
+                       rc = -EDQUOT;
+                       goto extendOut;
+               }
+               quota_allocation += n;
+
                if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen,
                                    (s64) n, &nxaddr)))
                        goto extendOut;
@@ -1284,6 +1296,10 @@ static int dtSplitUp(tid_t tid,
       freeKeyName:
        kfree(key.name);
 
+       /* Rollback quota allocation */
+       if (rc && quota_allocation)
+               DQUOT_FREE_BLOCK(ip, quota_allocation);
+
       dtSplitUp_Exit:
 
        return rc;
@@ -1304,7 +1320,6 @@ static int dtSplitUp(tid_t tid,
 static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
            struct metapage ** rmpp, dtpage_t ** rpp, pxd_t * rpxdp)
 {
-       struct super_block *sb = ip->i_sb;
        int rc = 0;
        struct metapage *smp;
        dtpage_t *sp;
@@ -1343,6 +1358,12 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
        if (rmp == NULL)
                return -EIO;
 
+       /* Allocate blocks to quota. */
+       if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+               release_metapage(rmp);
+               return -EDQUOT;
+       }
+
        jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
 
        BT_MARK_DIRTY(rmp, ip);
@@ -1549,7 +1570,7 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
        if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) {
                s64 lblock;
 
-               mp = 0;
+               mp = NULL;
                stbl = DT_GETSTBL(rp);
                for (n = 0; n < rp->header.nextindex; n++) {
                        ldtentry = (struct ldtentry *) & rp->slot[stbl[n]];
@@ -1592,8 +1613,6 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
        *rmpp = rmp;
        *rpxdp = *pxd;
 
-       ip->i_blocks += LBLK2PBLK(sb, lengthPXD(pxd));
-
        return rc;
 }
 
@@ -1675,7 +1694,7 @@ static int dtExtendPage(tid_t tid,
                if (DO_INDEX(ip)) {
                        s64 lblock;
 
-                       mp = 0;
+                       mp = NULL;
                        stbl = DT_GETSTBL(sp);
                        for (n = 0; n < sp->header.nextindex; n++) {
                                ldtentry =
@@ -1822,16 +1841,6 @@ static int dtExtendPage(tid_t tid,
        tpxd = (pxd_t *) & pp->slot[1];
        *tpxd = *pxd;
 
-       /* Since the directory might have an EA and/or ACL associated with it
-        * we need to make sure we take that into account when setting the
-        * i_nblocks
-        */
-       ip->i_blocks = LBLK2PBLK(ip->i_sb, xlen +
-                                ((JFS_IP(ip)->ea.flag & DXD_EXTENT) ?
-                                 lengthDXD(&JFS_IP(ip)->ea) : 0) +
-                                ((JFS_IP(ip)->acl.flag & DXD_EXTENT) ?
-                                 lengthDXD(&JFS_IP(ip)->acl) : 0));
-
        DT_PUTPAGE(pmp);
        return 0;
 }
@@ -1899,6 +1908,12 @@ static int dtSplitRoot(tid_t tid,
 
        rp = rmp->data;
 
+       /* Allocate blocks to quota. */
+       if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+               release_metapage(rmp);
+               return -EDQUOT;
+       }
+
        BT_MARK_DIRTY(rmp, ip);
        /*
         * acquire a transaction lock on the new right page
@@ -1969,7 +1984,7 @@ static int dtSplitRoot(tid_t tid,
         */
        if ((rp->header.flag & BT_LEAF) && DO_INDEX(ip)) {
                s64 lblock;
-               struct metapage *mp = 0;
+               struct metapage *mp = NULL;
                struct ldtentry *ldtentry;
 
                stbl = DT_GETSTBL(rp);
@@ -2041,7 +2056,6 @@ static int dtSplitRoot(tid_t tid,
 
        *rmpp = rmp;
 
-       ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
        return 0;
 }
 
@@ -2180,7 +2194,7 @@ int dtDelete(tid_t tid,
                if (DO_INDEX(ip) && index < p->header.nextindex) {
                        s64 lblock;
 
-                       imp = 0;
+                       imp = NULL;
                        stbl = DT_GETSTBL(p);
                        for (i = index; i < p->header.nextindex; i++) {
                                ldtentry =
@@ -2264,7 +2278,9 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
        }
 
        xlen = lengthPXD(&fp->header.self);
-       ip->i_blocks -= LBLK2PBLK(ip->i_sb, xlen);
+
+       /* Free quota allocation. */
+       DQUOT_FREE_BLOCK(ip, xlen);
 
        /* free/invalidate its buffer page */
        discard_metapage(fmp);
@@ -2338,7 +2354,9 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
                                }
 
                                xlen = lengthPXD(&p->header.self);
-                               ip->i_blocks -= LBLK2PBLK(ip->i_sb, xlen);
+
+                               /* Free quota allocation */
+                               DQUOT_FREE_BLOCK(ip, xlen);
 
                                /* free/invalidate its buffer page */
                                discard_metapage(mp);
@@ -2876,14 +2894,6 @@ void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot)
        /* init '..' entry */
        p->header.idotdot = cpu_to_le32(idotdot);
 
-#if 0
-       ip->i_blocks = LBLK2PBLK(ip->i_sb,
-                                ((jfs_ip->ea.flag & DXD_EXTENT) ?
-                                 lengthDXD(&jfs_ip->ea) : 0) +
-                                ((jfs_ip->acl.flag & DXD_EXTENT) ?
-                                 lengthDXD(&jfs_ip->acl) : 0));
-#endif
-
        return;
 }
 
@@ -3872,8 +3882,8 @@ static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
                          ddata_t * data, struct dt_lock ** dtlock)
 {
        struct dtslot *h, *t;
-       struct ldtentry *lh = 0;
-       struct idtentry *ih = 0;
+       struct ldtentry *lh = NULL;
+       struct idtentry *ih = NULL;
        int hsi, fsi, klen, len, nextindex;
        wchar_t *kname, *name;
        s8 *stbl;
@@ -3882,7 +3892,7 @@ static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
        struct lv *lv;
        int xsi, n;
        s64 bn = 0;
-       struct metapage *mp = 0;
+       struct metapage *mp = NULL;
 
        klen = key->namlen;
        kname = key->name;
@@ -3998,7 +4008,7 @@ static void dtInsertEntry(dtpage_t * p, int index, struct component_name * key,
                         * Need to update slot number for entries that moved
                         * in the stbl
                         */
-                       mp = 0;
+                       mp = NULL;
                        for (n = index + 1; n <= nextindex; n++) {
                                lh = (struct ldtentry *) & (p->slot[stbl[n]]);
                                modify_index(data->leaf.tid, data->leaf.ip,
@@ -4034,8 +4044,8 @@ static void dtMoveEntry(dtpage_t * sp, int si, dtpage_t * dp,
        int dsi;                /* dst slot index */
        s8 *sstbl, *dstbl;      /* sorted entry table */
        int snamlen, len;
-       struct ldtentry *slh, *dlh = 0;
-       struct idtentry *sih, *dih = 0;
+       struct ldtentry *slh, *dlh = NULL;
+       struct idtentry *sih, *dih = NULL;
        struct dtslot *h, *s, *d;
        struct dt_lock *sdtlck = *sdtlock, *ddtlck = *ddtlock;
        struct lv *slv, *dlv;