[Midnightbsd-cvs] src [12316] trunk/sys/ufs: sync with FreeBSD 11-stable
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Sat Feb 8 14:39:08 EST 2020
Revision: 12316
http://svnweb.midnightbsd.org/src/?rev=12316
Author: laffer1
Date: 2020-02-08 14:39:08 -0500 (Sat, 08 Feb 2020)
Log Message:
-----------
sync with FreeBSD 11-stable
Modified Paths:
--------------
trunk/sys/ufs/ffs/ffs_alloc.c
trunk/sys/ufs/ffs/ffs_balloc.c
trunk/sys/ufs/ffs/ffs_extern.h
trunk/sys/ufs/ffs/ffs_inode.c
trunk/sys/ufs/ffs/ffs_rawread.c
trunk/sys/ufs/ffs/ffs_snapshot.c
trunk/sys/ufs/ffs/ffs_softdep.c
trunk/sys/ufs/ffs/ffs_subr.c
trunk/sys/ufs/ffs/ffs_suspend.c
trunk/sys/ufs/ffs/ffs_tables.c
trunk/sys/ufs/ffs/ffs_vfsops.c
trunk/sys/ufs/ffs/ffs_vnops.c
trunk/sys/ufs/ffs/fs.h
trunk/sys/ufs/ffs/softdep.h
trunk/sys/ufs/ufs/README.acls
trunk/sys/ufs/ufs/README.extattr
trunk/sys/ufs/ufs/acl.h
trunk/sys/ufs/ufs/dinode.h
trunk/sys/ufs/ufs/dir.h
trunk/sys/ufs/ufs/dirhash.h
trunk/sys/ufs/ufs/extattr.h
trunk/sys/ufs/ufs/gjournal.h
trunk/sys/ufs/ufs/inode.h
trunk/sys/ufs/ufs/quota.h
trunk/sys/ufs/ufs/ufs_acl.c
trunk/sys/ufs/ufs/ufs_bmap.c
trunk/sys/ufs/ufs/ufs_dirhash.c
trunk/sys/ufs/ufs/ufs_extattr.c
trunk/sys/ufs/ufs/ufs_extern.h
trunk/sys/ufs/ufs/ufs_gjournal.c
trunk/sys/ufs/ufs/ufs_inode.c
trunk/sys/ufs/ufs/ufs_lookup.c
trunk/sys/ufs/ufs/ufs_quota.c
trunk/sys/ufs/ufs/ufs_vfsops.c
trunk/sys/ufs/ufs/ufs_vnops.c
trunk/sys/ufs/ufs/ufsmount.h
Modified: trunk/sys/ufs/ffs/ffs_alloc.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_alloc.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_alloc.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ffs/ffs_alloc.c 306630 2016-10-03 10:15:16Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ffs/ffs_alloc.c 344861 2019-03-06 23:59:56Z mckusick $");
#include "opt_quota.h"
@@ -164,13 +164,13 @@
#endif
*bnp = 0;
- fs = ip->i_fs;
- ump = ip->i_ump;
+ ump = ITOUMP(ip);
+ fs = ump->um_fs;
mtx_assert(UFS_MTX(ump), MA_OWNED);
#ifdef INVARIANTS
if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) {
printf("dev = %s, bsize = %ld, size = %d, fs = %s\n",
- devtoname(ip->i_dev), (long)fs->fs_bsize, size,
+ devtoname(ump->um_dev), (long)fs->fs_bsize, size,
fs->fs_fsmnt);
panic("ffs_alloc: bad size");
}
@@ -261,9 +261,9 @@
int64_t delta;
vp = ITOV(ip);
- fs = ip->i_fs;
+ ump = ITOUMP(ip);
+ fs = ump->um_fs;
bp = NULL;
- ump = ip->i_ump;
gbflags = (flags & BA_UNMAPPED) != 0 ? GB_UNMAPPED : 0;
mtx_assert(UFS_MTX(ump), MA_OWNED);
@@ -274,7 +274,7 @@
(u_int)nsize > fs->fs_bsize || fragoff(fs, nsize) != 0) {
printf(
"dev = %s, bsize = %ld, osize = %d, nsize = %d, fs = %s\n",
- devtoname(ip->i_dev), (long)fs->fs_bsize, osize,
+ devtoname(ump->um_dev), (long)fs->fs_bsize, osize,
nsize, fs->fs_fsmnt);
panic("ffs_realloccg: bad size");
}
@@ -289,7 +289,7 @@
}
if (bprev == 0) {
printf("dev = %s, bsize = %ld, bprev = %jd, fs = %s\n",
- devtoname(ip->i_dev), (long)fs->fs_bsize, (intmax_t)bprev,
+ devtoname(ump->um_dev), (long)fs->fs_bsize, (intmax_t)bprev,
fs->fs_fsmnt);
panic("ffs_realloccg: bad bprev");
}
@@ -384,7 +384,7 @@
break;
default:
printf("dev = %s, optim = %ld, fs = %s\n",
- devtoname(ip->i_dev), (long)fs->fs_optim, fs->fs_fsmnt);
+ devtoname(ump->um_dev), (long)fs->fs_optim, fs->fs_fsmnt);
panic("ffs_realloccg: bad optim");
/* NOTREACHED */
}
@@ -392,7 +392,7 @@
if (bno > 0) {
bp->b_blkno = fsbtodb(fs, bno);
if (!DOINGSOFTDEP(vp))
- ffs_blkfree(ump, fs, ip->i_devvp, bprev, (long)osize,
+ ffs_blkfree(ump, fs, ump->um_devvp, bprev, (long)osize,
ip->i_number, vp->v_type, NULL);
delta = btodb(nsize - osize);
DIP_SET(ip, i_blocks, DIP(ip, i_blocks) + delta);
@@ -482,9 +482,19 @@
struct cluster_save *a_buflist;
} */ *ap;
{
+ struct ufsmount *ump;
- if (doreallocblks == 0)
+ /*
+ * If the underlying device can do deletes, then skip reallocating
+ * the blocks of this file into contiguous sequences. Devices that
+ * benefit from BIO_DELETE also benefit from not moving the data.
+ * These devices are flash and therefore work less well with this
+ * optimization. Also skip if reallocblks has been disabled globally.
+ */
+ ump = ap->a_vp->v_mount->mnt_data;
+ if (ump->um_candelete || doreallocblks == 0)
return (ENOSPC);
+
/*
* We can't wait in softdep prealloc as it may fsync and recurse
* here. Instead we simply fail to reallocate blocks if this
@@ -493,7 +503,7 @@
if (DOINGSOFTDEP(ap->a_vp))
if (softdep_prealloc(ap->a_vp, MNT_NOWAIT) != 0)
return (ENOSPC);
- if (VTOI(ap->a_vp)->i_ump->um_fstype == UFS1)
+ if (ump->um_fstype == UFS1)
return (ffs_reallocblks_ufs1(ap));
return (ffs_reallocblks_ufs2(ap));
}
@@ -520,8 +530,8 @@
vp = ap->a_vp;
ip = VTOI(vp);
- fs = ip->i_fs;
- ump = ip->i_ump;
+ ump = ITOUMP(ip);
+ fs = ump->um_fs;
/*
* If we are not tracking block clusters or if we have less than 4%
* free blocks left, then do not attempt to cluster. Running with
@@ -718,7 +728,7 @@
#endif
for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) {
if (!DOINGSOFTDEP(vp))
- ffs_blkfree(ump, fs, ip->i_devvp,
+ ffs_blkfree(ump, fs, ump->um_devvp,
dbtofsb(fs, buflist->bs_children[i]->b_blkno),
fs->fs_bsize, ip->i_number, vp->v_type, NULL);
buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno);
@@ -769,8 +779,8 @@
vp = ap->a_vp;
ip = VTOI(vp);
- fs = ip->i_fs;
- ump = ip->i_ump;
+ ump = ITOUMP(ip);
+ fs = ump->um_fs;
/*
* If we are not tracking block clusters or if we have less than 4%
* free blocks left, then do not attempt to cluster. Running with
@@ -895,7 +905,7 @@
*/
#ifdef DEBUG
if (prtrealloc)
- printf("realloc: ino %d, lbns %jd-%jd\n\told:", ip->i_number,
+ printf("realloc: ino %ju, lbns %jd-%jd\n\told:", (uintmax_t)ip->i_number,
(intmax_t)start_lbn, (intmax_t)end_lbn);
#endif
blkno = newblk;
@@ -966,7 +976,7 @@
#endif
for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) {
if (!DOINGSOFTDEP(vp))
- ffs_blkfree(ump, fs, ip->i_devvp,
+ ffs_blkfree(ump, fs, ump->um_devvp,
dbtofsb(fs, buflist->bs_children[i]->b_blkno),
fs->fs_bsize, ip->i_number, vp->v_type, NULL);
buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno);
@@ -1031,8 +1041,8 @@
*vpp = NULL;
pip = VTOI(pvp);
- fs = pip->i_fs;
- ump = pip->i_ump;
+ ump = ITOUMP(pip);
+ fs = ump->um_fs;
UFS_LOCK(ump);
reclaimed = 0;
@@ -1079,8 +1089,8 @@
ip = VTOI(*vpp);
if (ip->i_mode) {
dup_alloc:
- printf("mode = 0%o, inum = %lu, fs = %s\n",
- ip->i_mode, (u_long)ip->i_number, fs->fs_fsmnt);
+ printf("mode = 0%o, inum = %ju, fs = %s\n",
+ ip->i_mode, (uintmax_t)ip->i_number, fs->fs_fsmnt);
panic("ffs_valloc: dup alloc");
}
if (DIP(ip, i_blocks) && (fs->fs_flags & FS_UNCLEAN) == 0) { /* XXX */
@@ -1093,8 +1103,8 @@
/*
* Set up a new generation number for this inode.
*/
- if (ip->i_gen == 0 || ++ip->i_gen == 0)
- ip->i_gen = arc4random() / 2 + 1;
+ while (ip->i_gen == 0 || ++ip->i_gen == 0)
+ ip->i_gen = arc4random();
DIP_SET(ip, i_gen, ip->i_gen);
if (fs->fs_magic == FS_UFS2_MAGIC) {
vfs_timestamp(&ts);
@@ -1105,10 +1115,12 @@
ip->i_flag = 0;
(*vpp)->v_vflag = 0;
(*vpp)->v_type = VNON;
- if (fs->fs_magic == FS_UFS2_MAGIC)
+ if (fs->fs_magic == FS_UFS2_MAGIC) {
(*vpp)->v_op = &ffs_vnodeops2;
- else
+ ip->i_flag |= IN_UFS2;
+ } else {
(*vpp)->v_op = &ffs_vnodeops1;
+ }
return (0);
noinodes:
if (reclaimed == 0) {
@@ -1149,8 +1161,8 @@
u_int mincg, minndir;
u_int maxcontigdirs;
- mtx_assert(UFS_MTX(pip->i_ump), MA_OWNED);
- fs = pip->i_fs;
+ mtx_assert(UFS_MTX(ITOUMP(pip)), MA_OWNED);
+ fs = ITOFS(pip);
avgifree = fs->fs_cstotal.cs_nifree / fs->fs_ncg;
avgbfree = fs->fs_cstotal.cs_nbfree / fs->fs_ncg;
@@ -1217,16 +1229,17 @@
* We scan from our preferred cylinder group forward looking
* for a cylinder group that meets our criterion. If we get
* to the final cylinder group and do not find anything,
- * we start scanning backwards from our preferred cylinder
- * group. The ideal would be to alternate looking forward
- * and backward, but that is just too complex to code for
- * the gain it would get. The most likely place where the
- * backward scan would take effect is when we start near
- * the end of the filesystem and do not find anything from
- * where we are to the end. In that case, scanning backward
- * will likely find us a suitable cylinder group much closer
- * to our desired location than if we were to start scanning
- * forward from the beginning of the filesystem.
+ * we start scanning forwards from the beginning of the
+ * filesystem. While it might seem sensible to start scanning
+ * backwards or even to alternate looking forward and backward,
+ * this approach fails badly when the filesystem is nearly full.
+ * Specifically, we first search all the areas that have no space
+ * and finally try the one preceding that. We repeat this on
+ * every request and in the case of the final block end up
+ * searching the entire filesystem. By jumping to the front
+ * of the filesystem, our future forward searches always look
+ * in new cylinder groups so finds every possible block after
+ * one pass over the filesystem.
*/
prefcg = ino_to_cg(fs, pip->i_number);
for (cg = prefcg; cg < fs->fs_ncg; cg++)
@@ -1297,8 +1310,8 @@
ufs2_daddr_t pref;
KASSERT(indx <= 0 || bap != NULL, ("need non-NULL bap"));
- mtx_assert(UFS_MTX(ip->i_ump), MA_OWNED);
- fs = ip->i_fs;
+ mtx_assert(UFS_MTX(ITOUMP(ip)), MA_OWNED);
+ fs = ITOFS(ip);
/*
* Allocation of indirect blocks is indicated by passing negative
* values in indx: -1 for single indirect, -2 for double indirect,
@@ -1341,7 +1354,7 @@
/*
* If we are at the beginning of a file, or we have already allocated
* the maximum number of blocks per cylinder group, or we do not
- * have a block allocated immediately preceeding us, then we need
+ * have a block allocated immediately preceding us, then we need
* to decide where to start allocating new blocks.
*/
if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) {
@@ -1402,8 +1415,8 @@
ufs2_daddr_t pref;
KASSERT(indx <= 0 || bap != NULL, ("need non-NULL bap"));
- mtx_assert(UFS_MTX(ip->i_ump), MA_OWNED);
- fs = ip->i_fs;
+ mtx_assert(UFS_MTX(ITOUMP(ip)), MA_OWNED);
+ fs = ITOFS(ip);
/*
* Allocation of indirect blocks is indicated by passing negative
* values in indx: -1 for single indirect, -2 for double indirect,
@@ -1446,7 +1459,7 @@
/*
* If we are at the beginning of a file, or we have already allocated
* the maximum number of blocks per cylinder group, or we do not
- * have a block allocated immediately preceeding us, then we need
+ * have a block allocated immediately preceding us, then we need
* to decide where to start allocating new blocks.
*/
if (indx % fs->fs_maxbpg == 0 || bap[indx - 1] == 0) {
@@ -1516,12 +1529,12 @@
ufs2_daddr_t result;
u_int i, icg = cg;
- mtx_assert(UFS_MTX(ip->i_ump), MA_OWNED);
+ mtx_assert(UFS_MTX(ITOUMP(ip)), MA_OWNED);
#ifdef INVARIANTS
if (ITOV(ip)->v_mount->mnt_kern_flag & MNTK_SUSPENDED)
panic("ffs_hashalloc: allocation on suspended filesystem");
#endif
- fs = ip->i_fs;
+ fs = ITOFS(ip);
/*
* 1: preferred cylinder group
*/
@@ -1579,8 +1592,8 @@
int i, error;
u_int8_t *blksfree;
- ump = ip->i_ump;
- fs = ip->i_fs;
+ ump = ITOUMP(ip);
+ fs = ump->um_fs;
if (fs->fs_cs(fs, cg).cs_nffree < numfrags(fs, nsize - osize))
return (0);
frags = numfrags(fs, nsize);
@@ -1590,8 +1603,8 @@
return (0);
}
UFS_UNLOCK(ump);
- error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
- (int)fs->fs_cgsize, NOCRED, &bp);
+ error = bread(ump->um_devvp, fsbtodb(fs, cgtod(fs, cg)),
+ (int)fs->fs_cgsize, NOCRED, &bp);
if (error)
goto fail;
cgp = (struct cg *)bp->b_data;
@@ -1663,13 +1676,13 @@
int i, allocsiz, error, frags;
u_int8_t *blksfree;
- ump = ip->i_ump;
- fs = ip->i_fs;
+ ump = ITOUMP(ip);
+ fs = ump->um_fs;
if (fs->fs_cs(fs, cg).cs_nbfree == 0 && size == fs->fs_bsize)
return (0);
UFS_UNLOCK(ump);
- error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
- (int)fs->fs_cgsize, NOCRED, &bp);
+ error = bread(ump->um_devvp, fsbtodb(fs, cgtod(fs, cg)),
+ (int)fs->fs_cgsize, NOCRED, &bp);
if (error)
goto fail;
cgp = (struct cg *)bp->b_data;
@@ -1765,8 +1778,8 @@
u_int8_t *blksfree;
int i, cgbpref;
- fs = ip->i_fs;
- ump = ip->i_ump;
+ ump = ITOUMP(ip);
+ fs = ump->um_fs;
mtx_assert(UFS_MTX(ump), MA_OWNED);
cgp = (struct cg *)bp->b_data;
blksfree = cg_blksfree(cgp);
@@ -1851,12 +1864,12 @@
int32_t *lp;
u_int8_t *blksfree;
- fs = ip->i_fs;
- ump = ip->i_ump;
+ ump = ITOUMP(ip);
+ fs = ump->um_fs;
if (fs->fs_maxcluster[cg] < len)
return (0);
UFS_UNLOCK(ump);
- if (bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
+ if (bread(ump->um_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
NOCRED, &bp))
goto fail_lock;
cgp = (struct cg *)bp->b_data;
@@ -1955,13 +1968,23 @@
{
struct fs *fs;
- fs = ip->i_fs;
- return (getblk(ip->i_devvp, fsbtodb(fs, ino_to_fsba(fs,
+ fs = ITOFS(ip);
+ return (getblk(ITODEVVP(ip), fsbtodb(fs, ino_to_fsba(fs,
cg * fs->fs_ipg + cginoblk)), (int)fs->fs_bsize, 0, 0,
gbflags));
}
/*
+ * Synchronous inode initialization is needed only when barrier writes do not
+ * work as advertised, and will impose a heavy cost on file creation in a newly
+ * created filesystem.
+ */
+static int doasyncinodeinit = 1;
+SYSCTL_INT(_vfs_ffs, OID_AUTO, doasyncinodeinit, CTLFLAG_RWTUN,
+ &doasyncinodeinit, 0,
+ "Perform inode block initialization using asynchronous writes");
+
+/*
* Determine whether an inode can be allocated.
*
* Check to see if an inode is available, and if it is,
@@ -1987,13 +2010,13 @@
int error, start, len, i;
u_int32_t old_initediblk;
- fs = ip->i_fs;
- ump = ip->i_ump;
+ ump = ITOUMP(ip);
+ fs = ump->um_fs;
check_nifree:
if (fs->fs_cs(fs, cg).cs_nifree == 0)
return (0);
UFS_UNLOCK(ump);
- error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
+ error = bread(ump->um_devvp, fsbtodb(fs, cgtod(fs, cg)),
(int)fs->fs_cgsize, NOCRED, &bp);
if (error) {
brelse(bp);
@@ -2070,9 +2093,11 @@
bzero(ibp->b_data, (int)fs->fs_bsize);
dp2 = (struct ufs2_dinode *)(ibp->b_data);
for (i = 0; i < INOPB(fs); i++) {
- dp2->di_gen = arc4random() / 2 + 1;
+ while (dp2->di_gen == 0)
+ dp2->di_gen = arc4random();
dp2++;
}
+
/*
* Rather than adding a soft updates dependency to ensure
* that the new inode block is written before it is claimed
@@ -2082,7 +2107,10 @@
* written. The barrier write should only slow down bulk
* loading of newly created filesystems.
*/
- babarrierwrite(ibp);
+ if (doasyncinodeinit)
+ babarrierwrite(ibp);
+ else
+ bwrite(ibp);
/*
* After the inode block is written, try to update the
@@ -2090,7 +2118,7 @@
* to it, then leave it unchanged as the other thread
* has already set it correctly.
*/
- error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
+ error = bread(ump->um_devvp, fsbtodb(fs, cgtod(fs, cg)),
(int)fs->fs_cgsize, NOCRED, &bp);
UFS_LOCK(ump);
ACTIVECLEAR(fs, cg);
@@ -2155,7 +2183,8 @@
cg = dtog(fs, bno);
if (devvp->v_type == VREG) {
/* devvp is a snapshot */
- dev = VTOI(devvp)->i_devvp->v_rdev;
+ MPASS(devvp->v_mount->mnt_data == ump);
+ dev = ump->um_devvp->v_rdev;
cgblkno = fragstoblks(fs, cgtod(fs, cg));
} else if (devvp->v_type == VCHR) {
/* devvp is a normal disk device */
@@ -2386,7 +2415,7 @@
int i, error, frags, free;
u_int8_t *blksfree;
- fs = ip->i_fs;
+ fs = ITOFS(ip);
if ((u_int)size > fs->fs_bsize || fragoff(fs, size) != 0) {
printf("bsize = %ld, size = %ld, fs = %s\n",
(long)fs->fs_bsize, size, fs->fs_fsmnt);
@@ -2394,7 +2423,7 @@
}
if ((u_int)bno >= fs->fs_size)
panic("ffs_checkblk: bad block %jd", (intmax_t)bno);
- error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, dtog(fs, bno))),
+ error = bread(ITODEVVP(ip), fsbtodb(fs, cgtod(fs, dtog(fs, bno))),
(int)fs->fs_cgsize, NOCRED, &bp);
if (error)
panic("ffs_checkblk: cg bread failed");
@@ -2428,6 +2457,7 @@
ino_t ino;
int mode;
{
+ struct ufsmount *ump;
struct inode *ip;
if (DOINGSOFTDEP(pvp)) {
@@ -2435,8 +2465,8 @@
return (0);
}
ip = VTOI(pvp);
- return (ffs_freefile(ip->i_ump, ip->i_fs, ip->i_devvp, ino, mode,
- NULL));
+ ump = VFSTOUFS(pvp->v_mount);
+ return (ffs_freefile(ump, ump->um_fs, ump->um_devvp, ino, mode, NULL));
}
/*
@@ -2463,7 +2493,8 @@
cg = ino_to_cg(fs, ino);
if (devvp->v_type == VREG) {
/* devvp is a snapshot */
- dev = VTOI(devvp)->i_devvp->v_rdev;
+ MPASS(devvp->v_mount->mnt_data == ump);
+ dev = ump->um_devvp->v_rdev;
cgbno = fragstoblks(fs, cgtod(fs, cg));
} else if (devvp->v_type == VCHR) {
/* devvp is a normal disk device */
@@ -2658,6 +2689,8 @@
* the count to zero will cause the inode to be freed.
* adjblkcnt(inode, amt) - adjust the number of blocks used by the
* inode by the specified amount.
+ * adjsize(inode, size) - set the size of the inode to the
+ * specified size.
* adjndir, adjbfree, adjifree, adjffree, adjnumclusters(amt) -
* adjust the superblock summary.
* freedirs(inode, count) - directory inodes [inode..inode + count - 1]
@@ -2699,6 +2732,9 @@
static SYSCTL_NODE(_vfs_ffs, FFS_ADJ_BLKCNT, adjblkcnt, CTLFLAG_WR,
sysctl_ffs_fsck, "Adjust Inode Used Blocks Count");
+static SYSCTL_NODE(_vfs_ffs, FFS_SET_SIZE, setsize, CTLFLAG_WR,
+ sysctl_ffs_fsck, "Set the inode size");
+
static SYSCTL_NODE(_vfs_ffs, FFS_ADJ_NDIR, adjndir, CTLFLAG_WR,
sysctl_ffs_fsck, "Adjust number of directories");
@@ -2756,13 +2792,12 @@
struct thread *td = curthread;
struct fsck_cmd cmd;
struct ufsmount *ump;
- struct vnode *vp, *vpold, *dvp, *fdvp;
+ struct vnode *vp, *dvp, *fdvp;
struct inode *ip, *dp;
struct mount *mp;
struct fs *fs;
ufs2_daddr_t blkno;
long blkcnt, blksize;
- struct filedesc *fdp;
struct file *fp, *vfp;
cap_rights_t rights;
int filetype, error;
@@ -2774,7 +2809,7 @@
return (error);
if (cmd.version != FFS_CMD_VERSION)
return (ERPCMISMATCH);
- if ((error = getvnode(td->td_proc->p_fd, cmd.handle,
+ if ((error = getvnode(td, cmd.handle,
cap_rights_init(&rights, CAP_FSCK), &fp)) != 0)
return (error);
vp = fp->f_data;
@@ -2851,6 +2886,23 @@
vput(vp);
break;
+ case FFS_SET_SIZE:
+#ifdef DEBUG
+ if (fsckcmds) {
+ printf("%s: set inode %jd size to %jd\n",
+ mp->mnt_stat.f_mntonname, (intmax_t)cmd.value,
+ (intmax_t)cmd.size);
+ }
+#endif /* DEBUG */
+ if ((error = ffs_vget(mp, (ino_t)cmd.value, LK_EXCLUSIVE, &vp)))
+ break;
+ ip = VTOI(vp);
+ DIP_SET(ip, i_size, cmd.size);
+ ip->i_flag |= IN_CHANGE | IN_MODIFIED;
+ error = ffs_update(vp, 1);
+ vput(vp);
+ break;
+
case FFS_DIR_FREE:
filetype = IFDIR;
/* fall through */
@@ -2977,12 +3029,7 @@
break;
}
VOP_UNLOCK(vp, 0);
- fdp = td->td_proc->p_fd;
- FILEDESC_XLOCK(fdp);
- vpold = fdp->fd_cdir;
- fdp->fd_cdir = vp;
- FILEDESC_XUNLOCK(fdp);
- vrele(vpold);
+ pwd_chdir(td, vp);
break;
case FFS_SET_DOTDOT:
@@ -3057,7 +3104,7 @@
break;
AUDIT_ARG_VNODE1(vp);
ip = VTOI(vp);
- if (ip->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(ip))
error = copyin((void *)(intptr_t)cmd.size, ip->i_din1,
sizeof(struct ufs1_dinode));
else
@@ -3077,7 +3124,7 @@
error = EPERM;
break;
}
- if (VTOI(vp)->i_ump != ump) {
+ if (ITOUMP(VTOI(vp)) != ump) {
error = EINVAL;
break;
}
@@ -3089,7 +3136,7 @@
(intmax_t)cmd.value);
}
#endif /* DEBUG */
- if ((error = getvnode(td->td_proc->p_fd, cmd.value,
+ if ((error = getvnode(td, cmd.value,
cap_rights_init(&rights, CAP_FSCK), &vfp)) != 0)
break;
if (vfp->f_vnode->v_type != VCHR) {
@@ -3174,11 +3221,11 @@
return (EINVAL);
}
ip = VTOI(vp);
- if (ip->i_devvp != devvp) {
+ if (ITODEVVP(ip) != devvp) {
vput(vp);
return (EINVAL);
}
- fs = ip->i_fs;
+ fs = ITOFS(ip);
vput(vp);
foffset_lock_uio(fp, uio, flags);
vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
Modified: trunk/sys/ufs/ffs/ffs_balloc.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_balloc.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_balloc.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ffs/ffs_balloc.c 304672 2016-08-23 07:55:32Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ffs/ffs_balloc.c 331722 2018-03-29 02:50:57Z eadler $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -70,6 +70,7 @@
#include <sys/lock.h>
#include <sys/mount.h>
#include <sys/vnode.h>
+#include <sys/vmmeter.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
@@ -112,8 +113,8 @@
ip = VTOI(vp);
dp = ip->i_din1;
- fs = ip->i_fs;
- ump = ip->i_ump;
+ fs = ITOFS(ip);
+ ump = ITOUMP(ip);
lbn = lblkno(fs, startoffset);
size = blkoff(fs, startoffset) + size;
reclaimed = 0;
@@ -549,7 +550,7 @@
}
lbns_remfree++;
#endif
- ffs_blkfree(ump, fs, ip->i_devvp, *blkp, fs->fs_bsize,
+ ffs_blkfree(ump, fs, ump->um_devvp, *blkp, fs->fs_bsize,
ip->i_number, vp->v_type, NULL);
}
return (error);
@@ -585,8 +586,8 @@
ip = VTOI(vp);
dp = ip->i_din2;
- fs = ip->i_fs;
- ump = ip->i_ump;
+ fs = ITOFS(ip);
+ ump = ITOUMP(ip);
lbn = lblkno(fs, startoffset);
size = blkoff(fs, startoffset) + size;
reclaimed = 0;
@@ -1144,7 +1145,7 @@
}
lbns_remfree++;
#endif
- ffs_blkfree(ump, fs, ip->i_devvp, *blkp, fs->fs_bsize,
+ ffs_blkfree(ump, fs, ump->um_devvp, *blkp, fs->fs_bsize,
ip->i_number, vp->v_type, NULL);
}
return (error);
Modified: trunk/sys/ufs/ffs/ffs_extern.h
===================================================================
--- trunk/sys/ufs/ffs/ffs_extern.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_extern.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -28,7 +28,7 @@
* SUCH DAMAGE.
*
* @(#)ffs_extern.h 8.6 (Berkeley) 3/30/95
- * $FreeBSD: stable/10/sys/ufs/ffs/ffs_extern.h 306175 2016-09-22 10:42:40Z kib $
+ * $FreeBSD: stable/11/sys/ufs/ffs/ffs_extern.h 331722 2018-03-29 02:50:57Z eadler $
*/
#ifndef _UFS_FFS_EXTERN_H
@@ -78,7 +78,6 @@
int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t);
int ffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t);
void ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t);
-int ffs_mountroot(void);
void ffs_oldfscompat_write(struct fs *, struct ufsmount *);
int ffs_own_mount(const struct mount *mp);
int ffs_reallocblks(struct vop_reallocblks_args *);
@@ -179,6 +178,11 @@
* deadlock when flushing snapshot inodes while holding snaplk.
*/
#define NO_INO_UPDT 0x00000001
+/*
+ * Request data sync only from ffs_syncvnode(), not touching even more
+ * metadata than NO_INO_UPDT.
+ */
+#define DATA_ONLY 0x00000002
int ffs_rdonly(struct inode *);
Modified: trunk/sys/ufs/ffs/ffs_inode.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_inode.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_inode.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -31,22 +31,24 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ffs/ffs_inode.c 300600 2016-05-24 10:41:34Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ffs/ffs_inode.c 349308 2019-06-23 14:49:30Z asomers $");
#include "opt_quota.h"
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/mount.h>
-#include <sys/proc.h>
#include <sys/bio.h>
#include <sys/buf.h>
-#include <sys/vnode.h>
#include <sys/malloc.h>
+#include <sys/mount.h>
+#include <sys/proc.h>
+#include <sys/racct.h>
+#include <sys/random.h>
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
+#include <sys/stat.h>
#include <sys/vmmeter.h>
-#include <sys/stat.h>
+#include <sys/vnode.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@@ -91,8 +93,8 @@
if ((ip->i_flag & IN_MODIFIED) == 0 && waitfor == 0)
return (0);
ip->i_flag &= ~(IN_LAZYACCESS | IN_LAZYMOD | IN_MODIFIED);
- fs = ip->i_fs;
- if (fs->fs_ronly && ip->i_ump->um_fsckpid == 0)
+ fs = ITOFS(ip);
+ if (fs->fs_ronly && ITOUMP(ip)->um_fsckpid == 0)
return (0);
/*
* If we are updating a snapshot and another process is currently
@@ -109,14 +111,12 @@
if (IS_SNAPSHOT(ip))
flags = GB_LOCK_NOWAIT;
loop:
- error = breadn_flags(ip->i_devvp,
+ error = breadn_flags(ITODEVVP(ip),
fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
(int) fs->fs_bsize, 0, 0, 0, NOCRED, flags, &bp);
if (error != 0) {
- if (error != EBUSY) {
- brelse(bp);
+ if (error != EBUSY)
return (error);
- }
KASSERT((IS_SNAPSHOT(ip)), ("EBUSY from non-snapshot"));
/*
* Wait for our inode block to become available.
@@ -144,12 +144,17 @@
softdep_update_inodeblock(ip, bp, waitfor);
else if (ip->i_effnlink != ip->i_nlink)
panic("ffs_update: bad link cnt");
- if (ip->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(ip)) {
*((struct ufs1_dinode *)bp->b_data +
ino_to_fsbo(fs, ip->i_number)) = *ip->i_din1;
- else
+ /* XXX: FIX? The entropy here is desirable, but the harvesting may be expensive */
+ random_harvest_queue(&(ip->i_din1), sizeof(ip->i_din1), 1, RANDOM_FS_ATIME);
+ } else {
*((struct ufs2_dinode *)bp->b_data +
ino_to_fsbo(fs, ip->i_number)) = *ip->i_din2;
+ /* XXX: FIX? The entropy here is desirable, but the harvesting may be expensive */
+ random_harvest_queue(&(ip->i_din2), sizeof(ip->i_din2), 1, RANDOM_FS_ATIME);
+ }
if (waitfor && !DOINGASYNC(vp))
error = bwrite(bp);
else if (vm_page_count_severe() || buf_dirty_count_severe()) {
@@ -181,7 +186,7 @@
struct inode *ip;
ufs2_daddr_t bn, lbn, lastblock, lastiblock[NIADDR], indir_lbn[NIADDR];
ufs2_daddr_t oldblks[NDADDR + NIADDR], newblks[NDADDR + NIADDR];
- ufs2_daddr_t count, blocksreleased = 0, datablocks;
+ ufs2_daddr_t count, blocksreleased = 0, datablocks, blkno;
struct bufobj *bo;
struct fs *fs;
struct buf *bp;
@@ -189,12 +194,12 @@
int softdeptrunc, journaltrunc;
int needextclean, extblocks;
int offset, size, level, nblocks;
- int i, error, allerror;
+ int i, error, allerror, indiroff;
off_t osize;
ip = VTOI(vp);
- fs = ip->i_fs;
- ump = ip->i_ump;
+ ump = VFSTOUFS(vp->v_mount);
+ fs = ump->um_fs;
bo = &vp->v_bufobj;
ASSERT_VOP_LOCKED(vp, "ffs_truncate");
@@ -265,7 +270,7 @@
for (i = 0; i < NXADDR; i++) {
if (oldblks[i] == 0)
continue;
- ffs_blkfree(ump, fs, ip->i_devvp, oldblks[i],
+ ffs_blkfree(ump, fs, ITODEVVP(ip), oldblks[i],
sblksize(fs, osize, i), ip->i_number,
vp->v_type, NULL);
}
@@ -326,16 +331,57 @@
ip->i_flag |= IN_CHANGE | IN_UPDATE;
return (ffs_update(vp, !DOINGASYNC(vp)));
}
- if (DOINGSOFTDEP(vp)) {
+ /*
+ * Lookup block number for a given offset. Zero length files
+ * have no blocks, so return a blkno of -1.
+ */
+ lbn = lblkno(fs, length - 1);
+ if (length == 0) {
+ blkno = -1;
+ } else if (lbn < NDADDR) {
+ blkno = DIP(ip, i_db[lbn]);
+ } else {
+ error = UFS_BALLOC(vp, lblktosize(fs, (off_t)lbn), fs->fs_bsize,
+ cred, BA_METAONLY, &bp);
+ if (error)
+ return (error);
+ indiroff = (lbn - NDADDR) % NINDIR(fs);
+ if (I_IS_UFS1(ip))
+ blkno = ((ufs1_daddr_t *)(bp->b_data))[indiroff];
+ else
+ blkno = ((ufs2_daddr_t *)(bp->b_data))[indiroff];
+ /*
+ * If the block number is non-zero, then the indirect block
+ * must have been previously allocated and need not be written.
+ * If the block number is zero, then we may have allocated
+ * the indirect block and hence need to write it out.
+ */
+ if (blkno != 0)
+ brelse(bp);
+ else if (DOINGSOFTDEP(vp) || DOINGASYNC(vp))
+ bdwrite(bp);
+ else
+ bwrite(bp);
+ }
+ /*
+ * If the block number at the new end of the file is zero,
+ * then we must allocate it to ensure that the last block of
+ * the file is allocated. Soft updates does not handle this
+ * case, so here we have to clean up the soft updates data
+ * structures describing the allocation past the truncation
+ * point. Finding and deallocating those structures is a lot of
+ * work. Since partial truncation with a hole at the end occurs
+ * rarely, we solve the problem by syncing the file so that it
+ * will have no soft updates data structures left.
+ */
+ if (blkno == 0 && (error = ffs_syncvnode(vp, MNT_WAIT, 0)) != 0)
+ return (error);
+ if (blkno != 0 && DOINGSOFTDEP(vp)) {
if (softdeptrunc == 0 && journaltrunc == 0) {
/*
- * If a file is only partially truncated, then
- * we have to clean up the data structures
- * describing the allocation past the truncation
- * point. Finding and deallocating those structures
- * is a lot of work. Since partial truncation occurs
- * rarely, we solve the problem by syncing the file
- * so that it will have no data structures left.
+ * If soft updates cannot handle this truncation,
+ * clean up soft dependency data structures and
+ * fall through to the synchronous truncation.
*/
if ((error = ffs_syncvnode(vp, MNT_WAIT, 0)) != 0)
return (error);
@@ -355,15 +401,17 @@
}
}
/*
- * Shorten the size of the file. If the file is not being
- * truncated to a block boundary, the contents of the
- * partial block following the end of the file must be
- * zero'ed in case it ever becomes accessible again because
- * of subsequent file growth. Directories however are not
+ * Shorten the size of the file. If the last block of the
+ * shortened file is unallocated, we must allocate it.
+ * Additionally, if the file is not being truncated to a
+ * block boundary, the contents of the partial block
+ * following the end of the file must be zero'ed in
+ * case it ever becomes accessible again because of
+ * subsequent file growth. Directories however are not
* zero'ed as they should grow back initialized to empty.
*/
offset = blkoff(fs, length);
- if (offset == 0) {
+ if (blkno != 0 && offset == 0) {
ip->i_size = length;
DIP_SET(ip, i_size, length);
} else {
@@ -387,7 +435,7 @@
ip->i_size = length;
DIP_SET(ip, i_size, length);
size = blksize(fs, ip, lbn);
- if (vp->v_type != VDIR)
+ if (vp->v_type != VDIR && offset != 0)
bzero((char *)bp->b_data + offset,
(u_int)(size - offset));
/* Kirk's code has reallocbuf(bp, size, 1) here */
@@ -450,7 +498,7 @@
ip->i_size = osize;
DIP_SET(ip, i_size, osize);
- error = vtruncbuf(vp, cred, length, fs->fs_bsize);
+ error = vtruncbuf(vp, length, fs->fs_bsize);
if (error && (allerror == 0))
allerror = error;
@@ -470,7 +518,7 @@
blocksreleased += count;
if (lastiblock[level] < 0) {
DIP_SET(ip, i_ib[level], 0);
- ffs_blkfree(ump, fs, ip->i_devvp, bn,
+ ffs_blkfree(ump, fs, ump->um_devvp, bn,
fs->fs_bsize, ip->i_number,
vp->v_type, NULL);
blocksreleased += nblocks;
@@ -491,7 +539,7 @@
continue;
DIP_SET(ip, i_db[i], 0);
bsize = blksize(fs, ip, i);
- ffs_blkfree(ump, fs, ip->i_devvp, bn, bsize, ip->i_number,
+ ffs_blkfree(ump, fs, ump->um_devvp, bn, bsize, ip->i_number,
vp->v_type, NULL);
blocksreleased += btodb(bsize);
}
@@ -523,7 +571,7 @@
* required for the storage we're keeping.
*/
bn += numfrags(fs, newspace);
- ffs_blkfree(ump, fs, ip->i_devvp, bn,
+ ffs_blkfree(ump, fs, ump->um_devvp, bn,
oldspace - newspace, ip->i_number, vp->v_type, NULL);
blocksreleased += btodb(oldspace - newspace);
}
@@ -582,7 +630,7 @@
ufs2_daddr_t *countp;
{
struct buf *bp;
- struct fs *fs = ip->i_fs;
+ struct fs *fs;
struct vnode *vp;
caddr_t copy = NULL;
int i, nblocks, error = 0, allerror = 0;
@@ -590,8 +638,10 @@
ufs2_daddr_t blkcount, factor, blocksreleased = 0;
ufs1_daddr_t *bap1 = NULL;
ufs2_daddr_t *bap2 = NULL;
-# define BAP(ip, i) (((ip)->i_ump->um_fstype == UFS1) ? bap1[i] : bap2[i])
+#define BAP(ip, i) (I_IS_UFS1(ip) ? bap1[i] : bap2[i])
+ fs = ITOFS(ip);
+
/*
* Calculate index in current block of last
* block to be kept. -1 indicates the entire
@@ -613,6 +663,13 @@
vp = ITOV(ip);
bp = getblk(vp, lbn, (int)fs->fs_bsize, 0, 0, 0);
if ((bp->b_flags & B_CACHE) == 0) {
+#ifdef RACCT
+ if (racct_enable) {
+ PROC_LOCK(curproc);
+ racct_add_buf(curproc, bp, 0);
+ PROC_UNLOCK(curproc);
+ }
+#endif /* RACCT */
curthread->td_ru.ru_inblock++; /* pay for read */
bp->b_iocmd = BIO_READ;
bp->b_flags &= ~B_INVAL;
@@ -631,7 +688,7 @@
return (error);
}
- if (ip->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(ip))
bap1 = (ufs1_daddr_t *)bp->b_data;
else
bap2 = (ufs2_daddr_t *)bp->b_data;
@@ -639,7 +696,7 @@
copy = malloc(fs->fs_bsize, M_TEMP, M_WAITOK);
bcopy((caddr_t)bp->b_data, copy, (u_int)fs->fs_bsize);
for (i = last + 1; i < NINDIR(fs); i++)
- if (ip->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(ip))
bap1[i] = 0;
else
bap2[i] = 0;
@@ -650,7 +707,7 @@
if (error)
allerror = error;
}
- if (ip->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(ip))
bap1 = (ufs1_daddr_t *)copy;
else
bap2 = (ufs2_daddr_t *)copy;
@@ -670,7 +727,7 @@
allerror = error;
blocksreleased += blkcount;
}
- ffs_blkfree(ip->i_ump, fs, ip->i_devvp, nb, fs->fs_bsize,
+ ffs_blkfree(ITOUMP(ip), fs, ITODEVVP(ip), nb, fs->fs_bsize,
ip->i_number, vp->v_type, NULL);
blocksreleased += nblocks;
}
@@ -704,6 +761,6 @@
ffs_rdonly(struct inode *ip)
{
- return (ip->i_ump->um_fs->fs_ronly != 0);
+ return (ITOFS(ip)->fs_ronly != 0);
}
Modified: trunk/sys/ufs/ffs/ffs_rawread.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_rawread.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_rawread.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ffs/ffs_rawread.c 318267 2017-05-14 12:00:00Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ffs/ffs_rawread.c 318266 2017-05-14 11:51:30Z kib $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -63,8 +63,7 @@
off_t offset,
size_t len,
struct thread *td,
- struct buf *bp,
- caddr_t sa);
+ struct buf *bp);
static int ffs_rawread_main(struct vnode *vp,
struct uio *uio);
@@ -191,8 +190,7 @@
off_t offset,
size_t len,
struct thread *td,
- struct buf *bp,
- caddr_t sa)
+ struct buf *bp)
{
int error;
u_int iolen;
@@ -207,7 +205,7 @@
bsize = vp->v_mount->mnt_stat.f_iosize;
ip = VTOI(vp);
- dp = ip->i_devvp;
+ dp = ITODEVVP(ip);
iolen = ((vm_offset_t) udata) & PAGE_MASK;
bp->b_bcount = len;
@@ -220,7 +218,6 @@
bp->b_iocmd = BIO_READ;
bp->b_iodone = bdone;
bp->b_data = udata;
- bp->b_saveaddr = sa;
blockno = offset / bsize;
blockoff = (offset % bsize) / DEV_BSIZE;
if ((daddr_t) blockno != blockno) {
@@ -273,7 +270,6 @@
{
int error, nerror;
struct buf *bp, *nbp, *tbp;
- caddr_t sa, nsa, tsa;
u_int iolen;
caddr_t udata;
long resid;
@@ -295,8 +291,6 @@
bp = NULL;
nbp = NULL;
- sa = NULL;
- nsa = NULL;
while (resid > 0) {
@@ -303,10 +297,9 @@
if (bp == NULL) { /* Setup first read */
/* XXX: Leave some bufs for swap */
bp = getpbuf(&ffsrawbufcnt);
- sa = bp->b_data;
pbgetvp(vp, bp);
error = ffs_rawread_readahead(vp, udata, offset,
- resid, td, bp, sa);
+ resid, td, bp);
if (error != 0)
break;
@@ -317,7 +310,6 @@
else
nbp = NULL;
if (nbp != NULL) {
- nsa = nbp->b_data;
pbgetvp(vp, nbp);
nerror = ffs_rawread_readahead(vp,
@@ -328,8 +320,7 @@
resid -
bp->b_bufsize,
td,
- nbp,
- nsa);
+ nbp);
if (nerror) {
pbrelvp(nbp);
relpbuf(nbp, &ffsrawbufcnt);
@@ -362,8 +353,7 @@
offset,
bp->b_bufsize - iolen,
td,
- bp,
- sa);
+ bp);
if (error != 0)
break;
} else if (nbp != NULL) { /* Complete read with readahead */
@@ -372,10 +362,6 @@
bp = nbp;
nbp = tbp;
- tsa = sa;
- sa = nsa;
- nsa = tsa;
-
if (resid <= bp->b_bufsize) { /* No more readaheads */
pbrelvp(nbp);
relpbuf(nbp, &ffsrawbufcnt);
@@ -389,8 +375,7 @@
resid -
bp->b_bufsize,
td,
- nbp,
- nsa);
+ nbp);
if (nerror != 0) {
pbrelvp(nbp);
relpbuf(nbp, &ffsrawbufcnt);
@@ -401,7 +386,7 @@
break;
} else if (resid > 0) { /* More to read, no readahead */
error = ffs_rawread_readahead(vp, udata, offset,
- resid, td, bp, sa);
+ resid, td, bp);
if (error != 0)
break;
}
@@ -450,7 +435,7 @@
/* Only handle sector aligned reads */
ip = VTOI(vp);
- secsize = ip->i_devvp->v_bufobj.bo_bsize;
+ secsize = ITODEVVP(ip)->v_bufobj.bo_bsize;
if ((uio->uio_offset & (secsize - 1)) == 0 &&
(uio->uio_resid & (secsize - 1)) == 0) {
@@ -470,7 +455,7 @@
}
partialbytes = ((unsigned int) ip->i_size) %
- ip->i_fs->fs_bsize;
+ ITOFS(ip)->fs_bsize;
blockbytes = (int) filebytes - partialbytes;
if (blockbytes > 0) {
skipbytes = uio->uio_resid -
Modified: trunk/sys/ufs/ffs/ffs_snapshot.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_snapshot.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_snapshot.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ffs/ffs_snapshot.c 322132 2017-08-07 02:29:09Z mckusick $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ffs/ffs_snapshot.c 342819 2019-01-06 22:34:47Z mckusick $");
#include "opt_quota.h"
@@ -301,9 +301,10 @@
return (error);
}
vp = nd.ni_vp;
+ vnode_create_vobject(nd.ni_vp, fs->fs_size, td);
vp->v_vflag |= VV_SYSTEM;
ip = VTOI(vp);
- devvp = ip->i_devvp;
+ devvp = ITODEVVP(ip);
/*
* Allocate and copy the last block contents so as to be able
* to set size to that of the filesystem.
@@ -559,7 +560,7 @@
}
VI_UNLOCK(xvp);
if (snapdebug)
- vprint("ffs_snapshot: busy vnode", xvp);
+ vn_printf(xvp, "ffs_snapshot: busy vnode ");
if (VOP_GETATTR(xvp, &vat, td->td_ucred) == 0 &&
vat.va_nlink > 0) {
VOP_UNLOCK(xvp, 0);
@@ -588,7 +589,7 @@
}
}
snaplistsize += 1;
- if (xp->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(xp))
error = expunge_ufs1(vp, xp, copy_fs, fullacct_ufs1,
BLK_NOCOPY, 1);
else
@@ -621,7 +622,7 @@
goto out1;
}
xp = VTOI(xvp);
- if (xp->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(xp))
error = expunge_ufs1(vp, xp, copy_fs, fullacct_ufs1,
BLK_NOCOPY, 0);
else
@@ -707,7 +708,7 @@
TAILQ_FOREACH(xp, &sn->sn_head, i_nextsnap) {
if (xp == ip)
break;
- if (xp->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(xp))
error = expunge_ufs1(vp, xp, fs, snapacct_ufs1,
BLK_SNAP, 0);
else
@@ -736,7 +737,7 @@
* blocks marked as used in the snapshot bitmaps. Also, collect
* the list of allocated blocks in i_snapblklist.
*/
- if (ip->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(ip))
error = expunge_ufs1(vp, ip, copy_fs, mapacct_ufs1,
BLK_SNAP, 0);
else
@@ -888,9 +889,9 @@
int error, len, loc, indiroff;
ip = VTOI(vp);
- fs = ip->i_fs;
- error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)),
- (int)fs->fs_cgsize, KERNCRED, &bp);
+ fs = ITOFS(ip);
+ error = bread(ITODEVVP(ip), fsbtodb(fs, cgtod(fs, cg)),
+ (int)fs->fs_cgsize, KERNCRED, &bp);
if (error) {
brelse(bp);
return (error);
@@ -900,7 +901,7 @@
brelse(bp);
return (EIO);
}
- UFS_LOCK(ip->i_ump);
+ UFS_LOCK(ITOUMP(ip));
ACTIVESET(fs, cg);
/*
* Recomputation of summary information might not have been performed
@@ -909,7 +910,7 @@
* fsck is slightly more consistent.
*/
fs->fs_cs(fs, cg) = cgp->cg_cs;
- UFS_UNLOCK(ip->i_ump);
+ UFS_UNLOCK(ITOUMP(ip));
bcopy(bp->b_data, nbp->b_data, fs->fs_cgsize);
if (fs->fs_cgsize < fs->fs_bsize)
bzero(&nbp->b_data[fs->fs_cgsize],
@@ -953,7 +954,7 @@
}
indiroff = 0;
}
- if (ip->i_ump->um_fstype == UFS1) {
+ if (I_IS_UFS1(ip)) {
if (ffs_isblock(fs, cg_blksfree(cgp), loc))
((ufs1_daddr_t *)(ibp->b_data))[indiroff] =
BLK_NOCOPY;
@@ -1258,7 +1259,7 @@
*ip->i_snapblklist++ = lblkno;
if (blkno == BLK_SNAP)
blkno = blkstofrags(fs, lblkno);
- ffs_blkfree(ip->i_ump, fs, vp, blkno, fs->fs_bsize, inum,
+ ffs_blkfree(ITOUMP(ip), fs, vp, blkno, fs->fs_bsize, inum,
vp->v_type, NULL);
}
return (0);
@@ -1542,7 +1543,7 @@
*ip->i_snapblklist++ = lblkno;
if (blkno == BLK_SNAP)
blkno = blkstofrags(fs, lblkno);
- ffs_blkfree(ip->i_ump, fs, vp, blkno, fs->fs_bsize, inum,
+ ffs_blkfree(ITOUMP(ip), fs, vp, blkno, fs->fs_bsize, inum,
vp->v_type, NULL);
}
return (0);
@@ -1566,7 +1567,7 @@
* Find snapshot in incore list.
*/
xp = NULL;
- sn = ip->i_devvp->v_rdev->si_snapdata;
+ sn = ITODEVVP(ip)->v_rdev->si_snapdata;
if (sn != NULL)
TAILQ_FOREACH(xp, &sn->sn_head, i_nextsnap)
if (xp == ip)
@@ -1579,8 +1580,8 @@
/*
* Delete snapshot inode from superblock. Keep list dense.
*/
- fs = ip->i_fs;
- ump = ip->i_ump;
+ ump = ITOUMP(ip);
+ fs = ump->um_fs;
UFS_LOCK(ump);
for (snaploc = 0; snaploc < FSMAXSNAP; snaploc++)
if (fs->fs_snapinum[snaploc] == ip->i_number)
@@ -1612,8 +1613,8 @@
struct snapdata *sn;
ip = VTOI(vp);
- fs = ip->i_fs;
- devvp = ip->i_devvp;
+ fs = ITOFS(ip);
+ devvp = ITODEVVP(ip);
/*
* If active, delete from incore list (this snapshot may
* already have been in the process of being deleted, so
@@ -1651,7 +1652,7 @@
if (dblk == BLK_NOCOPY || dblk == BLK_SNAP)
DIP_SET(ip, i_db[blkno], 0);
else if ((dblk == blkstofrags(fs, blkno) &&
- ffs_snapblkfree(fs, ip->i_devvp, dblk, fs->fs_bsize,
+ ffs_snapblkfree(fs, ITODEVVP(ip), dblk, fs->fs_bsize,
ip->i_number, vp->v_type, NULL))) {
DIP_SET(ip, i_blocks, DIP(ip, i_blocks) -
btodb(fs->fs_bsize));
@@ -1669,7 +1670,7 @@
else
last = fs->fs_size - blkno;
for (loc = 0; loc < last; loc++) {
- if (ip->i_ump->um_fstype == UFS1) {
+ if (I_IS_UFS1(ip)) {
dblk = ((ufs1_daddr_t *)(ibp->b_data))[loc];
if (dblk == 0)
continue;
@@ -1676,7 +1677,7 @@
if (dblk == BLK_NOCOPY || dblk == BLK_SNAP)
((ufs1_daddr_t *)(ibp->b_data))[loc]= 0;
else if ((dblk == blkstofrags(fs, blkno) &&
- ffs_snapblkfree(fs, ip->i_devvp, dblk,
+ ffs_snapblkfree(fs, ITODEVVP(ip), dblk,
fs->fs_bsize, ip->i_number, vp->v_type,
NULL))) {
ip->i_din1->di_blocks -=
@@ -1691,7 +1692,7 @@
if (dblk == BLK_NOCOPY || dblk == BLK_SNAP)
((ufs2_daddr_t *)(ibp->b_data))[loc] = 0;
else if ((dblk == blkstofrags(fs, blkno) &&
- ffs_snapblkfree(fs, ip->i_devvp, dblk,
+ ffs_snapblkfree(fs, ITODEVVP(ip), dblk,
fs->fs_bsize, ip->i_number, vp->v_type, NULL))) {
ip->i_din2->di_blocks -= btodb(fs->fs_bsize);
((ufs2_daddr_t *)(ibp->b_data))[loc] = 0;
@@ -1786,7 +1787,7 @@
if (error)
break;
indiroff = (lbn - NDADDR) % NINDIR(fs);
- if (ip->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(ip))
blkno=((ufs1_daddr_t *)(ibp->b_data))[indiroff];
else
blkno=((ufs2_daddr_t *)(ibp->b_data))[indiroff];
@@ -1811,7 +1812,7 @@
if (lbn < NDADDR) {
DIP_SET(ip, i_db[lbn], BLK_NOCOPY);
ip->i_flag |= IN_CHANGE | IN_UPDATE;
- } else if (ip->i_ump->um_fstype == UFS1) {
+ } else if (I_IS_UFS1(ip)) {
((ufs1_daddr_t *)(ibp->b_data))[indiroff] =
BLK_NOCOPY;
bdwrite(ibp);
@@ -1859,7 +1860,7 @@
}
if (lbn < NDADDR) {
DIP_SET(ip, i_db[lbn], bno);
- } else if (ip->i_ump->um_fstype == UFS1) {
+ } else if (I_IS_UFS1(ip)) {
((ufs1_daddr_t *)(ibp->b_data))[indiroff] = bno;
bdwrite(ibp);
} else {
@@ -1991,15 +1992,19 @@
continue;
}
ip = VTOI(vp);
- if (!IS_SNAPSHOT(ip) || ip->i_size ==
+ if (vp->v_type != VREG) {
+ reason = "non-file snapshot";
+ } else if (!IS_SNAPSHOT(ip)) {
+ reason = "non-snapshot";
+ } else if (ip->i_size ==
lblktosize(fs, howmany(fs->fs_size, fs->fs_frag))) {
- if (!IS_SNAPSHOT(ip)) {
- reason = "non-snapshot";
- } else {
- reason = "old format snapshot";
- (void)ffs_truncate(vp, (off_t)0, 0, NOCRED);
- (void)ffs_syncvnode(vp, MNT_WAIT, 0);
- }
+ reason = "old format snapshot";
+ (void)ffs_truncate(vp, (off_t)0, 0, NOCRED);
+ (void)ffs_syncvnode(vp, MNT_WAIT, 0);
+ } else {
+ reason = NULL;
+ }
+ if (reason != NULL) {
printf("ffs_snapshot_mount: %s inode %d\n",
reason, fs->fs_snapinum[snaploc]);
vput(vp);
@@ -2141,7 +2146,7 @@
sn = devvp->v_rdev->si_snapdata;
if (sn == NULL || TAILQ_FIRST(&sn->sn_head) == NULL)
return (0);
- fs = TAILQ_FIRST(&sn->sn_head)->i_fs;
+ fs = ITOFS(TAILQ_FIRST(&sn->sn_head));
lbn = fragstoblks(fs, dbtofsb(fs, bp->b_blkno));
snapblklist = sn->sn_blklist;
upper = sn->sn_listsize - 1;
@@ -2268,7 +2273,7 @@
return (0); /* No snapshot */
}
ip = TAILQ_FIRST(&sn->sn_head);
- fs = ip->i_fs;
+ fs = ITOFS(ip);
lbn = fragstoblks(fs, dbtofsb(fs, bp->b_blkno));
snapblklist = sn->sn_blklist;
upper = sn->sn_listsize - 1;
@@ -2342,7 +2347,7 @@
if (error)
break;
indiroff = (lbn - NDADDR) % NINDIR(fs);
- if (ip->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(ip))
blkno=((ufs1_daddr_t *)(ibp->b_data))[indiroff];
else
blkno=((ufs2_daddr_t *)(ibp->b_data))[indiroff];
@@ -2498,15 +2503,19 @@
{
struct inode *ip = VTOI(vp);
struct bio *bip;
+ struct fs *fs;
+ ip = VTOI(vp);
+ fs = ITOFS(ip);
+
bip = g_alloc_bio();
bip->bio_cmd = BIO_READ;
- bip->bio_offset = dbtob(fsbtodb(ip->i_fs, blkstofrags(ip->i_fs, lbn)));
+ bip->bio_offset = dbtob(fsbtodb(fs, blkstofrags(fs, lbn)));
bip->bio_data = bp->b_data;
bip->bio_length = bp->b_bcount;
bip->bio_done = NULL;
- g_io_request(bip, ip->i_devvp->v_bufobj.bo_private);
+ g_io_request(bip, ITODEVVP(ip)->v_bufobj.bo_private);
bp->b_error = biowait(bip, "snaprdb");
g_destroy_bio(bip);
return (bp->b_error);
Modified: trunk/sys/ufs/ffs/ffs_softdep.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_softdep.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_softdep.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ffs/ffs_softdep.c 324612 2017-10-13 22:40:57Z jhb $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ffs/ffs_softdep.c 357034 2020-01-23 06:24:11Z mckusick $");
#include "opt_ffs.h"
#include "opt_quota.h"
@@ -70,6 +70,7 @@
#include <sys/namei.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/racct.h>
#include <sys/rwlock.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
@@ -901,8 +902,10 @@
struct pagedep **);
static void pause_timer(void *);
static int request_cleanup(struct mount *, int);
+static int softdep_request_cleanup_flush(struct mount *, struct ufsmount *);
static void schedule_cleanup(struct mount *);
-static void softdep_ast_cleanup_proc(void);
+static void softdep_ast_cleanup_proc(struct thread *);
+static struct ufsmount *softdep_bp_to_mp(struct buf *bp);
static int process_worklist_item(struct mount *, int, int);
static void process_removes(struct vnode *);
static void process_truncates(struct vnode *);
@@ -1105,7 +1108,7 @@
LIST_FOREACH_SAFE(wk, dst, wk_list, wkn) {
if (wk->wk_type == D_JSEGDEP)
jsegdep = jsegdep_merge(WK_JSEGDEP(wk), jsegdep);
- if (wk->wk_type == D_FREEDEP)
+ else if (wk->wk_type == D_FREEDEP)
freedep = freedep_merge(WK_FREEDEP(wk), freedep);
}
@@ -1534,10 +1537,10 @@
struct ufsmount *ump;
ump = VFSTOUFS(wk->wk_mp);
- WORKLIST_REMOVE(wk);
if (ump->softdep_worklist_tail == wk)
ump->softdep_worklist_tail =
(struct worklist *)wk->wk_list.le_prev;
+ WORKLIST_REMOVE(wk);
ump->softdep_on_worklist -= 1;
}
@@ -1835,11 +1838,11 @@
wake_worklist(wk);
add_to_worklist(wk, WK_HEAD);
}
- LIST_REMOVE(&sentinel, wk_list);
/* Sentinal could've become the tail from remove_from_worklist. */
if (ump->softdep_worklist_tail == &sentinel)
ump->softdep_worklist_tail =
(struct worklist *)sentinel.wk_list.le_prev;
+ LIST_REMOVE(&sentinel, wk_list);
PRELE(curproc);
return (matchcnt);
}
@@ -2893,7 +2896,6 @@
if (ump->softdep_journal_tail == wk)
ump->softdep_journal_tail =
(struct worklist *)wk->wk_list.le_prev;
-
WORKLIST_REMOVE(wk);
ump->softdep_on_journal -= 1;
}
@@ -3994,7 +3996,7 @@
struct jmvref *jmvref;
jmvref = malloc(sizeof(*jmvref), M_JMVREF, M_SOFTDEP_FLAGS);
- workitem_alloc(&jmvref->jm_list, D_JMVREF, UFSTOVFS(dp->i_ump));
+ workitem_alloc(&jmvref->jm_list, D_JMVREF, ITOVFS(dp));
jmvref->jm_list.wk_state = ATTACHED | DEPCOMPLETE;
jmvref->jm_parent = dp->i_number;
jmvref->jm_ino = ino;
@@ -4021,7 +4023,7 @@
struct jremref *jremref;
jremref = malloc(sizeof(*jremref), M_JREMREF, M_SOFTDEP_FLAGS);
- workitem_alloc(&jremref->jr_list, D_JREMREF, UFSTOVFS(dp->i_ump));
+ workitem_alloc(&jremref->jr_list, D_JREMREF, ITOVFS(dp));
jremref->jr_state = ATTACHED;
newinoref(&jremref->jr_ref, ip->i_number, dp->i_number, diroff,
nlink, ip->i_mode);
@@ -4057,7 +4059,7 @@
struct jaddref *jaddref;
jaddref = malloc(sizeof(*jaddref), M_JADDREF, M_SOFTDEP_FLAGS);
- workitem_alloc(&jaddref->ja_list, D_JADDREF, UFSTOVFS(dp->i_ump));
+ workitem_alloc(&jaddref->ja_list, D_JADDREF, ITOVFS(dp));
jaddref->ja_state = ATTACHED;
jaddref->ja_mkdir = NULL;
newinoref(&jaddref->ja_ref, ino, dp->i_number, diroff, nlink, mode);
@@ -4645,7 +4647,7 @@
KASSERT(ip->i_nlink >= ip->i_effnlink,
("inodedep_lookup_ip: bad delta"));
- (void) inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, DEPALLOC,
+ (void) inodedep_lookup(ITOVFS(ip), ip->i_number, DEPALLOC,
&inodedep);
inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
KASSERT((inodedep->id_state & UNLINKED) == 0, ("inode unlinked"));
@@ -4668,12 +4670,12 @@
struct jaddref *jaddref;
struct vnode *dvp;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(dp->i_ump)) != 0,
+ KASSERT(MOUNTEDSOFTDEP(ITOVFS(dp)) != 0,
("softdep_setup_create called on non-softdep filesystem"));
KASSERT(ip->i_nlink == 1,
("softdep_setup_create: Invalid link count."));
dvp = ITOV(dp);
- ACQUIRE_LOCK(dp->i_ump);
+ ACQUIRE_LOCK(ITOUMP(dp));
inodedep = inodedep_lookup_ip(ip);
if (DOINGSUJ(dvp)) {
jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
@@ -4682,7 +4684,7 @@
("softdep_setup_create: No addref structure present."));
}
softdep_prelink(dvp, NULL);
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ITOUMP(dp));
}
/*
@@ -4700,7 +4702,7 @@
struct jaddref *jaddref;
struct vnode *dvp;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(dp->i_ump)) != 0,
+ KASSERT(MOUNTEDSOFTDEP(ITOVFS(dp)) != 0,
("softdep_setup_dotdot_link called on non-softdep filesystem"));
dvp = ITOV(dp);
jaddref = NULL;
@@ -4711,13 +4713,13 @@
if (DOINGSUJ(dvp))
jaddref = newjaddref(ip, dp->i_number, DOTDOT_OFFSET,
dp->i_effnlink - 1, dp->i_mode);
- ACQUIRE_LOCK(dp->i_ump);
+ ACQUIRE_LOCK(ITOUMP(dp));
inodedep = inodedep_lookup_ip(dp);
if (jaddref)
TAILQ_INSERT_TAIL(&inodedep->id_inoreflst, &jaddref->ja_ref,
if_deps);
softdep_prelink(dvp, ITOV(ip));
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ITOUMP(dp));
}
/*
@@ -4735,7 +4737,7 @@
struct jaddref *jaddref;
struct vnode *dvp;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(dp->i_ump)) != 0,
+ KASSERT(MOUNTEDSOFTDEP(ITOVFS(dp)) != 0,
("softdep_setup_link called on non-softdep filesystem"));
dvp = ITOV(dp);
jaddref = NULL;
@@ -4742,13 +4744,13 @@
if (DOINGSUJ(dvp))
jaddref = newjaddref(dp, ip->i_number, 0, ip->i_effnlink - 1,
ip->i_mode);
- ACQUIRE_LOCK(dp->i_ump);
+ ACQUIRE_LOCK(ITOUMP(dp));
inodedep = inodedep_lookup_ip(ip);
if (jaddref)
TAILQ_INSERT_TAIL(&inodedep->id_inoreflst, &jaddref->ja_ref,
if_deps);
softdep_prelink(dvp, ITOV(ip));
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ITOUMP(dp));
}
/*
@@ -4768,7 +4770,7 @@
struct jaddref *jaddref;
struct vnode *dvp;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(dp->i_ump)) != 0,
+ KASSERT(MOUNTEDSOFTDEP(ITOVFS(dp)) != 0,
("softdep_setup_mkdir called on non-softdep filesystem"));
dvp = ITOV(dp);
dotaddref = dotdotaddref = NULL;
@@ -4780,7 +4782,7 @@
dp->i_effnlink - 1, dp->i_mode);
dotdotaddref->ja_state |= MKDIR_PARENT;
}
- ACQUIRE_LOCK(dp->i_ump);
+ ACQUIRE_LOCK(ITOUMP(dp));
inodedep = inodedep_lookup_ip(ip);
if (DOINGSUJ(dvp)) {
jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
@@ -4798,7 +4800,7 @@
TAILQ_INSERT_TAIL(&inodedep->id_inoreflst,
&dotdotaddref->ja_ref, if_deps);
softdep_prelink(ITOV(dp), NULL);
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ITOUMP(dp));
}
/*
@@ -4812,14 +4814,14 @@
{
struct vnode *dvp;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(dp->i_ump)) != 0,
+ KASSERT(MOUNTEDSOFTDEP(ITOVFS(dp)) != 0,
("softdep_setup_rmdir called on non-softdep filesystem"));
dvp = ITOV(dp);
- ACQUIRE_LOCK(dp->i_ump);
+ ACQUIRE_LOCK(ITOUMP(dp));
(void) inodedep_lookup_ip(ip);
(void) inodedep_lookup_ip(dp);
softdep_prelink(dvp, ITOV(ip));
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ITOUMP(dp));
}
/*
@@ -4833,14 +4835,14 @@
{
struct vnode *dvp;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(dp->i_ump)) != 0,
+ KASSERT(MOUNTEDSOFTDEP(ITOVFS(dp)) != 0,
("softdep_setup_unlink called on non-softdep filesystem"));
dvp = ITOV(dp);
- ACQUIRE_LOCK(dp->i_ump);
+ ACQUIRE_LOCK(ITOUMP(dp));
(void) inodedep_lookup_ip(ip);
(void) inodedep_lookup_ip(dp);
softdep_prelink(dvp, ITOV(ip));
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ITOUMP(dp));
}
/*
@@ -4856,10 +4858,10 @@
struct jaddref *jaddref;
struct vnode *dvp;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(dp->i_ump)) != 0,
+ KASSERT(MOUNTEDSOFTDEP(ITOVFS((dp))) != 0,
("softdep_revert_create called on non-softdep filesystem"));
dvp = ITOV(dp);
- ACQUIRE_LOCK(dp->i_ump);
+ ACQUIRE_LOCK(ITOUMP(dp));
inodedep = inodedep_lookup_ip(ip);
if (DOINGSUJ(dvp)) {
jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
@@ -4868,7 +4870,7 @@
("softdep_revert_create: addref parent mismatch"));
cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
}
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ITOUMP(dp));
}
/*
@@ -4884,10 +4886,10 @@
struct jaddref *jaddref;
struct vnode *dvp;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(dp->i_ump)) != 0,
+ KASSERT(MOUNTEDSOFTDEP(ITOVFS(dp)) != 0,
("softdep_revert_link called on non-softdep filesystem"));
dvp = ITOV(dp);
- ACQUIRE_LOCK(dp->i_ump);
+ ACQUIRE_LOCK(ITOUMP(dp));
inodedep = inodedep_lookup_ip(ip);
if (DOINGSUJ(dvp)) {
jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
@@ -4896,7 +4898,7 @@
("softdep_revert_link: addref parent mismatch"));
cancel_jaddref(jaddref, inodedep, &inodedep->id_inowait);
}
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ITOUMP(dp));
}
/*
@@ -4913,11 +4915,11 @@
struct jaddref *dotaddref;
struct vnode *dvp;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(dp->i_ump)) != 0,
+ KASSERT(MOUNTEDSOFTDEP(ITOVFS(dp)) != 0,
("softdep_revert_mkdir called on non-softdep filesystem"));
dvp = ITOV(dp);
- ACQUIRE_LOCK(dp->i_ump);
+ ACQUIRE_LOCK(ITOUMP(dp));
inodedep = inodedep_lookup_ip(dp);
if (DOINGSUJ(dvp)) {
jaddref = (struct jaddref *)TAILQ_LAST(&inodedep->id_inoreflst,
@@ -4939,7 +4941,7 @@
("softdep_revert_mkdir: dot addref parent mismatch"));
cancel_jaddref(dotaddref, inodedep, &inodedep->id_inowait);
}
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ITOUMP(dp));
}
/*
@@ -4951,12 +4953,12 @@
struct inode *ip;
{
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(dp->i_ump)) != 0,
+ KASSERT(MOUNTEDSOFTDEP(ITOVFS(dp)) != 0,
("softdep_revert_rmdir called on non-softdep filesystem"));
- ACQUIRE_LOCK(dp->i_ump);
+ ACQUIRE_LOCK(ITOUMP(dp));
(void) inodedep_lookup_ip(ip);
(void) inodedep_lookup_ip(dp);
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ITOUMP(dp));
}
/*
@@ -5007,10 +5009,10 @@
struct mount *mp;
struct fs *fs;
- mp = UFSTOVFS(ip->i_ump);
+ mp = ITOVFS(ip);
KASSERT(MOUNTEDSOFTDEP(mp) != 0,
("softdep_setup_inomapdep called on non-softdep filesystem"));
- fs = ip->i_ump->um_fs;
+ fs = VFSTOUFS(mp)->um_fs;
jaddref = NULL;
/*
@@ -5042,7 +5044,7 @@
bmsafemap = malloc(sizeof(struct bmsafemap),
M_BMSAFEMAP, M_SOFTDEP_FLAGS);
workitem_alloc(&bmsafemap->sm_list, D_BMSAFEMAP, mp);
- ACQUIRE_LOCK(ip->i_ump);
+ ACQUIRE_LOCK(ITOUMP(ip));
if ((inodedep_lookup(mp, newinum, DEPALLOC, &inodedep)))
panic("softdep_setup_inomapdep: dependency %p for new"
"inode already exists", inodedep);
@@ -5057,7 +5059,7 @@
}
inodedep->id_bmsafemap = bmsafemap;
inodedep->id_state &= ~DEPCOMPLETE;
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ITOUMP(ip));
}
/*
@@ -5279,7 +5281,7 @@
ufs_lbn_t lbn;
lbn = bp->b_lblkno;
- mp = UFSTOVFS(ip->i_ump);
+ mp = ITOVFS(ip);
KASSERT(MOUNTEDSOFTDEP(mp) != 0,
("softdep_setup_allocdirect called on non-softdep filesystem"));
if (oldblkno && oldblkno != newblkno)
@@ -5291,7 +5293,7 @@
"softdep_setup_allocdirect: ino %d blkno %jd oldblkno %jd "
"off %jd newsize %ld oldsize %d",
ip->i_number, newblkno, oldblkno, off, newsize, oldsize);
- ACQUIRE_LOCK(ip->i_ump);
+ ACQUIRE_LOCK(ITOUMP(ip));
if (off >= NDADDR) {
if (lbn > 0)
panic("softdep_setup_allocdirect: bad lbn %jd, off %jd",
@@ -5363,7 +5365,7 @@
TAILQ_INSERT_TAIL(adphead, adp, ad_next);
if (oldadp != NULL && oldadp->ad_offset == off)
allocdirect_merge(adphead, adp, oldadp);
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ITOUMP(ip));
return;
}
TAILQ_FOREACH(oldadp, adphead, ad_next) {
@@ -5377,7 +5379,7 @@
if (oldadp->ad_offset == off)
allocdirect_merge(adphead, adp, oldadp);
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ITOUMP(ip));
}
/*
@@ -5541,10 +5543,10 @@
struct jfreefrag *jfreefrag;
struct fs *fs;
- fs = ip->i_fs;
+ fs = ITOFS(ip);
jfreefrag = malloc(sizeof(struct jfreefrag), M_JFREEFRAG,
M_SOFTDEP_FLAGS);
- workitem_alloc(&jfreefrag->fr_list, D_JFREEFRAG, UFSTOVFS(ip->i_ump));
+ workitem_alloc(&jfreefrag->fr_list, D_JFREEFRAG, ITOVFS(ip));
jfreefrag->fr_jsegdep = newjsegdep(&jfreefrag->fr_list);
jfreefrag->fr_state = ATTACHED | DEPCOMPLETE;
jfreefrag->fr_ino = ip->i_number;
@@ -5567,16 +5569,18 @@
ufs_lbn_t lbn;
{
struct freefrag *freefrag;
+ struct ufsmount *ump;
struct fs *fs;
CTR4(KTR_SUJ, "newfreefrag: ino %d blkno %jd size %ld lbn %jd",
ip->i_number, blkno, size, lbn);
- fs = ip->i_fs;
+ ump = ITOUMP(ip);
+ fs = ump->um_fs;
if (fragnum(fs, blkno) + numfrags(fs, size) > fs->fs_frag)
panic("newfreefrag: frag size");
freefrag = malloc(sizeof(struct freefrag),
M_FREEFRAG, M_SOFTDEP_FLAGS);
- workitem_alloc(&freefrag->ff_list, D_FREEFRAG, UFSTOVFS(ip->i_ump));
+ workitem_alloc(&freefrag->ff_list, D_FREEFRAG, UFSTOVFS(ump));
freefrag->ff_state = ATTACHED;
LIST_INIT(&freefrag->ff_jwork);
freefrag->ff_inum = ip->i_number;
@@ -5584,7 +5588,7 @@
freefrag->ff_blkno = blkno;
freefrag->ff_fragsize = size;
- if (MOUNTEDSUJ(UFSTOVFS(ip->i_ump))) {
+ if (MOUNTEDSUJ(UFSTOVFS(ump))) {
freefrag->ff_jdep = (struct worklist *)
newjfreefrag(freefrag, ip, blkno, size, lbn);
} else {
@@ -5656,9 +5660,11 @@
struct jnewblk *jnewblk;
struct newblk *newblk;
struct mount *mp;
+ struct ufsmount *ump;
ufs_lbn_t lbn;
- mp = UFSTOVFS(ip->i_ump);
+ mp = ITOVFS(ip);
+ ump = VFSTOUFS(mp);
KASSERT(MOUNTEDSOFTDEP(mp) != 0,
("softdep_setup_allocext called on non-softdep filesystem"));
KASSERT(off < NXADDR, ("softdep_setup_allocext: lbn %lld > NXADDR",
@@ -5670,7 +5676,7 @@
else
freefrag = NULL;
- ACQUIRE_LOCK(ip->i_ump);
+ ACQUIRE_LOCK(ump);
if (newblk_lookup(mp, newblkno, 0, &newblk) == 0)
panic("softdep_setup_allocext: lost block");
KASSERT(newblk->nb_list.wk_type == D_NEWBLK,
@@ -5721,7 +5727,7 @@
TAILQ_INSERT_TAIL(adphead, adp, ad_next);
if (oldadp != NULL && oldadp->ad_offset == off)
allocdirect_merge(adphead, adp, oldadp);
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ump);
return;
}
TAILQ_FOREACH(oldadp, adphead, ad_next) {
@@ -5734,7 +5740,7 @@
TAILQ_INSERT_BEFORE(oldadp, adp, ad_next);
if (oldadp->ad_offset == off)
allocdirect_merge(adphead, adp, oldadp);
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ump);
}
/*
@@ -5779,11 +5785,11 @@
struct jnewblk *jnewblk;
if (oldblkno)
- freefrag = newfreefrag(ip, oldblkno, ip->i_fs->fs_bsize, lbn);
+ freefrag = newfreefrag(ip, oldblkno, ITOFS(ip)->fs_bsize, lbn);
else
freefrag = NULL;
- ACQUIRE_LOCK(ip->i_ump);
- if (newblk_lookup(UFSTOVFS(ip->i_ump), newblkno, 0, &newblk) == 0)
+ ACQUIRE_LOCK(ITOUMP(ip));
+ if (newblk_lookup(ITOVFS(ip), newblkno, 0, &newblk) == 0)
panic("new_allocindir: lost block");
KASSERT(newblk->nb_list.wk_type == D_NEWBLK,
("newallocindir: newblk already initialized"));
@@ -5823,8 +5829,10 @@
struct allocindir *aip;
struct pagedep *pagedep;
struct mount *mp;
+ struct ufsmount *ump;
- mp = UFSTOVFS(ip->i_ump);
+ mp = ITOVFS(ip);
+ ump = VFSTOUFS(mp);
KASSERT(MOUNTEDSOFTDEP(mp) != 0,
("softdep_setup_allocindir_page called on non-softdep filesystem"));
KASSERT(lbn == nbp->b_lblkno,
@@ -5845,7 +5853,7 @@
pagedep_lookup(mp, nbp, ip->i_number, lbn, DEPALLOC, &pagedep);
WORKLIST_INSERT(&nbp->b_dep, &aip->ai_block.nb_list);
freefrag = setup_allocindir_phase2(bp, ip, inodedep, aip, lbn);
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ump);
if (freefrag)
handle_workitem_freefrag(freefrag);
}
@@ -5864,9 +5872,11 @@
{
struct inodedep *inodedep;
struct allocindir *aip;
+ struct ufsmount *ump;
ufs_lbn_t lbn;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ip->i_ump)) != 0,
+ ump = ITOUMP(ip);
+ KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ump)) != 0,
("softdep_setup_allocindir_meta called on non-softdep filesystem"));
CTR3(KTR_SUJ,
"softdep_setup_allocindir_meta: ino %d blkno %jd ptrno %d",
@@ -5874,12 +5884,11 @@
lbn = nbp->b_lblkno;
ASSERT_VOP_LOCKED(ITOV(ip), "softdep_setup_allocindir_meta");
aip = newallocindir(ip, ptrno, newblkno, 0, lbn);
- inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, DEPALLOC,
- &inodedep);
+ inodedep_lookup(UFSTOVFS(ump), ip->i_number, DEPALLOC, &inodedep);
WORKLIST_INSERT(&nbp->b_dep, &aip->ai_block.nb_list);
if (setup_allocindir_phase2(bp, ip, inodedep, aip, lbn))
panic("softdep_setup_allocindir_meta: Block already existed");
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ump);
}
static void
@@ -5921,7 +5930,7 @@
LOCK_OWNED(ump);
indirdep = NULL;
newindirdep = NULL;
- fs = ip->i_fs;
+ fs = ump->um_fs;
for (;;) {
LIST_FOREACH(wk, &bp->b_dep, wk_list) {
if (wk->wk_type != D_INDIRDEP)
@@ -5943,7 +5952,7 @@
M_INDIRDEP, M_SOFTDEP_FLAGS);
workitem_alloc(&newindirdep->ir_list, D_INDIRDEP, mp);
newindirdep->ir_state = ATTACHED;
- if (ip->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(ip))
newindirdep->ir_state |= UFS1FMT;
TAILQ_INIT(&newindirdep->ir_trunc);
newindirdep->ir_saveddata = NULL;
@@ -5958,7 +5967,7 @@
}
newindirdep->ir_freeblks = NULL;
newindirdep->ir_savebp =
- getblk(ip->i_devvp, bp->b_blkno, bp->b_bcount, 0, 0, 0);
+ getblk(ump->um_devvp, bp->b_blkno, bp->b_bcount, 0, 0, 0);
newindirdep->ir_bp = bp;
BUF_KERNPROC(newindirdep->ir_savebp);
bcopy(bp->b_data, newindirdep->ir_savebp->b_data, bp->b_bcount);
@@ -5996,10 +6005,12 @@
struct allocindir *oldaip;
struct freefrag *freefrag;
struct mount *mp;
+ struct ufsmount *ump;
- LOCK_OWNED(ip->i_ump);
- mp = UFSTOVFS(ip->i_ump);
- fs = ip->i_fs;
+ mp = ITOVFS(ip);
+ ump = VFSTOUFS(mp);
+ LOCK_OWNED(ump);
+ fs = ump->um_fs;
if (bp->b_lblkno >= 0)
panic("setup_allocindir_phase2: not indir blk");
KASSERT(aip->ai_offset >= 0 && aip->ai_offset < NINDIR(fs),
@@ -6084,6 +6095,7 @@
int i;
int needj;
{
+ struct ufsmount *ump;
ufs2_daddr_t blkno;
int frags;
@@ -6091,9 +6103,10 @@
if (blkno == 0)
return;
DIP_SET(ip, i_db[i], 0);
- frags = sblksize(ip->i_fs, ip->i_size, i);
- frags = numfrags(ip->i_fs, frags);
- newfreework(ip->i_ump, freeblks, NULL, i, blkno, frags, 0, needj);
+ ump = ITOUMP(ip);
+ frags = sblksize(ump->um_fs, ip->i_size, i);
+ frags = numfrags(ump->um_fs, frags);
+ newfreework(ump, freeblks, NULL, i, blkno, frags, 0, needj);
}
static inline void
@@ -6103,6 +6116,7 @@
int i;
int needj;
{
+ struct ufsmount *ump;
ufs2_daddr_t blkno;
int frags;
@@ -6110,9 +6124,10 @@
if (blkno == 0)
return;
ip->i_din2->di_extb[i] = 0;
- frags = sblksize(ip->i_fs, ip->i_din2->di_extsize, i);
- frags = numfrags(ip->i_fs, frags);
- newfreework(ip->i_ump, freeblks, NULL, -1 - i, blkno, frags, 0, needj);
+ ump = ITOUMP(ip);
+ frags = sblksize(ump->um_fs, ip->i_din2->di_extsize, i);
+ frags = numfrags(ump->um_fs, frags);
+ newfreework(ump, freeblks, NULL, -1 - i, blkno, frags, 0, needj);
}
static inline void
@@ -6123,6 +6138,7 @@
ufs_lbn_t lbn;
int needj;
{
+ struct ufsmount *ump;
ufs2_daddr_t blkno;
blkno = DIP(ip, i_ib[i]);
@@ -6129,7 +6145,8 @@
if (blkno == 0)
return;
DIP_SET(ip, i_ib[i], 0);
- newfreework(ip->i_ump, freeblks, NULL, lbn, blkno, ip->i_fs->fs_frag,
+ ump = ITOUMP(ip);
+ newfreework(ump, freeblks, NULL, lbn, blkno, ump->um_fs->fs_frag,
0, needj);
}
@@ -6152,7 +6169,7 @@
freeblks->fb_inum = ip->i_number;
freeblks->fb_vtype = ITOV(ip)->v_type;
freeblks->fb_modrev = DIP(ip, i_modrev);
- freeblks->fb_devvp = ip->i_devvp;
+ freeblks->fb_devvp = ITODEVVP(ip);
freeblks->fb_chkcnt = 0;
freeblks->fb_len = 0;
@@ -6207,6 +6224,7 @@
struct freework *freework;
struct newblk *newblk;
struct mount *mp;
+ struct ufsmount *ump;
struct buf *bp;
uint8_t *start;
uint8_t *end;
@@ -6220,6 +6238,7 @@
if (blkno == 0)
return (0);
mp = freeblks->fb_list.wk_mp;
+ ump = VFSTOUFS(mp);
bp = getblk(ITOV(ip), lbn, mp->mnt_stat.f_iosize, 0, 0, 0);
if ((bp->b_flags & B_CACHE) == 0) {
bp->b_blkno = blkptrtodb(VFSTOUFS(mp), blkno);
@@ -6229,6 +6248,13 @@
vfs_busy_pages(bp, 0);
bp->b_iooffset = dbtob(bp->b_blkno);
bstrategy(bp);
+#ifdef RACCT
+ if (racct_enable) {
+ PROC_LOCK(curproc);
+ racct_add_buf(curproc, bp, 0);
+ PROC_UNLOCK(curproc);
+ }
+#endif /* RACCT */
curthread->td_ru.ru_inblock++;
error = bufwait(bp);
if (error) {
@@ -6237,22 +6263,21 @@
}
}
level = lbn_level(lbn);
- lbnadd = lbn_offset(ip->i_fs, level);
+ lbnadd = lbn_offset(ump->um_fs, level);
/*
* Compute the offset of the last block we want to keep. Store
* in the freework the first block we want to completely free.
*/
off = (lastlbn - -(lbn + level)) / lbnadd;
- if (off + 1 == NINDIR(ip->i_fs))
+ if (off + 1 == NINDIR(ump->um_fs))
goto nowork;
- freework = newfreework(ip->i_ump, freeblks, NULL, lbn, blkno, 0, off+1,
- 0);
+ freework = newfreework(ump, freeblks, NULL, lbn, blkno, 0, off + 1, 0);
/*
* Link the freework into the indirdep. This will prevent any new
* allocations from proceeding until we are finished with the
* truncate and the block is written.
*/
- ACQUIRE_LOCK(ip->i_ump);
+ ACQUIRE_LOCK(ump);
indirdep = indirdep_lookup(mp, ip, bp);
if (indirdep->ir_freeblks)
panic("setup_trunc_indir: indirdep already truncated.");
@@ -6264,12 +6289,12 @@
* live on this newblk.
*/
if ((indirdep->ir_state & DEPCOMPLETE) == 0) {
- newblk_lookup(mp, dbtofsb(ip->i_fs, bp->b_blkno), 0, &newblk);
+ newblk_lookup(mp, dbtofsb(ump->um_fs, bp->b_blkno), 0, &newblk);
LIST_FOREACH(indirn, &newblk->nb_indirdeps, ir_next)
trunc_indirdep(indirn, freeblks, bp, off);
} else
trunc_indirdep(indirdep, freeblks, bp, off);
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ump);
/*
* Creation is protected by the buf lock. The saveddata is only
* needed if a full truncation follows a partial truncation but it
@@ -6280,7 +6305,7 @@
M_SOFTDEP_FLAGS);
nowork:
/* Fetch the blkno of the child and the zero start offset. */
- if (ip->i_ump->um_fstype == UFS1) {
+ if (I_IS_UFS1(ip)) {
blkno = ((ufs1_daddr_t *)bp->b_data)[off];
start = (uint8_t *)&((ufs1_daddr_t *)bp->b_data)[off+1];
} else {
@@ -6490,9 +6515,9 @@
ufs_lbn_t tmpval, lbn, lastlbn;
int frags, lastoff, iboff, allocblock, needj, error, i;
- fs = ip->i_fs;
- ump = ip->i_ump;
+ ump = ITOUMP(ip);
mp = UFSTOVFS(ump);
+ fs = ump->um_fs;
KASSERT(MOUNTEDSOFTDEP(mp) != 0,
("softdep_journal_freeblocks called on non-softdep filesystem"));
vp = ITOV(ip);
@@ -6572,13 +6597,13 @@
blkno = DIP(ip, i_db[lastlbn]);
if (blkno && oldfrags != frags) {
oldfrags -= frags;
- oldfrags = numfrags(ip->i_fs, oldfrags);
- blkno += numfrags(ip->i_fs, frags);
+ oldfrags = numfrags(fs, oldfrags);
+ blkno += numfrags(fs, frags);
newfreework(ump, freeblks, NULL, lastlbn,
blkno, oldfrags, 0, needj);
if (needj)
adjust_newfreework(freeblks,
- numfrags(ip->i_fs, frags));
+ numfrags(fs, frags));
} else if (blkno == 0)
allocblock = 1;
}
@@ -6595,7 +6620,7 @@
DIP_SET(ip, i_size, ip->i_size);
datablocks = DIP(ip, i_blocks) - extblocks;
if (length != 0)
- datablocks = blkcount(ip->i_fs, datablocks, length);
+ datablocks = blkcount(fs, datablocks, length);
freeblks->fb_len = length;
}
if ((flags & IO_EXT) != 0) {
@@ -6622,7 +6647,7 @@
*/
ufs_itimes(vp);
ip->i_flag &= ~(IN_LAZYACCESS | IN_LAZYMOD | IN_MODIFIED);
- error = bread(ip->i_devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
+ error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
(int)fs->fs_bsize, cred, &bp);
if (error) {
brelse(bp);
@@ -6762,20 +6787,22 @@
struct inode *ip;
{
struct jfsync *jfsync;
+ struct ufsmount *ump;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ip->i_ump)) != 0,
+ ump = ITOUMP(ip);
+ KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ump)) != 0,
("softdep_journal_fsync called on non-softdep filesystem"));
if ((ip->i_flag & IN_TRUNCATED) == 0)
return;
ip->i_flag &= ~IN_TRUNCATED;
jfsync = malloc(sizeof(*jfsync), M_JFSYNC, M_SOFTDEP_FLAGS | M_ZERO);
- workitem_alloc(&jfsync->jfs_list, D_JFSYNC, UFSTOVFS(ip->i_ump));
+ workitem_alloc(&jfsync->jfs_list, D_JFSYNC, UFSTOVFS(ump));
jfsync->jfs_size = ip->i_size;
jfsync->jfs_ino = ip->i_number;
- ACQUIRE_LOCK(ip->i_ump);
+ ACQUIRE_LOCK(ump);
add_to_journal(&jfsync->jfs_list);
jwait(&jfsync->jfs_list, MNT_WAIT);
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ump);
}
/*
@@ -6827,7 +6854,7 @@
ufs_lbn_t tmpval;
ufs_lbn_t lbn;
- ump = ip->i_ump;
+ ump = ITOUMP(ip);
mp = UFSTOVFS(ump);
KASSERT(MOUNTEDSOFTDEP(mp) != 0,
("softdep_setup_freeblocks called on non-softdep filesystem"));
@@ -6834,7 +6861,14 @@
CTR2(KTR_SUJ, "softdep_setup_freeblks: ip %d length %ld",
ip->i_number, length);
KASSERT(length == 0, ("softdep_setup_freeblocks: non-zero length"));
- fs = ip->i_fs;
+ fs = ump->um_fs;
+ if ((error = bread(ump->um_devvp,
+ fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
+ (int)fs->fs_bsize, NOCRED, &bp)) != 0) {
+ brelse(bp);
+ softdep_error("softdep_setup_freeblocks", error);
+ return;
+ }
freeblks = newfreeblks(mp, ip);
extblocks = 0;
datablocks = 0;
@@ -6867,16 +6901,10 @@
UFS_UNLOCK(ump);
DIP_SET(ip, i_blocks, DIP(ip, i_blocks) - datablocks);
/*
- * Push the zero'ed inode to to its disk buffer so that we are free
+ * Push the zero'ed inode to its disk buffer so that we are free
* to delete its dependencies below. Once the dependencies are gone
* the buffer can be safely released.
*/
- if ((error = bread(ip->i_devvp,
- fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
- (int)fs->fs_bsize, NOCRED, &bp)) != 0) {
- brelse(bp);
- softdep_error("softdep_setup_freeblocks", error);
- }
if (ump->um_fstype == UFS1) {
dp1 = ((struct ufs1_dinode *)bp->b_data +
ino_to_fsbo(fs, ip->i_number));
@@ -6969,7 +6997,7 @@
off_t end, extend;
vp = ITOV(ip);
- fs = ip->i_fs;
+ fs = ITOFS(ip);
extend = OFF_TO_IDX(lblktosize(fs, -extblocks));
if ((flags & IO_EXT) != 0)
vn_pages_remove(vp, extend, 0);
@@ -7219,9 +7247,9 @@
struct worklist *wk, *wkn;
struct ufsmount *ump;
- if ((wk = LIST_FIRST(&bp->b_dep)) == NULL)
+ ump = softdep_bp_to_mp(bp);
+ if (ump == NULL)
goto done;
- ump = VFSTOUFS(wk->wk_mp);
ACQUIRE_LOCK(ump);
LIST_FOREACH_SAFE(wk, &bp->b_dep, wk_list, wkn) {
switch (wk->wk_type) {
@@ -7505,7 +7533,7 @@
struct freeblks *freeblks;
struct ufsmount *ump;
- ump = ip->i_ump;
+ ump = ITOUMP(ip);
KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ump)) != 0,
("softdep_freefile called on non-softdep filesystem"));
/*
@@ -7516,10 +7544,10 @@
workitem_alloc(&freefile->fx_list, D_FREEFILE, pvp->v_mount);
freefile->fx_mode = mode;
freefile->fx_oldinum = ino;
- freefile->fx_devvp = ip->i_devvp;
+ freefile->fx_devvp = ump->um_devvp;
LIST_INIT(&freefile->fx_jwork);
UFS_LOCK(ump);
- ip->i_fs->fs_pendinginodes += 1;
+ ump->um_fs->fs_pendinginodes += 1;
UFS_UNLOCK(ump);
/*
@@ -8439,8 +8467,8 @@
struct mount *mp;
int isindir;
- ump = dp->i_ump;
- mp = UFSTOVFS(ump);
+ mp = ITOVFS(dp);
+ ump = VFSTOUFS(mp);
KASSERT(MOUNTEDSOFTDEP(mp) != 0,
("softdep_setup_directory_add called on non-softdep filesystem"));
/*
@@ -8453,7 +8481,7 @@
}
jaddref = NULL;
mkdir1 = mkdir2 = NULL;
- fs = dp->i_fs;
+ fs = ump->um_fs;
lbn = lblkno(fs, diroffset);
offset = blkoff(fs, diroffset);
dap = malloc(sizeof(struct diradd), M_DIRADD,
@@ -8606,10 +8634,12 @@
struct diradd *dap;
struct direct *de;
struct mount *mp;
+ struct ufsmount *ump;
ufs_lbn_t lbn;
int flags;
- mp = UFSTOVFS(dp->i_ump);
+ mp = ITOVFS(dp);
+ ump = VFSTOUFS(mp);
KASSERT(MOUNTEDSOFTDEP(mp) != 0,
("softdep_change_directoryentry_offset called on "
"non-softdep filesystem"));
@@ -8627,11 +8657,11 @@
dp->i_offset + (oldloc - base),
dp->i_offset + (newloc - base));
}
- lbn = lblkno(dp->i_fs, dp->i_offset);
- offset = blkoff(dp->i_fs, dp->i_offset);
+ lbn = lblkno(ump->um_fs, dp->i_offset);
+ offset = blkoff(ump->um_fs, dp->i_offset);
oldoffset = offset + (oldloc - base);
newoffset = offset + (newloc - base);
- ACQUIRE_LOCK(dp->i_ump);
+ ACQUIRE_LOCK(ump);
if (pagedep_lookup(mp, bp, dp->i_number, lbn, flags, &pagedep) == 0)
goto done;
dap = diradd_lookup(pagedep, oldoffset);
@@ -8653,7 +8683,7 @@
add_to_journal(&jmvref->jm_list);
}
bcopy(oldloc, newloc, entrysize);
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ump);
}
/*
@@ -8896,9 +8926,11 @@
{
struct dirrem *dirrem, *prevdirrem;
struct inodedep *inodedep;
+ struct ufsmount *ump;
int direct;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ip->i_ump)) != 0,
+ ump = ITOUMP(ip);
+ KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ump)) != 0,
("softdep_setup_remove called on non-softdep filesystem"));
/*
* Allocate a new dirrem if appropriate and ACQUIRE_LOCK. We want
@@ -8910,8 +8942,7 @@
* Add the dirrem to the inodedep's pending remove list for quick
* discovery later.
*/
- if (inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0,
- &inodedep) == 0)
+ if (inodedep_lookup(UFSTOVFS(ump), ip->i_number, 0, &inodedep) == 0)
panic("softdep_setup_remove: Lost inodedep.");
KASSERT((inodedep->id_state & UNLINKED) == 0, ("inode unlinked"));
dirrem->dm_state |= ONDEPLIST;
@@ -8931,7 +8962,7 @@
if ((dirrem->dm_state & COMPLETE) == 0) {
LIST_INSERT_HEAD(&dirrem->dm_pagedep->pd_dirremhd, dirrem,
dm_next);
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ump);
} else {
if (prevdirrem != NULL)
LIST_INSERT_HEAD(&dirrem->dm_pagedep->pd_dirremhd,
@@ -8938,7 +8969,7 @@
prevdirrem, dm_next);
dirrem->dm_dirinum = dirrem->dm_pagedep->pd_ino;
direct = LIST_EMPTY(&dirrem->dm_jremrefhd);
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ump);
if (direct)
handle_workitem_remove(dirrem, 0);
}
@@ -8980,8 +9011,7 @@
struct diradd *dap;
struct worklist *wk;
- if (pagedep_lookup(UFSTOVFS(ip->i_ump), NULL, ip->i_number, 0, 0,
- &pagedep) == 0)
+ if (pagedep_lookup(ITOVFS(ip), NULL, ip->i_number, 0, 0, &pagedep) == 0)
return (jremref);
dap = diradd_lookup(pagedep, DOTDOT_OFFSET);
if (dap == NULL)
@@ -9013,9 +9043,10 @@
struct ufsmount *ump;
struct mkdir *mkdir;
struct diradd *dap;
+ struct mount *mp;
- if (inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0,
- &inodedep) == 0)
+ mp = ITOVFS(ip);
+ if (inodedep_lookup(mp, ip->i_number, 0, &inodedep) == 0)
return (jremref);
dap = inodedep->id_mkdiradd;
if (dap == NULL || (dap->da_state & MKDIR_PARENT) == 0)
@@ -9030,8 +9061,7 @@
if ((jaddref = mkdir->md_jaddref) != NULL) {
mkdir->md_jaddref = NULL;
jaddref->ja_state &= ~MKDIR_PARENT;
- if (inodedep_lookup(UFSTOVFS(ip->i_ump), jaddref->ja_ino, 0,
- &inodedep) == 0)
+ if (inodedep_lookup(mp, jaddref->ja_ino, 0, &inodedep) == 0)
panic("cancel_mkdir_dotdot: Lost parent inodedep");
if (cancel_jaddref(jaddref, inodedep, &dirrem->dm_jwork)) {
journal_jremref(dirrem, jremref, inodedep);
@@ -9102,6 +9132,7 @@
struct jremref *dotremref;
struct jremref *dotdotremref;
struct vnode *dvp;
+ struct ufsmount *ump;
/*
* Whiteouts have no deletion dependencies.
@@ -9109,6 +9140,8 @@
if (ip == NULL)
panic("newdirrem: whiteout");
dvp = ITOV(dp);
+ ump = ITOUMP(dp);
+
/*
* If the system is over its limit and our filesystem is
* responsible for more than our share of that usage and
@@ -9116,11 +9149,11 @@
* Limiting the number of dirrem structures will also limit
* the number of freefile and freeblks structures.
*/
- ACQUIRE_LOCK(ip->i_ump);
- if (!IS_SNAPSHOT(ip) && softdep_excess_items(ip->i_ump, D_DIRREM))
- schedule_cleanup(ITOV(dp)->v_mount);
+ ACQUIRE_LOCK(ump);
+ if (!IS_SNAPSHOT(ip) && softdep_excess_items(ump, D_DIRREM))
+ schedule_cleanup(UFSTOVFS(ump));
else
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ump);
dirrem = malloc(sizeof(struct dirrem), M_DIRREM, M_SOFTDEP_FLAGS |
M_ZERO);
workitem_alloc(&dirrem->dm_list, D_DIRREM, dvp->v_mount);
@@ -9150,10 +9183,10 @@
jremref = newjremref(dirrem, dp, ip, dp->i_offset,
ip->i_effnlink + 1);
}
- ACQUIRE_LOCK(ip->i_ump);
- lbn = lblkno(dp->i_fs, dp->i_offset);
- offset = blkoff(dp->i_fs, dp->i_offset);
- pagedep_lookup(UFSTOVFS(dp->i_ump), bp, dp->i_number, lbn, DEPALLOC,
+ ACQUIRE_LOCK(ump);
+ lbn = lblkno(ump->um_fs, dp->i_offset);
+ offset = blkoff(ump->um_fs, dp->i_offset);
+ pagedep_lookup(UFSTOVFS(ump), bp, dp->i_number, lbn, DEPALLOC,
&pagedep);
dirrem->dm_pagedep = pagedep;
dirrem->dm_offset = offset;
@@ -9260,9 +9293,11 @@
struct inodedep *inodedep;
struct jaddref *jaddref;
struct mount *mp;
+ struct ufsmount *ump;
- offset = blkoff(dp->i_fs, dp->i_offset);
- mp = UFSTOVFS(dp->i_ump);
+ mp = ITOVFS(dp);
+ ump = VFSTOUFS(mp);
+ offset = blkoff(ump->um_fs, dp->i_offset);
KASSERT(MOUNTEDSOFTDEP(mp) != 0,
("softdep_setup_directory_change called on non-softdep filesystem"));
@@ -9312,7 +9347,7 @@
if (LIST_EMPTY(&dirrem->dm_jremrefhd))
add_to_worklist(&dirrem->dm_list, 0);
}
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ump);
return;
}
/*
@@ -9386,7 +9421,7 @@
*/
if (inodedep->id_mkdiradd && dp->i_offset != DOTDOT_OFFSET)
merge_diradd(inodedep, dap);
- FREE_LOCK(dp->i_ump);
+ FREE_LOCK(ump);
}
/*
@@ -9400,16 +9435,17 @@
struct inode *ip; /* the inode with the increased link count */
{
struct inodedep *inodedep;
+ struct ufsmount *ump;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ip->i_ump)) != 0,
+ ump = ITOUMP(ip);
+ KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ump)) != 0,
("softdep_change_linkcnt called on non-softdep filesystem"));
- ACQUIRE_LOCK(ip->i_ump);
- inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, DEPALLOC,
- &inodedep);
+ ACQUIRE_LOCK(ump);
+ inodedep_lookup(UFSTOVFS(ump), ip->i_number, DEPALLOC, &inodedep);
if (ip->i_nlink < ip->i_effnlink)
panic("softdep_change_linkcnt: bad delta");
inodedep->id_nlinkdelta = ip->i_nlink - ip->i_effnlink;
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ump);
}
/*
@@ -9741,14 +9777,20 @@
/*
* Move all dependencies waiting on the remove to complete
* from the dirrem to the inode inowait list to be completed
- * after the inode has been updated and written to disk. Any
- * marked MKDIR_PARENT are saved to be completed when the .. ref
- * is removed.
+ * after the inode has been updated and written to disk.
+ *
+ * Any marked MKDIR_PARENT are saved to be completed when the
+ * dotdot ref is removed unless DIRCHG is specified. For
+ * directory change operations there will be no further
+ * directory writes and the jsegdeps need to be moved along
+ * with the rest to be completed when the inode is free or
+ * stable in the inode free list.
*/
LIST_INIT(&dotdotwk);
while ((wk = LIST_FIRST(&dirrem->dm_jwork)) != NULL) {
WORKLIST_REMOVE(wk);
- if (wk->wk_state & MKDIR_PARENT) {
+ if ((dirrem->dm_state & DIRCHG) == 0 &&
+ wk->wk_state & MKDIR_PARENT) {
wk->wk_state &= ~MKDIR_PARENT;
WORKLIST_INSERT(&dotdotwk, wk);
continue;
@@ -9938,9 +9980,9 @@
panic("softdep_disk_io_initiation: Writing buffer with "
"background write in progress: %p", bp);
- if ((wk = LIST_FIRST(&bp->b_dep)) == NULL)
+ ump = softdep_bp_to_mp(bp);
+ if (ump == NULL)
return;
- ump = VFSTOUFS(wk->wk_mp);
marker.wk_type = D_LAST + 1; /* Not a normal workitem */
PHOLD(curproc); /* Don't swap out kernel stack */
@@ -10181,22 +10223,22 @@
prevlbn = adp->ad_offset;
if (adp->ad_offset < NDADDR &&
dp->di_db[adp->ad_offset] != adp->ad_newblkno)
- panic("%s: direct pointer #%jd mismatch %d != %jd",
- "softdep_write_inodeblock",
+ panic("initiate_write_inodeblock_ufs1: "
+ "direct pointer #%jd mismatch %d != %jd",
(intmax_t)adp->ad_offset,
dp->di_db[adp->ad_offset],
(intmax_t)adp->ad_newblkno);
if (adp->ad_offset >= NDADDR &&
dp->di_ib[adp->ad_offset - NDADDR] != adp->ad_newblkno)
- panic("%s: indirect pointer #%jd mismatch %d != %jd",
- "softdep_write_inodeblock",
+ panic("initiate_write_inodeblock_ufs1: "
+ "indirect pointer #%jd mismatch %d != %jd",
(intmax_t)adp->ad_offset - NDADDR,
dp->di_ib[adp->ad_offset - NDADDR],
(intmax_t)adp->ad_newblkno);
deplist |= 1 << adp->ad_offset;
if ((adp->ad_state & ATTACHED) == 0)
- panic("softdep_write_inodeblock: Unknown state 0x%x",
- adp->ad_state);
+ panic("initiate_write_inodeblock_ufs1: "
+ "Unknown state 0x%x", adp->ad_state);
#endif /* INVARIANTS */
adp->ad_state &= ~ATTACHED;
adp->ad_state |= UNDONE;
@@ -10219,7 +10261,8 @@
for (i = adp->ad_offset + 1; i < NDADDR; i++) {
#ifdef INVARIANTS
if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0)
- panic("softdep_write_inodeblock: lost dep1");
+ panic("initiate_write_inodeblock_ufs1: "
+ "lost dep1");
#endif /* INVARIANTS */
dp->di_db[i] = 0;
}
@@ -10227,7 +10270,8 @@
#ifdef INVARIANTS
if (dp->di_ib[i] != 0 &&
(deplist & ((1 << NDADDR) << i)) == 0)
- panic("softdep_write_inodeblock: lost dep2");
+ panic("initiate_write_inodeblock_ufs1: "
+ "lost dep2");
#endif /* INVARIANTS */
dp->di_ib[i] = 0;
}
@@ -10349,18 +10393,18 @@
adp = TAILQ_NEXT(adp, ad_next)) {
#ifdef INVARIANTS
if (deplist != 0 && prevlbn >= adp->ad_offset)
- panic("softdep_write_inodeblock: lbn order");
+ panic("initiate_write_inodeblock_ufs2: lbn order");
prevlbn = adp->ad_offset;
if (dp->di_extb[adp->ad_offset] != adp->ad_newblkno)
- panic("%s: direct pointer #%jd mismatch %jd != %jd",
- "softdep_write_inodeblock",
+ panic("initiate_write_inodeblock_ufs2: "
+ "ext pointer #%jd mismatch %jd != %jd",
(intmax_t)adp->ad_offset,
(intmax_t)dp->di_extb[adp->ad_offset],
(intmax_t)adp->ad_newblkno);
deplist |= 1 << adp->ad_offset;
if ((adp->ad_state & ATTACHED) == 0)
- panic("softdep_write_inodeblock: Unknown state 0x%x",
- adp->ad_state);
+ panic("initiate_write_inodeblock_ufs2: Unknown "
+ "state 0x%x", adp->ad_state);
#endif /* INVARIANTS */
adp->ad_state &= ~ATTACHED;
adp->ad_state |= UNDONE;
@@ -10381,7 +10425,8 @@
for (i = adp->ad_offset + 1; i < NXADDR; i++) {
#ifdef INVARIANTS
if (dp->di_extb[i] != 0 && (deplist & (1 << i)) == 0)
- panic("softdep_write_inodeblock: lost dep1");
+ panic("initiate_write_inodeblock_ufs2: "
+ "lost dep1");
#endif /* INVARIANTS */
dp->di_extb[i] = 0;
}
@@ -10414,22 +10459,22 @@
prevlbn = adp->ad_offset;
if (adp->ad_offset < NDADDR &&
dp->di_db[adp->ad_offset] != adp->ad_newblkno)
- panic("%s: direct pointer #%jd mismatch %jd != %jd",
- "softdep_write_inodeblock",
+ panic("initiate_write_inodeblock_ufs2: "
+ "direct pointer #%jd mismatch %jd != %jd",
(intmax_t)adp->ad_offset,
(intmax_t)dp->di_db[adp->ad_offset],
(intmax_t)adp->ad_newblkno);
if (adp->ad_offset >= NDADDR &&
dp->di_ib[adp->ad_offset - NDADDR] != adp->ad_newblkno)
- panic("%s indirect pointer #%jd mismatch %jd != %jd",
- "softdep_write_inodeblock:",
+ panic("initiate_write_inodeblock_ufs2: "
+ "indirect pointer #%jd mismatch %jd != %jd",
(intmax_t)adp->ad_offset - NDADDR,
(intmax_t)dp->di_ib[adp->ad_offset - NDADDR],
(intmax_t)adp->ad_newblkno);
deplist |= 1 << adp->ad_offset;
if ((adp->ad_state & ATTACHED) == 0)
- panic("softdep_write_inodeblock: Unknown state 0x%x",
- adp->ad_state);
+ panic("initiate_write_inodeblock_ufs2: Unknown "
+ "state 0x%x", adp->ad_state);
#endif /* INVARIANTS */
adp->ad_state &= ~ATTACHED;
adp->ad_state |= UNDONE;
@@ -10452,7 +10497,8 @@
for (i = adp->ad_offset + 1; i < NDADDR; i++) {
#ifdef INVARIANTS
if (dp->di_db[i] != 0 && (deplist & (1 << i)) == 0)
- panic("softdep_write_inodeblock: lost dep2");
+ panic("initiate_write_inodeblock_ufs2: "
+ "lost dep2");
#endif /* INVARIANTS */
dp->di_db[i] = 0;
}
@@ -10460,7 +10506,8 @@
#ifdef INVARIANTS
if (dp->di_ib[i] != 0 &&
(deplist & ((1 << NDADDR) << i)) == 0)
- panic("softdep_write_inodeblock: lost dep3");
+ panic("initiate_write_inodeblock_ufs2: "
+ "lost dep3");
#endif /* INVARIANTS */
dp->di_ib[i] = 0;
}
@@ -10940,6 +10987,10 @@
struct freeblks *freeblks;
struct buf *sbp;
+ ump = softdep_bp_to_mp(bp);
+ if (ump == NULL)
+ return;
+
/*
* If an error occurred while doing the write, then the data
* has not hit the disk and the dependencies cannot be processed.
@@ -10946,6 +10997,7 @@
* But we do have to go through and roll forward any dependencies
* that were rolled back before the disk write.
*/
+ ACQUIRE_LOCK(ump);
if ((bp->b_ioflags & BIO_ERROR) != 0 && (bp->b_flags & B_INVAL) == 0) {
LIST_FOREACH(wk, &bp->b_dep, wk_list) {
switch (wk->wk_type) {
@@ -10973,18 +11025,16 @@
continue;
}
}
+ FREE_LOCK(ump);
return;
}
- if ((wk = LIST_FIRST(&bp->b_dep)) == NULL)
- return;
- ump = VFSTOUFS(wk->wk_mp);
LIST_INIT(&reattach);
+
/*
- * This lock must not be released anywhere in this code segment.
+ * Ump SU lock must not be released anywhere in this code segment.
*/
sbp = NULL;
owk = NULL;
- ACQUIRE_LOCK(ump);
while ((wk = LIST_FIRST(&bp->b_dep)) != NULL) {
WORKLIST_REMOVE(wk);
atomic_add_long(&dep_write[wk->wk_type], 1);
@@ -11487,7 +11537,8 @@
panic("handle_written_inodeblock: bad size");
if (inodedep->id_savednlink > LINK_MAX)
panic("handle_written_inodeblock: Invalid link count "
- "%d for inodedep %p", inodedep->id_savednlink, inodedep);
+ "%jd for inodedep %p", (uintmax_t)inodedep->id_savednlink,
+ inodedep);
if (fstype == UFS1) {
if (dp1->di_nlink != inodedep->id_savednlink) {
dp1->di_nlink = inodedep->id_savednlink;
@@ -12104,21 +12155,22 @@
struct inode *ip; /* the "in_core" copy of the inode */
{
struct inodedep *inodedep;
+ struct ufsmount *ump;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ip->i_ump)) != 0,
+ ump = ITOUMP(ip);
+ KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ump)) != 0,
("softdep_load_inodeblock called on non-softdep filesystem"));
/*
* Check for alternate nlink count.
*/
ip->i_effnlink = ip->i_nlink;
- ACQUIRE_LOCK(ip->i_ump);
- if (inodedep_lookup(UFSTOVFS(ip->i_ump), ip->i_number, 0,
- &inodedep) == 0) {
- FREE_LOCK(ip->i_ump);
+ ACQUIRE_LOCK(ump);
+ if (inodedep_lookup(UFSTOVFS(ump), ip->i_number, 0, &inodedep) == 0) {
+ FREE_LOCK(ump);
return;
}
ip->i_effnlink -= inodedep->id_nlinkdelta;
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(ump);
}
/*
@@ -12146,11 +12198,11 @@
struct fs *fs;
int error;
- ump = ip->i_ump;
+ ump = ITOUMP(ip);
mp = UFSTOVFS(ump);
KASSERT(MOUNTEDSOFTDEP(mp) != 0,
("softdep_update_inodeblock called on non-softdep filesystem"));
- fs = ip->i_fs;
+ fs = ump->um_fs;
/*
* Preserve the freelink that is on disk. clear_unlinked_inodedep()
* does not have access to the in-core ip so must write directly into
@@ -12315,9 +12367,9 @@
ufs_lbn_t lbn;
ip = VTOI(vp);
- fs = ip->i_fs;
- ump = ip->i_ump;
mp = vp->v_mount;
+ ump = VFSTOUFS(mp);
+ fs = ump->um_fs;
if (MOUNTEDSOFTDEP(mp) == 0)
return (0);
ACQUIRE_LOCK(ump);
@@ -12384,24 +12436,13 @@
FREE_LOCK(ump);
if (ffs_vgetf(mp, parentino, LK_NOWAIT | LK_EXCLUSIVE, &pvp,
FFSV_FORCEINSMQ)) {
- error = vfs_busy(mp, MBF_NOWAIT);
- if (error != 0) {
- vfs_ref(mp);
- VOP_UNLOCK(vp, 0);
- error = vfs_busy(mp, 0);
- vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
- vfs_rel(mp);
- if (error != 0)
- return (ENOENT);
- if (vp->v_iflag & VI_DOOMED) {
- vfs_unbusy(mp);
- return (ENOENT);
- }
- }
+ /*
+ * Unmount cannot proceed after unlock because
+ * caller must have called vn_start_write().
+ */
VOP_UNLOCK(vp, 0);
error = ffs_vgetf(mp, parentino, LK_EXCLUSIVE,
&pvp, FFSV_FORCEINSMQ);
- vfs_unbusy(mp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
if (vp->v_iflag & VI_DOOMED) {
if (error == 0)
@@ -12590,13 +12631,13 @@
int error;
ip = VTOI(vp);
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ip->i_ump)) != 0,
+ KASSERT(MOUNTEDSOFTDEP(vp->v_mount) != 0,
("softdep_sync_metadata called on non-softdep filesystem"));
/*
* Ensure that any direct block dependencies have been cleared,
* truncations are started, and inode references are journaled.
*/
- ACQUIRE_LOCK(ip->i_ump);
+ ACQUIRE_LOCK(VFSTOUFS(vp->v_mount));
/*
* Write all journal records to prevent rollbacks on devvp.
*/
@@ -12608,7 +12649,7 @@
* indirect blocks.
*/
process_truncates(vp);
- FREE_LOCK(ip->i_ump);
+ FREE_LOCK(VFSTOUFS(vp->v_mount));
return (error);
}
@@ -12643,7 +12684,7 @@
return (EBUSY);
return (0);
}
- ump = VTOI(vp)->i_ump;
+ ump = VFSTOUFS(vp->v_mount);
ACQUIRE_LOCK(ump);
/*
* As we hold the buffer locked, none of its dependencies
@@ -13226,10 +13267,9 @@
{
struct ufsmount *ump;
struct mount *mp;
- struct vnode *lvp, *mvp;
long starttime;
ufs2_daddr_t needed;
- int error;
+ int error, failed_vnode;
/*
* If we are being called because of a process doing a
@@ -13281,7 +13321,7 @@
*
* Additionally, if we are unpriviledged and allocating space,
* we need to ensure that we clean up enough blocks to get the
- * needed number of blocks over the threshhold of the minimum
+ * needed number of blocks over the threshold of the minimum
* number of blocks required to be kept free by the filesystem
* (fs_minfree).
*/
@@ -13320,43 +13360,90 @@
* to the worklist that we can then process to reap addition
* resources. We walk the vnodes associated with the mount point
* until we get the needed worklist requests that we can reap.
+ *
+ * If there are several threads all needing to clean the same
+ * mount point, only one is allowed to walk the mount list.
+ * When several threads all try to walk the same mount list,
+ * they end up competing with each other and often end up in
+ * livelock. This approach ensures that forward progress is
+ * made at the cost of occational ENOSPC errors being returned
+ * that might otherwise have been avoided.
*/
+ error = 1;
if ((resource == FLUSH_BLOCKS_WAIT &&
fs->fs_cstotal.cs_nbfree <= needed) ||
(resource == FLUSH_INODES_WAIT && fs->fs_pendinginodes > 0 &&
fs->fs_cstotal.cs_nifree <= needed)) {
- MNT_VNODE_FOREACH_ALL(lvp, mp, mvp) {
- if (TAILQ_FIRST(&lvp->v_bufobj.bo_dirty.bv_hd) == 0) {
- VI_UNLOCK(lvp);
- continue;
+ ACQUIRE_LOCK(ump);
+ if ((ump->um_softdep->sd_flags & FLUSH_RC_ACTIVE) == 0) {
+ ump->um_softdep->sd_flags |= FLUSH_RC_ACTIVE;
+ FREE_LOCK(ump);
+ failed_vnode = softdep_request_cleanup_flush(mp, ump);
+ ACQUIRE_LOCK(ump);
+ ump->um_softdep->sd_flags &= ~FLUSH_RC_ACTIVE;
+ FREE_LOCK(ump);
+ if (ump->softdep_on_worklist > 0) {
+ stat_cleanup_retries += 1;
+ if (!failed_vnode)
+ goto retry;
}
- if (vget(lvp, LK_EXCLUSIVE | LK_INTERLOCK | LK_NOWAIT,
- curthread))
- continue;
- if (lvp->v_vflag & VV_NOSYNC) { /* unlinked */
- vput(lvp);
- continue;
- }
- (void) ffs_syncvnode(lvp, MNT_NOWAIT, 0);
- vput(lvp);
+ } else {
+ FREE_LOCK(ump);
+ error = 0;
}
- lvp = ump->um_devvp;
- if (vn_lock(lvp, LK_EXCLUSIVE | LK_NOWAIT) == 0) {
- VOP_FSYNC(lvp, MNT_NOWAIT, curthread);
- VOP_UNLOCK(lvp, 0);
- }
- if (ump->softdep_on_worklist > 0) {
- stat_cleanup_retries += 1;
- goto retry;
- }
stat_cleanup_failures += 1;
}
if (time_second - starttime > stat_cleanup_high_delay)
stat_cleanup_high_delay = time_second - starttime;
UFS_LOCK(ump);
- return (1);
+ return (error);
}
+/*
+ * Scan the vnodes for the specified mount point flushing out any
+ * vnodes that can be locked without waiting. Finally, try to flush
+ * the device associated with the mount point if it can be locked
+ * without waiting.
+ *
+ * We return 0 if we were able to lock every vnode in our scan.
+ * If we had to skip one or more vnodes, we return 1.
+ */
+static int
+softdep_request_cleanup_flush(mp, ump)
+ struct mount *mp;
+ struct ufsmount *ump;
+{
+ struct thread *td;
+ struct vnode *lvp, *mvp;
+ int failed_vnode;
+
+ failed_vnode = 0;
+ td = curthread;
+ MNT_VNODE_FOREACH_ALL(lvp, mp, mvp) {
+ if (TAILQ_FIRST(&lvp->v_bufobj.bo_dirty.bv_hd) == 0) {
+ VI_UNLOCK(lvp);
+ continue;
+ }
+ if (vget(lvp, LK_EXCLUSIVE | LK_INTERLOCK | LK_NOWAIT,
+ td) != 0) {
+ failed_vnode = 1;
+ continue;
+ }
+ if (lvp->v_vflag & VV_NOSYNC) { /* unlinked */
+ vput(lvp);
+ continue;
+ }
+ (void) ffs_syncvnode(lvp, MNT_NOWAIT, 0);
+ vput(lvp);
+ }
+ lvp = ump->um_devvp;
+ if (vn_lock(lvp, LK_EXCLUSIVE | LK_NOWAIT) == 0) {
+ VOP_FSYNC(lvp, MNT_NOWAIT, td);
+ VOP_UNLOCK(lvp, 0);
+ }
+ return (failed_vnode);
+}
+
static bool
softdep_excess_items(struct ufsmount *ump, int item)
{
@@ -13397,15 +13484,13 @@
}
static void
-softdep_ast_cleanup_proc(void)
+softdep_ast_cleanup_proc(struct thread *td)
{
- struct thread *td;
struct mount *mp;
struct ufsmount *ump;
int error;
bool req;
- td = curthread;
while ((mp = td->td_su) != NULL) {
td->td_su = NULL;
error = vfs_busy(mp, MBF_NOWAIT);
@@ -13443,6 +13528,10 @@
}
vfs_unbusy(mp);
}
+ if ((mp = td->td_su) != NULL) {
+ td->td_su = NULL;
+ vfs_rel(mp);
+ }
}
/*
@@ -13688,7 +13777,7 @@
/*
* Find the last inode in the block with dependencies.
*/
- firstino = inodedep->id_ino & ~(INOPB(fs) - 1);
+ firstino = rounddown2(inodedep->id_ino, INOPB(fs));
for (lastino = firstino + INOPB(fs) - 1; lastino > firstino; lastino--)
if (inodedep_lookup(mp, lastino, 0, &inodedep) != 0)
break;
@@ -13764,12 +13853,14 @@
{
struct buf *bp;
struct fs *fs;
+ struct ufsmount *ump;
int error;
- KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ip->i_ump)) != 0,
+ ump = ITOUMP(ip);
+ KASSERT(MOUNTEDSOFTDEP(UFSTOVFS(ump)) != 0,
("softdep_inode_append called on non-softdep filesystem"));
- fs = ip->i_fs;
- error = bread(ip->i_devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
+ fs = ump->um_fs;
+ error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
(int)fs->fs_bsize, cred, &bp);
if (error) {
bqrelse(bp);
@@ -13797,6 +13888,58 @@
FREE_LOCK(ump);
}
+static struct ufsmount *
+softdep_bp_to_mp(bp)
+ struct buf *bp;
+{
+ struct mount *mp;
+ struct vnode *vp;
+
+ if (LIST_EMPTY(&bp->b_dep))
+ return (NULL);
+ vp = bp->b_vp;
+ KASSERT(vp != NULL,
+ ("%s, buffer with dependencies lacks vnode", __func__));
+
+ /*
+ * The ump mount point is stable after we get a correct
+ * pointer, since bp is locked and this prevents unmount from
+ * proceeding. But to get to it, we cannot dereference bp->b_dep
+ * head wk_mp, because we do not yet own SU ump lock and
+ * workitem might be freed while dereferenced.
+ */
+retry:
+ switch (vp->v_type) {
+ case VCHR:
+ VI_LOCK(vp);
+ mp = vp->v_type == VCHR ? vp->v_rdev->si_mountpt : NULL;
+ VI_UNLOCK(vp);
+ if (mp == NULL)
+ goto retry;
+ break;
+ case VREG:
+ case VDIR:
+ case VLNK:
+ case VFIFO:
+ case VSOCK:
+ mp = vp->v_mount;
+ break;
+ case VBLK:
+ vn_printf(vp, "softdep_bp_to_mp: unexpected block device\n");
+ /* FALLTHROUGH */
+ case VNON:
+ case VBAD:
+ case VMARKER:
+ mp = NULL;
+ break;
+ default:
+ vn_printf(vp, "unknown vnode type");
+ mp = NULL;
+ break;
+ }
+ return (VFSTOUFS(mp));
+}
+
/*
* Function to determine if the buffer has outstanding dependencies
* that will cause a roll-back if the buffer is written. If wantcount
@@ -13822,10 +13965,10 @@
struct diradd *dap;
int i, retval;
+ ump = softdep_bp_to_mp(bp);
+ if (ump == NULL)
+ return (0);
retval = 0;
- if ((wk = LIST_FIRST(&bp->b_dep)) == NULL)
- return (0);
- ump = VFSTOUFS(wk->wk_mp);
ACQUIRE_LOCK(ump);
LIST_FOREACH(wk, &bp->b_dep, wk_list) {
switch (wk->wk_type) {
@@ -13960,7 +14103,7 @@
}
out:
FREE_LOCK(ump);
- return retval;
+ return (retval);
}
/*
@@ -13982,7 +14125,7 @@
error = BUF_LOCK(bp,
LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, lock);
/*
- * Even if we sucessfully acquire bp here, we have dropped
+ * Even if we successfully acquire bp here, we have dropped
* lock, which may violates our guarantee.
*/
if (error == 0)
@@ -14009,11 +14152,7 @@
BUF_UNLOCK(bp);
if (waitfor != MNT_WAIT)
return (NULL);
- /*
- * The lock argument must be bp->b_vp's mutex in
- * this case.
- */
-#ifdef DEBUG_VFS_LOCKS
+#ifdef DEBUG_VFS_LOCKS
if (bp->b_vp->v_type != VCHR)
ASSERT_BO_WLOCKED(bp->b_bufobj);
#endif
@@ -14170,25 +14309,14 @@
/*
* Wait for pending output on a vnode to complete.
- * Must be called with vnode lock and interlock locked.
- *
- * XXX: Should just be a call to bufobj_wwait().
*/
static void
drain_output(vp)
struct vnode *vp;
{
- struct bufobj *bo;
- bo = &vp->v_bufobj;
ASSERT_VOP_LOCKED(vp, "drain_output");
- ASSERT_BO_WLOCKED(bo);
-
- while (bo->bo_numoutput) {
- bo->bo_flag |= BO_WWAIT;
- msleep((caddr_t)&bo->bo_numoutput,
- BO_LOCKPTR(bo), PRIBIO + 1, "drainvp", 0);
- }
+ (void)bufobj_wwait(&vp->v_bufobj, 0, 0);
}
/*
@@ -14230,13 +14358,14 @@
static void
inodedep_print(struct inodedep *inodedep, int verbose)
{
- db_printf("%p fs %p st %x ino %jd inoblk %jd delta %d nlink %d"
+ db_printf("%p fs %p st %x ino %jd inoblk %jd delta %jd nlink %jd"
" saveino %p\n",
inodedep, inodedep->id_fs, inodedep->id_state,
(intmax_t)inodedep->id_ino,
(intmax_t)fsbtodb(inodedep->id_fs,
ino_to_fsba(inodedep->id_fs, inodedep->id_ino)),
- inodedep->id_nlinkdelta, inodedep->id_savednlink,
+ (intmax_t)inodedep->id_nlinkdelta,
+ (intmax_t)inodedep->id_savednlink,
inodedep->id_savedino1);
if (verbose == 0)
Modified: trunk/sys/ufs/ffs/ffs_subr.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_subr.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_subr.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ffs/ffs_subr.c 207141 2010-04-24 07:05:35Z jeff $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ffs/ffs_subr.c 331722 2018-03-29 02:50:57Z eadler $");
#include <sys/param.h>
@@ -56,10 +56,6 @@
#include <ufs/ffs/ffs_extern.h>
#include <ufs/ffs/fs.h>
-#ifdef KDB
-void ffs_checkoverlap(struct buf *, struct inode *);
-#endif
-
/*
* Return buffer with the contents of block "offset" from the beginning of
* directory "ip". If "res" is non-zero, fill it in with a pointer to the
@@ -79,7 +75,7 @@
int bsize, error;
ip = VTOI(vp);
- fs = ip->i_fs;
+ fs = ITOFS(ip);
lbn = lblkno(fs, offset);
bsize = blksize(fs, ip, lbn);
@@ -107,7 +103,7 @@
ino_t ino;
{
- if (ip->i_ump->um_fstype == UFS1) {
+ if (I_IS_UFS1(ip)) {
*ip->i_din1 =
*((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
ip->i_mode = ip->i_din1->di_mode;
@@ -166,37 +162,6 @@
}
}
-#ifdef KDB
-void
-ffs_checkoverlap(bp, ip)
- struct buf *bp;
- struct inode *ip;
-{
- struct buf *ebp, *ep;
- ufs2_daddr_t start, last;
- struct vnode *vp;
-
- ebp = &buf[nbuf];
- start = bp->b_blkno;
- last = start + btodb(bp->b_bcount) - 1;
- for (ep = buf; ep < ebp; ep++) {
- if (ep == bp || (ep->b_flags & B_INVAL) ||
- ep->b_vp == NULLVP)
- continue;
- vp = ip->i_devvp;
- /* look for overlap */
- if (ep->b_bcount == 0 || ep->b_blkno > last ||
- ep->b_blkno + btodb(ep->b_bcount) <= start)
- continue;
- vprint("Disk overlap", vp);
- printf("\tstart %jd, end %jd overlap start %jd, end %jd\n",
- (intmax_t)start, (intmax_t)last, (intmax_t)ep->b_blkno,
- (intmax_t)(ep->b_blkno + btodb(ep->b_bcount) - 1));
- panic("ffs_checkoverlap: Disk buffer overlap");
- }
-}
-#endif /* KDB */
-
/*
* block operations
*
Modified: trunk/sys/ufs/ffs/ffs_suspend.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_suspend.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_suspend.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -27,14 +27,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: stable/10/sys/ufs/ffs/ffs_suspend.c 306175 2016-09-22 10:42:40Z kib $
+ * $FreeBSD: stable/11/sys/ufs/ffs/ffs_suspend.c 337483 2018-08-08 18:51:39Z kib $
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ffs/ffs_suspend.c 306175 2016-09-22 10:42:40Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ffs/ffs_suspend.c 337483 2018-08-08 18:51:39Z kib $");
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/buf.h>
#include <sys/ioccom.h>
#include <sys/mount.h>
#include <sys/vnode.h>
@@ -214,6 +215,31 @@
}
static void
+ffs_susp_unsuspend(struct mount *mp)
+{
+ struct ufsmount *ump;
+
+ sx_assert(&ffs_susp_lock, SA_XLOCKED);
+
+ /*
+ * XXX: The status is kept per-process; the vfs_write_resume() routine
+ * asserts that the resuming thread is the same one that called
+ * vfs_write_suspend(). The cdevpriv data, however, is attached
+ * to the file descriptor, e.g. is inherited during fork. Thus,
+ * it's possible that the resuming process will be different from
+ * the one that started the suspension.
+ *
+ * Work around by fooling the check in vfs_write_resume().
+ */
+ mp->mnt_susp_owner = curthread;
+
+ vfs_write_resume(mp, 0);
+ ump = VFSTOUFS(mp);
+ ump->um_writesuspended = 0;
+ vfs_unbusy(mp);
+}
+
+static void
ffs_susp_dtor(void *data)
{
struct fs *fs;
@@ -239,22 +265,7 @@
if (error != 0)
panic("failed to unsuspend writes on %s", fs->fs_fsmnt);
- /*
- * XXX: The status is kept per-process; the vfs_write_resume() routine
- * asserts that the resuming thread is the same one that called
- * vfs_write_suspend(). The cdevpriv data, however, is attached
- * to the file descriptor, e.g. is inherited during fork. Thus,
- * it's possible that the resuming process will be different from
- * the one that started the suspension.
- *
- * Work around by fooling the check in vfs_write_resume().
- */
- mp->mnt_susp_owner = curthread;
-
- vfs_write_resume(mp, 0);
- vfs_unbusy(mp);
- ump->um_writesuspended = 0;
-
+ ffs_susp_unsuspend(mp);
sx_xunlock(&ffs_susp_lock);
}
@@ -294,7 +305,8 @@
break;
}
error = devfs_set_cdevpriv(mp, ffs_susp_dtor);
- KASSERT(error == 0, ("devfs_set_cdevpriv failed"));
+ if (error != 0)
+ ffs_susp_unsuspend(mp);
break;
case UFSRESUME:
error = devfs_get_cdevpriv((void **)&mp);
Modified: trunk/sys/ufs/ffs/ffs_tables.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_tables.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_tables.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ffs/ffs_tables.c 139825 2005-01-07 02:29:27Z imp $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ffs/ffs_tables.c 331722 2018-03-29 02:50:57Z eadler $");
#include <sys/param.h>
#include <ufs/ufs/dinode.h>
Modified: trunk/sys/ufs/ffs/ffs_vfsops.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_vfsops.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_vfsops.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ffs/ffs_vfsops.c 309208 2016-11-27 09:14:52Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ffs/ffs_vfsops.c 357030 2020-01-23 06:06:32Z mckusick $");
#include "opt_quota.h"
#include "opt_ufs.h"
@@ -55,6 +55,7 @@
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/rwlock.h>
+#include <sys/vmmeter.h>
#include <security/mac/mac_framework.h>
@@ -149,7 +150,7 @@
struct fs *fs;
pid_t fsckpid = 0;
int error, error1, flags;
- uint64_t mntorflags;
+ uint64_t mntorflags, saved_mnt_flag;
accmode_t accmode;
struct nameidata ndp;
char *fspec;
@@ -240,7 +241,6 @@
if ((error = ffs_flushfiles(mp, WRITECLOSE, td)) != 0 ||
(error = ffs_sbupdate(ump, MNT_WAIT, 0)) != 0)
return (error);
- DROP_GIANT();
g_topology_lock();
/*
* Return to normal read-only mode.
@@ -247,7 +247,6 @@
*/
error = g_access(ump->um_cp, 0, -1, 0);
g_topology_unlock();
- PICKUP_GIANT();
ump->um_fsckpid = 0;
}
if (fs->fs_ronly == 0 &&
@@ -295,7 +294,6 @@
}
if (MOUNTEDSOFTDEP(mp))
softdep_unmount(mp);
- DROP_GIANT();
g_topology_lock();
/*
* Drop our write and exclusive access.
@@ -302,7 +300,6 @@
*/
g_access(ump->um_cp, 0, -1, -1);
g_topology_unlock();
- PICKUP_GIANT();
fs->fs_ronly = 1;
MNT_ILOCK(mp);
mp->mnt_flag |= MNT_RDONLY;
@@ -360,7 +357,6 @@
return (EPERM);
}
}
- DROP_GIANT();
g_topology_lock();
/*
* Request exclusive write access.
@@ -367,30 +363,44 @@
*/
error = g_access(ump->um_cp, 0, 1, 1);
g_topology_unlock();
- PICKUP_GIANT();
if (error)
return (error);
if ((error = vn_start_write(NULL, &mp, V_WAIT)) != 0)
return (error);
+ error = vfs_write_suspend_umnt(mp);
+ if (error != 0)
+ return (error);
fs->fs_ronly = 0;
MNT_ILOCK(mp);
- mp->mnt_flag &= ~MNT_RDONLY;
+ saved_mnt_flag = MNT_RDONLY;
+ if (MOUNTEDSOFTDEP(mp) && (mp->mnt_flag &
+ MNT_ASYNC) != 0)
+ saved_mnt_flag |= MNT_ASYNC;
+ mp->mnt_flag &= ~saved_mnt_flag;
MNT_IUNLOCK(mp);
fs->fs_mtime = time_second;
/* check to see if we need to start softdep */
if ((fs->fs_flags & FS_DOSOFTDEP) &&
(error = softdep_mount(devvp, mp, fs, td->td_ucred))){
- vn_finished_write(mp);
+ fs->fs_ronly = 1;
+ MNT_ILOCK(mp);
+ mp->mnt_flag |= saved_mnt_flag;
+ MNT_IUNLOCK(mp);
+ vfs_write_resume(mp, 0);
return (error);
}
fs->fs_clean = 0;
if ((error = ffs_sbupdate(ump, MNT_WAIT, 0)) != 0) {
- vn_finished_write(mp);
+ fs->fs_ronly = 1;
+ MNT_ILOCK(mp);
+ mp->mnt_flag |= saved_mnt_flag;
+ MNT_IUNLOCK(mp);
+ vfs_write_resume(mp, 0);
return (error);
}
if (fs->fs_snapinum[0] != 0)
ffs_snapshot_mount(mp);
- vn_finished_write(mp);
+ vfs_write_resume(mp, 0);
}
/*
* Soft updates is incompatible with "async",
@@ -434,7 +444,6 @@
}
KASSERT(MOUNTEDSOFTDEP(mp) == 0,
("soft updates enabled on read-only file system"));
- DROP_GIANT();
g_topology_lock();
/*
* Request write access.
@@ -441,7 +450,6 @@
*/
error = g_access(ump->um_cp, 0, 1, 0);
g_topology_unlock();
- PICKUP_GIANT();
if (error) {
vfs_mount_error(mp,
"Checker activation failed on %s",
@@ -540,7 +548,6 @@
("soft updates enabled on read-only file system"));
ump = VFSTOUFS(mp);
fs = ump->um_fs;
- DROP_GIANT();
g_topology_lock();
/*
* Request write access.
@@ -547,7 +554,6 @@
*/
error = g_access(ump->um_cp, 0, 1, 0);
g_topology_unlock();
- PICKUP_GIANT();
if (error) {
printf("WARNING: %s: Checker activation "
"failed\n", fs->fs_fsmnt);
@@ -798,11 +804,9 @@
VOP_UNLOCK(devvp, 0);
return (EBUSY);
}
- DROP_GIANT();
g_topology_lock();
error = g_vfs_open(devvp, &cp, "ffs", ronly ? 0 : 1);
g_topology_unlock();
- PICKUP_GIANT();
if (error != 0) {
atomic_store_rel_ptr((uintptr_t *)&dev->si_mountpt, 0);
VOP_UNLOCK(devvp, 0);
@@ -849,7 +853,7 @@
goto out;
}
fs->fs_fmod = 0;
- fs->fs_flags &= ~FS_INDEXDIRS; /* no support for directory indicies */
+ fs->fs_flags &= ~FS_INDEXDIRS; /* no support for directory indices */
fs->fs_flags &= ~FS_UNCLEAN;
if (fs->fs_clean == 0) {
fs->fs_flags |= FS_UNCLEAN;
@@ -1117,11 +1121,9 @@
if (bp)
brelse(bp);
if (cp != NULL) {
- DROP_GIANT();
g_topology_lock();
g_vfs_close(cp);
g_topology_unlock();
- PICKUP_GIANT();
}
if (ump) {
mtx_destroy(UFS_MTX(ump));
@@ -1307,7 +1309,6 @@
taskqueue_drain_all(ump->um_trim_tq);
taskqueue_free(ump->um_trim_tq);
}
- DROP_GIANT();
g_topology_lock();
if (ump->um_fsckpid > 0) {
/*
@@ -1318,7 +1319,6 @@
}
g_vfs_close(ump->um_cp);
g_topology_unlock();
- PICKUP_GIANT();
atomic_store_rel_ptr((uintptr_t *)&ump->um_dev->si_mountpt, 0);
vrele(ump->um_devvp);
dev_rel(ump->um_dev);
@@ -1334,6 +1334,10 @@
MNT_ILOCK(mp);
mp->mnt_flag &= ~MNT_LOCAL;
MNT_IUNLOCK(mp);
+ if (td->td_su == mp) {
+ td->td_su = NULL;
+ vfs_rel(mp);
+ }
return (error);
fail:
@@ -1480,8 +1484,12 @@
allerror = 0;
td = curthread;
- if ((mp->mnt_flag & MNT_NOATIME) != 0)
- goto qupdate;
+ if ((mp->mnt_flag & MNT_NOATIME) != 0) {
+#ifdef QUOTA
+ qsync(mp);
+#endif
+ goto sbupdate;
+ }
MNT_VNODE_FOREACH_ACTIVE(vp, mp, mvp) {
if (vp->v_type == VNON) {
VI_UNLOCK(vp);
@@ -1503,6 +1511,9 @@
if ((error = vget(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_INTERLOCK,
td)) != 0)
continue;
+#ifdef QUOTA
+ qsyncvp(vp);
+#endif
if (sync_doupdate(ip))
error = ffs_update(vp, 0);
if (error != 0)
@@ -1509,12 +1520,7 @@
allerror = error;
vput(vp);
}
-
-qupdate:
-#ifdef QUOTA
- qsync(mp);
-#endif
-
+sbupdate:
if (VFSTOUFS(mp)->um_fs->fs_fmod != 0 &&
(error = ffs_sbupdate(VFSTOUFS(mp), MNT_LAZY, 0)) != 0)
allerror = error;
@@ -1607,6 +1613,9 @@
}
continue;
}
+#ifdef QUOTA
+ qsyncvp(vp);
+#endif
if ((error = ffs_syncvnode(vp, waitfor, 0)) != 0)
allerror = error;
vput(vp);
@@ -1621,9 +1630,6 @@
if (allerror == 0 && count)
goto loop;
}
-#ifdef QUOTA
- qsync(mp);
-#endif
devvp = ump->um_devvp;
bo = &devvp->v_bufobj;
@@ -1687,7 +1693,6 @@
struct ufsmount *ump;
struct buf *bp;
struct vnode *vp;
- struct cdev *dev;
int error;
error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL);
@@ -1711,7 +1716,6 @@
*/
ump = VFSTOUFS(mp);
- dev = ump->um_dev;
fs = ump->um_fs;
ip = uma_zalloc(uma_inode, M_WAITOK | M_ZERO);
@@ -1732,11 +1736,10 @@
vp->v_bufobj.bo_bsize = fs->fs_bsize;
ip->i_vnode = vp;
ip->i_ump = ump;
- ip->i_fs = fs;
- ip->i_dev = dev;
ip->i_number = ino;
ip->i_ea_refs = 0;
ip->i_nextclustercg = -1;
+ ip->i_flag = fs->fs_magic == FS_UFS1_MAGIC ? 0 : IN_UFS2;
#ifdef QUOTA
{
int i;
@@ -1773,7 +1776,7 @@
*vpp = NULL;
return (error);
}
- if (ip->i_ump->um_fstype == UFS1)
+ if (I_IS_UFS1(ip))
ip->i_din1 = uma_zalloc(uma_ufs1, M_WAITOK);
else
ip->i_din2 = uma_zalloc(uma_ufs2, M_WAITOK);
@@ -1788,10 +1791,8 @@
* Initialize the vnode from the inode, check for aliases.
* Note that the underlying vnode may have changed.
*/
- if (ip->i_ump->um_fstype == UFS1)
- error = ufs_vinit(mp, &ffs_fifoops1, &vp);
- else
- error = ufs_vinit(mp, &ffs_fifoops2, &vp);
+ error = ufs_vinit(mp, I_IS_UFS1(ip) ? &ffs_fifoops1 : &ffs_fifoops2,
+ &vp);
if (error) {
vput(vp);
*vpp = NULL;
@@ -1811,7 +1812,8 @@
* already have one. This should only happen on old filesystems.
*/
if (ip->i_gen == 0) {
- ip->i_gen = arc4random() / 2 + 1;
+ while (ip->i_gen == 0)
+ ip->i_gen = arc4random();
if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
ip->i_flag |= IN_MODIFIED;
DIP_SET(ip, i_gen, ip->i_gen);
@@ -1843,6 +1845,7 @@
*
* Have to be really careful about stale file handles:
* - check that the inode number is valid
+ * - for UFS2 check that the inode number is initialized
* - call ffs_vget() to get the locked inode
* - check for an unallocated inode (i_mode == 0)
* - check that the given client host has export rights and return
@@ -1856,13 +1859,37 @@
struct vnode **vpp;
{
struct ufid *ufhp;
+ struct ufsmount *ump;
struct fs *fs;
+ struct cg *cgp;
+ struct buf *bp;
+ ino_t ino;
+ u_int cg;
+ int error;
ufhp = (struct ufid *)fhp;
- fs = VFSTOUFS(mp)->um_fs;
- if (ufhp->ufid_ino < ROOTINO ||
- ufhp->ufid_ino >= fs->fs_ncg * fs->fs_ipg)
+ ino = ufhp->ufid_ino;
+ ump = VFSTOUFS(mp);
+ fs = ump->um_fs;
+ if (ino < ROOTINO || ino >= fs->fs_ncg * fs->fs_ipg)
return (ESTALE);
+ /*
+ * Need to check if inode is initialized because UFS2 does lazy
+ * initialization and nfs_fhtovp can offer arbitrary inode numbers.
+ */
+ if (fs->fs_magic != FS_UFS2_MAGIC)
+ return (ufs_fhtovp(mp, ufhp, flags, vpp));
+ cg = ino_to_cg(fs, ino);
+ error = bread(ump->um_devvp, fsbtodb(fs, cgtod(fs, cg)),
+ (int)fs->fs_cgsize, NOCRED, &bp);
+ if (error)
+ return (error);
+ cgp = (struct cg *)bp->b_data;
+ if (!cg_chkmagic(cgp) || ino >= cg * fs->fs_ipg + cgp->cg_initediblk) {
+ brelse(bp);
+ return (ESTALE);
+ }
+ brelse(bp);
return (ufs_fhtovp(mp, ufhp, flags, vpp));
}
@@ -1950,13 +1977,13 @@
}
bp = sbbp;
if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_sblockloc != SBLOCK_UFS1 &&
- (fs->fs_flags & FS_FLAGS_UPDATED) == 0) {
+ (fs->fs_old_flags & FS_FLAGS_UPDATED) == 0) {
printf("WARNING: %s: correcting fs_sblockloc from %jd to %d\n",
fs->fs_fsmnt, fs->fs_sblockloc, SBLOCK_UFS1);
fs->fs_sblockloc = SBLOCK_UFS1;
}
if (fs->fs_magic == FS_UFS2_MAGIC && fs->fs_sblockloc != SBLOCK_UFS2 &&
- (fs->fs_flags & FS_FLAGS_UPDATED) == 0) {
+ (fs->fs_old_flags & FS_FLAGS_UPDATED) == 0) {
printf("WARNING: %s: correcting fs_sblockloc from %jd to %d\n",
fs->fs_fsmnt, fs->fs_sblockloc, SBLOCK_UFS2);
fs->fs_sblockloc = SBLOCK_UFS2;
@@ -2032,7 +2059,6 @@
/*
* Process dependencies then return any unfinished ones.
*/
- pbrelvp(bp);
if (!LIST_EMPTY(&bp->b_dep) && (bp->b_ioflags & BIO_ERROR) == 0)
buf_complete(bp);
#ifdef SOFTUPDATES
@@ -2045,6 +2071,7 @@
*/
bp->b_flags |= B_NOCACHE;
bp->b_flags &= ~B_CACHE;
+ pbrelvp(bp);
/*
* Prevent brelse() from trying to keep and re-dirtying bp on
@@ -2138,7 +2165,7 @@
if (newbp == NULL)
goto normal_write;
- KASSERT((bp->b_flags & B_UNMAPPED) == 0, ("Unmapped cg"));
+ KASSERT(buf_mapped(bp), ("Unmapped cg"));
memcpy(newbp->b_data, bp->b_data, bp->b_bufsize);
BO_LOCK(bp->b_bufobj);
bp->b_vflags |= BV_BKGRDINPROG;
Modified: trunk/sys/ufs/ffs/ffs_vnops.c
===================================================================
--- trunk/sys/ufs/ffs/ffs_vnops.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/ffs_vnops.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -63,7 +63,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ffs/ffs_vnops.c 284201 2015-06-10 02:14:33Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ffs/ffs_vnops.c 331722 2018-03-29 02:50:57Z eadler $");
#include <sys/param.h>
#include <sys/bio.h>
@@ -78,6 +78,7 @@
#include <sys/priv.h>
#include <sys/rwlock.h>
#include <sys/stat.h>
+#include <sys/sysctl.h>
#include <sys/vmmeter.h>
#include <sys/vnode.h>
@@ -103,9 +104,10 @@
#ifdef DIRECTIO
extern int ffs_rawread(struct vnode *vp, struct uio *uio, int *workdone);
#endif
+static vop_fdatasync_t ffs_fdatasync;
static vop_fsync_t ffs_fsync;
+static vop_getpages_t ffs_getpages;
static vop_lock1_t ffs_lock;
-static vop_getpages_t ffs_getpages;
static vop_read_t ffs_read;
static vop_write_t ffs_write;
static int ffs_extread(struct vnode *vp, struct uio *uio, int ioflag);
@@ -120,12 +122,13 @@
static vop_setextattr_t ffs_setextattr;
static vop_vptofh_t ffs_vptofh;
-
/* Global vfs data structures for ufs. */
struct vop_vector ffs_vnodeops1 = {
.vop_default = &ufs_vnodeops,
.vop_fsync = ffs_fsync,
+ .vop_fdatasync = ffs_fdatasync,
.vop_getpages = ffs_getpages,
+ .vop_getpages_async = vnode_pager_local_getpages_async,
.vop_lock1 = ffs_lock,
.vop_read = ffs_read,
.vop_reallocblks = ffs_reallocblks,
@@ -136,6 +139,7 @@
struct vop_vector ffs_fifoops1 = {
.vop_default = &ufs_fifoops,
.vop_fsync = ffs_fsync,
+ .vop_fdatasync = ffs_fdatasync,
.vop_reallocblks = ffs_reallocblks, /* XXX: really ??? */
.vop_vptofh = ffs_vptofh,
};
@@ -144,7 +148,9 @@
struct vop_vector ffs_vnodeops2 = {
.vop_default = &ufs_vnodeops,
.vop_fsync = ffs_fsync,
+ .vop_fdatasync = ffs_fdatasync,
.vop_getpages = ffs_getpages,
+ .vop_getpages_async = vnode_pager_local_getpages_async,
.vop_lock1 = ffs_lock,
.vop_read = ffs_read,
.vop_reallocblks = ffs_reallocblks,
@@ -161,6 +167,7 @@
struct vop_vector ffs_fifoops2 = {
.vop_default = &ufs_fifoops,
.vop_fsync = ffs_fsync,
+ .vop_fdatasync = ffs_fdatasync,
.vop_lock1 = ffs_lock,
.vop_reallocblks = ffs_reallocblks,
.vop_strategy = ffsext_strategy,
@@ -216,10 +223,10 @@
{
struct inode *ip;
struct bufobj *bo;
- struct buf *bp;
- struct buf *nbp;
+ struct buf *bp, *nbp;
ufs_lbn_t lbn;
- int error, wait, passes;
+ int error, passes;
+ bool still_dirty, wait;
ip = VTOI(vp);
ip->i_flag &= ~IN_NEEDSYNC;
@@ -238,8 +245,8 @@
*/
error = 0;
passes = 0;
- wait = 0; /* Always do an async pass first. */
- lbn = lblkno(ip->i_fs, (ip->i_size + ip->i_fs->fs_bsize - 1));
+ wait = false; /* Always do an async pass first. */
+ lbn = lblkno(ITOFS(ip), (ip->i_size + ITOFS(ip)->fs_bsize - 1));
BO_LOCK(bo);
loop:
TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs)
@@ -254,15 +261,23 @@
if ((bp->b_vflags & BV_SCANNED) != 0)
continue;
bp->b_vflags |= BV_SCANNED;
- /* Flush indirects in order. */
+ /*
+ * Flush indirects in order, if requested.
+ *
+ * Note that if only datasync is requested, we can
+ * skip indirect blocks when softupdates are not
+ * active. Otherwise we must flush them with data,
+ * since dependencies prevent data block writes.
+ */
if (waitfor == MNT_WAIT && bp->b_lblkno <= -NDADDR &&
- lbn_level(bp->b_lblkno) >= passes)
+ (lbn_level(bp->b_lblkno) >= passes ||
+ ((flags & DATA_ONLY) != 0 && !DOINGSOFTDEP(vp))))
continue;
if (bp->b_lblkno > lbn)
panic("ffs_syncvnode: syncing truncated data.");
if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL) == 0) {
BO_UNLOCK(bo);
- } else if (wait != 0) {
+ } else if (wait) {
if (BUF_LOCK(bp,
LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK,
BO_LOCKPTR(bo)) != 0) {
@@ -330,31 +345,59 @@
* these will be done with one sync and one async pass.
*/
if (bo->bo_dirty.bv_cnt > 0) {
- /* Write the inode after sync passes to flush deps. */
- if (wait && DOINGSOFTDEP(vp) && (flags & NO_INO_UPDT) == 0) {
- BO_UNLOCK(bo);
- ffs_update(vp, 1);
- BO_LOCK(bo);
+ if ((flags & DATA_ONLY) == 0) {
+ still_dirty = true;
+ } else {
+ /*
+ * For data-only sync, dirty indirect buffers
+ * are ignored.
+ */
+ still_dirty = false;
+ TAILQ_FOREACH(bp, &bo->bo_dirty.bv_hd, b_bobufs) {
+ if (bp->b_lblkno > -NDADDR) {
+ still_dirty = true;
+ break;
+ }
+ }
}
- /* switch between sync/async. */
- wait = !wait;
- if (wait == 1 || ++passes < NIADDR + 2)
- goto loop;
+
+ if (still_dirty) {
+ /* Write the inode after sync passes to flush deps. */
+ if (wait && DOINGSOFTDEP(vp) &&
+ (flags & NO_INO_UPDT) == 0) {
+ BO_UNLOCK(bo);
+ ffs_update(vp, 1);
+ BO_LOCK(bo);
+ }
+ /* switch between sync/async. */
+ wait = !wait;
+ if (wait || ++passes < NIADDR + 2)
+ goto loop;
#ifdef INVARIANTS
- if (!vn_isdisk(vp, NULL))
- vprint("ffs_fsync: dirty", vp);
+ if (!vn_isdisk(vp, NULL))
+ vn_printf(vp, "ffs_fsync: dirty ");
#endif
+ }
}
BO_UNLOCK(bo);
error = 0;
- if ((flags & NO_INO_UPDT) == 0)
- error = ffs_update(vp, 1);
- if (DOINGSUJ(vp))
- softdep_journal_fsync(VTOI(vp));
+ if ((flags & DATA_ONLY) == 0) {
+ if ((flags & NO_INO_UPDT) == 0)
+ error = ffs_update(vp, 1);
+ if (DOINGSUJ(vp))
+ softdep_journal_fsync(VTOI(vp));
+ }
return (error);
}
static int
+ffs_fdatasync(struct vop_fdatasync_args *ap)
+{
+
+ return (ffs_syncvnode(ap->a_vp, MNT_WAIT, DATA_ONLY));
+}
+
+static int
ffs_lock(ap)
struct vop_lock1_args /* {
struct vnode *a_vp;
@@ -477,7 +520,7 @@
if (orig_resid == 0)
return (0);
KASSERT(uio->uio_offset >= 0, ("ffs_read: uio->uio_offset < 0"));
- fs = ip->i_fs;
+ fs = ITOFS(ip);
if (uio->uio_offset < ip->i_size &&
uio->uio_offset >= fs->fs_maxfilesize)
return (EOVERFLOW);
@@ -559,15 +602,6 @@
}
/*
- * If IO_DIRECT then set B_DIRECT for the buffer. This
- * will cause us to attempt to release the buffer later on
- * and will cause the buffer cache to attempt to free the
- * underlying pages.
- */
- if (ioflag & IO_DIRECT)
- bp->b_flags |= B_DIRECT;
-
- /*
* We should only get non-zero b_resid when an I/O error
* has occurred, which should cause us to break above.
* However, if the short read did not cause an error,
@@ -581,7 +615,7 @@
xfersize = size;
}
- if ((bp->b_flags & B_UNMAPPED) == 0) {
+ if (buf_mapped(bp)) {
error = vn_io_fault_uiomove((char *)bp->b_data +
blkoffset, (int)xfersize, uio);
} else {
@@ -591,25 +625,7 @@
if (error)
break;
- if ((ioflag & (IO_VMIO|IO_DIRECT)) &&
- (LIST_EMPTY(&bp->b_dep))) {
- /*
- * If there are no dependencies, and it's VMIO,
- * then we don't need the buf, mark it available
- * for freeing. For non-direct VMIO reads, the VM
- * has the data.
- */
- bp->b_flags |= B_RELBUF;
- brelse(bp);
- } else {
- /*
- * Otherwise let whoever
- * made the request take care of
- * freeing it. We just queue
- * it onto another list.
- */
- bqrelse(bp);
- }
+ vfs_bio_brelse(bp, ioflag);
}
/*
@@ -618,15 +634,8 @@
* and on normal completion has not set a new value into it.
* so it must have come from a 'break' statement
*/
- if (bp != NULL) {
- if ((ioflag & (IO_VMIO|IO_DIRECT)) &&
- (LIST_EMPTY(&bp->b_dep))) {
- bp->b_flags |= B_RELBUF;
- brelse(bp);
- } else {
- bqrelse(bp);
- }
- }
+ if (bp != NULL)
+ vfs_bio_brelse(bp, ioflag);
if ((error == 0 || uio->uio_resid != orig_resid) &&
(vp->v_mount->mnt_flag & (MNT_NOATIME | MNT_RDONLY)) == 0 &&
@@ -700,7 +709,7 @@
KASSERT(uio->uio_resid >= 0, ("ffs_write: uio->uio_resid < 0"));
KASSERT(uio->uio_offset >= 0, ("ffs_write: uio->uio_offset < 0"));
- fs = ip->i_fs;
+ fs = ITOFS(ip);
if ((uoff_t)uio->uio_offset + uio->uio_resid > fs->fs_maxfilesize)
return (EFBIG);
/*
@@ -744,8 +753,6 @@
vnode_pager_setsize(vp, ip->i_size);
break;
}
- if (ioflag & IO_DIRECT)
- bp->b_flags |= B_DIRECT;
if ((ioflag & (IO_SYNC|IO_INVAL)) == (IO_SYNC|IO_INVAL))
bp->b_flags |= B_NOCACHE;
@@ -758,7 +765,7 @@
if (size < xfersize)
xfersize = size;
- if ((bp->b_flags & B_UNMAPPED) == 0) {
+ if (buf_mapped(bp)) {
error = vn_io_fault_uiomove((char *)bp->b_data +
blkoffset, (int)xfersize, uio);
} else {
@@ -785,11 +792,9 @@
if (error != 0 && (bp->b_flags & B_CACHE) == 0 &&
fs->fs_bsize == xfersize)
vfs_bio_clrbuf(bp);
- if ((ioflag & (IO_VMIO|IO_DIRECT)) &&
- (LIST_EMPTY(&bp->b_dep))) {
- bp->b_flags |= B_RELBUF;
- }
+ vfs_bio_set_flags(bp, ioflag);
+
/*
* If IO_SYNC each buffer is written synchronously. Otherwise
* if we have a severe page deficiency write the buffer
@@ -848,48 +853,6 @@
}
/*
- * get page routine
- */
-static int
-ffs_getpages(ap)
- struct vop_getpages_args *ap;
-{
- int i;
- vm_page_t mreq;
- int pcount;
-
- pcount = round_page(ap->a_count) / PAGE_SIZE;
- mreq = ap->a_m[ap->a_reqpage];
-
- /*
- * if ANY DEV_BSIZE blocks are valid on a large filesystem block,
- * then the entire page is valid. Since the page may be mapped,
- * user programs might reference data beyond the actual end of file
- * occuring within the page. We have to zero that data.
- */
- VM_OBJECT_WLOCK(mreq->object);
- if (mreq->valid) {
- if (mreq->valid != VM_PAGE_BITS_ALL)
- vm_page_zero_invalid(mreq, TRUE);
- for (i = 0; i < pcount; i++) {
- if (i != ap->a_reqpage) {
- vm_page_lock(ap->a_m[i]);
- vm_page_free(ap->a_m[i]);
- vm_page_unlock(ap->a_m[i]);
- }
- }
- VM_OBJECT_WUNLOCK(mreq->object);
- return VM_PAGER_OK;
- }
- VM_OBJECT_WUNLOCK(mreq->object);
-
- return vnode_pager_generic_getpages(ap->a_vp, ap->a_m,
- ap->a_count,
- ap->a_reqpage);
-}
-
-
-/*
* Extended attribute area reading.
*/
static int
@@ -906,7 +869,7 @@
int error;
ip = VTOI(vp);
- fs = ip->i_fs;
+ fs = ITOFS(ip);
dp = ip->i_din2;
#ifdef INVARIANTS
@@ -978,15 +941,6 @@
}
/*
- * If IO_DIRECT then set B_DIRECT for the buffer. This
- * will cause us to attempt to release the buffer later on
- * and will cause the buffer cache to attempt to free the
- * underlying pages.
- */
- if (ioflag & IO_DIRECT)
- bp->b_flags |= B_DIRECT;
-
- /*
* We should only get non-zero b_resid when an I/O error
* has occurred, which should cause us to break above.
* However, if the short read did not cause an error,
@@ -1004,26 +958,7 @@
(int)xfersize, uio);
if (error)
break;
-
- if ((ioflag & (IO_VMIO|IO_DIRECT)) &&
- (LIST_EMPTY(&bp->b_dep))) {
- /*
- * If there are no dependencies, and it's VMIO,
- * then we don't need the buf, mark it available
- * for freeing. For non-direct VMIO reads, the VM
- * has the data.
- */
- bp->b_flags |= B_RELBUF;
- brelse(bp);
- } else {
- /*
- * Otherwise let whoever
- * made the request take care of
- * freeing it. We just queue
- * it onto another list.
- */
- bqrelse(bp);
- }
+ vfs_bio_brelse(bp, ioflag);
}
/*
@@ -1032,15 +967,8 @@
* and on normal completion has not set a new value into it.
* so it must have come from a 'break' statement
*/
- if (bp != NULL) {
- if ((ioflag & (IO_VMIO|IO_DIRECT)) &&
- (LIST_EMPTY(&bp->b_dep))) {
- bp->b_flags |= B_RELBUF;
- brelse(bp);
- } else {
- bqrelse(bp);
- }
- }
+ if (bp != NULL)
+ vfs_bio_brelse(bp, ioflag);
return (error);
}
@@ -1060,7 +988,7 @@
int blkoffset, error, flags, size, xfersize;
ip = VTOI(vp);
- fs = ip->i_fs;
+ fs = ITOFS(ip);
dp = ip->i_din2;
#ifdef INVARIANTS
@@ -1109,8 +1037,6 @@
*/
if ((bp->b_flags & B_CACHE) == 0 && fs->fs_bsize <= xfersize)
vfs_bio_clrbuf(bp);
- if (ioflag & IO_DIRECT)
- bp->b_flags |= B_DIRECT;
if (uio->uio_offset + xfersize > dp->di_extsize)
dp->di_extsize = uio->uio_offset + xfersize;
@@ -1121,11 +1047,9 @@
error =
uiomove((char *)bp->b_data + blkoffset, (int)xfersize, uio);
- if ((ioflag & (IO_VMIO|IO_DIRECT)) &&
- (LIST_EMPTY(&bp->b_dep))) {
- bp->b_flags |= B_RELBUF;
- }
+ vfs_bio_set_flags(bp, ioflag);
+
/*
* If IO_SYNC each buffer is written synchronously. Otherwise
* if we have a severe page deficiency write the buffer
@@ -1232,7 +1156,7 @@
u_char *eae;
ip = VTOI(vp);
- fs = ip->i_fs;
+ fs = ITOFS(ip);
dp = ip->i_din2;
easize = dp->di_extsize;
if ((uoff_t)easize + extra > NXADDR * fs->fs_bsize)
@@ -1386,8 +1310,7 @@
vp = ap->a_vp;
lbn = ap->a_bp->b_lblkno;
- if (VTOI(vp)->i_fs->fs_magic == FS_UFS2_MAGIC &&
- lbn < 0 && lbn >= -NXADDR)
+ if (I_IS_UFS2(VTOI(vp)) && lbn < 0 && lbn >= -NXADDR)
return (VOP_STRATEGY_APV(&ufs_vnodeops, ap));
if (vp->v_type == VFIFO)
return (VOP_STRATEGY_APV(&ufs_fifoops, ap));
@@ -1463,7 +1386,7 @@
u_char *eae, *p;
ip = VTOI(ap->a_vp);
- fs = ip->i_fs;
+ fs = ITOFS(ip);
if (ap->a_vp->v_type == VCHR || ap->a_vp->v_type == VBLK)
return (EOPNOTSUPP);
@@ -1666,7 +1589,7 @@
u_char *eae, *p;
ip = VTOI(ap->a_vp);
- fs = ip->i_fs;
+ fs = ITOFS(ip);
if (ap->a_vp->v_type == VCHR || ap->a_vp->v_type == VBLK)
return (EOPNOTSUPP);
@@ -1786,3 +1709,38 @@
ufhp->ufid_gen = ip->i_gen;
return (0);
}
+
+SYSCTL_DECL(_vfs_ffs);
+static int use_buf_pager = 0;
+SYSCTL_INT(_vfs_ffs, OID_AUTO, use_buf_pager, CTLFLAG_RWTUN, &use_buf_pager, 0,
+ "Always use buffer pager instead of bmap");
+
+static daddr_t
+ffs_gbp_getblkno(struct vnode *vp, vm_ooffset_t off)
+{
+
+ return (lblkno(VFSTOUFS(vp->v_mount)->um_fs, off));
+}
+
+static int
+ffs_gbp_getblksz(struct vnode *vp, daddr_t lbn)
+{
+
+ return (blksize(VFSTOUFS(vp->v_mount)->um_fs, VTOI(vp), lbn));
+}
+
+static int
+ffs_getpages(struct vop_getpages_args *ap)
+{
+ struct vnode *vp;
+ struct ufsmount *um;
+
+ vp = ap->a_vp;
+ um = VFSTOUFS(vp->v_mount);
+
+ if (!use_buf_pager && um->um_devvp->v_bufobj.bo_bsize <= PAGE_SIZE)
+ return (vnode_pager_generic_getpages(vp, ap->a_m, ap->a_count,
+ ap->a_rbehind, ap->a_rahead, NULL, NULL));
+ return (vfs_bio_getpages(vp, ap->a_m, ap->a_count, ap->a_rbehind,
+ ap->a_rahead, ffs_gbp_getblkno, ffs_gbp_getblksz));
+}
Modified: trunk/sys/ufs/ffs/fs.h
===================================================================
--- trunk/sys/ufs/ffs/fs.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/fs.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -11,7 +11,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -28,7 +28,7 @@
* SUCH DAMAGE.
*
* @(#)fs.h 8.13 (Berkeley) 3/21/95
- * $FreeBSD: stable/10/sys/ufs/ffs/fs.h 322860 2017-08-24 21:44:23Z mckusick $
+ * $FreeBSD: stable/11/sys/ufs/ffs/fs.h 356905 2020-01-20 08:28:54Z eugen $
*/
#ifndef _UFS_FFS_FS_H_
@@ -220,7 +220,8 @@
#define FFS_UNLINK 14 /* remove a name in the filesystem */
#define FFS_SET_INODE 15 /* update an on-disk inode */
#define FFS_SET_BUFOUTPUT 16 /* set buffered writing on descriptor */
-#define FFS_MAXID 16 /* number of valid ffs ids */
+#define FFS_SET_SIZE 17 /* set inode size */
+#define FFS_MAXID 17 /* number of valid ffs ids */
/*
* Command structure passed in to the filesystem to adjust filesystem values.
@@ -238,9 +239,7 @@
* A recovery structure placed at the end of the boot block area by newfs
* that can be used by fsck to search for alternate superblocks.
*/
-#define RESID (4096 - 20) /* disk sector size minus recovery area size */
struct fsrecovery {
- char block[RESID]; /* unused part of sector */
int32_t fsr_magic; /* magic number */
int32_t fsr_fsbtodb; /* fsbtodb and dbtofsb shift constant */
int32_t fsr_sblkno; /* offset of super-block in filesys */
@@ -416,8 +415,8 @@
* flag to enforce that inconsistent filesystems be mounted read-only.
* The FS_INDEXDIRS flag when set indicates that the kernel maintains
* on-disk auxiliary indexes (such as B-trees) for speeding directory
- * accesses. Kernels that do not support auxiliary indicies clear the
- * flag to indicate that the indicies need to be rebuilt (by fsck) before
+ * accesses. Kernels that do not support auxiliary indices clear the
+ * flag to indicate that the indices need to be rebuilt (by fsck) before
* they can be used.
*
* FS_ACLS indicates that POSIX.1e ACLs are administratively enabled
Modified: trunk/sys/ufs/ffs/softdep.h
===================================================================
--- trunk/sys/ufs/ffs/softdep.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ffs/softdep.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -37,7 +37,7 @@
* SUCH DAMAGE.
*
* @(#)softdep.h 9.7 (McKusick) 6/21/00
- * $FreeBSD: stable/10/sys/ufs/ffs/softdep.h 307534 2016-10-17 21:49:54Z mckusick $
+ * $FreeBSD: stable/11/sys/ufs/ffs/softdep.h 320057 2017-06-17 17:10:50Z kib $
*/
#include <sys/queue.h>
@@ -133,7 +133,7 @@
#define INPROGRESS 0x001000 /* dirrem, freeblks, freefrag, freefile only */
#define UFS1FMT 0x002000 /* indirdep only */
#define EXTDATA 0x004000 /* allocdirect only */
-#define ONWORKLIST 0x008000
+#define ONWORKLIST 0x008000
#define IOWAITING 0x010000 /* Thread is waiting for IO to complete. */
#define ONDEPLIST 0x020000 /* Structure is on a dependency list. */
#define UNLINKED 0x040000 /* inodedep has been unlinked. */
@@ -1066,6 +1066,7 @@
#define FLUSH_EXIT 0x0001 /* time to exit */
#define FLUSH_CLEANUP 0x0002 /* need to clear out softdep structures */
#define FLUSH_STARTING 0x0004 /* flush thread not yet started */
+#define FLUSH_RC_ACTIVE 0x0008 /* a thread is flushing the mount point */
/*
* Keep the old names from when these were in the ufsmount structure.
Modified: trunk/sys/ufs/ufs/README.acls
===================================================================
--- trunk/sys/ufs/ufs/README.acls 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/README.acls 2020-02-08 19:39:08 UTC (rev 12316)
@@ -1,4 +1,4 @@
-$FreeBSD: stable/10/sys/ufs/ufs/README.acls 105456 2002-10-19 16:09:16Z rwatson $
+$FreeBSD: stable/11/sys/ufs/ufs/README.acls 105456 2002-10-19 16:09:16Z rwatson $
UFS Access Control Lists Copyright
Modified: trunk/sys/ufs/ufs/README.extattr
===================================================================
--- trunk/sys/ufs/ufs/README.extattr 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/README.extattr 2020-02-08 19:39:08 UTC (rev 12316)
@@ -1,4 +1,4 @@
-$FreeBSD: stable/10/sys/ufs/ufs/README.extattr 105417 2002-10-18 21:11:36Z rwatson $
+$FreeBSD: stable/11/sys/ufs/ufs/README.extattr 105417 2002-10-18 21:11:36Z rwatson $
UFS Extended Attributes Copyright
Modified: trunk/sys/ufs/ufs/acl.h
===================================================================
--- trunk/sys/ufs/ufs/acl.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/acl.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: stable/10/sys/ufs/ufs/acl.h 200796 2009-12-21 19:39:10Z trasz $
+ * $FreeBSD: stable/11/sys/ufs/ufs/acl.h 200796 2009-12-21 19:39:10Z trasz $
*/
/*
* Developed by the TrustedBSD Project.
Modified: trunk/sys/ufs/ufs/dinode.h
===================================================================
--- trunk/sys/ufs/ufs/dinode.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/dinode.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -63,7 +63,7 @@
* SUCH DAMAGE.
*
* @(#)dinode.h 8.3 (Berkeley) 1/21/94
- * $FreeBSD: stable/10/sys/ufs/ufs/dinode.h 259223 2013-12-11 19:25:17Z pfg $
+ * $FreeBSD: stable/11/sys/ufs/ufs/dinode.h 257029 2013-10-24 00:33:29Z pfg $
*/
#ifndef _UFS_UFS_DINODE_H_
Modified: trunk/sys/ufs/ufs/dir.h
===================================================================
--- trunk/sys/ufs/ufs/dir.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/dir.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -16,7 +16,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -33,7 +33,7 @@
* SUCH DAMAGE.
*
* @(#)dir.h 8.2 (Berkeley) 1/21/94
- * $FreeBSD: stable/10/sys/ufs/ufs/dir.h 262779 2014-03-05 04:23:19Z pfg $
+ * $FreeBSD: stable/11/sys/ufs/ufs/dir.h 347475 2019-05-10 23:46:42Z mckusick $
*/
#ifndef _UFS_UFS_DIR_H_
@@ -106,13 +106,11 @@
* The DIRSIZ macro gives the minimum record length which will hold
* the directory entry. This requires the amount of space in struct direct
* without the d_name field, plus enough space for the name with a terminating
- * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
- *
- *
+ * null byte (dp->d_namlen + 1), rounded up to a 4 byte boundary.
*/
-#define DIRECTSIZ(namlen) \
- (((uintptr_t)&((struct direct *)0)->d_name + \
- ((namlen)+1)*sizeof(((struct direct *)0)->d_name[0]) + 3) & ~3)
+#define DIR_ROUNDUP 4 /* Directory name roundup size */
+#define DIRECTSIZ(namlen) \
+ (roundup2(__offsetof(struct direct, d_name) + (namlen) + 1, DIR_ROUNDUP))
#if (BYTE_ORDER == LITTLE_ENDIAN)
#define DIRSIZ(oldfmt, dp) \
((oldfmt) ? DIRECTSIZ((dp)->d_type) : DIRECTSIZ((dp)->d_namlen))
Modified: trunk/sys/ufs/ufs/dirhash.h
===================================================================
--- trunk/sys/ufs/ufs/dirhash.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/dirhash.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: stable/10/sys/ufs/ufs/dirhash.h 262779 2014-03-05 04:23:19Z pfg $
+ * $FreeBSD: stable/11/sys/ufs/ufs/dirhash.h 298804 2016-04-29 20:43:51Z pfg $
*/
#ifndef _UFS_UFS_DIRHASH_H_
@@ -61,7 +61,7 @@
* together on a TAILQ list, and hashes with higher scores filter
* towards the tail (most recently used) end of the list.
*
- * New hash entries are given an inital score of DH_SCOREINIT and are
+ * New hash entries are given an initial score of DH_SCOREINIT and are
* placed at the most-recently-used end of the list. This helps a lot
* in the worst-case case scenario where every directory access is
* to a directory that is not hashed (i.e. the working set of hash
Modified: trunk/sys/ufs/ufs/extattr.h
===================================================================
--- trunk/sys/ufs/ufs/extattr.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/extattr.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -26,7 +26,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: stable/10/sys/ufs/ufs/extattr.h 262779 2014-03-05 04:23:19Z pfg $
+ * $FreeBSD: stable/11/sys/ufs/ufs/extattr.h 306553 2016-10-01 09:19:43Z kib $
*/
/*
* Developed by the TrustedBSD Project.
@@ -134,6 +134,10 @@
int uepm_flags;
};
+struct vop_getextattr_args;
+struct vop_deleteextattr_args;
+struct vop_setextattr_args;
+
void ufs_extattr_uepm_init(struct ufs_extattr_per_mount *uepm);
void ufs_extattr_uepm_destroy(struct ufs_extattr_per_mount *uepm);
int ufs_extattr_start(struct mount *mp, struct thread *td);
Modified: trunk/sys/ufs/ufs/gjournal.h
===================================================================
--- trunk/sys/ufs/ufs/gjournal.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/gjournal.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -24,7 +24,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $FreeBSD: stable/10/sys/ufs/ufs/gjournal.h 262779 2014-03-05 04:23:19Z pfg $
+ * $FreeBSD: stable/11/sys/ufs/ufs/gjournal.h 262678 2014-03-02 02:52:34Z pfg $
*/
#ifndef _UFS_UFS_GJOURNAL_H_
Modified: trunk/sys/ufs/ufs/inode.h
===================================================================
--- trunk/sys/ufs/ufs/inode.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/inode.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -33,7 +33,7 @@
* SUCH DAMAGE.
*
* @(#)inode.h 8.9 (Berkeley) 5/14/95
- * $FreeBSD: stable/10/sys/ufs/ufs/inode.h 283640 2015-05-28 00:11:36Z mckusick $
+ * $FreeBSD: stable/11/sys/ufs/ufs/inode.h 331722 2018-03-29 02:50:57Z eadler $
*/
#ifndef _UFS_UFS_INODE_H_
@@ -67,14 +67,25 @@
struct inode {
TAILQ_ENTRY(inode) i_nextsnap; /* snapshot file list. */
struct vnode *i_vnode;/* Vnode associated with this inode. */
- struct ufsmount *i_ump;/* Ufsmount point associated with this inode. */
+ struct ufsmount *i_ump;/* Ufsmount point associated with this inode. */
+ struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
+ union {
+ struct dirhash *dirhash; /* Hashing for large directories. */
+ daddr_t *snapblklist; /* Collect expunged snapshot blocks. */
+ } i_un;
+ /*
+ * The real copy of the on-disk inode.
+ */
+ union {
+ struct ufs1_dinode *din1; /* UFS1 on-disk dinode. */
+ struct ufs2_dinode *din2; /* UFS2 on-disk dinode. */
+ } dinode_u;
+
+ ino_t i_number; /* The identity of the inode. */
u_int32_t i_flag; /* flags, see below */
- struct cdev *i_dev; /* Device associated with the inode. */
- ino_t i_number; /* The identity of the inode. */
int i_effnlink; /* i_nlink when I/O completes */
- struct fs *i_fs; /* Associated filesystem superblock. */
- struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
+
/*
* Side effects; used during directory lookup.
*/
@@ -83,11 +94,6 @@
doff_t i_diroff; /* Offset in dir, where we found last entry. */
doff_t i_offset; /* Offset of free space in directory. */
- union {
- struct dirhash *dirhash; /* Hashing for large directories. */
- daddr_t *snapblklist; /* Collect expunged snapshot blocks. */
- } i_un;
-
int i_nextclustercg; /* last cg searched for cluster */
/*
@@ -101,20 +107,13 @@
/*
* Copies from the on-disk dinode itself.
*/
- u_int16_t i_mode; /* IFMT, permissions; see below. */
- int16_t i_nlink; /* File link count. */
u_int64_t i_size; /* File byte count. */
+ u_int64_t i_gen; /* Generation number. */
u_int32_t i_flags; /* Status flags (chflags). */
- u_int64_t i_gen; /* Generation number. */
u_int32_t i_uid; /* File owner. */
u_int32_t i_gid; /* File group. */
- /*
- * The real copy of the on-disk inode.
- */
- union {
- struct ufs1_dinode *din1; /* UFS1 on-disk dinode. */
- struct ufs2_dinode *din2; /* UFS2 on-disk dinode. */
- } dinode_u;
+ u_int16_t i_mode; /* IFMT, permissions; see below. */
+ int16_t i_nlink; /* File link count. */
};
/*
* These flags are kept in i_flag.
@@ -124,16 +123,16 @@
#define IN_UPDATE 0x0004 /* Modification time update request. */
#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_LAZYACCESS 0x0100 /* Process IN_ACCESS after the
+#define IN_LAZYMOD 0x0020 /* Modified, but don't write yet. */
+#define IN_LAZYACCESS 0x0040 /* Process IN_ACCESS after the
suspension finished */
-#define IN_EA_LOCKED 0x0200
-#define IN_EA_LOCKWAIT 0x0400
+#define IN_EA_LOCKED 0x0080
+#define IN_EA_LOCKWAIT 0x0100
-#define IN_TRUNCATED 0x0800 /* Journaled truncation pending. */
+#define IN_TRUNCATED 0x0200 /* Journaled truncation pending. */
-#define i_devvp i_ump->um_devvp
-#define i_umbufobj i_ump->um_bo
+#define IN_UFS2 0x0400 /* UFS2 vs UFS1 */
+
#define i_dirhash i_un.dirhash
#define i_snapblklist i_un.snapblklist
#define i_din1 dinode_u.din1
@@ -140,23 +139,42 @@
#define i_din2 dinode_u.din2
#ifdef _KERNEL
+
+#define ITOUMP(ip) ((ip)->i_ump)
+#define ITODEV(ip) (ITOUMP(ip)->um_dev)
+#define ITODEVVP(ip) (ITOUMP(ip)->um_devvp)
+#define ITOFS(ip) (ITOUMP(ip)->um_fs)
+#define ITOVFS(ip) ((ip)->i_vnode->v_mount)
+
+static inline _Bool
+I_IS_UFS1(const struct inode *ip)
+{
+
+ return ((ip->i_flag & IN_UFS2) == 0);
+}
+
+static inline _Bool
+I_IS_UFS2(const struct inode *ip)
+{
+
+ return ((ip->i_flag & IN_UFS2) != 0);
+}
+
/*
* The DIP macro is used to access fields in the dinode that are
* not cached in the inode itself.
*/
-#define DIP(ip, field) \
- (((ip)->i_ump->um_fstype == UFS1) ? \
- (ip)->i_din1->d##field : (ip)->i_din2->d##field)
-#define DIP_SET(ip, field, val) do { \
- if ((ip)->i_ump->um_fstype == UFS1) \
- (ip)->i_din1->d##field = (val); \
- else \
- (ip)->i_din2->d##field = (val); \
+#define DIP(ip, field) (I_IS_UFS1(ip) ? (ip)->i_din1->d##field : \
+ (ip)->i_din2->d##field)
+#define DIP_SET(ip, field, val) do { \
+ if (I_IS_UFS1(ip)) \
+ (ip)->i_din1->d##field = (val); \
+ else \
+ (ip)->i_din2->d##field = (val); \
} while (0)
-#define SHORTLINK(ip) \
- (((ip)->i_ump->um_fstype == UFS1) ? \
- (caddr_t)(ip)->i_din1->di_db : (caddr_t)(ip)->i_din2->di_db)
+#define SHORTLINK(ip) (I_IS_UFS1(ip) ? \
+ (caddr_t)(ip)->i_din1->di_db : (caddr_t)(ip)->i_din2->di_db)
#define IS_SNAPSHOT(ip) ((ip)->i_flags & SF_SNAPSHOT)
/*
Modified: trunk/sys/ufs/ufs/quota.h
===================================================================
--- trunk/sys/ufs/ufs/quota.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/quota.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)quota.h 8.3 (Berkeley) 8/19/94
- * $FreeBSD: stable/10/sys/ufs/ufs/quota.h 262779 2014-03-05 04:23:19Z pfg $
+ * $FreeBSD: stable/11/sys/ufs/ufs/quota.h 331722 2018-03-29 02:50:57Z eadler $
*/
#ifndef _UFS_UFS_QUOTA_H_
Modified: trunk/sys/ufs/ufs/ufs_acl.c
===================================================================
--- trunk/sys/ufs/ufs/ufs_acl.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufs_acl.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ufs/ufs_acl.c 241011 2012-09-27 23:30:49Z mdf $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ufs/ufs_acl.c 306553 2016-10-01 09:19:43Z kib $");
#include "opt_ufs.h"
#include "opt_quota.h"
@@ -46,6 +46,7 @@
#include <sys/acl.h>
#include <sys/event.h>
#include <sys/extattr.h>
+#include <sys/proc.h>
#include <ufs/ufs/quota.h>
#include <ufs/ufs/inode.h>
@@ -184,7 +185,7 @@
*/
printf("ufs_getacl_nfs4(): Loaded invalid ACL ("
"%d bytes), inumber %ju on %s\n", len,
- (uintmax_t)ip->i_number, ip->i_fs->fs_fsmnt);
+ (uintmax_t)ip->i_number, ITOFS(ip)->fs_fsmnt);
return (EPERM);
}
@@ -193,7 +194,7 @@
if (error) {
printf("ufs_getacl_nfs4(): Loaded invalid ACL "
"(failed acl_nfs4_check), inumber %ju on %s\n",
- (uintmax_t)ip->i_number, ip->i_fs->fs_fsmnt);
+ (uintmax_t)ip->i_number, ITOFS(ip)->fs_fsmnt);
return (EPERM);
}
@@ -220,7 +221,7 @@
/*
* Read POSIX.1e ACL from an EA. Return error if its not found
- * or if any other error has occured.
+ * or if any other error has occurred.
*/
static int
ufs_get_oldacl(acl_type_t type, struct oldacl *old, struct vnode *vp,
@@ -261,7 +262,7 @@
*/
printf("ufs_get_oldacl(): Loaded invalid ACL "
"(len = %d), inumber %ju on %s\n", len,
- (uintmax_t)ip->i_number, ip->i_fs->fs_fsmnt);
+ (uintmax_t)ip->i_number, ITOFS(ip)->fs_fsmnt);
return (EPERM);
}
Modified: trunk/sys/ufs/ufs/ufs_bmap.c
===================================================================
--- trunk/sys/ufs/ufs/ufs_bmap.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufs_bmap.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ufs/ufs_bmap.c 284021 2015-06-05 08:36:25Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ufs/ufs_bmap.c 331722 2018-03-29 02:50:57Z eadler $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -45,6 +45,7 @@
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/mount.h>
+#include <sys/racct.h>
#include <sys/resourcevar.h>
#include <sys/stat.h>
@@ -78,7 +79,7 @@
* to physical mapping is requested.
*/
if (ap->a_bop != NULL)
- *ap->a_bop = &VTOI(ap->a_vp)->i_devvp->v_bufobj;
+ *ap->a_bop = &VFSTOUFS(ap->a_vp->v_mount)->um_devvp->v_bufobj;
if (ap->a_bnp == NULL)
return (0);
@@ -224,6 +225,13 @@
vfs_busy_pages(bp, 0);
bp->b_iooffset = dbtob(bp->b_blkno);
bstrategy(bp);
+#ifdef RACCT
+ if (racct_enable) {
+ PROC_LOCK(curproc);
+ racct_add_buf(curproc, bp, 0);
+ PROC_UNLOCK(curproc);
+ }
+#endif /* RACCT */
curthread->td_ru.ru_inblock++;
error = bufwait(bp);
if (error) {
@@ -232,7 +240,7 @@
}
}
- if (ip->i_ump->um_fstype == UFS1) {
+ if (I_IS_UFS1(ip)) {
daddr = ((ufs1_daddr_t *)bp->b_data)[ap->in_off];
if (num == 1 && daddr && runp) {
for (bn = ap->in_off + 1;
Modified: trunk/sys/ufs/ufs/ufs_dirhash.c
===================================================================
--- trunk/sys/ufs/ufs/ufs_dirhash.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufs_dirhash.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ufs/ufs_dirhash.c 326846 2017-12-14 11:45:02Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ufs/ufs_dirhash.c 326845 2017-12-14 11:41:12Z kib $");
#include "opt_ufs.h"
@@ -86,10 +86,11 @@
static int ufs_dirhashlowmemcount = 0;
SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_lowmemcount, CTLFLAG_RD,
&ufs_dirhashlowmemcount, 0, "number of times low memory hook called");
-static int ufs_dirhashreclaimage = 60;
-SYSCTL_INT(_vfs_ufs, OID_AUTO, dirhash_reclaimage, CTLFLAG_RW,
- &ufs_dirhashreclaimage, 0,
- "max time in seconds of hash inactivity before deletion in low VM events");
+static int ufs_dirhashreclaimpercent = 10;
+static int ufsdirhash_set_reclaimpercent(SYSCTL_HANDLER_ARGS);
+SYSCTL_PROC(_vfs_ufs, OID_AUTO, dirhash_reclaimpercent,
+ CTLTYPE_INT | CTLFLAG_RW, 0, 0, ufsdirhash_set_reclaimpercent, "I",
+ "set percentage of dirhash cache to be removed in low VM events");
static int ufsdirhash_hash(struct dirhash *dh, char *name, int namelen);
@@ -1151,7 +1152,7 @@
doff_t blkoff, prevoff;
int entrypos, i;
- blkoff = offset & ~(DIRBLKSIZ - 1); /* offset of start of block */
+ blkoff = rounddown2(offset, DIRBLKSIZ); /* offset of start of block */
entrypos = offset & (DIRBLKSIZ - 1); /* entry relative to block */
blkbuf = (char *)dirp - entrypos;
prevoff = blkoff;
@@ -1250,50 +1251,53 @@
ufsdirhash_lowmem()
{
struct dirhash *dh, *dh_temp;
- int memfreed = 0;
- /*
- * Will free a *minimum* of 10% of the dirhash, but possibly much
- * more (depending on dirhashreclaimage). System with large dirhashes
- * probably also need a much larger dirhashreclaimage.
- * XXX: this percentage may need to be adjusted.
- */
- int memwanted = ufs_dirhashmem / 10;
+ int memfreed, memwanted;
ufs_dirhashlowmemcount++;
+ memfreed = 0;
+ memwanted = ufs_dirhashmem * ufs_dirhashreclaimpercent / 100;
DIRHASHLIST_LOCK();
- /*
- * Delete dirhashes not used for more than ufs_dirhashreclaimage
- * seconds. If we can't get a lock on the dirhash, it will be skipped.
+
+ /*
+ * Reclaim up to memwanted from the oldest dirhashes. This will allow
+ * us to make some progress when the system is running out of memory
+ * without compromising the dinamicity of maximum age. If the situation
+ * does not improve lowmem will be eventually retriggered and free some
+ * other entry in the cache. The entries on the head of the list should
+ * be the oldest. If during list traversal we can't get a lock on the
+ * dirhash, it will be skipped.
*/
TAILQ_FOREACH_SAFE(dh, &ufsdirhash_list, dh_list, dh_temp) {
- if (!sx_try_xlock(&dh->dh_lock))
- continue;
- if (time_second - dh->dh_lastused > ufs_dirhashreclaimage)
+ if (sx_try_xlock(&dh->dh_lock))
memfreed += ufsdirhash_destroy(dh);
- /* Unlock if we didn't delete the dirhash */
- else
- ufsdirhash_release(dh);
+ if (memfreed >= memwanted)
+ break;
}
-
- /*
- * If not enough memory was freed, keep deleting hashes from the head
- * of the dirhash list. The ones closest to the head should be the
- * oldest.
- */
- if (memfreed < memwanted) {
- TAILQ_FOREACH_SAFE(dh, &ufsdirhash_list, dh_list, dh_temp) {
- if (!sx_try_xlock(&dh->dh_lock))
- continue;
- memfreed += ufsdirhash_destroy(dh);
- if (memfreed >= memwanted)
- break;
- }
- }
DIRHASHLIST_UNLOCK();
}
+static int
+ufsdirhash_set_reclaimpercent(SYSCTL_HANDLER_ARGS)
+{
+ int error, v;
+ v = ufs_dirhashreclaimpercent;
+ error = sysctl_handle_int(oidp, &v, v, req);
+ if (error)
+ return (error);
+ if (req->newptr == NULL)
+ return (error);
+ if (v == ufs_dirhashreclaimpercent)
+ return (0);
+
+ /* Refuse invalid percentages */
+ if (v < 0 || v > 100)
+ return (EINVAL);
+ ufs_dirhashreclaimpercent = v;
+ return (0);
+}
+
void
ufsdirhash_init()
{
Modified: trunk/sys/ufs/ufs/ufs_extattr.c
===================================================================
--- trunk/sys/ufs/ufs/ufs_extattr.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufs_extattr.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ufs/ufs_extattr.c 302233 2016-06-27 21:44:27Z bdrewery $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ufs/ufs_extattr.c 298463 2016-04-22 08:09:27Z ngie $");
#include "opt_ufs.h"
Modified: trunk/sys/ufs/ufs/ufs_extern.h
===================================================================
--- trunk/sys/ufs/ufs/ufs_extern.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufs_extern.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -28,7 +28,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_extern.h 8.10 (Berkeley) 5/14/95
- * $FreeBSD: stable/10/sys/ufs/ufs/ufs_extern.h 262779 2014-03-05 04:23:19Z pfg $
+ * $FreeBSD: stable/11/sys/ufs/ufs/ufs_extern.h 331722 2018-03-29 02:50:57Z eadler $
*/
#ifndef _UFS_UFS_EXTERN_H_
Modified: trunk/sys/ufs/ufs/ufs_gjournal.c
===================================================================
--- trunk/sys/ufs/ufs/ufs_gjournal.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufs_gjournal.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -26,12 +26,13 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ufs/ufs_gjournal.c 306630 2016-10-03 10:15:16Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ufs/ufs_gjournal.c 306627 2016-10-03 09:37:56Z kib $");
#include "opt_ufs.h"
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/buf.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
#include <sys/lock.h>
@@ -65,15 +66,15 @@
ino_t ino;
ip = VTOI(vp);
- ump = ip->i_ump;
- fs = ip->i_fs;
- devvp = ip->i_devvp;
+ ump = VFSTOUFS(vp->v_mount);
+ fs = ump->um_fs;
+ devvp = ump->um_devvp;
ino = ip->i_number;
cg = ino_to_cg(fs, ino);
if (devvp->v_type == VREG) {
/* devvp is a snapshot */
- dev = VTOI(devvp)->i_devvp->v_rdev;
+ dev = VFSTOUFS(devvp->v_mount)->um_devvp->v_rdev;
cgbno = fragstoblks(fs, cgtod(fs, cg));
} else if (devvp->v_type == VCHR) {
/* devvp is a normal disk device */
Modified: trunk/sys/ufs/ufs/ufs_inode.c
===================================================================
--- trunk/sys/ufs/ufs/ufs_inode.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufs_inode.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ufs/ufs_inode.c 234612 2012-04-23 17:54:49Z trasz $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ufs/ufs_inode.c 331722 2018-03-29 02:50:57Z eadler $");
#include "opt_quota.h"
#include "opt_ufs.h"
@@ -126,7 +126,7 @@
}
}
isize = ip->i_size;
- if (ip->i_ump->um_fstype == UFS2)
+ if (I_IS_UFS2(ip))
isize += ip->i_din2->di_extsize;
if (ip->i_effnlink <= 0 && isize && !UFS_RDONLY(ip))
error = UFS_TRUNCATE(vp, (off_t)0, IO_EXT | IO_NORMAL, NOCRED);
@@ -215,7 +215,6 @@
{
struct vnode *vp = ap->a_vp;
struct inode *ip = VTOI(vp);
- struct ufsmount *ump = ip->i_ump;
ufs_prepare_reclaim(vp);
@@ -234,6 +233,6 @@
VI_LOCK(vp);
vp->v_data = 0;
VI_UNLOCK(vp);
- UFS_IFREE(ump, ip);
+ UFS_IFREE(ITOUMP(ip), ip);
return (0);
}
Modified: trunk/sys/ufs/ufs/ufs_lookup.c
===================================================================
--- trunk/sys/ufs/ufs/ufs_lookup.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufs_lookup.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ufs/ufs_lookup.c 306180 2016-09-22 10:51:47Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ufs/ufs_lookup.c 356965 2020-01-22 01:31:02Z mckusick $");
#include "opt_ufs.h"
#include "opt_quota.h"
@@ -565,7 +565,7 @@
* in the cache as to where the entry was found.
*/
if ((flags & ISLASTCN) && nameiop == LOOKUP)
- dp->i_diroff = i_offset &~ (DIRBLKSIZ - 1);
+ dp->i_diroff = rounddown2(i_offset, DIRBLKSIZ);
/*
* If deleting, and at end of pathname, return
@@ -824,14 +824,21 @@
struct componentname *cnp;
struct direct *newdirp;
{
+ u_int namelen;
-#ifdef INVARIANTS
- if ((cnp->cn_flags & SAVENAME) == 0)
- panic("ufs_makedirentry: missing name");
-#endif
+ namelen = (unsigned)cnp->cn_namelen;
+ KASSERT((cnp->cn_flags & SAVENAME) != 0,
+ ("ufs_makedirentry: missing name"));
+ KASSERT(namelen <= MAXNAMLEN,
+ ("ufs_makedirentry: name too long"));
newdirp->d_ino = ip->i_number;
- newdirp->d_namlen = cnp->cn_namelen;
- bcopy(cnp->cn_nameptr, newdirp->d_name, (unsigned)cnp->cn_namelen + 1);
+ newdirp->d_namlen = namelen;
+
+ /* Zero out after-name padding */
+ *(u_int32_t *)(&newdirp->d_name[namelen & ~(DIR_ROUNDUP - 1)]) = 0;
+
+ bcopy(cnp->cn_nameptr, newdirp->d_name, namelen);
+
if (ITOV(ip)->v_mount->mnt_maxsymlinklen > 0)
newdirp->d_type = IFTODT(ip->i_mode);
else {
@@ -1092,7 +1099,7 @@
if (dp->i_dirhash != NULL)
ufsdirhash_checkblock(dp, dirbuf -
(dp->i_offset & (DIRBLKSIZ - 1)),
- dp->i_offset & ~(DIRBLKSIZ - 1));
+ rounddown2(dp->i_offset, DIRBLKSIZ));
#endif
if (DOINGSOFTDEP(dvp)) {
@@ -1125,8 +1132,9 @@
error = UFS_TRUNCATE(dvp, (off_t)dp->i_endoff,
IO_NORMAL | (DOINGASYNC(dvp) ? 0 : IO_SYNC), cr);
if (error != 0)
- vn_printf(dvp, "ufs_direnter: failed to truncate "
- "err %d", error);
+ vn_printf(dvp,
+ "ufs_direnter: failed to truncate, error %d\n",
+ error);
#ifdef UFS_DIRHASH
if (error == 0 && dp->i_dirhash != NULL)
ufsdirhash_dirtrunc(dp, dp->i_endoff);
@@ -1160,6 +1168,7 @@
struct inode *dp;
struct direct *ep, *rep;
struct buf *bp;
+ off_t offset;
int error;
dp = VTOI(dvp);
@@ -1169,6 +1178,7 @@
*/
if (ip) {
ip->i_effnlink--;
+ ip->i_flag |= IN_CHANGE;
if (DOINGSOFTDEP(dvp)) {
softdep_setup_unlink(dp, ip);
} else {
@@ -1177,22 +1187,32 @@
ip->i_flag |= IN_CHANGE;
}
}
+ if (flags & DOWHITEOUT)
+ offset = dp->i_offset;
+ else
+ offset = dp->i_offset - dp->i_count;
+ if ((error = UFS_BLKATOFF(dvp, offset, (char **)&ep, &bp)) != 0) {
+ if (ip) {
+ ip->i_effnlink++;
+ ip->i_flag |= IN_CHANGE;
+ if (DOINGSOFTDEP(dvp)) {
+ softdep_change_linkcnt(ip);
+ } else {
+ ip->i_nlink++;
+ DIP_SET(ip, i_nlink, ip->i_nlink);
+ ip->i_flag |= IN_CHANGE;
+ }
+ }
+ return (error);
+ }
if (flags & DOWHITEOUT) {
/*
* Whiteout entry: set d_ino to WINO.
*/
- if ((error =
- UFS_BLKATOFF(dvp, (off_t)dp->i_offset, (char **)&ep, &bp)) != 0)
- return (error);
ep->d_ino = WINO;
ep->d_type = DT_WHT;
goto out;
}
-
- if ((error = UFS_BLKATOFF(dvp,
- (off_t)(dp->i_offset - dp->i_count), (char **)&ep, &bp)) != 0)
- return (error);
-
/* Set 'rep' to the entry being removed. */
if (dp->i_count == 0)
rep = ep;
@@ -1209,22 +1229,27 @@
if (ip && rep->d_ino != ip->i_number)
panic("ufs_dirremove: ip %ju does not match dirent ino %ju\n",
(uintmax_t)ip->i_number, (uintmax_t)rep->d_ino);
- if (dp->i_count == 0) {
+ /*
+ * Zero out the file directory entry metadata to reduce disk
+ * scavenging disclosure.
+ */
+ bzero(&rep->d_name[0], rep->d_namlen);
+ rep->d_namlen = 0;
+ rep->d_type = 0;
+ rep->d_ino = 0;
+
+ if (dp->i_count != 0) {
/*
- * First entry in block: set d_ino to zero.
- */
- ep->d_ino = 0;
- } else {
- /*
* Collapse new free space into previous entry.
*/
ep->d_reclen += rep->d_reclen;
+ rep->d_reclen = 0;
}
#ifdef UFS_DIRHASH
if (dp->i_dirhash != NULL)
ufsdirhash_checkblock(dp, (char *)ep -
((dp->i_offset - dp->i_count) & (DIRBLKSIZ - 1)),
- dp->i_offset & ~(DIRBLKSIZ - 1));
+ rounddown2(dp->i_offset, DIRBLKSIZ));
#endif
out:
error = 0;
@@ -1277,6 +1302,7 @@
* necessary.
*/
oip->i_effnlink--;
+ oip->i_flag |= IN_CHANGE;
if (DOINGSOFTDEP(vdp)) {
softdep_setup_unlink(dp, oip);
} else {
@@ -1286,13 +1312,23 @@
}
error = UFS_BLKATOFF(vdp, (off_t)dp->i_offset, (char **)&ep, &bp);
- if (error)
- return (error);
- if (ep->d_namlen == 2 && ep->d_name[1] == '.' && ep->d_name[0] == '.' &&
- ep->d_ino != oip->i_number) {
+ if (error == 0 && ep->d_namlen == 2 && ep->d_name[1] == '.' &&
+ ep->d_name[0] == '.' && ep->d_ino != oip->i_number) {
brelse(bp);
- return (EIDRM);
+ error = EIDRM;
}
+ if (error) {
+ oip->i_effnlink++;
+ oip->i_flag |= IN_CHANGE;
+ if (DOINGSOFTDEP(vdp)) {
+ softdep_change_linkcnt(oip);
+ } else {
+ oip->i_nlink++;
+ DIP_SET(oip, i_nlink, oip->i_nlink);
+ oip->i_flag |= IN_CHANGE;
+ }
+ return (error);
+ }
ep->d_ino = newinum;
if (!OFSFMT(vdp))
ep->d_type = newtype;
@@ -1469,7 +1505,8 @@
}
}
KASSERT(dd_ino == VTOI(vp1)->i_number,
- ("directory %d reparented\n", VTOI(vp1)->i_number));
+ ("directory %ju reparented\n",
+ (uintmax_t)VTOI(vp1)->i_number));
if (vp != tvp)
vput(vp);
vp = vp1;
Modified: trunk/sys/ufs/ufs/ufs_quota.c
===================================================================
--- trunk/sys/ufs/ufs/ufs_quota.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufs_quota.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ufs/ufs_quota.c 306178 2016-09-22 10:47:56Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ufs/ufs_quota.c 338943 2018-09-26 14:26:29Z kib $");
#include "opt_ffs.h"
@@ -233,13 +233,13 @@
/* Reset timer when crossing soft limit */
if (dq->dq_curblocks + change >= dq->dq_bsoftlimit &&
dq->dq_curblocks < dq->dq_bsoftlimit)
- dq->dq_btime = time_second + ip->i_ump->um_btime[i];
+ dq->dq_btime = time_second + ITOUMP(ip)->um_btime[i];
dq->dq_curblocks += change;
dq->dq_flags |= DQ_MOD;
DQI_UNLOCK(dq);
if (warn)
uprintf("\n%s: warning, %s disk quota exceeded\n",
- ITOV(ip)->v_mount->mnt_stat.f_mntonname,
+ ITOVFS(ip)->mnt_stat.f_mntonname,
quotatypes[i]);
}
return (0);
@@ -265,7 +265,7 @@
dq->dq_flags |= DQ_BLKS;
DQI_UNLOCK(dq);
uprintf("\n%s: write failed, %s disk limit reached\n",
- ITOV(ip)->v_mount->mnt_stat.f_mntonname,
+ ITOVFS(ip)->mnt_stat.f_mntonname,
quotatypes[type]);
return (EDQUOT);
}
@@ -278,7 +278,7 @@
*/
if (ncurblocks >= dq->dq_bsoftlimit && dq->dq_bsoftlimit) {
if (dq->dq_curblocks < dq->dq_bsoftlimit) {
- dq->dq_btime = time_second + ip->i_ump->um_btime[type];
+ dq->dq_btime = time_second + ITOUMP(ip)->um_btime[type];
if (ip->i_uid == cred->cr_uid)
*warn = 1;
return (0);
@@ -290,7 +290,7 @@
DQI_UNLOCK(dq);
uprintf("\n%s: write failed, %s "
"disk quota exceeded for too long\n",
- ITOV(ip)->v_mount->mnt_stat.f_mntonname,
+ ITOVFS(ip)->mnt_stat.f_mntonname,
quotatypes[type]);
return (EDQUOT);
}
@@ -371,13 +371,13 @@
/* Reset timer when crossing soft limit */
if (dq->dq_curinodes + change >= dq->dq_isoftlimit &&
dq->dq_curinodes < dq->dq_isoftlimit)
- dq->dq_itime = time_second + ip->i_ump->um_itime[i];
+ dq->dq_itime = time_second + ITOUMP(ip)->um_itime[i];
dq->dq_curinodes += change;
dq->dq_flags |= DQ_MOD;
DQI_UNLOCK(dq);
if (warn)
uprintf("\n%s: warning, %s inode quota exceeded\n",
- ITOV(ip)->v_mount->mnt_stat.f_mntonname,
+ ITOVFS(ip)->mnt_stat.f_mntonname,
quotatypes[i]);
}
return (0);
@@ -402,7 +402,7 @@
dq->dq_flags |= DQ_INODS;
DQI_UNLOCK(dq);
uprintf("\n%s: write failed, %s inode limit reached\n",
- ITOV(ip)->v_mount->mnt_stat.f_mntonname,
+ ITOVFS(ip)->mnt_stat.f_mntonname,
quotatypes[type]);
return (EDQUOT);
}
@@ -415,7 +415,7 @@
*/
if (ncurinodes >= dq->dq_isoftlimit && dq->dq_isoftlimit) {
if (dq->dq_curinodes < dq->dq_isoftlimit) {
- dq->dq_itime = time_second + ip->i_ump->um_itime[type];
+ dq->dq_itime = time_second + ITOUMP(ip)->um_itime[type];
if (ip->i_uid == cred->cr_uid)
*warn = 1;
return (0);
@@ -427,7 +427,7 @@
DQI_UNLOCK(dq);
uprintf("\n%s: write failed, %s "
"inode quota exceeded for too long\n",
- ITOV(ip)->v_mount->mnt_stat.f_mntonname,
+ ITOVFS(ip)->mnt_stat.f_mntonname,
quotatypes[type]);
return (EDQUOT);
}
@@ -446,10 +446,13 @@
static void
chkdquot(struct inode *ip)
{
- struct ufsmount *ump = ip->i_ump;
- struct vnode *vp = ITOV(ip);
+ struct ufsmount *ump;
+ struct vnode *vp;
int i;
+ ump = ITOUMP(ip);
+ vp = ITOV(ip);
+
/*
* Disk quotas must be turned off for system files. Currently
* these are snapshots and quota files.
@@ -470,7 +473,7 @@
continue;
if (ip->i_dquot[i] == NODQUOT) {
UFS_UNLOCK(ump);
- vprint("chkdquot: missing dquot", ITOV(ip));
+ vn_printf(ITOV(ip), "chkdquot: missing dquot ");
panic("chkdquot: missing dquot");
}
}
@@ -708,6 +711,34 @@
return (error);
}
+static int
+quotaoff_inchange1(struct thread *td, struct mount *mp, int type)
+{
+ int error;
+ bool need_resume;
+
+ /*
+ * mp is already suspended on unmount. If not, suspend it, to
+ * avoid the situation where quotaoff operation eventually
+ * failing due to SU structures still keeping references on
+ * dquots, but vnode's references are already clean. This
+ * would cause quota accounting leak and asserts otherwise.
+ * Note that the thread has already called vn_start_write().
+ */
+ if (mp->mnt_susp_owner == td) {
+ need_resume = false;
+ } else {
+ error = vfs_write_suspend_umnt(mp);
+ if (error != 0)
+ return (error);
+ need_resume = true;
+ }
+ error = quotaoff1(td, mp, type);
+ if (need_resume)
+ vfs_write_resume(mp, VR_START_WRITE);
+ return (error);
+}
+
/*
* Turns off quotas, assumes that ump->um_qflags are already checked
* and QTF_CLOSING is set to indicate operation in progress. Fixes
@@ -717,10 +748,9 @@
quotaoff_inchange(struct thread *td, struct mount *mp, int type)
{
struct ufsmount *ump;
- int i;
- int error;
+ int error, i;
- error = quotaoff1(td, mp, type);
+ error = quotaoff_inchange1(td, mp, type);
ump = VFSTOUFS(mp);
UFS_LOCK(ump);
@@ -1040,11 +1070,9 @@
* Check if the mount point has any quotas.
* If not, simply return.
*/
- UFS_LOCK(ump);
for (i = 0; i < MAXQUOTAS; i++)
if (ump->um_quotas[i] != NULLVP)
break;
- UFS_UNLOCK(ump);
if (i == MAXQUOTAS)
return (0);
/*
@@ -1089,11 +1117,9 @@
* Check if the mount point has any quotas.
* If not, simply return.
*/
- UFS_LOCK(ump);
for (i = 0; i < MAXQUOTAS; i++)
if (ump->um_quotas[i] != NULLVP)
break;
- UFS_UNLOCK(ump);
if (i == MAXQUOTAS)
return (0);
/*
Modified: trunk/sys/ufs/ufs/ufs_vfsops.c
===================================================================
--- trunk/sys/ufs/ufs/ufs_vfsops.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufs_vfsops.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ufs/ufs_vfsops.c 278150 2015-02-03 11:54:33Z kib $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ufs/ufs_vfsops.c 338943 2018-09-26 14:26:29Z kib $");
#include "opt_quota.h"
#include "opt_ufs.h"
@@ -93,7 +93,8 @@
void *arg;
{
#ifndef QUOTA
- if ((cmds >> SUBCMDSHIFT) == Q_QUOTAON)
+ if ((cmds >> SUBCMDSHIFT) == Q_QUOTAON ||
+ (cmds >> SUBCMDSHIFT) == Q_QUOTAOFF)
vfs_unbusy(mp);
return (EOPNOTSUPP);
@@ -116,13 +117,13 @@
break;
default:
- if (cmd == Q_QUOTAON)
+ if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF)
vfs_unbusy(mp);
return (EINVAL);
}
}
if ((u_int)type >= MAXQUOTAS) {
- if (cmd == Q_QUOTAON)
+ if (cmd == Q_QUOTAON || cmd == Q_QUOTAOFF)
vfs_unbusy(mp);
return (EINVAL);
}
@@ -133,7 +134,11 @@
break;
case Q_QUOTAOFF:
+ vfs_ref(mp);
+ vfs_unbusy(mp);
+ vn_start_write(NULL, &mp, V_WAIT | V_MNTREF);
error = quotaoff(td, mp, type);
+ vn_finished_write(mp);
break;
case Q_SETQUOTA32:
Modified: trunk/sys/ufs/ufs/ufs_vnops.c
===================================================================
--- trunk/sys/ufs/ufs/ufs_vnops.c 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufs_vnops.c 2020-02-08 19:39:08 UTC (rev 12316)
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: stable/10/sys/ufs/ufs/ufs_vnops.c 332750 2018-04-19 02:50:15Z pfg $");
+__FBSDID("$FreeBSD: stable/11/sys/ufs/ufs/ufs_vnops.c 346032 2019-04-08 15:52:13Z sjg $");
#include "opt_quota.h"
#include "opt_suiddir.h"
@@ -123,7 +123,6 @@
static vop_whiteout_t ufs_whiteout;
static vop_close_t ufsfifo_close;
static vop_kqfilter_t ufsfifo_kqfilter;
-static vop_pathconf_t ufsfifo_pathconf;
SYSCTL_NODE(_vfs, OID_AUTO, ufs, CTLFLAG_RD, 0, "UFS filesystem");
@@ -325,9 +324,6 @@
struct inode *ip = VTOI(vp);
accmode_t accmode = ap->a_accmode;
int error;
-#ifdef QUOTA
- int relocked;
-#endif
#ifdef UFS_ACL
struct acl *acl;
acl_type_t type;
@@ -350,32 +346,14 @@
* Inode is accounted in the quotas only if struct
* dquot is attached to it. VOP_ACCESS() is called
* from vn_open_cred() and provides a convenient
- * point to call getinoquota().
+ * point to call getinoquota(). The lock mode is
+ * exclusive when the file is opening for write.
*/
- if (VOP_ISLOCKED(vp) != LK_EXCLUSIVE) {
-
- /*
- * Upgrade vnode lock, since getinoquota()
- * requires exclusive lock to modify inode.
- */
- relocked = 1;
- vhold(vp);
- vn_lock(vp, LK_UPGRADE | LK_RETRY);
- VI_LOCK(vp);
- if (vp->v_iflag & VI_DOOMED) {
- vdropl(vp);
- error = ENOENT;
- goto relock;
- }
- vdropl(vp);
- } else
- relocked = 0;
- error = getinoquota(ip);
-relock:
- if (relocked)
- vn_lock(vp, LK_DOWNGRADE | LK_RETRY);
- if (error != 0)
- return (error);
+ if (VOP_ISLOCKED(vp) == LK_EXCLUSIVE) {
+ error = getinoquota(ip);
+ if (error != 0)
+ return (error);
+ }
#endif
break;
default:
@@ -385,8 +363,7 @@
/*
* If immutable bit set, nobody gets to write it. "& ~VADMIN_PERMS"
- * is here, because without it, * it would be impossible for the owner
- * to remove the IMMUTABLE flag.
+ * permits the owner of the file to remove the IMMUTABLE flag.
*/
if ((accmode & (VMODIFY_PERMS & ~VADMIN_PERMS)) &&
(ip->i_flags & (IMMUTABLE | SF_SNAPSHOT)))
@@ -458,7 +435,7 @@
VI_LOCK(vp);
ufs_itimes_locked(vp);
- if (ip->i_ump->um_fstype == UFS1) {
+ if (I_IS_UFS1(ip)) {
vap->va_atime.tv_sec = ip->i_din1->di_atime;
vap->va_atime.tv_nsec = ip->i_din1->di_atimensec;
} else {
@@ -469,13 +446,13 @@
/*
* Copy from inode table
*/
- vap->va_fsid = dev2udev(ip->i_dev);
+ vap->va_fsid = dev2udev(ITOUMP(ip)->um_dev);
vap->va_fileid = ip->i_number;
vap->va_mode = ip->i_mode & ~IFMT;
vap->va_nlink = ip->i_effnlink;
vap->va_uid = ip->i_uid;
vap->va_gid = ip->i_gid;
- if (ip->i_ump->um_fstype == UFS1) {
+ if (I_IS_UFS1(ip)) {
vap->va_rdev = ip->i_din1->di_rdev;
vap->va_size = ip->i_din1->di_size;
vap->va_mtime.tv_sec = ip->i_din1->di_mtime;
@@ -653,8 +630,7 @@
DIP_SET(ip, i_mtime, vap->va_mtime.tv_sec);
DIP_SET(ip, i_mtimensec, vap->va_mtime.tv_nsec);
}
- if (vap->va_birthtime.tv_sec != VNOVAL &&
- ip->i_ump->um_fstype == UFS2) {
+ if (vap->va_birthtime.tv_sec != VNOVAL && I_IS_UFS2(ip)) {
ip->i_din2->di_birthtime = vap->va_birthtime.tv_sec;
ip->i_din2->di_birthnsec = vap->va_birthtime.tv_nsec;
}
@@ -951,8 +927,8 @@
struct inode *dip;
dip = VTOI(dvp);
- uprintf("%s: Bad link count %d on parent inode %d in file system %s\n",
- funcname, dip->i_effnlink, dip->i_number,
+ uprintf("%s: Bad link count %d on parent inode %jd in file system %s\n",
+ funcname, dip->i_effnlink, (intmax_t)dip->i_number,
dvp->v_mount->mnt_stat.f_mntonname);
}
@@ -1362,7 +1338,7 @@
* expunge the original entry's existence.
*/
if (tip == NULL) {
- if (tdp->i_dev != fip->i_dev)
+ if (ITODEV(tdp) != ITODEV(fip))
panic("ufs_rename: EXDEV");
if (doingdirectory && newparent) {
/*
@@ -1386,7 +1362,7 @@
tdp->i_endoff < tdp->i_size)
endoff = tdp->i_endoff;
} else {
- if (tip->i_dev != tdp->i_dev || tip->i_dev != fip->i_dev)
+ if (ITODEV(tip) != ITODEV(tdp) || ITODEV(tip) != ITODEV(fip))
panic("ufs_rename: EXDEV");
/*
* Short circuit rename(foo, foo).
@@ -1547,8 +1523,9 @@
error = UFS_TRUNCATE(tdvp, endoff, IO_NORMAL | IO_SYNC,
tcnp->cn_cred);
if (error != 0)
- vn_printf(tdvp, "ufs_rename: failed to truncate "
- "err %d", error);
+ vn_printf(tdvp,
+ "ufs_rename: failed to truncate, error %d\n",
+ error);
#ifdef UFS_DIRHASH
else if (tdp->i_dirhash != NULL)
ufsdirhash_dirtrunc(tdp, endoff);
@@ -2240,7 +2217,7 @@
dstdp.d_fileno = dp->d_ino;
dstdp.d_reclen = GENERIC_DIRSIZ(&dstdp);
bcopy(dp->d_name, dstdp.d_name, dstdp.d_namlen);
- dstdp.d_name[dstdp.d_namlen] = '\0';
+ dirent_terminate(&dstdp);
if (dstdp.d_reclen > uio->uio_resid) {
if (uio->uio_resid == startresid)
error = EINVAL;
@@ -2323,12 +2300,9 @@
{
struct buf *bp = ap->a_bp;
struct vnode *vp = ap->a_vp;
- struct bufobj *bo;
- struct inode *ip;
ufs2_daddr_t blkno;
int error;
- ip = VTOI(vp);
if (bp->b_blkno == bp->b_lblkno) {
error = ufs_bmaparray(vp, bp->b_lblkno, &blkno, bp, NULL, NULL);
bp->b_blkno = blkno;
@@ -2346,8 +2320,7 @@
return (0);
}
bp->b_iooffset = dbtob(bp->b_blkno);
- bo = ip->i_umbufobj;
- BO_STRATEGY(bo, bp);
+ BO_STRATEGY(VFSTOUFS(vp->v_mount)->um_bo, bp);
return (0);
}
@@ -2364,7 +2337,7 @@
struct inode *ip = VTOI(vp);
printf("\tino %lu, on dev %s", (u_long)ip->i_number,
- devtoname(ip->i_dev));
+ devtoname(ITODEV(ip)));
if (vp->v_type == VFIFO)
fifo_printinfo(vp);
printf("\n");
@@ -2414,30 +2387,6 @@
}
/*
- * Return POSIX pathconf information applicable to fifos.
- */
-static int
-ufsfifo_pathconf(ap)
- struct vop_pathconf_args /* {
- struct vnode *a_vp;
- int a_name;
- int *a_retval;
- } */ *ap;
-{
-
- switch (ap->a_name) {
- case _PC_ACL_EXTENDED:
- case _PC_ACL_NFS4:
- case _PC_ACL_PATH_MAX:
- case _PC_MAC_PRESENT:
- return (ufs_pathconf(ap));
- default:
- return (fifo_specops.vop_pathconf(ap));
- }
- /* NOTREACHED */
-}
-
-/*
* Return POSIX pathconf information applicable to ufs filesystems.
*/
static int
@@ -2452,17 +2401,14 @@
error = 0;
switch (ap->a_name) {
- case _PC_LINK_MAX:
- *ap->a_retval = LINK_MAX;
- break;
case _PC_NAME_MAX:
*ap->a_retval = NAME_MAX;
break;
- case _PC_PATH_MAX:
- *ap->a_retval = PATH_MAX;
- break;
case _PC_PIPE_BUF:
- *ap->a_retval = PIPE_BUF;
+ if (ap->a_vp->v_type == VDIR || ap->a_vp->v_type == VFIFO)
+ *ap->a_retval = PIPE_BUF;
+ else
+ error = EINVAL;
break;
case _PC_CHOWN_RESTRICTED:
*ap->a_retval = 1;
@@ -2470,28 +2416,20 @@
case _PC_NO_TRUNC:
*ap->a_retval = 1;
break;
+#ifdef UFS_ACL
case _PC_ACL_EXTENDED:
-#ifdef UFS_ACL
if (ap->a_vp->v_mount->mnt_flag & MNT_ACLS)
*ap->a_retval = 1;
else
*ap->a_retval = 0;
-#else
- *ap->a_retval = 0;
-#endif
break;
-
case _PC_ACL_NFS4:
-#ifdef UFS_ACL
if (ap->a_vp->v_mount->mnt_flag & MNT_NFS4ACLS)
*ap->a_retval = 1;
else
*ap->a_retval = 0;
-#else
- *ap->a_retval = 0;
+ break;
#endif
- break;
-
case _PC_ACL_PATH_MAX:
#ifdef UFS_ACL
if (ap->a_vp->v_mount->mnt_flag & (MNT_ACLS | MNT_NFS4ACLS))
@@ -2502,24 +2440,17 @@
*ap->a_retval = 3;
#endif
break;
+#ifdef MAC
case _PC_MAC_PRESENT:
-#ifdef MAC
if (ap->a_vp->v_mount->mnt_flag & MNT_MULTILABEL)
*ap->a_retval = 1;
else
*ap->a_retval = 0;
-#else
- *ap->a_retval = 0;
+ break;
#endif
- break;
case _PC_MIN_HOLE_SIZE:
*ap->a_retval = ap->a_vp->v_mount->mnt_stat.f_iosize;
break;
- case _PC_ASYNC_IO:
- /* _PC_ASYNC_IO should have been handled by upper layers. */
- KASSERT(0, ("_PC_ASYNC_IO should not get here"));
- error = EINVAL;
- break;
case _PC_PRIO_IO:
*ap->a_retval = 0;
break;
@@ -2549,7 +2480,7 @@
break;
default:
- error = EINVAL;
+ error = vop_stdpathconf(ap);
break;
}
return (error);
@@ -2571,6 +2502,11 @@
vp = *vpp;
ip = VTOI(vp);
vp->v_type = IFTOVT(ip->i_mode);
+ /*
+ * Only unallocated inodes should be of type VNON.
+ */
+ if (ip->i_mode != 0 && vp->v_type == VNON)
+ return (EINVAL);
if (vp->v_type == VFIFO)
vp->v_op = fifoops;
ASSERT_VOP_LOCKED(vp, "ufs_vinit");
@@ -2822,7 +2758,7 @@
.vop_inactive = ufs_inactive,
.vop_kqfilter = ufsfifo_kqfilter,
.vop_markatime = ufs_markatime,
- .vop_pathconf = ufsfifo_pathconf,
+ .vop_pathconf = ufs_pathconf,
.vop_print = ufs_print,
.vop_read = VOP_PANIC,
.vop_reclaim = ufs_reclaim,
Modified: trunk/sys/ufs/ufs/ufsmount.h
===================================================================
--- trunk/sys/ufs/ufs/ufsmount.h 2020-02-08 19:38:54 UTC (rev 12315)
+++ trunk/sys/ufs/ufs/ufsmount.h 2020-02-08 19:39:08 UTC (rev 12316)
@@ -28,14 +28,12 @@
* SUCH DAMAGE.
*
* @(#)ufsmount.h 8.6 (Berkeley) 3/30/95
- * $FreeBSD: stable/10/sys/ufs/ufs/ufsmount.h 297787 2016-04-10 16:32:21Z kib $
+ * $FreeBSD: stable/11/sys/ufs/ufs/ufsmount.h 331722 2018-03-29 02:50:57Z eadler $
*/
#ifndef _UFS_UFS_UFSMOUNT_H_
#define _UFS_UFS_UFSMOUNT_H_
-#include <sys/buf.h> /* XXX For struct workhead. */
-
/*
* Arguments to mount UFS-based filesystems
*/
@@ -111,8 +109,8 @@
#define UFS_VALLOC(aa, bb, cc, dd) VFSTOUFS((aa)->v_mount)->um_valloc(aa, bb, cc, dd)
#define UFS_VFREE(aa, bb, cc) VFSTOUFS((aa)->v_mount)->um_vfree(aa, bb, cc)
#define UFS_IFREE(aa, bb) ((aa)->um_ifree(aa, bb))
-#define UFS_RDONLY(aa) ((aa)->i_ump->um_rdonly(aa))
-#define UFS_SNAPGONE(aa) ((aa)->i_ump->um_snapgone(aa))
+#define UFS_RDONLY(aa) (ITOUMP(aa)->um_rdonly(aa))
+#define UFS_SNAPGONE(aa) (ITOUMP(aa)->um_snapgone(aa))
#define UFS_LOCK(aa) mtx_lock(&(aa)->um_lock)
#define UFS_UNLOCK(aa) mtx_unlock(&(aa)->um_lock)
More information about the Midnightbsd-cvs
mailing list