Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 Jul 2012 17:33:34 +0000
From:      vbotton@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r239348 - soc2012/vbotton/head/sys/fs/ntfs
Message-ID:  <20120713173334.3B5E5106564A@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: vbotton
Date: Fri Jul 13 17:33:32 2012
New Revision: 239348
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=239348

Log:
  Add bootsector read, and VFS macros

Modified:
  soc2012/vbotton/head/sys/fs/ntfs/ntfs_vfsops.c

Modified: soc2012/vbotton/head/sys/fs/ntfs/ntfs_vfsops.c
==============================================================================
--- soc2012/vbotton/head/sys/fs/ntfs/ntfs_vfsops.c	Fri Jul 13 16:18:05 2012	(r239347)
+++ soc2012/vbotton/head/sys/fs/ntfs/ntfs_vfsops.c	Fri Jul 13 17:33:32 2012	(r239348)
@@ -39,6 +39,7 @@
 #include <sys/cdefs.h>
 #include <sys/disk.h>
 #include <sys/errno.h>
+#include <sys/namei.h>
 #include <sys/fcntl.h>
 #include <sys/mount.h>
 #include <sys/param.h>
@@ -51,7 +52,7 @@
 #include <sys/types.h>
 #include <machine/atomic.h>
 
-
+#define DEBUG 1
 #include "ntfs.h"
 #include "ntfs_attr.h"
 #include "ntfs_attr_list.h"
@@ -130,6 +131,11 @@
 }
 #endif
 
+static uint64_t vfs_devblocksize(struct mount *mp)
+{
+	return (mp->mnt_stat.f_bsize);
+}
+
 /**
  * ntfs_boot_sector_is_valid - check if @b contains a valid ntfs boot sector
  * @mp:		Mount of the device to which @b belongs.
@@ -141,7 +147,6 @@
  *
  * @mp is only needed for warning/error output, i.e. it can be NULL.
  */
-#if defined (UNUSED)
 static BOOL ntfs_boot_sector_is_valid(const mount_t mp,
 		const NTFS_BOOT_SECTOR *b)
 {
@@ -226,7 +231,6 @@
 	ntfs_debug("Not an NTFS boot sector.");
 	return FALSE;
 }
-#endif
 
 /**
  * ntfs_boot_sector_read - read the ntfs boot sector of a device
@@ -253,8 +257,8 @@
  * invalidating them when we release them.  This is needed because the
  * buffer(s) may get read later using a different vnode ($Boot for example).
  */
-#if defined (DIRTY_HACK)
-static errno_t ntfs_boot_sector_read(ntfs_volume *vol, kauth_cred_t cred,
+
+static errno_t ntfs_boot_sector_read(ntfs_volume *vol, struct ucred *cred,
 		buf_t *buf, NTFS_BOOT_SECTOR **bs)
 {
 	daddr_t nr_blocks = vol->nr_blocks;
@@ -262,22 +266,24 @@
 			"Unable to read %s boot sector (error %d).";
 	mount_t mp = vol->mp;
 	vnode_t dev_vn = vol->dev_vn;
-	buf_t primary, backup;
+	buf_t primary = NULL, backup = NULL;
 	NTFS_BOOT_SECTOR *bs1, *bs2;
-	errno_t err, err2;
+	errno_t err/*, err2*/;
 	u32 blocksize = vfs_devblocksize(mp);
 
 	ntfs_debug("Entering.");
 	/* Try to read primary boot sector. */
-	err = buf_meta_bread(dev_vn, 0, blocksize, cred, &primary);
-	buf_setflags(primary, B_NOCACHE);
+	err = bread(dev_vn, 0, blocksize, cred, &primary);
+	//buf_setflags(primary, B_NOCACHE);
+	primary->b_flags |= B_NOCACHE;
 	if (!err) {
-		err = buf_map(primary, (caddr_t*)&bs1);
-		if (err) {
-			ntfs_error(mp, "Failed to map buffer of primary boot "
-					"sector (error %d).", err);
-			bs1 = NULL;
-		} else {
+	//	err = buf_map(primary, (caddr_t*)&bs1);
+	//	if (err) {
+	//		ntfs_error(mp, "Failed to map buffer of primary boot "
+	//				"sector (error %d).", err);
+	//		bs1 = NULL;
+	//	} else {
+		bs1 = (NTFS_BOOT_SECTOR*)primary->b_data;
 			if (ntfs_boot_sector_is_valid(mp, bs1)) {
 				*buf = primary;
 				*bs = bs1;
@@ -286,7 +292,7 @@
 			}
 			ntfs_error(mp, "Primary boot sector is invalid.");
 			err = EIO;
-		}
+	//	}
 	} else {
 		ntfs_error(mp, read_err_str, "primary", err);
 		bs1 = NULL;
@@ -294,66 +300,61 @@
 	if (!(vol->on_errors & ON_ERRORS_RECOVER)) {
 		ntfs_error(mp, "Mount option errors=recover not used.  "
 				"Aborting without trying to recover.");
-		if (bs1) {
-			err2 = buf_unmap(primary);
-			if (err2)
-				ntfs_error(mp, "Failed to unmap buffer of "
-						"primary boot sector (error "
-						"%d).", err2);
-		}
-		buf_brelse(primary);
+		brelse(primary);
 		return err;
 	}
 	/* Try to read NT4+ backup boot sector. */
-	err = buf_meta_bread(dev_vn, nr_blocks - 1, blocksize, cred, &backup);
-	buf_setflags(backup, B_NOCACHE);
+	err = bread(dev_vn, nr_blocks - 1, blocksize, cred, &backup);
+	backup->b_flags |= B_NOCACHE;
 	if (!err) {
-		err = buf_map(backup, (caddr_t*)&bs2);
-		if (err)
-			ntfs_error(mp, "Failed to map buffer of backup boot "
-					"sector (error %d).", err);
-		else {
+		//err = buf_map(backup, (caddr_t*)&bs2);
+		//if (err)
+		//	ntfs_error(mp, "Failed to map buffer of backup boot "
+		//			"sector (error %d).", err);
+		//else {
+		bs2 = (NTFS_BOOT_SECTOR*)backup->b_data;
 			if (ntfs_boot_sector_is_valid(mp, bs2))
 				goto hotfix_primary_boot_sector;
-			err = buf_unmap(backup);
-			if (err)
-				ntfs_error(mp, "Failed to unmap buffer of "
-						"backup boot sector (error "
-						"%d).", err);
-		}
+			//err = buf_unmap(backup);
+			//if (err)
+			//	ntfs_error(mp, "Failed to unmap buffer of "
+			//			"backup boot sector (error "
+			//			"%d).", err);
+		//}
 	} else
 		ntfs_error(mp, read_err_str, "backup", err);
-	buf_brelse(backup);
+	brelse(backup);
 	/* Try to read NT3.51- backup boot sector. */
-	err = buf_meta_bread(dev_vn, nr_blocks >> 1, blocksize, cred, &backup);
-	buf_setflags(backup, B_NOCACHE);
+	err = bread(dev_vn, nr_blocks >> 1, blocksize, cred, &backup);
+	backup->b_flags |= B_NOCACHE;
 	if (!err) {
-		err = buf_map(backup, (caddr_t*)&bs2);
-		if (err)
-			ntfs_error(mp, "Failed to map buffer of old backup "
-					"boot sector (error %d).", err);
-		else {
+		//err = buf_map(backup, (caddr_t*)&bs2);
+		//if (err)
+		//	ntfs_error(mp, "Failed to map buffer of old backup "
+		//			"boot sector (error %d).", err);
+		//else {
+		bs2 = (NTFS_BOOT_SECTOR*)backup->b_data;
 			if (ntfs_boot_sector_is_valid(mp, bs2))
 				goto hotfix_primary_boot_sector;
-			err = buf_unmap(backup);
+	/*		err = buf_unmap(backup);
 			if (err)
 				ntfs_error(mp, "Failed to unmap buffer of old "
 						"backup boot sector (error "
-						"%d).", err);
+						"%d).", err);*/
 			err = EIO;
-		}
+		//}
 		ntfs_error(mp, "Could not find a valid backup boot sector.");
 	} else
 		ntfs_error(mp, read_err_str, "backup", err);
-	buf_brelse(backup);
+	brelse(backup);
 	/* We failed.  Clean up and return. */
-	if (bs1) {
+	/*if (bs1) {
 		err2 = buf_unmap(primary);
 		if (err2)
 			ntfs_error(mp, "Failed to unmap buffer of primary "
 					"boot sector (error %d).", err2);
-	}
-	buf_brelse(primary);
+	}*/
+	brelse(primary);
 	return err;
 hotfix_primary_boot_sector:
 	ntfs_warning(mp, "Using backup boot sector.");
@@ -368,31 +369,30 @@
 		ntfs_warning(mp, "Hot-fix: Recovering invalid primary boot "
 				"sector from backup copy.");
 		memcpy(bs1, bs2, blocksize);
-		err = buf_bwrite(primary);
-		if (err)
-			ntfs_error(mp, "Hot-fix: Device write error while "
-					"recovering primary boot sector "
-					"(error %d).", err);
+		bdwrite(primary);
+		//if (err)
+		//	ntfs_error(mp, "Hot-fix: Device write error while "
+		//			"recovering primary boot sector "
+		//			"(error %d).", err);
 	} else {
 		if (bs1) {
 			ntfs_warning(mp, "Hot-fix: Recovery of primary boot "
 					"sector failed: Read-only mount.");
-			err = buf_unmap(primary);
+			/*err = buf_unmap(primary);
 			if (err)
 				ntfs_error(mp, "Failed to unmap buffer of "
 						"primary boot sector (error "
-						"%d).", err);
+						"%d).", err);*/
 		} else
 			ntfs_warning(mp, "Hot-fix: Recovery of primary boot "
 					"sector failed as it could not be "
 					"mapped.");
-		buf_brelse(primary);
+		brelse(primary);
 	}
 	*buf = backup;
 	*bs = bs2;
 	return 0;
 }
-#endif
 
 /**
  * ntfs_boot_sector_parse - parse the boot sector and store the data in @vol
@@ -407,7 +407,7 @@
  *	EINVAL	- Boot sector is invalid.
  *	ENOTSUP - Volume is not supported by this ntfs driver.
  */
-#if defined (UNUSED)
+
 static errno_t ntfs_boot_sector_parse(ntfs_volume *vol,
 		const NTFS_BOOT_SECTOR *b)
 {
@@ -423,15 +423,13 @@
 	ntfs_debug("vol->sector_size = %u (0x%x)", vol->sector_size,
 			vol->sector_size);
 	ntfs_debug("vol->sector_size_shift = %u", vol->sector_size_shift);
-#if defined (DIRTY_HACK)
 	if (vol->sector_size < (u32)vfs_devblocksize(mp)) {
 		ntfs_error(mp, "Sector size (%u) is smaller than the device "
 				"block size (%d).  This is not supported.  "
 				"Sorry.", vol->sector_size,
-				vfs_devblocksize(mp));
+				(int)vfs_devblocksize(mp));
 		return ENOTSUP;
 	}
-#endif
 	ntfs_debug("sectors_per_cluster = %u", b->bpb.sectors_per_cluster);
 	sectors_per_cluster_shift = ffs(b->bpb.sectors_per_cluster) - 1;
 	ntfs_debug("sectors_per_cluster_shift = %u", sectors_per_cluster_shift);
@@ -589,7 +587,6 @@
 	ntfs_debug("Done.");
 	return 0;
 }
-#endif
 
 /**
  * ntfs_setup_allocators - initialize the cluster and mft allocators
@@ -2097,7 +2094,7 @@
 	do {
 		if (*kaddr) {
 			ntfs_debug("hiberfil.sys is larger than 4kiB "
-					"(0x%llx), does not contain the "
+					"(0x%lx), does not contain the "
 					"\"hibr\" magic, and does not have a "
 					"zero header.  Windows is hibernated "
 					"on the volume.  This is not the "
@@ -4128,11 +4125,11 @@
  * unloaded automatically while in use.  If the mount fails, we must call
  * OSKextReleaseKextWithLoadTag() to allow the KEXT to be unloaded.
  */
-/*
+
 static struct statfs *vfs_statfs(struct mount *mp)
 {
 	return (&mp->mnt_stat);
-}*/
+}
 
 static void vfs_setfsprivate(struct mount *mp, void *data)
 {
@@ -4149,26 +4146,25 @@
 	return (mp->mnt_flag & MNT_UPDATE);
 }
 
-static uint64_t vfs_devblocksize(struct mount *mp)
-{
-	return (mp->mnt_stat.f_bsize);
-}
+
 
 static int ntfs_mount(mount_t mp /*, vnode_t dev_vn, user_addr_t data,
 		vfs_context_t context*/)
 {
 	daddr_t nr_blocks = 0;
-	//struct statfs *sfs = vfs_statfs(mp);
-	//struct vnode *dev_vn = mp->mnt_vnodecovered;
+	struct statfs *sfs = vfs_statfs(mp);
+	struct vnode *dev_vn;
 	ntfs_volume *vol;
 	buf_t buf;
-	//kauth_cred_t cred;
+	struct ucred *cred = curthread->td_ucred;
 	//dev_t dev;
 	NTFS_BOOT_SECTOR *bs;
 	errno_t err/*, err2*/;
 	u32 blocksize = 0;
 	//ntfs_mount_options_header opts_hdr;
 	ntfs_mount_options_1_0 opts;
+	struct nameidata ndp;
+	char *from;
 
 	ntfs_debug("Entering.");	
 	#if defined (DIRTY_HACK)
@@ -4250,8 +4246,23 @@
 	 * other way round.
 	 */
 	#endif
+	from = vfs_getopts(mp->mnt_optnew, "from", &err);
+	if (err)	
+		return (err);
 	if (vfs_isupdate(mp))
 		return ntfs_remount(mp, &opts);
+	NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, from, curthread);
+	err = namei(&ndp);
+	if (err)
+		return (err);
+	NDFREE(&ndp, NDF_ONLY_PNBUF);
+	dev_vn = ndp.ni_vp;
+
+	if (!vn_isdisk(dev_vn, &err))  {
+		vput(dev_vn);
+		return (err);
+	}
+
 	/* We know this is a real mount request thus @dev_vn is not NULL. */
 	//dev = vnode_specrdev(dev_vn);
 	/* Let the VFS do advisory locking for us. */
@@ -4274,8 +4285,9 @@
 	 * value to satisfy the ATTR_CMN_DEVID request in getattrlist() and
 	 * getvolattrlist() thus it must be the device.
 	 */
-	//sfs->f_fsid.val[0] = (int32_t)dev;
-	//sfs->f_fsid.val[1] = (int32_t)vfs_typenum(mp);
+	sfs->f_fsid.val[0] = dev2udev(dev_vn->v_rdev);
+	sfs->f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
+	mp->mnt_maxsymlinklen = 0;
 	/*
 	 * Allocate and initialize an ntfs volume and attach it to the vfs
 	 * mount.
@@ -4360,7 +4372,7 @@
 	/* Get the size of the device in units of blocksize bytes. */
 	//err = VNOP_IOCTL(dev_vn, DKIOCGETBLOCKCOUNT, (caddr_t)&nr_blocks, 0,
 	//		context);
-	err = 1;
+	err = 0;
 	if (err) {
 		ntfs_error(mp, "Failed to determine the size of the device "
 				"(DKIOCGETBLOCKCOUNT ioctl returned error "
@@ -4404,7 +4416,6 @@
 	/* Read the boot sector and return the buffer containing it. */
 	buf = NULL;
 	bs = NULL;
-	#if defined (DIRTY_HACK)
 	err = ntfs_boot_sector_read(vol, cred, &buf, &bs);
 	if (err) {
 		ntfs_error(mp, "Not an NTFS volume.");
@@ -4415,17 +4426,16 @@
 	 * using it.
 	 */
 	err = ntfs_boot_sector_parse(vol, bs);
-	err2 = buf_unmap(buf);
+	/*err2 = buf_unmap(buf);
 	if (err2)
 		ntfs_error(mp, "Failed to unmap buffer of boot sector (error "
-				"%d).", err2);
-	buf_brelse(buf);
+				"%d).", err2);*/
+	brelse(buf);
 	if (err) {
 		ntfs_error(mp, "%s NTFS file system.",
 				err == ENOTSUP ? "Unsupported" : "Invalid");
 		goto err;
 	}
-	#endif
 	/*
 	 * If the boot sector indicates a sector size bigger than the current
 	 * device block size, switch the device block size to the sector size.
@@ -4444,7 +4454,7 @@
 	if (vol->sector_size > blocksize) {
 		ntfs_debug("Setting device block size to sector size.");
 		//err = ntfs_blocksize_set(mp, dev_vn, vol->sector_size, context);
-		err = 1;
+		err = 0;
 		if (err) {
 			ntfs_error(mp, "Failed to set device block size to "
 					"sector size (%u bytes) because "
@@ -4559,6 +4569,7 @@
 	 * it in the vfs mount structure.
 	 */
 	//ntfs_statfs(vol, sfs);
+	vfs_mountedfrom(mp, from);
 	ntfs_debug("Done.");
 	return 0;
 unload:
@@ -4575,7 +4586,6 @@
 	 */
 	ntfs_unmount(mp, MNT_FORCE/*, context*/);
 	return err;
-	return 0;
 }
 
 /**
@@ -5620,6 +5630,9 @@
 	//.vfs_setattr	= ntfs_setattr,
 };
 
+VFS_SET(ntfs_vfsops, ntfs, 0);
+MODULE_VERSION(ntfs, 1);
+
 #if defined (DIRTY_HACK)
 static struct vnodeopv_desc *ntfs_vnodeopv_desc_list[1] = {
 	&ntfs_vnodeopv_desc,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120713173334.3B5E5106564A>