Check for out of space condition before extending ifile.
[unix-history] / usr / src / sys / ufs / lfs / lfs_alloc.c
index 09c0a5d..96bd309 100644 (file)
@@ -4,7 +4,7 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)lfs_alloc.c 7.51 (Berkeley) %G%
+ *     @(#)lfs_alloc.c 7.54 (Berkeley) %G%
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -45,7 +45,7 @@ lfs_valloc(ap)
        daddr_t blkno;
        ino_t new_ino;
        u_long i, max;
        daddr_t blkno;
        ino_t new_ino;
        u_long i, max;
-       int error;
+       int bb, error;
 
        /* Get the head of the freelist. */
        fs = VTOI(ap->a_pvp)->i_lfs;
 
        /* Get the head of the freelist. */
        fs = VTOI(ap->a_pvp)->i_lfs;
@@ -66,16 +66,13 @@ lfs_valloc(ap)
 
        /* Extend IFILE so that the next lfs_valloc will succeed. */
        if (fs->lfs_free == LFS_UNUSED_INUM) {
 
        /* Extend IFILE so that the next lfs_valloc will succeed. */
        if (fs->lfs_free == LFS_UNUSED_INUM) {
+               bb = fsbtodb(fs, 1);
+               if (!ISSPACE(fs, bb, ap->a_cred))
+                       return(ENOSPC);
                vp = fs->lfs_ivnode;
                ip = VTOI(vp);
                blkno = lblkno(fs, ip->i_size);
                bp = getblk(vp, blkno, fs->lfs_bsize);
                vp = fs->lfs_ivnode;
                ip = VTOI(vp);
                blkno = lblkno(fs, ip->i_size);
                bp = getblk(vp, blkno, fs->lfs_bsize);
-               if (!bp) {
-                       uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt);
-                       log(LOG_ERR, "uid %d on %s: out of inodes\n",
-                           ap->a_cred->cr_uid, fs->lfs_fsmnt);
-                       return (ENOSPC);
-               }
                i = (blkno - fs->lfs_segtabsz - fs->lfs_cleansz) *
                    fs->lfs_ifpb;
                fs->lfs_free = i;
                i = (blkno - fs->lfs_segtabsz - fs->lfs_cleansz) *
                    fs->lfs_ifpb;
                fs->lfs_free = i;
@@ -93,7 +90,8 @@ lfs_valloc(ap)
                ip->i_size += fs->lfs_bsize;
                vnode_pager_setsize(vp, (u_long)ip->i_size);
                vnode_pager_uncache(vp);
                ip->i_size += fs->lfs_bsize;
                vnode_pager_setsize(vp, (u_long)ip->i_size);
                vnode_pager_uncache(vp);
-               LFS_UBWRITE(bp);
+               if (error = VOP_BWRITE(bp))
+                       return (error);
        }
 
        /* Create a vnode to associate with the inode. */
        }
 
        /* Create a vnode to associate with the inode. */
@@ -147,7 +145,7 @@ lfs_vcreate(mp, ino, vpp)
        (*vpp)->v_data = ip;
        ip->i_vnode = *vpp;
        ip->i_devvp = ump->um_devvp;
        (*vpp)->v_data = ip;
        ip->i_vnode = *vpp;
        ip->i_devvp = ump->um_devvp;
-       ip->i_flag = 0;
+       ip->i_flag = IMOD;
        ip->i_dev = ump->um_dev;
        ip->i_number = ip->i_din.di_inum = ino;
        ip->i_lfs = ump->um_lfs;
        ip->i_dev = ump->um_dev;
        ip->i_number = ip->i_din.di_inum = ino;
        ip->i_lfs = ump->um_lfs;
@@ -160,6 +158,7 @@ lfs_vcreate(mp, ino, vpp)
        ip->i_mode = 0;
        ip->i_size = 0;
        ip->i_blocks = 0;
        ip->i_mode = 0;
        ip->i_size = 0;
        ip->i_blocks = 0;
+       ++ump->um_lfs->lfs_uinodes;
        return (0);
 }
 
        return (0);
 }
 
@@ -180,12 +179,16 @@ lfs_vfree(ap)
        struct lfs *fs;
        daddr_t old_iaddr;
        ino_t ino;
        struct lfs *fs;
        daddr_t old_iaddr;
        ino_t ino;
+       int error;
 
        /* Get the inode number and file system. */
        ip = VTOI(ap->a_pvp);
        fs = ip->i_lfs;
        ino = ip->i_number;
 
        /* Get the inode number and file system. */
        ip = VTOI(ap->a_pvp);
        fs = ip->i_lfs;
        ino = ip->i_number;
-
+       if (ip->i_flag & IMOD) {
+               --fs->lfs_uinodes;
+               ip->i_flag &= ~(IMOD | IACC | IUPD | ICHG);
+       }
        /*
         * Set the ifile's inode entry to unused, increment its version number
         * and link it into the free chain.
        /*
         * Set the ifile's inode entry to unused, increment its version number
         * and link it into the free chain.
@@ -196,7 +199,7 @@ lfs_vfree(ap)
        ++ifp->if_version;
        ifp->if_nextfree = fs->lfs_free;
        fs->lfs_free = ino;
        ++ifp->if_version;
        ifp->if_nextfree = fs->lfs_free;
        fs->lfs_free = ino;
-       LFS_UBWRITE(bp);
+       (void) VOP_BWRITE(bp);
 
        if (old_iaddr != LFS_UNUSED_DADDR) {
                LFS_SEGENTRY(sup, fs, datosn(fs, old_iaddr), bp);
 
        if (old_iaddr != LFS_UNUSED_DADDR) {
                LFS_SEGENTRY(sup, fs, datosn(fs, old_iaddr), bp);
@@ -206,7 +209,7 @@ lfs_vfree(ap)
                            datosn(fs, old_iaddr));
 #endif
                sup->su_nbytes -= sizeof(struct dinode);
                            datosn(fs, old_iaddr));
 #endif
                sup->su_nbytes -= sizeof(struct dinode);
-               LFS_UBWRITE(bp);
+               (void) VOP_BWRITE(bp);
        }
 
        /* Set superblock modified bit and decrement file count. */
        }
 
        /* Set superblock modified bit and decrement file count. */