svn commit: r362292 - in head/sys/ufs: ffs ufs

Chuck Silvers chs at FreeBSD.org
Wed Jun 17 23:39:54 UTC 2020


Author: chs
Date: Wed Jun 17 23:39:52 2020
New Revision: 362292
URL: https://svnweb.freebsd.org/changeset/base/362292

Log:
  Move all of the functions in ffs_subr.c that are only used by the ufs kernel
  module from that file into ffs_vfsops.c.  This fixes the build for kernel
  configs that don't include FFS.
  
  PR:		247256
  Submitted by:	glebius
  Reviewed by:	mckusick (earlier version)
  Sponsored by:	Netflix
  Differential Revision:	https://reviews.freebsd.org/D25285

Modified:
  head/sys/ufs/ffs/ffs_extern.h
  head/sys/ufs/ffs/ffs_subr.c
  head/sys/ufs/ffs/ffs_vfsops.c
  head/sys/ufs/ufs/ufs_vnops.c

Modified: head/sys/ufs/ffs/ffs_extern.h
==============================================================================
--- head/sys/ufs/ffs/ffs_extern.h	Wed Jun 17 21:51:32 2020	(r362291)
+++ head/sys/ufs/ffs/ffs_extern.h	Wed Jun 17 23:39:52 2020	(r362292)
@@ -61,7 +61,6 @@ int	ffs_balloc_ufs1(struct vnode *a_vp, off_t a_starto
             struct ucred *a_cred, int a_flags, struct buf **a_bpp);
 int	ffs_balloc_ufs2(struct vnode *a_vp, off_t a_startoffset, int a_size,
             struct ucred *a_cred, int a_flags, struct buf **a_bpp);
-int	ffs_blkatoff(struct vnode *, off_t, char **, struct buf **);
 void	ffs_blkfree(struct ufsmount *, struct fs *, struct vnode *,
 	    ufs2_daddr_t, long, ino_t, enum vtype, struct workhead *, u_long);
 ufs2_daddr_t ffs_blkpref_ufs1(struct inode *, ufs_lbn_t, int, ufs1_daddr_t *);
@@ -69,7 +68,6 @@ ufs2_daddr_t ffs_blkpref_ufs2(struct inode *, ufs_lbn_
 void	ffs_blkrelease_finish(struct ufsmount *, u_long);
 u_long	ffs_blkrelease_start(struct ufsmount *, struct vnode *, ino_t);
 uint32_t ffs_calc_sbhash(struct fs *);
-int	ffs_check_blkno(struct mount *, ino_t, ufs2_daddr_t, int);
 int	ffs_checkfreefile(struct fs *, struct vnode *, ino_t);
 void	ffs_clrblock(struct fs *, u_char *, ufs1_daddr_t);
 void	ffs_clusteracct(struct fs *, struct cg *, ufs1_daddr_t, int);
@@ -84,7 +82,6 @@ int	ffs_getcg(struct fs *, struct vnode *, u_int, int,
 	    struct cg **);
 int	ffs_isblock(struct fs *, u_char *, ufs1_daddr_t);
 int	ffs_isfreeblock(struct fs *, u_char *, ufs1_daddr_t);
-int	ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t);
 void	ffs_oldfscompat_write(struct fs *, struct ufsmount *);
 int	ffs_own_mount(const struct mount *mp);
 int	ffs_reallocblks(struct vop_reallocblks_args *);

Modified: head/sys/ufs/ffs/ffs_subr.c
==============================================================================
--- head/sys/ufs/ffs/ffs_subr.c	Wed Jun 17 21:51:32 2020	(r362291)
+++ head/sys/ufs/ffs/ffs_subr.c	Wed Jun 17 23:39:52 2020	(r362292)
@@ -67,7 +67,6 @@ struct malloc_type;
 #include <sys/bio.h>
 #include <sys/buf.h>
 #include <sys/ucred.h>
-#include <sys/taskqueue.h>
 
 #include <ufs/ufs/quota.h>
 #include <ufs/ufs/inode.h>
@@ -81,216 +80,6 @@ struct malloc_type;
 #define UFS_FREE(ptr, type) free(ptr, type)
 #define UFS_TIME time_second
 
-/*
- * 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
- * remaining space in the directory.
- */
-int
-ffs_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp)
-{
-	struct inode *ip;
-	struct fs *fs;
-	struct buf *bp;
-	ufs_lbn_t lbn;
-	int bsize, error;
-
-	ip = VTOI(vp);
-	fs = ITOFS(ip);
-	lbn = lblkno(fs, offset);
-	bsize = blksize(fs, ip, lbn);
-
-	*bpp = NULL;
-	error = bread(vp, lbn, bsize, NOCRED, &bp);
-	if (error) {
-		return (error);
-	}
-	if (res)
-		*res = (char *)bp->b_data + blkoff(fs, offset);
-	*bpp = bp;
-	return (0);
-}
-
-/*
- * Load up the contents of an inode and copy the appropriate pieces
- * to the incore copy.
- */
-int
-ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino)
-{
-	struct ufs1_dinode *dip1;
-	struct ufs2_dinode *dip2;
-	int error;
-
-	if (I_IS_UFS1(ip)) {
-		dip1 = ip->i_din1;
-		*dip1 =
-		    *((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
-		ip->i_mode = dip1->di_mode;
-		ip->i_nlink = dip1->di_nlink;
-		ip->i_effnlink = dip1->di_nlink;
-		ip->i_size = dip1->di_size;
-		ip->i_flags = dip1->di_flags;
-		ip->i_gen = dip1->di_gen;
-		ip->i_uid = dip1->di_uid;
-		ip->i_gid = dip1->di_gid;
-		return (0);
-	}
-	dip2 = ((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
-	if ((error = ffs_verify_dinode_ckhash(fs, dip2)) != 0 &&
-	    !ffs_fsfail_cleanup(ITOUMP(ip), error)) {
-		printf("%s: inode %jd: check-hash failed\n", fs->fs_fsmnt,
-		    (intmax_t)ino);
-		return (error);
-	}
-	*ip->i_din2 = *dip2;
-	dip2 = ip->i_din2;
-	ip->i_mode = dip2->di_mode;
-	ip->i_nlink = dip2->di_nlink;
-	ip->i_effnlink = dip2->di_nlink;
-	ip->i_size = dip2->di_size;
-	ip->i_flags = dip2->di_flags;
-	ip->i_gen = dip2->di_gen;
-	ip->i_uid = dip2->di_uid;
-	ip->i_gid = dip2->di_gid;
-	return (0);
-}
-
-/*
- * Verify that a filesystem block number is a valid data block.
- * This routine is only called on untrusted filesystems.
- */
-int
-ffs_check_blkno(struct mount *mp, ino_t inum, ufs2_daddr_t daddr, int blksize)
-{
-	struct fs *fs;
-	struct ufsmount *ump;
-	ufs2_daddr_t end_daddr;
-	int cg, havemtx;
-
-	KASSERT((mp->mnt_flag & MNT_UNTRUSTED) != 0,
-	    ("ffs_check_blkno called on a trusted file system"));
-	ump = VFSTOUFS(mp);
-	fs = ump->um_fs;
-	cg = dtog(fs, daddr);
-	end_daddr = daddr + numfrags(fs, blksize);
-	/*
-	 * Verify that the block number is a valid data block. Also check
-	 * that it does not point to an inode block or a superblock. Accept
-	 * blocks that are unalloacted (0) or part of snapshot metadata
-	 * (BLK_NOCOPY or BLK_SNAP).
-	 *
-	 * Thus, the block must be in a valid range for the filesystem and
-	 * either in the space before a backup superblock (except the first
-	 * cylinder group where that space is used by the bootstrap code) or
-	 * after the inode blocks and before the end of the cylinder group.
-	 */
-	if ((uint64_t)daddr <= BLK_SNAP ||
-	    ((uint64_t)end_daddr <= fs->fs_size &&
-	    ((cg > 0 && end_daddr <= cgsblock(fs, cg)) ||
-	    (daddr >= cgdmin(fs, cg) &&
-	    end_daddr <= cgbase(fs, cg) + fs->fs_fpg))))
-		return (0);
-	if ((havemtx = mtx_owned(UFS_MTX(ump))) == 0)
-		UFS_LOCK(ump);
-	if (ppsratecheck(&ump->um_last_integritymsg,
-	    &ump->um_secs_integritymsg, 1)) {
-		UFS_UNLOCK(ump);
-		uprintf("\n%s: inode %jd, out-of-range indirect block "
-		    "number %jd\n", mp->mnt_stat.f_mntonname, inum, daddr);
-		if (havemtx)
-			UFS_LOCK(ump);
-	} else if (!havemtx)
-		UFS_UNLOCK(ump);
-	return (EINTEGRITY);
-}
-
-/*
- * Initiate a forcible unmount.
- * Used to unmount filesystems whose underlying media has gone away.
- */
-static void
-ffs_fsfail_unmount(void *v, int pending)
-{
-	struct fsfail_task *etp;
-	struct mount *mp;
-
-	etp = v;
-
-	/*
-	 * Find our mount and get a ref on it, then try to unmount.
-	 */
-	mp = vfs_getvfs(&etp->fsid);
-	if (mp != NULL)
-		dounmount(mp, MNT_FORCE, curthread);
-	free(etp, M_UFSMNT);
-}
-
-/*
- * On first ENXIO error, start a task that forcibly unmounts the filesystem.
- *
- * Return true if a cleanup is in progress.
- */
-int
-ffs_fsfail_cleanup(struct ufsmount *ump, int error)
-{
-	int retval;
-
-	UFS_LOCK(ump);
-	retval = ffs_fsfail_cleanup_locked(ump, error);
-	UFS_UNLOCK(ump);
-	return (retval);
-}
-
-int
-ffs_fsfail_cleanup_locked(struct ufsmount *ump, int error)
-{
-	struct fsfail_task *etp;
-	struct task *tp;
-
-	mtx_assert(UFS_MTX(ump), MA_OWNED);
-	if (error == ENXIO && (ump->um_flags & UM_FSFAIL_CLEANUP) == 0) {
-		ump->um_flags |= UM_FSFAIL_CLEANUP;
-		/*
-		 * Queue an async forced unmount.
-		 */
-		etp = ump->um_fsfail_task;
-		ump->um_fsfail_task = NULL;
-		if (etp != NULL) {
-			tp = &etp->task;
-			TASK_INIT(tp, 0, ffs_fsfail_unmount, etp);
-			taskqueue_enqueue(taskqueue_thread, tp);
-			printf("UFS: forcibly unmounting %s from %s\n",
-			    ump->um_mountp->mnt_stat.f_mntfromname,
-			    ump->um_mountp->mnt_stat.f_mntonname);
-		}
-	}
-	return ((ump->um_flags & UM_FSFAIL_CLEANUP) != 0);
-}
-
-/*
- * Wrapper used during ENXIO cleanup to allocate empty buffers when
- * the kernel is unable to read the real one. They are needed so that
- * the soft updates code can use them to unwind its dependencies.
- */
-int
-ffs_breadz(struct ufsmount *ump, struct vnode *vp, daddr_t lblkno,
-    daddr_t dblkno, int size, daddr_t *rablkno, int *rabsize, int cnt,
-    struct ucred *cred, int flags, void (*ckhashfunc)(struct buf *),
-    struct buf **bpp)
-{
-	int error;
-
-	flags |= GB_CVTENXIO;
-	error = breadn_flags(vp, lblkno, dblkno, size, rablkno, rabsize, cnt,
-	    cred, flags, ckhashfunc, bpp);
-	if (error != 0 && ffs_fsfail_cleanup(ump, error)) {
-		error = getblkx(vp, lblkno, dblkno, size, 0, 0, flags, bpp);
-		KASSERT(error == 0, ("getblkx failed"));
-		vfs_bio_bzero_buf(*bpp, 0, size);
-	}
-	return (error);
-}
 #endif /* _KERNEL */
 
 /*

Modified: head/sys/ufs/ffs/ffs_vfsops.c
==============================================================================
--- head/sys/ufs/ffs/ffs_vfsops.c	Wed Jun 17 21:51:32 2020	(r362291)
+++ head/sys/ufs/ffs/ffs_vfsops.c	Wed Jun 17 23:39:52 2020	(r362292)
@@ -155,6 +155,217 @@ SYSCTL_INT(_vfs_ffs, OID_AUTO, enxio_enable, CTLFLAG_R
     &ffs_enxio_enable, 0,
     "enable mapping of other disk I/O errors to ENXIO");
 
+/*
+ * 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
+ * remaining space in the directory.
+ */
+static int
+ffs_blkatoff(struct vnode *vp, off_t offset, char **res, struct buf **bpp)
+{
+	struct inode *ip;
+	struct fs *fs;
+	struct buf *bp;
+	ufs_lbn_t lbn;
+	int bsize, error;
+
+	ip = VTOI(vp);
+	fs = ITOFS(ip);
+	lbn = lblkno(fs, offset);
+	bsize = blksize(fs, ip, lbn);
+
+	*bpp = NULL;
+	error = bread(vp, lbn, bsize, NOCRED, &bp);
+	if (error) {
+		return (error);
+	}
+	if (res)
+		*res = (char *)bp->b_data + blkoff(fs, offset);
+	*bpp = bp;
+	return (0);
+}
+
+/*
+ * Load up the contents of an inode and copy the appropriate pieces
+ * to the incore copy.
+ */
+static int
+ffs_load_inode(struct buf *bp, struct inode *ip, struct fs *fs, ino_t ino)
+{
+	struct ufs1_dinode *dip1;
+	struct ufs2_dinode *dip2;
+	int error;
+
+	if (I_IS_UFS1(ip)) {
+		dip1 = ip->i_din1;
+		*dip1 =
+		    *((struct ufs1_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
+		ip->i_mode = dip1->di_mode;
+		ip->i_nlink = dip1->di_nlink;
+		ip->i_effnlink = dip1->di_nlink;
+		ip->i_size = dip1->di_size;
+		ip->i_flags = dip1->di_flags;
+		ip->i_gen = dip1->di_gen;
+		ip->i_uid = dip1->di_uid;
+		ip->i_gid = dip1->di_gid;
+		return (0);
+	}
+	dip2 = ((struct ufs2_dinode *)bp->b_data + ino_to_fsbo(fs, ino));
+	if ((error = ffs_verify_dinode_ckhash(fs, dip2)) != 0 &&
+	    !ffs_fsfail_cleanup(ITOUMP(ip), error)) {
+		printf("%s: inode %jd: check-hash failed\n", fs->fs_fsmnt,
+		    (intmax_t)ino);
+		return (error);
+	}
+	*ip->i_din2 = *dip2;
+	dip2 = ip->i_din2;
+	ip->i_mode = dip2->di_mode;
+	ip->i_nlink = dip2->di_nlink;
+	ip->i_effnlink = dip2->di_nlink;
+	ip->i_size = dip2->di_size;
+	ip->i_flags = dip2->di_flags;
+	ip->i_gen = dip2->di_gen;
+	ip->i_uid = dip2->di_uid;
+	ip->i_gid = dip2->di_gid;
+	return (0);
+}
+
+/*
+ * Verify that a filesystem block number is a valid data block.
+ * This routine is only called on untrusted filesystems.
+ */
+static int
+ffs_check_blkno(struct mount *mp, ino_t inum, ufs2_daddr_t daddr, int blksize)
+{
+	struct fs *fs;
+	struct ufsmount *ump;
+	ufs2_daddr_t end_daddr;
+	int cg, havemtx;
+
+	KASSERT((mp->mnt_flag & MNT_UNTRUSTED) != 0,
+	    ("ffs_check_blkno called on a trusted file system"));
+	ump = VFSTOUFS(mp);
+	fs = ump->um_fs;
+	cg = dtog(fs, daddr);
+	end_daddr = daddr + numfrags(fs, blksize);
+	/*
+	 * Verify that the block number is a valid data block. Also check
+	 * that it does not point to an inode block or a superblock. Accept
+	 * blocks that are unalloacted (0) or part of snapshot metadata
+	 * (BLK_NOCOPY or BLK_SNAP).
+	 *
+	 * Thus, the block must be in a valid range for the filesystem and
+	 * either in the space before a backup superblock (except the first
+	 * cylinder group where that space is used by the bootstrap code) or
+	 * after the inode blocks and before the end of the cylinder group.
+	 */
+	if ((uint64_t)daddr <= BLK_SNAP ||
+	    ((uint64_t)end_daddr <= fs->fs_size &&
+	    ((cg > 0 && end_daddr <= cgsblock(fs, cg)) ||
+	    (daddr >= cgdmin(fs, cg) &&
+	    end_daddr <= cgbase(fs, cg) + fs->fs_fpg))))
+		return (0);
+	if ((havemtx = mtx_owned(UFS_MTX(ump))) == 0)
+		UFS_LOCK(ump);
+	if (ppsratecheck(&ump->um_last_integritymsg,
+	    &ump->um_secs_integritymsg, 1)) {
+		UFS_UNLOCK(ump);
+		uprintf("\n%s: inode %jd, out-of-range indirect block "
+		    "number %jd\n", mp->mnt_stat.f_mntonname, inum, daddr);
+		if (havemtx)
+			UFS_LOCK(ump);
+	} else if (!havemtx)
+		UFS_UNLOCK(ump);
+	return (EINTEGRITY);
+}
+
+/*
+ * Initiate a forcible unmount.
+ * Used to unmount filesystems whose underlying media has gone away.
+ */
+static void
+ffs_fsfail_unmount(void *v, int pending)
+{
+	struct fsfail_task *etp;
+	struct mount *mp;
+
+	etp = v;
+
+	/*
+	 * Find our mount and get a ref on it, then try to unmount.
+	 */
+	mp = vfs_getvfs(&etp->fsid);
+	if (mp != NULL)
+		dounmount(mp, MNT_FORCE, curthread);
+	free(etp, M_UFSMNT);
+}
+
+/*
+ * On first ENXIO error, start a task that forcibly unmounts the filesystem.
+ *
+ * Return true if a cleanup is in progress.
+ */
+int
+ffs_fsfail_cleanup(struct ufsmount *ump, int error)
+{
+	int retval;
+
+	UFS_LOCK(ump);
+	retval = ffs_fsfail_cleanup_locked(ump, error);
+	UFS_UNLOCK(ump);
+	return (retval);
+}
+
+int
+ffs_fsfail_cleanup_locked(struct ufsmount *ump, int error)
+{
+	struct fsfail_task *etp;
+	struct task *tp;
+
+	mtx_assert(UFS_MTX(ump), MA_OWNED);
+	if (error == ENXIO && (ump->um_flags & UM_FSFAIL_CLEANUP) == 0) {
+		ump->um_flags |= UM_FSFAIL_CLEANUP;
+		/*
+		 * Queue an async forced unmount.
+		 */
+		etp = ump->um_fsfail_task;
+		ump->um_fsfail_task = NULL;
+		if (etp != NULL) {
+			tp = &etp->task;
+			TASK_INIT(tp, 0, ffs_fsfail_unmount, etp);
+			taskqueue_enqueue(taskqueue_thread, tp);
+			printf("UFS: forcibly unmounting %s from %s\n",
+			    ump->um_mountp->mnt_stat.f_mntfromname,
+			    ump->um_mountp->mnt_stat.f_mntonname);
+		}
+	}
+	return ((ump->um_flags & UM_FSFAIL_CLEANUP) != 0);
+}
+
+/*
+ * Wrapper used during ENXIO cleanup to allocate empty buffers when
+ * the kernel is unable to read the real one. They are needed so that
+ * the soft updates code can use them to unwind its dependencies.
+ */
+int
+ffs_breadz(struct ufsmount *ump, struct vnode *vp, daddr_t lblkno,
+    daddr_t dblkno, int size, daddr_t *rablkno, int *rabsize, int cnt,
+    struct ucred *cred, int flags, void (*ckhashfunc)(struct buf *),
+    struct buf **bpp)
+{
+	int error;
+
+	flags |= GB_CVTENXIO;
+	error = breadn_flags(vp, lblkno, dblkno, size, rablkno, rabsize, cnt,
+	    cred, flags, ckhashfunc, bpp);
+	if (error != 0 && ffs_fsfail_cleanup(ump, error)) {
+		error = getblkx(vp, lblkno, dblkno, size, 0, 0, flags, bpp);
+		KASSERT(error == 0, ("getblkx failed"));
+		vfs_bio_bzero_buf(*bpp, 0, size);
+	}
+	return (error);
+}
+
 static int
 ffs_mount(struct mount *mp)
 {

Modified: head/sys/ufs/ufs/ufs_vnops.c
==============================================================================
--- head/sys/ufs/ufs/ufs_vnops.c	Wed Jun 17 21:51:32 2020	(r362291)
+++ head/sys/ufs/ufs/ufs_vnops.c	Wed Jun 17 23:39:52 2020	(r362292)
@@ -2184,7 +2184,7 @@ ufs_readdir(ap)
 	error = 0;
 	while (error == 0 && uio->uio_resid > 0 &&
 	    uio->uio_offset < ip->i_size) {
-		error = ffs_blkatoff(vp, uio->uio_offset, NULL, &bp);
+		error = UFS_BLKATOFF(vp, uio->uio_offset, NULL, &bp);
 		if (error)
 			break;
 		if (bp->b_offset + bp->b_bcount > ip->i_size)


More information about the svn-src-head mailing list