Revert to Fedora kernel-2.6.17-1.2187_FC5 patched with vs2.0.2.1; there are too many...
[linux-2.6.git] / fs / jfs / jfs_extent.c
index 2b411bc..0ce43f3 100644 (file)
@@ -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
  */
 
 #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"
@@ -32,12 +35,6 @@ static int extBrealloc(struct inode *, s64, s64, s64 *, s64 *);
 #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)                                        \
@@ -98,7 +95,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
        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)
@@ -140,10 +137,24 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
         */
        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;
 
@@ -161,13 +172,12 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
         */
        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);
@@ -176,7 +186,7 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, boolean_t abnr)
 
        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.
@@ -221,7 +231,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
        /* 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;
@@ -254,6 +264,20 @@ 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);
+               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
@@ -289,6 +313,8 @@ 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);
+                       DLIMIT_FREE_BLOCK(ip, nxlen);
+                       DQUOT_FREE_BLOCK(ip, nxlen);
                        goto exit;
                }
        } else {
@@ -299,6 +325,8 @@ 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);
+                       DLIMIT_FREE_BLOCK(ip, nxlen);
+                       DQUOT_FREE_BLOCK(ip, nxlen);
                        goto exit;
                }
        }
@@ -320,9 +348,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);
@@ -331,7 +356,7 @@ int extRealloc(struct inode *ip, s64 nxlen, xad_t * xp, boolean_t abnr)
 
        mark_inode_dirty(ip);
 exit:
-       up(&JFS_IP(ip)->commit_sem);
+       mutex_unlock(&JFS_IP(ip)->commit_mutex);
        return (rc);
 }
 #endif                 /* _NOTYET */
@@ -432,12 +457,12 @@ int extRecord(struct inode *ip, xad_t * xp)
 
        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;
 }