/*
- * Copyright (C) International Business Machines Corp., 2000-2003
+ * Copyright (C) International Business Machines Corp., 2000-2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*/
#include <linux/fs.h>
+#include <linux/quotaops.h>
#include "jfs_incore.h"
#include "jfs_filsys.h"
#include "jfs_metapage.h"
hint = addressXAD(xad) + lengthXAD(xad) - 1;
} else
hint = 0;
- if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr)))
+ if ((rc = DQUOT_ALLOC_BLOCK(ip, xlen)))
goto out;
+ if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) {
+ DQUOT_FREE_BLOCK(ip, xlen);
+ goto out;
+ }
}
/*
split.pxdlist = NULL;
if ((rc = xtSplitUp(tid, ip, &split, &btstack))) {
/* undo data extent allocation */
- if (*xaddrp == 0)
+ if (*xaddrp == 0) {
dbFree(ip, xaddr, (s64) xlen);
+ DQUOT_FREE_BLOCK(ip, xlen);
+ }
return rc;
}
pxd_t *pxd;
struct tlock *tlck;
struct xtlock *sxtlck = NULL, *rxtlck = NULL;
+ int quota_allocation = 0;
smp = split->mp;
sp = XT_PAGE(ip, smp);
INCREMENT(xtStat.split);
- /*
- * allocate the new right page for the split
- */
pxdlist = split->pxdlist;
pxd = &pxdlist->pxd[pxdlist->npxd];
pxdlist->npxd++;
rbn = addressPXD(pxd);
+
+ /* Allocate blocks to quota. */
+ if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+ rc = -EDQUOT;
+ goto clean_up;
+ }
+
+ quota_allocation += lengthPXD(pxd);
+
+ /*
+ * allocate the new right page for the split
+ */
rmp = get_metapage(ip, rbn, PSIZE, 1);
- if (rmp == NULL)
- return -EIO;
+ if (rmp == NULL) {
+ rc = -EIO;
+ goto clean_up;
+ }
jfs_info("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
*rmpp = rmp;
*rbnp = rbn;
- ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
-
jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp);
return 0;
}
XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
if (rc) {
XT_PUTPAGE(rmp);
- return rc;
+ goto clean_up;
}
BT_MARK_DIRTY(mp, ip);
*rmpp = rmp;
*rbnp = rbn;
- ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
-
jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp);
return rc;
+
+ clean_up:
+
+ /* Rollback quota allocation. */
+ if (quota_allocation)
+ DQUOT_FREE_BLOCK(ip, quota_allocation);
+
+ return (rc);
}
if (rmp == NULL)
return -EIO;
+ /* Allocate blocks to quota. */
+ if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
+ release_metapage(rmp);
+ return -EDQUOT;
+ }
+
jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp);
/*
*rmpp = rmp;
- ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
-
jfs_info("xtSplitRoot: sp:0x%p rp:0x%p", sp, rp);
return 0;
}
else
ip->i_size = newsize;
- /* update nblocks to reflect freed blocks */
- ip->i_blocks -= LBLK2PBLK(ip->i_sb, nfreed);
+ /* update quota allocation to reflect freed blocks */
+ DQUOT_FREE_BLOCK(ip, nfreed);
/*
* free tlock of invalidated pages