summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/ufs/ffs/ffs_alloc.c20
-rw-r--r--sys/ufs/ffs/ffs_inode.c6
-rw-r--r--sys/ufs/ffs/ffs_softdep.c82
-rw-r--r--sys/ufs/ffs/ffs_vnops.c3
-rw-r--r--sys/ufs/ffs/softdep.h2
-rw-r--r--sys/ufs/ufs/inode.h1
-rw-r--r--sys/ufs/ufs/ufs_inode.c14
-rw-r--r--sys/ufs/ufs/ufs_lookup.c2
-rw-r--r--sys/ufs/ufs/ufs_vnops.c32
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. */
OpenPOWER on IntegriCloud