X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fjfs%2Fjfs_extent.c;h=1953acb792663da3886de6a9e606312882f77c21;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=399572237f35b06668f65f8be64b5b5cd7e73e0a;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/fs/jfs/jfs_extent.c b/fs/jfs/jfs_extent.c index 399572237..1953acb79 100644 --- a/fs/jfs/jfs_extent.c +++ b/fs/jfs/jfs_extent.c @@ -1,5 +1,5 @@ /* - * 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 @@ -17,6 +17,7 @@ */ #include +#include #include "jfs_incore.h" #include "jfs_superblock.h" #include "jfs_dmap.h" @@ -144,6 +145,13 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) 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 */ xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0; @@ -161,13 +169,11 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr) */ if (rc) { dbFree(ip, nxaddr, nxlen); + DQUOT_FREE_BLOCK(ip, nxlen); up(&JFS_IP(ip)->commit_sem); 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 */ XADaddress(xp, nxaddr); XADlength(xp, nxlen); @@ -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))) 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; /* 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) /* extend the extent */ if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) { dbFree(ip, xaddr + xlen, delta); + DQUOT_FREE_BLOCK(ip, nxlen); goto exit; } } else { @@ -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))) { dbFree(ip, nxaddr, nxlen); + DQUOT_FREE_BLOCK(ip, nxlen); goto exit; } } @@ -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 */ XADaddress(xp, nxaddr); XADlength(xp, nxlen); @@ -533,7 +545,7 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) nb = nblks = *nblocks; /* try to allocate blocks */ - while ((rc = dbAlloc(ip, hint, nb, &daddr))) { + while ((rc = dbAlloc(ip, hint, nb, &daddr)) != 0) { /* if something other than an out of space error, * stop and return this error. */ @@ -553,6 +565,7 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) if (S_ISREG(ip->i_mode) && (ji->fileset == FILESYSTEM_I)) { ag = BLKTOAG(daddr, sbi); + spin_lock_irq(&ji->ag_lock); if (ji->active_ag == -1) { atomic_inc(&bmp->db_active[ag]); ji->active_ag = ag; @@ -561,6 +574,7 @@ extBalloc(struct inode *ip, s64 hint, s64 * nblocks, s64 * blkno) atomic_inc(&bmp->db_active[ag]); ji->active_ag = ag; } + spin_unlock_irq(&ji->ag_lock); } return (0);