summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpeadar <peadar@FreeBSD.org>2005-01-27 13:50:27 +0000
committerpeadar <peadar@FreeBSD.org>2005-01-27 13:50:27 +0000
commit80f3d1cb457b8b12ec5b66dc0878a60229d7e187 (patch)
treeaa8b5b038efa85d8a818ccc6e683307ae0d531f4
parente0ac0a48cd5f9e54521f1dc133f9fc10bee873fc (diff)
downloadFreeBSD-src-80f3d1cb457b8b12ec5b66dc0878a60229d7e187.zip
FreeBSD-src-80f3d1cb457b8b12ec5b66dc0878a60229d7e187.tar.gz
Make NTFS at least minimally usable after bufobj and GEOM fallout.
mmap() on NTFS files was hosed, returning pages offset from the start of the disk rather than the start of the file. (ie, "cp" of a 1-block file would get you a copy of the boot sector, not the data in the file.) The solution isn't ideal, but gives a functioning filesystem. Cached vnode lookup was also broken, resulting in vnode haemorrhage. A lookup on the same file twice would give you two vnodes, and the resulting cached pages. Just recently, mmap() was broken due to a lack of a call to vnode_create_vobject() in ntfs_open(). Discussed with: phk@
-rw-r--r--sys/fs/ntfs/ntfs_subr.c1
-rw-r--r--sys/fs/ntfs/ntfs_vfsops.c32
-rw-r--r--sys/fs/ntfs/ntfs_vnops.c7
3 files changed, 35 insertions, 5 deletions
diff --git a/sys/fs/ntfs/ntfs_subr.c b/sys/fs/ntfs/ntfs_subr.c
index 1ca9ffa..fb46539 100644
--- a/sys/fs/ntfs/ntfs_subr.c
+++ b/sys/fs/ntfs/ntfs_subr.c
@@ -399,6 +399,7 @@ ntfs_ntlookup(
/* Generic initialization */
ip->i_devvp = ntmp->ntm_devvp;
+ ip->i_dev = ntmp->ntm_devvp->v_rdev;
ip->i_number = ino;
ip->i_mp = ntmp;
diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c
index 1c2e6bd..60cd7b5 100644
--- a/sys/fs/ntfs/ntfs_vfsops.c
+++ b/sys/fs/ntfs/ntfs_vfsops.c
@@ -81,6 +81,19 @@ static vfs_statfs_t ntfs_statfs;
static vfs_unmount_t ntfs_unmount;
static vfs_vptofh_t ntfs_vptofh;
+static b_strategy_t ntfs_bufstrategy;
+
+/*
+ * Buffer operations for NTFS vnodes.
+ * We punt on VOP_BMAP, so we need to do
+ * strategy on the file's vnode rather
+ * than the underlying device's
+ */
+static struct buf_ops ntfs_vnbufops = {
+ .bop_name = "NTFS",
+ .bop_strategy = ntfs_bufstrategy,
+};
+
static int
ntfs_init (
struct vfsconf *vcp )
@@ -650,7 +663,7 @@ ntfs_vgetex(
dprintf(("ntfs_vgetex: ino: %d, attr: 0x%x:%s, lkf: 0x%lx, f: 0x%lx\n",
ino, attrtype, attrname?attrname:"", (u_long)lkflags,
- (u_long)flags ));
+ (u_long)flags));
ntmp = VFSTONTFS(mp);
*vpp = NULL;
@@ -721,6 +734,9 @@ ntfs_vgetex(
vp->v_data = fp;
vp->v_type = f_type;
+ vp->v_bufobj.bo_ops = &ntfs_vnbufops;
+ vp->v_bufobj.bo_private = vp;
+
if (ino == NTFS_ROOTINO)
vp->v_vflag |= VV_ROOT;
@@ -750,6 +766,20 @@ ntfs_vget(
curthread, vpp);
}
+static void
+ntfs_bufstrategy(struct bufobj *bo, struct buf *bp)
+{
+ struct vnode *vp;
+ int rc;
+
+ vp = bo->bo_private;
+ KASSERT(bo == &vp->v_bufobj, ("BO/VP mismatch: vp %p bo %p != %p",
+ vp, &vp->v_bufobj, bo));
+ rc = VOP_STRATEGY(vp, bp);
+ KASSERT(rc == 0, ("NTFS VOP_STRATEGY failed: bp=%p, "
+ "vp=%p, rc=%d", bp, vp, rc));
+}
+
static struct vfsops ntfs_vfsops = {
.vfs_fhtovp = ntfs_fhtovp,
.vfs_init = ntfs_init,
diff --git a/sys/fs/ntfs/ntfs_vnops.c b/sys/fs/ntfs/ntfs_vnops.c
index 4cc466d..e928325 100644
--- a/sys/fs/ntfs/ntfs_vnops.c
+++ b/sys/fs/ntfs/ntfs_vnops.c
@@ -98,13 +98,10 @@ ntfs_bmap(ap)
} */ *ap;
{
struct vnode *vp = ap->a_vp;
- struct fnode *fp = VTOF(vp);
- struct ntnode *ip = FTONT(fp);
- struct ntfsmount *ntmp = ip->i_mp;
dprintf(("ntfs_bmap: vn: %p, blk: %d\n", ap->a_vp,(u_int32_t)ap->a_bn));
if (ap->a_bop != NULL)
- *ap->a_bop = &ntmp->ntm_devvp->v_bufobj;
+ *ap->a_bop = &vp->v_bufobj;
if (ap->a_bnp != NULL)
*ap->a_bnp = ap->a_bn;
if (ap->a_runp != NULL)
@@ -445,6 +442,8 @@ ntfs_open(ap)
printf("ntfs_open: %d\n",ip->i_number);
#endif
+ vnode_create_vobject(ap->a_vp, VTOF(ap->a_vp)->f_size, ap->a_td);
+
/*
* Files marked append-only must be opened for appending.
*/
OpenPOWER on IntegriCloud