/*
- * 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 <linux/vs_dlimit.h>
#include "jfs_incore.h"
+#include "jfs_inode.h"
#include "jfs_superblock.h"
#include "jfs_dmap.h"
#include "jfs_extent.h"
#endif
static s64 extRoundDown(s64 nb);
-/*
- * external references
- */
-extern int jfs_commit_inode(struct inode *, int);
-
-
#define DPD(a) (printk("(a): %d\n",(a)))
#define DPC(a) (printk("(a): %c\n",(a)))
#define DPL1(a) \
txBeginAnon(ip->i_sb);
/* Avoid race with jfs_commit_inode() */
- down(&JFS_IP(ip)->commit_sem);
+ mutex_lock(&JFS_IP(ip)->commit_mutex);
/* validate extent length */
if (xlen > MAXXLEN)
*/
nxlen = xlen;
if ((rc = extBalloc(ip, hint ? hint : INOHINT(ip), &nxlen, &nxaddr))) {
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
return (rc);
}
+ /* Allocate blocks to quota. */
+ if (DQUOT_ALLOC_BLOCK(ip, nxlen)) {
+ dbFree(ip, nxaddr, (s64) nxlen);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ return -EDQUOT;
+ }
+ /* Allocate blocks to dlimit. */
+ if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
+ DQUOT_FREE_BLOCK(ip, nxlen);
+ dbFree(ip, nxaddr, (s64) nxlen);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ return -ENOSPC;
+ }
+
/* determine the value of the extent flag */
xflag = (abnr == TRUE) ? XAD_NOTRECORDED : 0;
*/
if (rc) {
dbFree(ip, nxaddr, nxlen);
- up(&JFS_IP(ip)->commit_sem);
+ DLIMIT_FREE_BLOCK(ip, nxlen);
+ DQUOT_FREE_BLOCK(ip, nxlen);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
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);
mark_inode_dirty(ip);
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
/*
* COMMIT_SyncList flags an anonymous tlock on page that is on
* sync list.
/* This blocks if we are low on resources */
txBeginAnon(ip->i_sb);
- down(&JFS_IP(ip)->commit_sem);
+ mutex_lock(&JFS_IP(ip)->commit_mutex);
/* validate extent length */
if (nxlen > MAXXLEN)
nxlen = MAXXLEN;
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);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
+ return -EDQUOT;
+ }
+ /* Allocate blocks to dlimit. */
+ if (DLIMIT_ALLOC_BLOCK(ip, nxlen)) {
+ DQUOT_FREE_BLOCK(ip, nxlen);
+ dbFree(ip, nxaddr, (s64) nxlen);
+ up(&JFS_IP(ip)->commit_sem);
+ return -ENOSPC;
+ }
+
delta = nxlen - xlen;
/* check if the extend page is not abnr but the request is abnr
/* extend the extent */
if ((rc = xtExtend(0, ip, xoff + xlen, (int) nextend, 0))) {
dbFree(ip, xaddr + xlen, delta);
+ DLIMIT_FREE_BLOCK(ip, nxlen);
+ DQUOT_FREE_BLOCK(ip, nxlen);
goto exit;
}
} else {
*/
if ((rc = xtTailgate(0, ip, xoff, (int) ntail, nxaddr, 0))) {
dbFree(ip, nxaddr, nxlen);
+ DLIMIT_FREE_BLOCK(ip, nxlen);
+ DQUOT_FREE_BLOCK(ip, nxlen);
goto exit;
}
}
}
}
- /* 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);
mark_inode_dirty(ip);
exit:
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
return (rc);
}
#endif /* _NOTYET */
txBeginAnon(ip->i_sb);
- down(&JFS_IP(ip)->commit_sem);
+ mutex_lock(&JFS_IP(ip)->commit_mutex);
/* update the extent */
rc = xtUpdate(0, ip, xp);
- up(&JFS_IP(ip)->commit_sem);
+ mutex_unlock(&JFS_IP(ip)->commit_mutex);
return rc;
}
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.
*/
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;
atomic_inc(&bmp->db_active[ag]);
ji->active_ag = ag;
}
+ spin_unlock_irq(&ji->ag_lock);
}
return (0);