Module Name:    src
Committed By:   dsl
Date:           Sun Dec  6 16:33:19 UTC 2009

Modified Files:
        src/sys/dev: vnd.c vndvar.h

Log Message:
Make vnd_size (the returned size) 64 bit, keeping old field for ioctl
compatibility. Both fields are now unsigned.
Add compatibility for the old ioctl size.
Detect and error files which are definitely sparse (va_bytes < va_size).
Part of fix for PR/41873.


To generate a diff of this commit:
cvs rdiff -u -r1.204 -r1.205 src/sys/dev/vnd.c
cvs rdiff -u -r1.24 -r1.25 src/sys/dev/vndvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/vnd.c
diff -u src/sys/dev/vnd.c:1.204 src/sys/dev/vnd.c:1.205
--- src/sys/dev/vnd.c:1.204	Fri Aug  7 00:08:07 2009
+++ src/sys/dev/vnd.c	Sun Dec  6 16:33:18 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vnd.c,v 1.204 2009/08/07 00:08:07 dyoung Exp $	*/
+/*	$NetBSD: vnd.c,v 1.205 2009/12/06 16:33:18 dsl Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2008 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vnd.c,v 1.204 2009/08/07 00:08:07 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vnd.c,v 1.205 2009/12/06 16:33:18 dsl Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "fs_nfs.h"
@@ -1037,6 +1037,10 @@
 	switch (cmd) {
 	case VNDIOCSET:
 	case VNDIOCCLR:
+#ifdef VNDIOOCSET
+	case VNDIOOCSET:
+	case VNDIOOCCLR:
+#endif
 	case DIOCSDINFO:
 	case DIOCWDINFO:
 #ifdef __HAVE_OLD_DISKLABEL
@@ -1052,6 +1056,9 @@
 	/* Must be initialized for these... */
 	switch (cmd) {
 	case VNDIOCCLR:
+#ifdef VNDIOOCCLR
+	case VNDIOOCCLR:
+#endif
 	case DIOCGDINFO:
 	case DIOCSDINFO:
 	case DIOCWDINFO:
@@ -1071,6 +1078,9 @@
 	}
 
 	switch (cmd) {
+#ifdef VNDIOOCSET
+	case VNDIOOCSET:
+#endif
 	case VNDIOCSET:
 		if (vnd->sc_flags & VNF_INITED)
 			return EBUSY;
@@ -1088,6 +1098,9 @@
 		error = VOP_GETATTR(nd.ni_vp, &vattr, l->l_cred);
 		if (!error && nd.ni_vp->v_type != VREG)
 			error = EOPNOTSUPP;
+		if (!error && vattr.va_bytes < vattr.va_size)
+			/* File is definitely sparse, reject here */
+			error = EINVAL;
 		if (error) {
 			VOP_UNLOCK(nd.ni_vp, 0);
 			goto close_and_exit;
@@ -1272,7 +1285,11 @@
 			goto close_and_exit;
 
 		vndthrottle(vnd, vnd->sc_vp);
-		vio->vnd_size = dbtob(vnd->sc_size);
+		vio->vnd_osize = dbtob(vnd->sc_size);
+#ifdef VNDIOOCSET
+		if (cmd != VNDIOOCSET)
+#endif
+			vio->vnd_size = dbtob(vnd->sc_size);
 		vnd->sc_flags |= VNF_INITED;
 
 		/* create the kernel thread, wait for it to be up */
@@ -1328,6 +1345,9 @@
 		vndunlock(vnd);
 		return error;
 
+#ifdef VNDIOOCCLR
+	case VNDIOOCCLR:
+#endif
 	case VNDIOCCLR:
 		part = DISKPART(dev);
 		pmask = (1 << part);

Index: src/sys/dev/vndvar.h
diff -u src/sys/dev/vndvar.h:1.24 src/sys/dev/vndvar.h:1.25
--- src/sys/dev/vndvar.h:1.24	Thu Apr 30 22:36:10 2009
+++ src/sys/dev/vndvar.h	Sun Dec  6 16:33:18 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: vndvar.h,v 1.24 2009/04/30 22:36:10 dyoung Exp $	*/
+/*	$NetBSD: vndvar.h,v 1.25 2009/12/06 16:33:18 dsl Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -125,7 +125,8 @@
 	char		*vnd_file;	/* pathname of file to mount */
 	int		vnd_flags;	/* flags; see below */
 	struct vndgeom	vnd_geom;	/* geometry to emulate */
-	int		vnd_size;	/* (returned) size of disk */
+	unsigned int	vnd_osize;	/* (returned) size of disk */
+	uint64_t	vnd_size;	/* (returned) size of disk */
 };
 
 /* vnd_flags */
@@ -213,3 +214,9 @@
 #define VNDIOCSET	_IOWR('F', 0, struct vnd_ioctl)	/* enable disk */
 #define VNDIOCCLR	_IOW('F', 1, struct vnd_ioctl)	/* disable disk */
 #define VNDIOCGET	_IOWR('F', 3, struct vnd_user)	/* get list */
+
+/* These only have the 32bit vnd_osize field */
+#define VNDIOOCSET	_IOC(IOC_INOUT, 'F', 0, \
+				offsetof(struct vnd_ioctl, vnd_size))
+#define VNDIOOCCLR	_IOC(IOC_IN, 'F', 1, \
+				offsetof(struct vnd_ioctl, vnd_size))

Reply via email to