From owner-svn-soc-all@FreeBSD.ORG Fri Jul 13 17:33:36 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 3B5E5106564A for ; Fri, 13 Jul 2012 17:33:34 +0000 (UTC) (envelope-from vbotton@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Fri, 13 Jul 2012 17:33:34 +0000 Date: Fri, 13 Jul 2012 17:33:34 +0000 From: vbotton@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120713173334.3B5E5106564A@hub.freebsd.org> Cc: Subject: socsvn commit: r239348 - soc2012/vbotton/head/sys/fs/ntfs X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Jul 2012 17:33:36 -0000 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 #include #include +#include #include #include #include @@ -51,7 +52,7 @@ #include #include - +#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,