Commit 639f284f authored by Dave Kleikamp's avatar Dave Kleikamp

Merge bk://linux.bkbits.net/linux-2.5

into hostme.bitkeeper.com:/repos/j/jfs/linux-2.5
parents 0bfcccd1 91ed0f3c
/* /*
* Copyright (c) International Business Machines Corp., 2002 * Copyright (C) International Business Machines Corp., 2002-2004
* Copyright (c) Andreas Gruenbacher, 2001 * Copyright (C) Andreas Gruenbacher, 2001
* Copyright (c) Linus Torvalds, 1991, 1992 * Copyright (C) Linus Torvalds, 1991, 1992
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/quotaops.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_xattr.h" #include "jfs_xattr.h"
#include "jfs_acl.h" #include "jfs_acl.h"
...@@ -281,6 +282,12 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr) ...@@ -281,6 +282,12 @@ int jfs_setattr(struct dentry *dentry, struct iattr *iattr)
if (rc) if (rc)
return rc; return rc;
if ((iattr->ia_valid & ATTR_UID && iattr->ia_uid != inode->i_uid) ||
(iattr->ia_valid & ATTR_GID && iattr->ia_gid != inode->i_gid)) {
if (DQUOT_TRANSFER(inode, iattr))
return -EDQUOT;
}
rc = inode_setattr(inode, iattr); rc = inode_setattr(inode, iattr);
if (!rc && (iattr->ia_valid & ATTR_MODE)) if (!rc && (iattr->ia_valid & ATTR_MODE))
......
/* /*
* Copyright (c) International Business Machines Corp., 2000-2002 * Copyright (C) International Business Machines Corp., 2000-2004
* Portions Copyright (c) Christoph Hellwig, 2001-2002 * Portions Copyright (C) Christoph Hellwig, 2001-2002
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/mpage.h> #include <linux/mpage.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/quotaops.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_filsys.h" #include "jfs_filsys.h"
#include "jfs_imap.h" #include "jfs_imap.h"
...@@ -134,6 +135,13 @@ void jfs_delete_inode(struct inode *inode) ...@@ -134,6 +135,13 @@ void jfs_delete_inode(struct inode *inode)
diFree(inode); diFree(inode);
/*
* Free the inode from the quota allocation.
*/
DQUOT_INIT(inode);
DQUOT_FREE_INODE(inode);
DQUOT_DROP(inode);
clear_inode(inode); clear_inode(inode);
} }
......
...@@ -101,6 +101,7 @@ ...@@ -101,6 +101,7 @@
*/ */
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/quotaops.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_superblock.h" #include "jfs_superblock.h"
#include "jfs_filsys.h" #include "jfs_filsys.h"
...@@ -380,7 +381,8 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) ...@@ -380,7 +381,8 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
* It's time to move the inline table to an external * It's time to move the inline table to an external
* page and begin to build the xtree * 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 */ goto clean_up; /* No space */
/* /*
...@@ -405,7 +407,6 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) ...@@ -405,7 +407,6 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
goto clean_up; goto clean_up;
} }
ip->i_size = PSIZE; ip->i_size = PSIZE;
ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage);
if ((mp = get_index_page(ip, 0)) == 0) { if ((mp = get_index_page(ip, 0)) == 0) {
jfs_err("add_index: get_metapage failed!"); jfs_err("add_index: get_metapage failed!");
...@@ -447,7 +448,6 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot) ...@@ -447,7 +448,6 @@ static u32 add_index(tid_t tid, struct inode *ip, s64 bn, int slot)
goto clean_up; goto clean_up;
} }
ip->i_size += PSIZE; ip->i_size += PSIZE;
ip->i_blocks += LBLK2PBLK(sb, sbi->nbperpage);
if ((mp = get_index_page(ip, blkno))) if ((mp = get_index_page(ip, blkno)))
memset(mp->data, 0, PSIZE); /* Just looks better */ memset(mp->data, 0, PSIZE); /* Just looks better */
...@@ -946,6 +946,7 @@ static int dtSplitUp(tid_t tid, ...@@ -946,6 +946,7 @@ static int dtSplitUp(tid_t tid,
struct dt_lock *dtlck; struct dt_lock *dtlck;
struct tlock *tlck; struct tlock *tlck;
struct lv *lv; struct lv *lv;
int quota_allocation = 0;
/* get split page */ /* get split page */
smp = split->mp; smp = split->mp;
...@@ -992,7 +993,9 @@ static int dtSplitUp(tid_t tid, ...@@ -992,7 +993,9 @@ static int dtSplitUp(tid_t tid,
split->pxdlist = &pxdlist; split->pxdlist = &pxdlist;
rc = dtSplitRoot(tid, ip, split, &rmp); rc = dtSplitRoot(tid, ip, split, &rmp);
if (!rc) if (rc)
dbFree(ip, xaddr, xlen);
else
DT_PUTPAGE(rmp); DT_PUTPAGE(rmp);
DT_PUTPAGE(smp); DT_PUTPAGE(smp);
...@@ -1017,6 +1020,14 @@ static int dtSplitUp(tid_t tid, ...@@ -1017,6 +1020,14 @@ static int dtSplitUp(tid_t tid,
n = xlen + (xlen << 1); n = xlen + (xlen << 1);
else else
n = xlen; 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, if ((rc = dbReAlloc(sbi->ipbmap, xaddr, (s64) xlen,
(s64) n, &nxaddr))) (s64) n, &nxaddr)))
goto extendOut; goto extendOut;
...@@ -1285,6 +1296,10 @@ static int dtSplitUp(tid_t tid, ...@@ -1285,6 +1296,10 @@ static int dtSplitUp(tid_t tid,
freeKeyName: freeKeyName:
kfree(key.name); kfree(key.name);
/* Rollback quota allocation */
if (rc && quota_allocation)
DQUOT_FREE_BLOCK(ip, quota_allocation);
dtSplitUp_Exit: dtSplitUp_Exit:
return rc; return rc;
...@@ -1305,7 +1320,6 @@ static int dtSplitUp(tid_t tid, ...@@ -1305,7 +1320,6 @@ static int dtSplitUp(tid_t tid,
static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
struct metapage ** rmpp, dtpage_t ** rpp, pxd_t * rpxdp) struct metapage ** rmpp, dtpage_t ** rpp, pxd_t * rpxdp)
{ {
struct super_block *sb = ip->i_sb;
int rc = 0; int rc = 0;
struct metapage *smp; struct metapage *smp;
dtpage_t *sp; dtpage_t *sp;
...@@ -1344,6 +1358,12 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, ...@@ -1344,6 +1358,12 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
if (rmp == NULL) if (rmp == NULL)
return -EIO; 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); jfs_info("dtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
BT_MARK_DIRTY(rmp, ip); BT_MARK_DIRTY(rmp, ip);
...@@ -1593,8 +1613,6 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split, ...@@ -1593,8 +1613,6 @@ static int dtSplitPage(tid_t tid, struct inode *ip, struct dtsplit * split,
*rmpp = rmp; *rmpp = rmp;
*rpxdp = *pxd; *rpxdp = *pxd;
ip->i_blocks += LBLK2PBLK(sb, lengthPXD(pxd));
return rc; return rc;
} }
...@@ -1823,16 +1841,6 @@ static int dtExtendPage(tid_t tid, ...@@ -1823,16 +1841,6 @@ static int dtExtendPage(tid_t tid,
tpxd = (pxd_t *) & pp->slot[1]; tpxd = (pxd_t *) & pp->slot[1];
*tpxd = *pxd; *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); DT_PUTPAGE(pmp);
return 0; return 0;
} }
...@@ -1900,6 +1908,12 @@ static int dtSplitRoot(tid_t tid, ...@@ -1900,6 +1908,12 @@ static int dtSplitRoot(tid_t tid,
rp = rmp->data; rp = rmp->data;
/* Allocate blocks to quota. */
if (DQUOT_ALLOC_BLOCK(ip, lengthPXD(pxd))) {
release_metapage(rmp);
return -EDQUOT;
}
BT_MARK_DIRTY(rmp, ip); BT_MARK_DIRTY(rmp, ip);
/* /*
* acquire a transaction lock on the new right page * acquire a transaction lock on the new right page
...@@ -2042,7 +2056,6 @@ static int dtSplitRoot(tid_t tid, ...@@ -2042,7 +2056,6 @@ static int dtSplitRoot(tid_t tid,
*rmpp = rmp; *rmpp = rmp;
ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
return 0; return 0;
} }
...@@ -2265,7 +2278,9 @@ static int dtDeleteUp(tid_t tid, struct inode *ip, ...@@ -2265,7 +2278,9 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
} }
xlen = lengthPXD(&fp->header.self); 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 */ /* free/invalidate its buffer page */
discard_metapage(fmp); discard_metapage(fmp);
...@@ -2339,7 +2354,9 @@ static int dtDeleteUp(tid_t tid, struct inode *ip, ...@@ -2339,7 +2354,9 @@ static int dtDeleteUp(tid_t tid, struct inode *ip,
} }
xlen = lengthPXD(&p->header.self); 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 */ /* free/invalidate its buffer page */
discard_metapage(mp); discard_metapage(mp);
...@@ -2877,14 +2894,6 @@ void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot) ...@@ -2877,14 +2894,6 @@ void dtInitRoot(tid_t tid, struct inode *ip, u32 idotdot)
/* init '..' entry */ /* init '..' entry */
p->header.idotdot = cpu_to_le32(idotdot); 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; return;
} }
......
/* /*
* 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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/quotaops.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_superblock.h" #include "jfs_superblock.h"
#include "jfs_dmap.h" #include "jfs_dmap.h"
...@@ -144,6 +145,13 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) ...@@ -144,6 +145,13 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
return (rc); return (rc);
} }
/* Allocate blocks to quota. */
if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
dbFree(ip, nxaddr, (s64) nxlen);
up(&JFS_IP(ip)->commit_sem);
return -EDQUOT;
}
/* determine the value of the extent flag */ /* determine the value of the extent flag */
xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0; xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0;
...@@ -161,13 +169,11 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) ...@@ -161,13 +169,11 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
*/ */
if (rc) { if (rc) {
dbFree(ip, nxaddr, nxlen); dbFree(ip, nxaddr, nxlen);
DQUOT_FREE_BLOCK(ip, nxlen);
up(&JFS_IP(ip)->commit_sem); up(&JFS_IP(ip)->commit_sem);
return (rc); return (rc);
} }
/* update the number of blocks allocated to the file */
ip->i_blocks += LBLK2PBLK(ip->i_sb, nxlen);
/* set the results of the extent allocation */ /* set the results of the extent allocation */
XADaddress(xp, nxaddr); XADaddress(xp, nxaddr);
XADlength(xp, nxlen); XADlength(xp, nxlen);
...@@ -254,6 +260,13 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr) ...@@ -254,6 +260,13 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
if ((rc = extBrealloc(ip, xaddr, xlen, &nxlen, &nxaddr))) if ((rc = extBrealloc(ip, xaddr, xlen, &nxlen, &nxaddr)))
goto exit; goto exit;
/* Allocat blocks to quota. */
if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
dbFree(ip, nxaddr, (s64) nxlen);
up(&JFS_IP(ip)->commit_sem);
return -EDQUOT;
}
delta = nxlen - xlen; delta = nxlen - xlen;
/* check if the extend page is not abnr but the request is abnr /* check if the extend page is not abnr but the request is abnr
...@@ -289,6 +302,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr) ...@@ -289,6 +302,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
/* extend the extent */ /* extend the extent */
if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) { if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
dbFree(ip, xaddr + xlen, delta); dbFree(ip, xaddr + xlen, delta);
DQUOT_FREE_BLOCK(ip, nxlen);
goto exit; goto exit;
} }
} else { } else {
...@@ -299,6 +313,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr) ...@@ -299,6 +313,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
*/ */
if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) { if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
dbFree(ip, nxaddr, nxlen); dbFree(ip, nxaddr, nxlen);
DQUOT_FREE_BLOCK(ip, nxlen);
goto exit; goto exit;
} }
} }
...@@ -320,9 +335,6 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr) ...@@ -320,9 +335,6 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
} }
} }
/* update the inode with the number of blocks allocated */
ip->i_blocks += LBLK2PBLK(sb, delta);
/* set the return results */ /* set the return results */
XADaddress(xp, nxaddr); XADaddress(xp, nxaddr);
XADlength(xp, nxlen); XADlength(xp, nxlen);
......
/* /*
* 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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/pagemap.h> #include <linux/pagemap.h>
#include <linux/quotaops.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_filsys.h" #include "jfs_filsys.h"
...@@ -504,6 +505,9 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) ...@@ -504,6 +505,9 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
ip->i_mapping->a_ops = &jfs_aops; ip->i_mapping->a_ops = &jfs_aops;
mapping_set_gfp_mask(ip->i_mapping, GFP_NOFS); mapping_set_gfp_mask(ip->i_mapping, GFP_NOFS);
/* Allocations to metadata inodes should not affect quotas */
ip->i_flags |= S_NOQUOTA;
if ((inum == FILESYSTEM_I) && (JFS_IP(ip)->ipimap == sbi->ipaimap)) { if ((inum == FILESYSTEM_I) && (JFS_IP(ip)->ipimap == sbi->ipaimap)) {
sbi->gengen = le32_to_cpu(dp->di_gengen); sbi->gengen = le32_to_cpu(dp->di_gengen);
sbi->inostamp = le32_to_cpu(dp->di_inostamp); sbi->inostamp = le32_to_cpu(dp->di_inostamp);
...@@ -2601,28 +2605,11 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) ...@@ -2601,28 +2605,11 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
iagp->inosmap[i] = ONES; iagp->inosmap[i] = ONES;
flush_metapage(mp); flush_metapage(mp);
#ifdef _STILL_TO_PORT
/* synchronously write the iag page */
if (bmWrite(bp)) {
/* Free the blocks allocated for the iag since it was
* not successfully added to the inode map
*/
dbFree(ipimap, xaddr, (s64) xlen);
/* release the inode map lock */
IWRITE_UNLOCK(ipimap);
rc = -EIO;
goto out;
}
/* Now the iag is on disk */
/* /*
* start tyransaction of update of the inode map * start tyransaction of update of the inode map
* addressing structure pointing to the new iag page; * addressing structure pointing to the new iag page;
*/ */
#endif /* _STILL_TO_PORT */
tid = txBegin(sb, COMMIT_FORCE); tid = txBegin(sb, COMMIT_FORCE);
down(&JFS_IP(ipimap)->commit_sem); down(&JFS_IP(ipimap)->commit_sem);
...@@ -2644,7 +2631,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp) ...@@ -2644,7 +2631,7 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
/* update the inode map's inode to reflect the extension */ /* update the inode map's inode to reflect the extension */
ipimap->i_size += PSIZE; ipimap->i_size += PSIZE;
ipimap->i_blocks += LBLK2PBLK(sb, xlen); inode_add_bytes(ipimap, PSIZE);
/* /*
* txCommit(COMMIT_FORCE) will synchronously write address * txCommit(COMMIT_FORCE) will synchronously write address
...@@ -3085,7 +3072,7 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno, ...@@ -3085,7 +3072,7 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno,
} }
/* update the inode map's inode to reflect the extension */ /* update the inode map's inode to reflect the extension */
ip->i_size += PSIZE; ip->i_size += PSIZE;
ip->i_blocks += LBLK2PBLK(sb, xlen); inode_add_bytes(ip, PSIZE);
txCommit(tid, 1, &ip, COMMIT_FORCE); txCommit(tid, 1, &ip, COMMIT_FORCE);
cleanup: cleanup:
txEnd(tid); txEnd(tid);
......
/* /*
* Copyright (c) International Business Machines Corp., 2000-2002 * Copyright (C) International Business Machines Corp., 2000-2004
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
*/ */
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/quotaops.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_filsys.h" #include "jfs_filsys.h"
#include "jfs_imap.h" #include "jfs_imap.h"
...@@ -60,6 +61,17 @@ struct inode *ialloc(struct inode *parent, umode_t mode) ...@@ -60,6 +61,17 @@ struct inode *ialloc(struct inode *parent, umode_t mode)
} else } else
inode->i_gid = current->fsgid; inode->i_gid = current->fsgid;
/*
* Allocate inode to quota.
*/
if (DQUOT_ALLOC_INODE(inode)) {
DQUOT_DROP(inode);
inode->i_flags |= S_NOQUOTA;
inode->i_nlink = 0;
iput(inode);
return NULL;
}
inode->i_mode = mode; inode->i_mode = mode;
if (S_ISDIR(mode)) if (S_ISDIR(mode))
jfs_inode->mode2 = IDIRECTORY | mode; jfs_inode->mode2 = IDIRECTORY | mode;
......
...@@ -2621,8 +2621,6 @@ void txAbort(tid_t tid, int dirty) ...@@ -2621,8 +2621,6 @@ void txAbort(tid_t tid, int dirty)
struct tblock *tblk = tid_to_tblock(tid); struct tblock *tblk = tid_to_tblock(tid);
struct tlock *tlck; struct tlock *tlck;
jfs_warn("txAbort: tid:%d dirty:0x%x", tid, dirty);
/* /*
* free tlocks of the transaction * free tlocks of the transaction
*/ */
......
/* /*
* 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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
*/ */
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/quotaops.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_filsys.h" #include "jfs_filsys.h"
#include "jfs_metapage.h" #include "jfs_metapage.h"
...@@ -829,8 +830,12 @@ int xtInsert(tid_t tid, /* transaction id */ ...@@ -829,8 +830,12 @@ int xtInsert(tid_t tid, /* transaction id */
hint = addressXAD(xad) + lengthXAD(xad) - 1; hint = addressXAD(xad) + lengthXAD(xad) - 1;
} else } else
hint = 0; hint = 0;
if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) if ((rc = DQUOT_ALLOC_BLOCK(ip, xlen)))
goto out; goto out;
if ((rc = dbAlloc(ip, hint, (s64) xlen, &xaddr))) {
DQUOT_FREE_BLOCK(ip, xlen);
goto out;
}
} }
/* /*
...@@ -855,8 +860,10 @@ int xtInsert(tid_t tid, /* transaction id */ ...@@ -855,8 +860,10 @@ int xtInsert(tid_t tid, /* transaction id */
split.pxdlist = NULL; split.pxdlist = NULL;
if ((rc = xtSplitUp(tid, ip, &split, &btstack))) { if ((rc = xtSplitUp(tid, ip, &split, &btstack))) {
/* undo data extent allocation */ /* undo data extent allocation */
if (*xaddrp == 0) if (*xaddrp == 0) {
dbFree(ip, xaddr, (s64) xlen); dbFree(ip, xaddr, (s64) xlen);
DQUOT_FREE_BLOCK(ip, xlen);
}
return rc; return rc;
} }
...@@ -1214,22 +1221,34 @@ xtSplitPage(tid_t tid, struct inode *ip, ...@@ -1214,22 +1221,34 @@ xtSplitPage(tid_t tid, struct inode *ip,
pxd_t *pxd; pxd_t *pxd;
struct tlock *tlck; struct tlock *tlck;
struct xtlock *sxtlck = NULL, *rxtlck = NULL; struct xtlock *sxtlck = NULL, *rxtlck = NULL;
int quota_allocation = 0;
smp = split->mp; smp = split->mp;
sp = XT_PAGE(ip, smp); sp = XT_PAGE(ip, smp);
INCREMENT(xtStat.split); INCREMENT(xtStat.split);
/*
* allocate the new right page for the split
*/
pxdlist = split->pxdlist; pxdlist = split->pxdlist;
pxd = &pxdlist->pxd[pxdlist->npxd]; pxd = &pxdlist->pxd[pxdlist->npxd];
pxdlist->npxd++; pxdlist->npxd++;
rbn = addressPXD(pxd); 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); rmp = get_metapage(ip, rbn, PSIZE, 1);
if (rmp == NULL) if (rmp == NULL) {
return -EIO; rc = -EIO;
goto clean_up;
}
jfs_info("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp); jfs_info("xtSplitPage: ip:0x%p smp:0x%p rmp:0x%p", ip, smp, rmp);
...@@ -1304,8 +1323,6 @@ xtSplitPage(tid_t tid, struct inode *ip, ...@@ -1304,8 +1323,6 @@ xtSplitPage(tid_t tid, struct inode *ip,
*rmpp = rmp; *rmpp = rmp;
*rbnp = rbn; *rbnp = rbn;
ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp); jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp);
return 0; return 0;
} }
...@@ -1321,7 +1338,7 @@ xtSplitPage(tid_t tid, struct inode *ip, ...@@ -1321,7 +1338,7 @@ xtSplitPage(tid_t tid, struct inode *ip,
XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc); XT_GETPAGE(ip, nextbn, mp, PSIZE, p, rc);
if (rc) { if (rc) {
XT_PUTPAGE(rmp); XT_PUTPAGE(rmp);
return rc; goto clean_up;
} }
BT_MARK_DIRTY(mp, ip); BT_MARK_DIRTY(mp, ip);
...@@ -1420,10 +1437,16 @@ xtSplitPage(tid_t tid, struct inode *ip, ...@@ -1420,10 +1437,16 @@ xtSplitPage(tid_t tid, struct inode *ip,
*rmpp = rmp; *rmpp = rmp;
*rbnp = rbn; *rbnp = rbn;
ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp); jfs_info("xtSplitPage: sp:0x%p rp:0x%p", sp, rp);
return rc; return rc;
clean_up:
/* Rollback quota allocation. */
if (quota_allocation)
DQUOT_FREE_BLOCK(ip, quota_allocation);
return (rc);
} }
...@@ -1478,6 +1501,12 @@ xtSplitRoot(tid_t tid, ...@@ -1478,6 +1501,12 @@ xtSplitRoot(tid_t tid,
if (rmp == NULL) if (rmp == NULL)
return -EIO; 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); jfs_info("xtSplitRoot: ip:0x%p rmp:0x%p", ip, rmp);
/* /*
...@@ -1561,8 +1590,6 @@ xtSplitRoot(tid_t tid, ...@@ -1561,8 +1590,6 @@ xtSplitRoot(tid_t tid,
*rmpp = rmp; *rmpp = rmp;
ip->i_blocks += LBLK2PBLK(ip->i_sb, lengthPXD(pxd));
jfs_info("xtSplitRoot: sp:0x%p rp:0x%p", sp, rp); jfs_info("xtSplitRoot: sp:0x%p rp:0x%p", sp, rp);
return 0; return 0;
} }
...@@ -3909,8 +3936,8 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) ...@@ -3909,8 +3936,8 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
else else
ip->i_size = newsize; ip->i_size = newsize;
/* update nblocks to reflect freed blocks */ /* update quota allocation to reflect freed blocks */
ip->i_blocks -= LBLK2PBLK(ip->i_sb, nfreed); DQUOT_FREE_BLOCK(ip, nfreed);
/* /*
* free tlock of invalidated pages * free tlock of invalidated pages
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/quotaops.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_superblock.h" #include "jfs_superblock.h"
#include "jfs_inode.h" #include "jfs_inode.h"
...@@ -123,10 +124,10 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode, ...@@ -123,10 +124,10 @@ static int jfs_create(struct inode *dip, struct dentry *dentry, int mode,
*/ */
ino = ip->i_ino; ino = ip->i_ino;
if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
jfs_err("jfs_create: dtInsert returned %d", rc); if (rc == -EIO) {
if (rc == -EIO) jfs_err("jfs_create: dtInsert returned -EIO");
txAbort(tid, 1); /* Marks Filesystem dirty */ txAbort(tid, 1); /* Marks Filesystem dirty */
else } else
txAbort(tid, 0); /* Filesystem full */ txAbort(tid, 0); /* Filesystem full */
goto out3; goto out3;
} }
...@@ -250,11 +251,10 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode) ...@@ -250,11 +251,10 @@ static int jfs_mkdir(struct inode *dip, struct dentry *dentry, int mode)
*/ */
ino = ip->i_ino; ino = ip->i_ino;
if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) { if ((rc = dtInsert(tid, dip, &dname, &ino, &btstack))) {
jfs_err("jfs_mkdir: dtInsert returned %d", rc); if (rc == -EIO) {
jfs_err("jfs_mkdir: dtInsert returned -EIO");
if (rc == -EIO)
txAbort(tid, 1); /* Marks Filesystem dirty */ txAbort(tid, 1); /* Marks Filesystem dirty */
else } else
txAbort(tid, 0); /* Filesystem full */ txAbort(tid, 0); /* Filesystem full */
goto out3; goto out3;
} }
...@@ -330,6 +330,9 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry) ...@@ -330,6 +330,9 @@ static int jfs_rmdir(struct inode *dip, struct dentry *dentry)
jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name); jfs_info("jfs_rmdir: dip:0x%p name:%s", dip, dentry->d_name.name);
/* Init inode for quota operations. */
DQUOT_INIT(ip);
/* directory must be empty to be removed */ /* directory must be empty to be removed */
if (!dtEmpty(ip)) { if (!dtEmpty(ip)) {
rc = -ENOTEMPTY; rc = -ENOTEMPTY;
...@@ -455,6 +458,9 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry) ...@@ -455,6 +458,9 @@ static int jfs_unlink(struct inode *dip, struct dentry *dentry)
jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name); jfs_info("jfs_unlink: dip:0x%p name:%s", dip, dentry->d_name.name);
/* Init inode for quota operations. */
DQUOT_INIT(ip);
if ((rc = get_UCSname(&dname, dentry))) if ((rc = get_UCSname(&dname, dentry)))
goto out; goto out;
...@@ -813,7 +819,10 @@ static int jfs_link(struct dentry *old_dentry, ...@@ -813,7 +819,10 @@ static int jfs_link(struct dentry *old_dentry,
iplist[1] = dir; iplist[1] = dir;
rc = txCommit(tid, 2, &iplist[0], 0); rc = txCommit(tid, 2, &iplist[0], 0);
if (!rc) if (rc) {
ip->i_nlink--;
iput(ip);
} else
d_instantiate(dentry, ip); d_instantiate(dentry, ip);
free_dname: free_dname:
...@@ -964,7 +973,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, ...@@ -964,7 +973,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
mp = get_metapage(ip, xaddr, PSIZE, 1); mp = get_metapage(ip, xaddr, PSIZE, 1);
if (mp == NULL) { if (mp == NULL) {
dbFree(ip, extent, xlen); xtTruncate(tid, ip, 0, COMMIT_PWMAP);
rc = -EIO; rc = -EIO;
txAbort(tid, 0); txAbort(tid, 0);
goto out3; goto out3;
...@@ -975,7 +984,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, ...@@ -975,7 +984,6 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
name += copy_size; name += copy_size;
xaddr += JFS_SBI(sb)->nbperpage; xaddr += JFS_SBI(sb)->nbperpage;
} }
ip->i_blocks = LBLK2PBLK(sb, xlen);
} }
/* /*
...@@ -988,7 +996,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry, ...@@ -988,7 +996,7 @@ static int jfs_symlink(struct inode *dip, struct dentry *dentry,
} }
if (rc) { if (rc) {
if (xlen) if (xlen)
dbFree(ip, extent, xlen); xtTruncate(tid, ip, 0, COMMIT_PWMAP);
txAbort(tid, 0); txAbort(tid, 0);
/* discard new inode */ /* discard new inode */
goto out3; goto out3;
...@@ -1104,8 +1112,11 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1104,8 +1112,11 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
rc = -EMLINK; rc = -EMLINK;
goto out3; goto out3;
} }
} else if (new_ip) } else if (new_ip) {
IWRITE_LOCK(new_ip); IWRITE_LOCK(new_ip);
/* Init inode for quota operations. */
DQUOT_INIT(new_ip);
}
/* /*
* The real work starts here * The real work starts here
...@@ -1174,8 +1185,8 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry, ...@@ -1174,8 +1185,8 @@ static int jfs_rename(struct inode *old_dir, struct dentry *old_dentry,
ino = old_ip->i_ino; ino = old_ip->i_ino;
rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack); rc = dtInsert(tid, new_dir, &new_dname, &ino, &btstack);
if (rc) { if (rc) {
jfs_err("jfs_rename: dtInsert failed w/rc = %d", if (rc == -EIO)
rc); jfs_err("jfs_rename: dtInsert returned -EIO");
goto out4; goto out4;
} }
if (S_ISDIR(old_ip->i_mode)) if (S_ISDIR(old_ip->i_mode))
......
/* /*
* 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 * 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 * it under the terms of the GNU General Public License as published by
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/quotaops.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_filsys.h" #include "jfs_filsys.h"
#include "jfs_metapage.h" #include "jfs_metapage.h"
...@@ -390,7 +391,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize) ...@@ -390,7 +391,7 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
} }
/* update bmap file size */ /* update bmap file size */
ipbmap->i_size += xlen << sbi->l2bsize; ipbmap->i_size += xlen << sbi->l2bsize;
ipbmap->i_blocks += LBLK2PBLK(sb, xlen); inode_add_bytes(ipbmap, xlen << sbi->l2bsize);
iplist[0] = ipbmap; iplist[0] = ipbmap;
rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE); rc = txCommit(tid, 1, &iplist[0], COMMIT_FORCE);
......
/* /*
* Copyright (C) International Business Machines Corp., 2000-2003 * Copyright (C) International Business Machines Corp., 2000-2004
* Copyright (C) Christoph Hellwig, 2002 * Copyright (C) Christoph Hellwig, 2002
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/xattr.h> #include <linux/xattr.h>
#include <linux/quotaops.h>
#include "jfs_incore.h" #include "jfs_incore.h"
#include "jfs_superblock.h" #include "jfs_superblock.h"
#include "jfs_dmap.h" #include "jfs_dmap.h"
...@@ -251,9 +252,17 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size, ...@@ -251,9 +252,17 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size,
/* figure out how many blocks we need */ /* figure out how many blocks we need */
nblocks = (size + (sb->s_blocksize - 1)) >> sb->s_blocksize_bits; nblocks = (size + (sb->s_blocksize - 1)) >> sb->s_blocksize_bits;
/* Allocate new blocks to quota. */
if (DQUOT_ALLOC_BLOCK(ip, nblocks)) {
return -EDQUOT;
}
rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno); rc = dbAlloc(ip, INOHINT(ip), nblocks, &blkno);
if (rc) if (rc) {
/*Rollback quota allocation. */
DQUOT_FREE_BLOCK(ip, nblocks);
return rc; return rc;
}
/* /*
* Now have nblocks worth of storage to stuff into the FEALIST. * Now have nblocks worth of storage to stuff into the FEALIST.
...@@ -315,6 +324,9 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size, ...@@ -315,6 +324,9 @@ static int ea_write(struct inode *ip, struct jfs_ea_list *ealist, int size,
return 0; return 0;
failed: failed:
/* Rollback quota allocation. */
DQUOT_FREE_BLOCK(ip, nblocks);
dbFree(ip, blkno, nblocks); dbFree(ip, blkno, nblocks);
return rc; return rc;
} }
...@@ -448,6 +460,7 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) ...@@ -448,6 +460,7 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
int blocks_needed, current_blocks; int blocks_needed, current_blocks;
s64 blkno; s64 blkno;
int rc; int rc;
int quota_allocation = 0;
/* When fsck.jfs clears a bad ea, it doesn't clear the size */ /* When fsck.jfs clears a bad ea, it doesn't clear the size */
if (ji->ea.flag == 0) if (ji->ea.flag == 0)
...@@ -517,10 +530,16 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) ...@@ -517,10 +530,16 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
sb->s_blocksize_bits; sb->s_blocksize_bits;
if (blocks_needed > current_blocks) { if (blocks_needed > current_blocks) {
/* Allocate new blocks to quota. */
if (DQUOT_ALLOC_BLOCK(inode, blocks_needed))
return -EDQUOT;
quota_allocation = blocks_needed;
rc = dbAlloc(inode, INOHINT(inode), (s64) blocks_needed, rc = dbAlloc(inode, INOHINT(inode), (s64) blocks_needed,
&blkno); &blkno);
if (rc) if (rc)
return rc; goto clean_up;
DXDlength(&ea_buf->new_ea, blocks_needed); DXDlength(&ea_buf->new_ea, blocks_needed);
DXDaddress(&ea_buf->new_ea, blkno); DXDaddress(&ea_buf->new_ea, blkno);
...@@ -534,7 +553,8 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) ...@@ -534,7 +553,8 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
1); 1);
if (ea_buf->mp == NULL) { if (ea_buf->mp == NULL) {
dbFree(inode, blkno, (s64) blocks_needed); dbFree(inode, blkno, (s64) blocks_needed);
return -EIO; rc = -EIO;
goto clean_up;
} }
ea_buf->xattr = ea_buf->mp->data; ea_buf->xattr = ea_buf->mp->data;
ea_buf->max_size = (min_size + sb->s_blocksize - 1) & ea_buf->max_size = (min_size + sb->s_blocksize - 1) &
...@@ -544,7 +564,7 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) ...@@ -544,7 +564,7 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
if ((rc = ea_read(inode, ea_buf->xattr))) { if ((rc = ea_read(inode, ea_buf->xattr))) {
discard_metapage(ea_buf->mp); discard_metapage(ea_buf->mp);
dbFree(inode, blkno, (s64) blocks_needed); dbFree(inode, blkno, (s64) blocks_needed);
return rc; goto clean_up;
} }
goto size_check; goto size_check;
} }
...@@ -552,8 +572,10 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) ...@@ -552,8 +572,10 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
ea_buf->mp = read_metapage(inode, addressDXD(&ji->ea), ea_buf->mp = read_metapage(inode, addressDXD(&ji->ea),
lengthDXD(&ji->ea) << sb->s_blocksize_bits, lengthDXD(&ji->ea) << sb->s_blocksize_bits,
1); 1);
if (ea_buf->mp == NULL) if (ea_buf->mp == NULL) {
return -EIO; rc = -EIO;
goto clean_up;
}
ea_buf->xattr = ea_buf->mp->data; ea_buf->xattr = ea_buf->mp->data;
ea_buf->max_size = (ea_size + sb->s_blocksize - 1) & ea_buf->max_size = (ea_size + sb->s_blocksize - 1) &
~(sb->s_blocksize - 1); ~(sb->s_blocksize - 1);
...@@ -563,10 +585,18 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size) ...@@ -563,10 +585,18 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
printk(KERN_ERR "ea_get: invalid extended attribute\n"); printk(KERN_ERR "ea_get: invalid extended attribute\n");
dump_mem("xattr", ea_buf->xattr, ea_size); dump_mem("xattr", ea_buf->xattr, ea_size);
ea_release(inode, ea_buf); ea_release(inode, ea_buf);
return -EIO; rc = -EIO;
goto clean_up;
} }
return ea_size; return ea_size;
clean_up:
/* Rollback quota allocation */
if (quota_allocation)
DQUOT_FREE_BLOCK(inode, quota_allocation);
return (rc);
} }
static void ea_release(struct inode *inode, struct ea_buffer *ea_buf) static void ea_release(struct inode *inode, struct ea_buffer *ea_buf)
...@@ -640,7 +670,10 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size) ...@@ -640,7 +670,10 @@ static int ea_put(struct inode *inode, struct ea_buffer *ea_buf, int new_size)
ji->ea.size = 0; ji->ea.size = 0;
} }
inode->i_blocks += LBLK2PBLK(inode->i_sb, new_blocks - old_blocks); /* If old blocks exist, they must be removed from quota allocation. */
if (old_blocks)
DQUOT_FREE_BLOCK(inode, old_blocks);
inode->i_ctime = CURRENT_TIME; inode->i_ctime = CURRENT_TIME;
rc = txCommit(tid, 1, &inode, 0); rc = txCommit(tid, 1, &inode, 0);
txEnd(tid); txEnd(tid);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment