svn commit: r236801 - in stable/8/sys: kern sys

Konstantin Belousov kib at FreeBSD.org
Sat Jun 9 09:01:25 UTC 2012


Author: kib
Date: Sat Jun  9 09:01:24 2012
New Revision: 236801
URL: http://svn.freebsd.org/changeset/base/236801

Log:
  MFC r236043:
  Add a vn_bmap_seekhole(9) vnode helper which can be used by any
  filesystem which supports VOP_BMAP(9) to implement SEEK_HOLE/SEEK_DATA
  commands for lseek(2).

Modified:
  stable/8/sys/kern/vfs_vnops.c
  stable/8/sys/sys/vnode.h
Directory Properties:
  stable/8/sys/   (props changed)

Modified: stable/8/sys/kern/vfs_vnops.c
==============================================================================
--- stable/8/sys/kern/vfs_vnops.c	Sat Jun  9 08:51:25 2012	(r236800)
+++ stable/8/sys/kern/vfs_vnops.c	Sat Jun  9 09:01:24 2012	(r236801)
@@ -1416,3 +1416,56 @@ vn_pages_remove(struct vnode *vp, vm_pin
 	vm_object_page_remove(object, start, end, 0);
 	VM_OBJECT_UNLOCK(object);
 }
+
+int
+vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off, struct ucred *cred)
+{
+	struct vattr va;
+	daddr_t bn, bnp;
+	uint64_t bsize;
+	off_t noff;
+	int error;
+
+	KASSERT(cmd == FIOSEEKHOLE || cmd == FIOSEEKDATA,
+	    ("Wrong command %lu", cmd));
+
+	if (vn_lock(vp, LK_SHARED) != 0)
+		return (EBADF);
+	if (vp->v_type != VREG) {
+		error = ENOTTY;
+		goto unlock;
+	}
+	error = VOP_GETATTR(vp, &va, cred);
+	if (error != 0)
+		goto unlock;
+	noff = *off;
+	if (noff >= va.va_size) {
+		error = ENXIO;
+		goto unlock;
+	}
+	bsize = vp->v_mount->mnt_stat.f_iosize;
+	for (bn = noff / bsize; noff < va.va_size; bn++, noff += bsize) {
+		error = VOP_BMAP(vp, bn, NULL, &bnp, NULL, NULL);
+		if (error == EOPNOTSUPP) {
+			error = ENOTTY;
+			goto unlock;
+		}
+		if ((bnp == -1 && cmd == FIOSEEKHOLE) ||
+		    (bnp != -1 && cmd == FIOSEEKDATA)) {
+			noff = bn * bsize;
+			if (noff < *off)
+				noff = *off;
+			goto unlock;
+		}
+	}
+	if (noff > va.va_size)
+		noff = va.va_size;
+	/* noff == va.va_size. There is an implicit hole at the end of file. */
+	if (cmd == FIOSEEKDATA)
+		error = ENXIO;
+unlock:
+	VOP_UNLOCK(vp, 0);
+	if (error == 0)
+		*off = noff;
+	return (error);
+}

Modified: stable/8/sys/sys/vnode.h
==============================================================================
--- stable/8/sys/sys/vnode.h	Sat Jun  9 08:51:25 2012	(r236800)
+++ stable/8/sys/sys/vnode.h	Sat Jun  9 09:01:24 2012	(r236801)
@@ -645,6 +645,8 @@ void	vunref(struct vnode *);
 void	vn_printf(struct vnode *vp, const char *fmt, ...) __printflike(2,3);
 #define vprint(label, vp) vn_printf((vp), "%s\n", (label))
 int	vrecycle(struct vnode *vp, struct thread *td);
+int	vn_bmap_seekhole(struct vnode *vp, u_long cmd, off_t *off,
+	    struct ucred *cred);
 int	vn_close(struct vnode *vp,
 	    int flags, struct ucred *file_cred, struct thread *td);
 void	vn_finished_write(struct mount *mp);


More information about the svn-src-all mailing list