Teach msdos_mount() about DUIDs

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Joel Sing
Date: Saturday, November 13, 2010 - 10:03 am

This allows MS-DOS file systems to be mounted by DUID. The primary change
is the inclusion of the disk_map() call, however we need to modify the error
handling to suit. Some long lines wrapped for free.

ok?

Index: msdosfs_vfsops.c
===================================================================
RCS file: /cvs/src/sys/msdosfs/msdosfs_vfsops.c,v
retrieving revision 1.58
diff -u -p -r1.58 msdosfs_vfsops.c
--- msdosfs_vfsops.c	23 Sep 2010 18:40:00 -0000	1.58
+++ msdosfs_vfsops.c	13 Nov 2010 16:51:53 -0000
@@ -62,6 +62,7 @@
 #include <sys/ioctl.h>
 #include <sys/malloc.h>
 #include <sys/dirent.h>
+#include <sys/disk.h>
 
 #include <msdosfs/bpb.h>
 #include <msdosfs/bootsect.h>
@@ -103,10 +104,12 @@ msdosfs_mount(struct mount *mp, const ch
 	size_t size;
 	int error, flags;
 	mode_t accessmode;
+	char *fspec = NULL;
 
 	error = copyin(data, &args, sizeof(struct msdosfs_args));
 	if (error)
 		return (error);
+
 	/*
 	 * If updating, check whether changing from read-only to
 	 * read/write; if there is no device name, that's all we do.
@@ -114,7 +117,8 @@ msdosfs_mount(struct mount *mp, const ch
 	if (mp->mnt_flag & MNT_UPDATE) {
 		pmp = VFSTOMSDOSFS(mp);
 		error = 0;
-		if (!(pmp->pm_flags & MSDOSFSMNT_RONLY) && (mp->mnt_flag & MNT_RDONLY)) {
+		if (!(pmp->pm_flags & MSDOSFSMNT_RONLY) &&
+		    (mp->mnt_flag & MNT_RDONLY)) {
 			flags = WRITECLOSE;
 			if (mp->mnt_flag & MNT_FORCE)
 				flags |= FORCECLOSE;
@@ -125,7 +129,8 @@ msdosfs_mount(struct mount *mp, const ch
 			error = EOPNOTSUPP;
 		if (error)
 			return (error);
-		if ((pmp->pm_flags & MSDOSFSMNT_RONLY) && (mp->mnt_flag & MNT_WANTRDWR)) {
+		if ((pmp->pm_flags & MSDOSFSMNT_RONLY) &&
+		    (mp->mnt_flag & MNT_WANTRDWR)) {
 			/*
 			 * If upgrade to read-write by non-root, then verify
 			 * that user has necessary permissions on the device.
@@ -157,23 +162,31 @@ msdosfs_mount(struct mount *mp, const ch
 			    &args.export_info));
 		}
 	}
+
 	/*
 	 * Not an update, or updating the name: look up the name
 	 * and verify that it refers to a sensible block device.
 	 */
-	NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p);
+	fspec = malloc(MNAMELEN, M_MOUNT, M_WAITOK);
+	if ((error = copyinstr(args.fspec, fspec, MNAMELEN - 1, &size)) != 0)
+		goto error;
+	disk_map(fspec, fspec, MNAMELEN, DM_OPENBLCK);
+
+	NDINIT(ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, fspec, p);
 	if ((error = namei(ndp)) != 0)
-		return (error);
+		goto error;
+
 	devvp = ndp->ni_vp;
 
 	if (devvp->v_type != VBLK) {
-		vrele(devvp);
-		return (ENOTBLK);
+		error = ENOTBLK;
+		goto error_devvp;
 	}
 	if (major(devvp->v_rdev) >= nblkdev) {
-		vrele(devvp);
-		return (ENXIO);
+		error = ENXIO;
+		goto error_devvp;
 	}
+
 	/*
 	 * If mount by non-root, then verify that user has necessary
 	 * permissions on the device.
@@ -184,12 +197,11 @@ msdosfs_mount(struct mount *mp, const ch
 			accessmode |= VWRITE;
 		vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p);
 		error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p);
-		if (error) {
-			vput(devvp);
-			return (error);
-		}
 		VOP_UNLOCK(devvp, 0, p);
+		if (error)
+			goto error_devvp;
 	}
+
 	if ((mp->mnt_flag & MNT_UPDATE) == 0)
 		error = msdosfs_mountfs(devvp, mp, p, &args);
 	else {
@@ -198,10 +210,9 @@ msdosfs_mount(struct mount *mp, const ch
 		else
 			vrele(devvp);
 	}
-	if (error) {
-		vrele(devvp);
-		return (error);
-	}
+	if (error)
+		goto error_devvp;
+
 	pmp = VFSTOMSDOSFS(mp);
 	pmp->pm_gid = args.gid;
 	pmp->pm_uid = args.uid;
@@ -210,7 +221,8 @@ msdosfs_mount(struct mount *mp, const ch
 
 	if (pmp->pm_flags & MSDOSFSMNT_NOWIN95)
 		pmp->pm_flags |= MSDOSFSMNT_SHORTNAME;
-	else if (!(pmp->pm_flags & (MSDOSFSMNT_SHORTNAME | MSDOSFSMNT_LONGNAME))) {
+	else if (!(pmp->pm_flags &
+	    (MSDOSFSMNT_SHORTNAME | MSDOSFSMNT_LONGNAME))) {
 		struct vnode *rvp;
 		
 		/*
@@ -221,7 +233,7 @@ msdosfs_mount(struct mount *mp, const ch
 		else {
 		        if ((error = msdosfs_root(mp, &rvp)) != 0) {
 			        msdosfs_unmount(mp, MNT_FORCE, p);
-			        return (error);
+			        goto error;
 			}
 			pmp->pm_flags |= findwin95(VTODE(rvp))
 			     ? MSDOSFSMNT_LONGNAME
@@ -231,14 +243,24 @@ msdosfs_mount(struct mount *mp, const ch
 	}
 	(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
 	bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
-	(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
-	    &size);
+
+	size = strlcpy(mp->mnt_stat.f_mntfromname, fspec, MNAMELEN - 1);
 	bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
 	bcopy(&args, &mp->mnt_stat.mount_info.msdosfs_args, sizeof(args));
 #ifdef MSDOSFS_DEBUG
-	printf("msdosfs_mount(): mp %x, pmp %x, inusemap %x\n", mp, pmp, pmp->pm_inusemap);
+	printf("msdosfs_mount(): mp %x, pmp %x, inusemap %x\n", mp,
+	    pmp, pmp->pm_inusemap);
 #endif
 	return (0);
+
+error_devvp:
+	vrele(devvp);
+
+error:
+	if (fspec)
+		free(fspec, M_MOUNT);
+
+	return (error);
 }
 
 int

-- 

   "Stop assuming that systems are secure unless demonstrated insecure;
    start assuming that systems are insecure unless designed securely."
          - Bruce Schneier
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Teach msdos_mount() about DUIDs, Joel Sing, (Sat Nov 13, 10:03 am)