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))