hpfs - Fix a couple panics and a little cleanup.
authorAntonio Huete Jimenez <tuxillo@quantumachine.net>
Thu, 22 Nov 2012 10:47:58 +0000 (11:47 +0100)
committerAntonio Huete Jimenez <tuxillo@quantumachine.net>
Tue, 8 Jan 2013 00:52:36 +0000 (01:52 +0100)
* Fix compilation with HPFS_DEBUG.

* Fix a panic due CNP_PDIRUNLOCK flag not being cleared.

* Fix a panic where returned vnode after a lookup is not
  NULL in the ENOENT case.

* Disable write support completely. It was pretty minimal
  and operations like create or rename were not supported.

It has been tested with a filesystem created by OS/2 Warp 2.1.
Copying data out of it worked fine, but there is still an
outstanding issue with overlapping buffers.

sbin/mount_hpfs/mount_hpfs.8
sbin/mount_hpfs/mount_hpfs.c
sys/vfs/hpfs/hpfs_vfsops.c
sys/vfs/hpfs/hpfs_vnops.c

index 4fc5561..595d186 100644 (file)
@@ -29,9 +29,8 @@
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\" $FreeBSD: src/sbin/mount_hpfs/mount_hpfs.8,v 1.1.2.5 2003/02/24 00:56:42 trhodes Exp $
-.\" $DragonFly: src/sbin/mount_hpfs/mount_hpfs.8,v 1.2 2003/06/17 04:27:33 dillon Exp $
 .\"
-.Dd May 20, 1999
+.Dd November 21, 2012
 .Dt MOUNT_HPFS 8
 .Os
 .Sh NAME
@@ -59,6 +58,7 @@ at boot time, but can be used by any user to mount an
 HPFS file system on any directory that they own (provided,
 of course, that they have appropriate access to the device that
 contains the file system).
+HPFS filesystems can only be mounted read only.
 .Pp
 The options are as follows:
 .Bl -tag -width Ds
@@ -77,13 +77,10 @@ Specify the maximum file permissions for files
 in the file system.
 .El
 .Sh EXAMPLES
-To mount an hpfs volume located in /dev/wd1s1:
+To mount an hpfs volume located in /dev/ad1s1:
 .Bd -literal -offset indent
-# mount_hpfs /dev/wd1s1 /mnt
+# mount_hpfs /dev/ad1s1 /mnt
 .Ed
-.Sh WRITING
-There is limited writing ability and it is not well-tested.
-It is strongly recommended to mount readonly!
 .Sh SEE ALSO
 .Xr mount 2 ,
 .Xr unmount 2 ,
index 139c63d..1ad9ec6 100644 (file)
@@ -65,18 +65,14 @@ main(int argc, char **argv)
        struct hpfs_args args;
        struct stat sb;
        int c, mntflags, set_gid, set_uid, set_mask,error;
-       int forcerw = 0;
        char *dev, *dir, ndir[MAXPATHLEN+1];
        struct vfsconf vfc;
 
        mntflags = set_gid = set_uid = set_mask = 0;
        memset(&args, '\0', sizeof(args));
 
-       while ((c = getopt(argc, argv, "u:g:m:o:c:W:F")) !=  -1) {
+       while ((c = getopt(argc, argv, "u:g:m:o:c:W:")) !=  -1) {
                switch (c) {
-               case 'F':
-                       forcerw=1;
-                       break;
                case 'u':
                        args.uid = a_uid(optarg);
                        set_uid = 1;
@@ -108,10 +104,7 @@ main(int argc, char **argv)
        if (optind + 2 != argc)
                usage();
 
-       if (!(mntflags & MNT_RDONLY) && !forcerw) {
-               warnx("Write support is BETA, you need -F flag to enable RW mount!");
-               exit (111);
-       }
+       mntflags |= MNT_RDONLY;
 
        dev = argv[optind];
        dir = argv[optind + 1];
index 0c0dffc..7031e4c 100644 (file)
@@ -460,7 +460,7 @@ hpfs_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
        struct buf *bp;
        int error;
 
-       dprintf(("hpfs_vget(0x%x): ",ino));
+       dprintf(("hpfs_vget(0x%jx): ", ino));
 
        *vpp = NULL;
        hp = NULL;
index 12fa3ac..5a02ee9 100644 (file)
@@ -274,7 +274,7 @@ hpfs_bmap(struct vop_bmap_args *ap)
        if (ap->a_doffsetp == NULL)
                return (0);
 
-       dprintf(("hpfs_bmap(0x%x, 0x%x): ",hp->h_no, ap->a_bn));
+       dprintf(("hpfs_bmap(0x%x): ", hp->h_no));
 
        lbn = ap->a_loffset >> DEV_BSHIFT;
        KKASSERT(((int)ap->a_loffset & DEV_BMASK) == 0);
@@ -308,15 +308,15 @@ hpfs_read(struct vop_read_args *ap)
 
        resid = (int)szmin(uio->uio_resid, hp->h_fn.fn_size - uio->uio_offset);
 
-       dprintf(("hpfs_read(0x%x, off: %d resid: %d, segflg: %d): "
-                "[resid: 0x%lx]\n",
+       dprintf(("hpfs_read(0x%x, off: %d resid: %zx, segflg: %d): "
+                "[resid: 0x%x]\n",
                 hp->h_no, (u_int32_t)uio->uio_offset,
                 uio->uio_resid, uio->uio_segflg, resid));
 
        while (resid) {
                lbn = uio->uio_offset >> DEV_BSHIFT;
                off = uio->uio_offset & (DEV_BSIZE - 1);
-               dprintf(("hpfs_read: resid: 0x%lx lbn: 0x%x off: 0x%x\n",
+               dprintf(("hpfs_read: resid: 0x%zx lbn: 0x%x off: 0x%x\n",
                        uio->uio_resid, lbn, off));
                error = hpfs_hpbmap(hp, lbn, &bn, &runl);
                if (error)
@@ -365,7 +365,7 @@ hpfs_write(struct vop_write_args *ap)
        int runl;
        int error = 0;
 
-       dprintf(("hpfs_write(0x%x, off: %d resid: %ld, segflg: %d):\n",
+       dprintf(("hpfs_write(0x%x, off: %d resid: %zd, segflg: %d):\n",
                hp->h_no, (u_int32_t)uio->uio_offset,
                uio->uio_resid, uio->uio_segflg));
 
@@ -384,7 +384,7 @@ hpfs_write(struct vop_write_args *ap)
        while (uio->uio_resid) {
                lbn = uio->uio_offset >> DEV_BSHIFT;
                off = uio->uio_offset & (DEV_BSIZE - 1);
-               dprintf(("hpfs_write: resid: 0x%lx lbn: 0x%x off: 0x%x\n",
+               dprintf(("hpfs_write: resid: 0x%zx lbn: 0x%x off: 0x%x\n",
                        uio->uio_resid, lbn, off));
                error = hpfs_hpbmap(hp, lbn, &bn, &runl);
                if (error)
@@ -750,7 +750,7 @@ hpfs_de_uiomove(int *error, struct hpfsmount *hpmp, struct hpfsdirent *dep,
                        (dep->de_flag & DE_DIR) ? DT_DIR : DT_REG,
                        dep->de_namelen, convname);
 
-       dprintf(("[0x%lx] ", uio->uio_resid));
+       dprintf(("[0x%zx] ", uio->uio_resid));
        return (success);
 }
 
@@ -775,7 +775,7 @@ hpfs_readdir(struct vop_readdir_args *ap)
        lsn_t lsn;
        int level;
 
-       dprintf(("hpfs_readdir(0x%x, 0x%x, 0x%lx): ",
+       dprintf(("hpfs_readdir(0x%x, 0x%x, 0x%zx): ",
                hp->h_no, (u_int32_t)uio->uio_offset, uio->uio_resid));
 
        /*
@@ -965,6 +965,7 @@ hpfs_lookup(struct vop_old_lookup_args *ap)
        struct hpfsmount *hpmp = dhp->h_hpmp;
        struct componentname *cnp = ap->a_cnp;
        struct ucred *cred = cnp->cn_cred;
+       struct vnode **vpp = ap->a_vpp;
        int error;
        int nameiop = cnp->cn_nameiop;
        int flags = cnp->cn_flags;
@@ -972,6 +973,7 @@ hpfs_lookup(struct vop_old_lookup_args *ap)
 #if HPFS_DEBUG
        int wantparent = flags & (CNP_LOCKPARENT | CNP_WANTPARENT);
 #endif
+       *vpp = NULL;
        dprintf(("hpfs_lookup(0x%x, %s, %ld, %d, %d): \n",
                dhp->h_no, cnp->cn_nameptr, cnp->cn_namelen,
                lockparent, wantparent));
@@ -990,7 +992,7 @@ hpfs_lookup(struct vop_old_lookup_args *ap)
                dprintf(("hpfs_lookup(0x%x,...): . faked\n",dhp->h_no));
 
                vref(dvp);
-               *ap->a_vpp = dvp;
+               *vpp = dvp;
 
                return (0);
        } else if( (cnp->cn_namelen == 2) &&
@@ -1001,14 +1003,14 @@ hpfs_lookup(struct vop_old_lookup_args *ap)
                VOP__UNLOCK(dvp, 0);
 
                error = VFS_VGET(hpmp->hpm_mp, NULL,
-                                dhp->h_fn.fn_parent, ap->a_vpp); 
+                                dhp->h_fn.fn_parent, vpp);
                if (error) {
                        VOP__LOCK(dvp, 0);
                        return(error);
                }
 
                if (lockparent && (error = VOP__LOCK(dvp, 0))) {
-                       vput( *(ap->a_vpp) );
+                       vput(*vpp);
                        return (error);
                }
                return (error);
@@ -1022,8 +1024,10 @@ hpfs_lookup(struct vop_old_lookup_args *ap)
                if (error) {
                        if (error == ENOENT && 
                            (nameiop == NAMEI_CREATE || nameiop == NAMEI_RENAME)) {
-                               if(!lockparent)
+                               if(!lockparent) {
+                                       cnp->cn_flags |= CNP_PDIRUNLOCK;
                                        VOP__UNLOCK(dvp, 0);
+                               }
                                return (EJUSTRETURN);
                        }
 
@@ -1044,18 +1048,18 @@ hpfs_lookup(struct vop_old_lookup_args *ap)
                if (dhp->h_no == dep->de_fnode) {
                        brelse(bp);
                        vref(dvp);
-                       *ap->a_vpp = dvp;
+                       *vpp = dvp;
                        return (0);
                }
 
-               error = VFS_VGET(hpmp->hpm_mp, NULL, dep->de_fnode, ap->a_vpp);
+               error = VFS_VGET(hpmp->hpm_mp, NULL, dep->de_fnode, vpp);
                if (error) {
                        kprintf("hpfs_lookup: VFS_VGET FAILED %d\n", error);
                        brelse(bp);
                        return(error);
                }
 
-               hp = VTOHP(*ap->a_vpp);
+               hp = VTOHP(*vpp);
 
                hp->h_mtime = dep->de_mtime;
                hp->h_ctime = dep->de_ctime;
@@ -1067,8 +1071,10 @@ hpfs_lookup(struct vop_old_lookup_args *ap)
 
                brelse(bp);
 
-               if(!lockparent)
+               if(!lockparent) {
+                       cnp->cn_flags |= CNP_PDIRUNLOCK;
                        VOP__UNLOCK(dvp, 0);
+               }
        }
        return (error);
 }