diff options
-rw-r--r-- | sys/ufs/ffs/ffs_alloc.c | 20 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_inode.c | 6 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_softdep.c | 82 | ||||
-rw-r--r-- | sys/ufs/ffs/ffs_vnops.c | 3 | ||||
-rw-r--r-- | sys/ufs/ffs/softdep.h | 2 | ||||
-rw-r--r-- | sys/ufs/ufs/inode.h | 1 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_inode.c | 14 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_lookup.c | 2 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 32 |
9 files changed, 34 insertions, 128 deletions
diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index b1f7ba0..b740bbb 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -191,11 +191,6 @@ retry: bno = ffs_hashalloc(ip, cg, bpref, size, size, ffs_alloccg); if (bno > 0) { delta = btodb(size); - if (ip->i_flag & IN_SPACECOUNTED) { - UFS_LOCK(ump); - fs->fs_pendingblocks += delta; - UFS_UNLOCK(ump); - } DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta); if (flags & IO_EXT) ip->i_flag |= IN_CHANGE; @@ -321,11 +316,6 @@ retry: if (bp->b_blkno != fsbtodb(fs, bno)) panic("ffs_realloccg: bad blockno"); delta = btodb(nsize - osize); - if (ip->i_flag & IN_SPACECOUNTED) { - UFS_LOCK(ump); - fs->fs_pendingblocks += delta; - UFS_UNLOCK(ump); - } DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta); if (flags & IO_EXT) ip->i_flag |= IN_CHANGE; @@ -394,11 +384,6 @@ retry: ffs_blkfree(ump, fs, ip->i_devvp, bprev, (long)osize, ip->i_number, NULL); delta = btodb(nsize - osize); - if (ip->i_flag & IN_SPACECOUNTED) { - UFS_LOCK(ump); - fs->fs_pendingblocks += delta; - UFS_UNLOCK(ump); - } DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta); if (flags & IO_EXT) ip->i_flag |= IN_CHANGE; @@ -2422,11 +2407,6 @@ sysctl_ffs_fsck(SYSCTL_HANDLER_ARGS) if ((error = ffs_vget(mp, (ino_t)cmd.value, LK_EXCLUSIVE, &vp))) break; ip = VTOI(vp); - if (ip->i_flag & IN_SPACECOUNTED) { - UFS_LOCK(ump); - fs->fs_pendingblocks += cmd.size; - UFS_UNLOCK(ump); - } DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + cmd.size); ip->i_flag |= IN_CHANGE; vput(vp); diff --git a/sys/ufs/ffs/ffs_inode.c b/sys/ufs/ffs/ffs_inode.c index 3b69832..ffbe16e 100644 --- a/sys/ufs/ffs/ffs_inode.c +++ b/sys/ufs/ffs/ffs_inode.c @@ -180,6 +180,8 @@ ffs_truncate(vp, length, flags, cred, td) */ if ((flags & (IO_EXT | IO_NORMAL)) == 0) flags |= IO_NORMAL; + if (!DOINGSOFTDEP(vp) && !DOINGASYNC(vp)) + flags |= IO_SYNC; /* * If we are truncating the extended-attributes, and cannot * do it with soft updates, then do it slowly here. If we are @@ -310,10 +312,6 @@ ffs_truncate(vp, length, flags, cred, td) */ if ((error = ffs_syncvnode(vp, MNT_WAIT)) != 0) goto out; - UFS_LOCK(ump); - if (ip->i_flag & IN_SPACECOUNTED) - fs->fs_pendingblocks -= datablocks; - UFS_UNLOCK(ump); /* * We have to journal the truncation before we change * any blocks so we don't leave the file partially diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c index 0a62000..1977d60 100644 --- a/sys/ufs/ffs/ffs_softdep.c +++ b/sys/ufs/ffs/ffs_softdep.c @@ -5183,16 +5183,9 @@ softdep_setup_freeblocks(ip, length, flags) fs->fs_frag, needj); lbn += tmpval; } - /* - * If the file was removed, then the space being freed was - * accounted for then (see softdep_releasefile()). If the - * file is merely being truncated, then we account for it now. - */ - if ((ip->i_flag & IN_SPACECOUNTED) == 0) { - UFS_LOCK(ip->i_ump); - fs->fs_pendingblocks += datablocks; - UFS_UNLOCK(ip->i_ump); - } + UFS_LOCK(ip->i_ump); + fs->fs_pendingblocks += datablocks; + UFS_UNLOCK(ip->i_ump); } if ((flags & IO_EXT) != 0) { oldextsize = ip->i_din2->di_extsize; @@ -5674,11 +5667,9 @@ softdep_freefile(pvp, ino, mode) freefile->fx_oldinum = ino; freefile->fx_devvp = ip->i_devvp; LIST_INIT(&freefile->fx_jwork); - if ((ip->i_flag & IN_SPACECOUNTED) == 0) { - UFS_LOCK(ip->i_ump); - ip->i_fs->fs_pendinginodes += 1; - UFS_UNLOCK(ip->i_ump); - } + UFS_LOCK(ip->i_ump); + ip->i_fs->fs_pendinginodes += 1; + UFS_UNLOCK(ip->i_ump); /* * If the inodedep does not exist, then the zero'ed inode has @@ -7379,55 +7370,6 @@ softdep_change_linkcnt(ip) } /* - * Called when the effective link count and the reference count - * on an inode drops to zero. At this point there are no names - * referencing the file in the filesystem and no active file - * references. The space associated with the file will be freed - * as soon as the necessary soft dependencies are cleared. - */ -void -softdep_releasefile(ip) - struct inode *ip; /* inode with the zero effective link count */ -{ - struct inodedep *inodedep; - struct fs *fs; - int extblocks; - - if (ip->i_effnlink > 0) - panic("softdep_releasefile: file still referenced"); - /* - * We may be called several times as the on-disk link count - * drops to zero. We only want to account for the space once. - */ - if (ip->i_flag & IN_SPACECOUNTED) - return; - /* - * We have to deactivate a snapshot otherwise copyonwrites may - * add blocks and the cleanup may remove blocks after we have - * tried to account for them. - */ - if ((ip->i_flags & SF_SNAPSHOT) != 0) - ffs_snapremove(ITOV(ip)); - /* - * If we are tracking an nlinkdelta, we have to also remember - * whether we accounted for the freed space yet. - */ - ACQUIRE_LOCK(&lk); - if ((inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0, &inodedep))) - inodedep->id_state |= SPACECOUNTED; - FREE_LOCK(&lk); - fs = ip->i_fs; - extblocks = 0; - if (fs->fs_magic == FS_UFS2_MAGIC) - extblocks = btodb(fragroundup(fs, ip->i_din2->di_extsize)); - UFS_LOCK(ip->i_ump); - ip->i_fs->fs_pendingblocks += DIP(ip, i_blocks) - extblocks; - ip->i_fs->fs_pendinginodes += 1; - UFS_UNLOCK(ip->i_ump); - ip->i_flag |= IN_SPACECOUNTED; -} - -/* * Attach a sbdep dependency to the superblock buf so that we can keep * track of the head of the linked list of referenced but unlinked inodes. */ @@ -7735,7 +7677,6 @@ handle_workitem_remove(dirrem, xp) struct dirrem *dirrem; struct vnode *xp; { - struct thread *td = curthread; struct inodedep *inodedep; struct workhead dotdotwk; struct worklist *wk; @@ -7808,9 +7749,8 @@ handle_workitem_remove(dirrem, xp) /* * Directory deletion. Decrement reference count for both the * just deleted parent directory entry and the reference for ".". - * Next truncate the directory to length zero. When the - * truncation completes, arrange to have the reference count on - * the parent decremented to account for the loss of "..". + * Arrange to have the reference count on the parent decremented + * to account for the loss of "..". */ ip->i_nlink -= 2; DIP_SET(ip, i_nlink, ip->i_nlink); @@ -7820,10 +7760,6 @@ handle_workitem_remove(dirrem, xp) if (ip->i_nlink == 0) unlinked_inodedep(mp, inodedep); inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink; - FREE_LOCK(&lk); - if ((error = ffs_truncate(vp, (off_t)0, 0, td->td_ucred, td)) != 0) - softdep_error("handle_workitem_remove: truncate", error); - ACQUIRE_LOCK(&lk); /* * Rename a directory to a new parent. Since, we are both deleting * and creating a new directory entry, the link count on the new @@ -9899,8 +9835,6 @@ softdep_load_inodeblock(ip) return; } ip->i_effnlink -= inodedep->id_nlinkdelta; - if (inodedep->id_state & SPACECOUNTED) - ip->i_flag |= IN_SPACECOUNTED; FREE_LOCK(&lk); } diff --git a/sys/ufs/ffs/ffs_vnops.c b/sys/ufs/ffs/ffs_vnops.c index 96d0c7a..15c3f9f 100644 --- a/sys/ufs/ffs/ffs_vnops.c +++ b/sys/ufs/ffs/ffs_vnops.c @@ -1036,9 +1036,6 @@ ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *ucred) fs = ip->i_fs; dp = ip->i_din2; - KASSERT(!(ip->i_flag & IN_SPACECOUNTED), ("inode %u: inode is dead", - ip->i_number)); - #ifdef INVARIANTS if (uio->uio_rw != UIO_WRITE || fs->fs_magic != FS_UFS2_MAGIC) panic("ffs_extwrite: mode"); diff --git a/sys/ufs/ffs/softdep.h b/sys/ufs/ffs/softdep.h index e61b81b..23afbf7 100644 --- a/sys/ufs/ffs/softdep.h +++ b/sys/ufs/ffs/softdep.h @@ -118,7 +118,7 @@ #define DIRCHG 0x000080 /* diradd, dirrem only */ #define GOINGAWAY 0x000100 /* indirdep, jremref only */ #define IOSTARTED 0x000200 /* inodedep, pagedep, bmsafemap only */ -#define SPACECOUNTED 0x000400 /* inodedep only */ +#define UNUSED400 0x000400 /* currently available. */ #define NEWBLOCK 0x000800 /* pagedep, jaddref only */ #define INPROGRESS 0x001000 /* dirrem, freeblks, freefrag, freefile only */ #define UFS1FMT 0x002000 /* indirdep only */ diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h index 295b129..f6c4bb5 100644 --- a/sys/ufs/ufs/inode.h +++ b/sys/ufs/ufs/inode.h @@ -122,7 +122,6 @@ struct inode { #define IN_MODIFIED 0x0008 /* Inode has been modified. */ #define IN_NEEDSYNC 0x0010 /* Inode requires fsync. */ #define IN_LAZYMOD 0x0040 /* Modified, but don't write yet. */ -#define IN_SPACECOUNTED 0x0080 /* Blocks to be freed in free count. */ #define IN_LAZYACCESS 0x0100 /* Process IN_ACCESS after the suspension finished */ #define IN_EA_LOCKED 0x0200 diff --git a/sys/ufs/ufs/ufs_inode.c b/sys/ufs/ufs/ufs_inode.c index 17ec28e..a281ae5 100644 --- a/sys/ufs/ufs/ufs_inode.c +++ b/sys/ufs/ufs/ufs_inode.c @@ -76,6 +76,7 @@ ufs_inactive(ap) struct thread *td = ap->a_td; mode_t mode; int error = 0; + int isize; struct mount *mp; mp = NULL; @@ -118,18 +119,21 @@ ufs_inactive(ap) } } } - if (ip->i_effnlink == 0 && DOINGSOFTDEP(vp)) - softdep_releasefile(ip); - if (ip->i_nlink <= 0 && !UFS_RDONLY(ip)) { + isize = ip->i_size; + if (ip->i_ump->um_fstype == UFS2) + isize += ip->i_din2->di_extsize; + if (ip->i_effnlink <= 0 && isize && !UFS_RDONLY(ip)) { #ifdef QUOTA if (!getinoquota(ip)) (void)chkiq(ip, -1, NOCRED, FORCE); #endif + error = UFS_TRUNCATE(vp, (off_t)0, IO_EXT | IO_NORMAL, + NOCRED, td); + } + if (ip->i_nlink <= 0 && ip->i_mode && !UFS_RDONLY(ip)) { #ifdef UFS_EXTATTR ufs_extattr_vnode_inactive(vp, td); #endif - error = UFS_TRUNCATE(vp, (off_t)0, IO_EXT | IO_NORMAL, - NOCRED, td); /* * Setting the mode to zero needs to wait for the inode * to be written just as does a change to the link count. diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index c779491..e997718 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -248,6 +248,8 @@ ufs_lookup_ino(struct vnode *vdp, struct vnode **vpp, struct componentname *cnp, *vpp = NULL; dp = VTOI(vdp); + if (dp->i_effnlink == 0) + return (ENOENT); /* * Create a vm object if vmiodirenable is enabled. diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index f8d45cf..9c8bc1b 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -1119,7 +1119,7 @@ ufs_rename(ap) struct direct newdir; off_t endoff; int doingdirectory, newparent; - int error = 0, ioflag; + int error = 0; struct mount *mp; ino_t ino; @@ -1443,8 +1443,8 @@ relock: } if (doingdirectory && !DOINGSOFTDEP(tvp)) { /* - * Truncate inode. The only stuff left in the directory - * is "." and "..". The "." reference is inconsequential + * The only stuff left in the directory is "." + * and "..". The "." reference is inconsequential * since we are quashing it. We have removed the "." * reference and the reference in the parent directory, * but there may be other hard links. The soft @@ -1461,13 +1461,6 @@ relock: tip->i_nlink--; DIP_SET(tip, i_nlink, tip->i_nlink); tip->i_flag |= IN_CHANGE; - ioflag = IO_NORMAL; - if (!DOINGASYNC(tvp)) - ioflag |= IO_SYNC; - /* Don't go to bad here as the new link exists. */ - if ((error = UFS_TRUNCATE(tvp, (off_t)0, ioflag, - tcnp->cn_cred, tcnp->cn_thread)) != 0) - goto unlockout; } } @@ -1993,7 +1986,7 @@ ufs_rmdir(ap) struct vnode *dvp = ap->a_dvp; struct componentname *cnp = ap->a_cnp; struct inode *ip, *dp; - int error, ioflag; + int error; ip = VTOI(vp); dp = VTOI(dvp); @@ -2049,10 +2042,10 @@ ufs_rmdir(ap) } cache_purge(dvp); /* - * Truncate inode. The only stuff left in the directory is "." and - * "..". The "." reference is inconsequential since we are quashing - * it. The soft dependency code will arrange to do these operations - * after the parent directory entry has been deleted on disk, so + * The only stuff left in the directory is "." and "..". The "." + * reference is inconsequential since we are quashing it. The soft + * dependency code will arrange to do these operations after + * the parent directory entry has been deleted on disk, so * when running with that code we avoid doing them now. */ if (!DOINGSOFTDEP(vp)) { @@ -2062,11 +2055,6 @@ ufs_rmdir(ap) ip->i_nlink--; DIP_SET(ip, i_nlink, ip->i_nlink); ip->i_flag |= IN_CHANGE; - ioflag = IO_NORMAL; - if (!DOINGASYNC(vp)) - ioflag |= IO_SYNC; - error = UFS_TRUNCATE(vp, (off_t)0, ioflag, cnp->cn_cred, - cnp->cn_thread); } cache_purge(vp); #ifdef UFS_DIRHASH @@ -2137,6 +2125,7 @@ ufs_readdir(ap) } */ *ap; { struct uio *uio = ap->a_uio; + struct inode *ip; int error; size_t count, lost; off_t off; @@ -2147,6 +2136,9 @@ ufs_readdir(ap) * the cookies to determine where in the block to start. */ uio->uio_offset &= ~(DIRBLKSIZ - 1); + ip = VTOI(ap->a_vp); + if (ip->i_effnlink == 0) + return (0); off = uio->uio_offset; count = uio->uio_resid; /* Make sure we don't return partial entries. */ |