Author: asomers
Date: Thu Jun 20 14:13:10 2019
New Revision: 349231
URL: https://svnweb.freebsd.org/changeset/base/349231

Log:
  Add FIOBMAP2 ioctl
  
  This ioctl exposes VOP_BMAP information to userland. It can be used by
  programs like fragmentation analyzers and optimized cp implementations. But
  I'm using it to test fusefs's VOP_BMAP implementation. The "2" in the name
  distinguishes it from the similar but incompatible FIBMAP ioctls in NetBSD
  and Linux.  FIOBMAP2 differs from FIBMAP in that it uses a 64-bit block
  number instead of 32-bit, and it also returns runp and runb.
  
  Reviewed by:  mckusick
  MFC after:    2 weeks
  Sponsored by: The FreeBSD Foundation
  Differential Revision:        https://reviews.freebsd.org/D20705

Modified:
  head/sys/kern/vfs_vnops.c
  head/sys/sys/filio.h
  head/sys/ufs/ufs/ufs_bmap.c

Modified: head/sys/kern/vfs_vnops.c
==============================================================================
--- head/sys/kern/vfs_vnops.c   Thu Jun 20 13:59:46 2019        (r349230)
+++ head/sys/kern/vfs_vnops.c   Thu Jun 20 14:13:10 2019        (r349231)
@@ -1458,6 +1458,25 @@ vn_stat(struct vnode *vp, struct stat *sb, struct ucre
        return (0);
 }
 
+/* generic FIOBMAP2 implementation */
+static int
+vn_ioc_bmap2(struct file *fp, struct fiobmap2_arg *arg, struct ucred *cred)
+{
+       struct vnode *vp = fp->f_vnode;
+       daddr_t lbn = arg->bn;
+       int error;
+
+       vn_lock(vp, LK_SHARED | LK_RETRY);
+#ifdef MAC
+       error = mac_vnode_check_read(cred, fp->f_cred, vp);
+       if (error == 0)
+#endif
+               error = VOP_BMAP(vp, lbn, NULL, &arg->bn, &arg->runp,
+                       &arg->runb);
+       VOP_UNLOCK(vp, 0);
+       return (error);
+}
+
 /*
  * File table vnode ioctl routine.
  */
@@ -1481,6 +1500,9 @@ vn_ioctl(struct file *fp, u_long com, void *data, stru
                        if (error == 0)
                                *(int *)data = vattr.va_size - fp->f_offset;
                        return (error);
+               case FIOBMAP2:
+                       return (vn_ioc_bmap2(fp, (struct fiobmap2_arg*)data,
+                               active_cred));
                case FIONBIO:
                case FIOASYNC:
                        return (0);

Modified: head/sys/sys/filio.h
==============================================================================
--- head/sys/sys/filio.h        Thu Jun 20 13:59:46 2019        (r349230)
+++ head/sys/sys/filio.h        Thu Jun 20 14:13:10 2019        (r349231)
@@ -62,6 +62,13 @@ struct fiodgname_arg {
 /* Handle lseek SEEK_DATA and SEEK_HOLE for holey file knowledge. */
 #define        FIOSEEKDATA     _IOWR('f', 97, off_t)   /* SEEK_DATA */
 #define        FIOSEEKHOLE     _IOWR('f', 98, off_t)   /* SEEK_HOLE */
+struct fiobmap2_arg {
+       int64_t bn;
+       int     runp;
+       int     runb;
+};
+/* Get the file's bmap info for the logical block bn */
+#define FIOBMAP2       _IOWR('f', 99, struct fiobmap2_arg)
 
 #ifdef _KERNEL
 #ifdef COMPAT_FREEBSD32

Modified: head/sys/ufs/ufs/ufs_bmap.c
==============================================================================
--- head/sys/ufs/ufs/ufs_bmap.c Thu Jun 20 13:59:46 2019        (r349230)
+++ head/sys/ufs/ufs/ufs_bmap.c Thu Jun 20 14:13:10 2019        (r349231)
@@ -200,12 +200,15 @@ ufs_bmaparray(vp, bn, bnp, nbp, runp, runb)
                        *bnp = blkptrtodb(ump, ip->i_din2->di_extb[-1 - bn]);
                        if (*bnp == 0)
                                *bnp = -1;
-                       if (nbp == NULL)
-                               panic("ufs_bmaparray: mapping ext data");
+                       if (nbp == NULL) {
+                               /* indirect block not found */
+                               return (EINVAL);
+                       }
                        nbp->b_xflags |= BX_ALTDATA;
                        return (0);
                } else {
-                       panic("ufs_bmaparray: blkno out of range");
+                       /* blkno out of range */
+                       return (EINVAL);
                }
                /*
                 * Since this is FFS independent code, we are out of
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to