socsvn commit: r239348 - soc2012/vbotton/head/sys/fs/ntfs
vbotton at FreeBSD.org
vbotton at FreeBSD.org
Fri Jul 13 17:33:36 UTC 2012
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,
More information about the svn-soc-all
mailing list