From 376a18e40fa97f618844a15f499d342b4c47d4a7 Mon Sep 17 00:00:00 2001 From: Alex Hornung Date: Fri, 24 Feb 2012 16:09:21 +0000 Subject: [PATCH] puffs - check whether the FS has the given op * Previously calls to some of the vnops that are unimplemented in the actual puffs filesystem were succeeding. * We now check whether the op exists before trying to pass it to the userland FS. If it doesn't exist, fail (or return ok if no real action needs to be taken). --- sys/vfs/puffs/puffs_vnops.c | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/sys/vfs/puffs/puffs_vnops.c b/sys/vfs/puffs/puffs_vnops.c index 26c446c934..d04b8d499b 100644 --- a/sys/vfs/puffs/puffs_vnops.c +++ b/sys/vfs/puffs/puffs_vnops.c @@ -259,6 +259,9 @@ puffs_vnop_create(struct vop_ncreate_args *ap) struct puffs_mount *pmp = MPTOPUFFSMP(mp); int error; + if (!EXISTSOP(pmp, CREATE)) + return EOPNOTSUPP; + DPRINTF(("puffs_create: dvp %p, name: %s\n", dvp, ncp->nc_name)); @@ -314,6 +317,9 @@ puffs_vnop_mknod(struct vop_nmknod_args *ap) struct puffs_mount *pmp = MPTOPUFFSMP(mp); int error; + if (!EXISTSOP(pmp, MKNOD)) + return EOPNOTSUPP; + DPRINTF(("puffs_mknod: dvp %p, name: %s\n", dvp, ncp->nc_name)); @@ -396,6 +402,9 @@ puffs_vnop_close(struct vop_close_args *ap) struct vnode *vp = ap->a_vp; struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); + if (!EXISTSOP(pmp, CLOSE)) + return vop_stdclose(ap); + PUFFS_MSG_ALLOC(vn, close); puffs_msg_setfaf(park_close); close_msg->pvnr_fflag = ap->a_fflag; @@ -722,6 +731,9 @@ puffs_vnop_readdir(struct vop_readdir_args *ap) size_t howmuch, resid; int error; + if (!EXISTSOP(pmp, READDIR)) + return EOPNOTSUPP; + /* * ok, so we need: resid + cookiemem = maxreq * => resid + cookiesize * (resid/minsize) = maxreq @@ -925,6 +937,9 @@ puffs_vnop_remove(struct vop_nremove_args *ap) struct puffs_mount *pmp = MPTOPUFFSMP(mp); int error; + if (!EXISTSOP(pmp, REMOVE)) + return EOPNOTSUPP; + error = vget(dvp, LK_EXCLUSIVE); if (error != 0) { DPRINTF(("puffs_vnop_remove: EAGAIN on parent vnode %p %s\n", @@ -982,6 +997,9 @@ puffs_vnop_mkdir(struct vop_nmkdir_args *ap) struct puffs_mount *pmp = MPTOPUFFSMP(mp); int error; + if (!EXISTSOP(pmp, MKDIR)) + return EOPNOTSUPP; + if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { DPRINTF(("puffs_vnop_mkdir: EAGAIN on ncp %p %s\n", ncp, ncp->nc_name)); @@ -1050,6 +1068,9 @@ puffs_vnop_rmdir(struct vop_nrmdir_args *ap) struct ucred *cred = ap->a_cred; int error; + if (!EXISTSOP(pmp, RMDIR)) + return EOPNOTSUPP; + error = vget(dvp, LK_EXCLUSIVE); if (error != 0) { DPRINTF(("puffs_vnop_rmdir: EAGAIN on parent vnode %p %s\n", @@ -1107,6 +1128,9 @@ puffs_vnop_link(struct vop_nlink_args *ap) struct ucred *cred = ap->a_cred; int error; + if (!EXISTSOP(pmp, LINK)) + return EOPNOTSUPP; + if (vp->v_mount != dvp->v_mount) return EXDEV; @@ -1159,6 +1183,9 @@ puffs_vnop_symlink(struct vop_nsymlink_args *ap) struct ucred *cred = ap->a_cred; int error; + if (!EXISTSOP(pmp, SYMLINK)) + return EOPNOTSUPP; + if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) { DPRINTF(("puffs_vnop_symlink: EAGAIN on ncp %p %s\n", ncp, ncp->nc_name)); @@ -1207,6 +1234,9 @@ puffs_vnop_readlink(struct vop_readlink_args *ap) size_t linklen; int error; + if (!EXISTSOP(pmp, READLINK)) + return EOPNOTSUPP; + PUFFS_MSG_ALLOC(vn, readlink); puffs_credcvt(&readlink_msg->pvnr_cred, ap->a_cred); linklen = sizeof(readlink_msg->pvnr_link); @@ -1249,6 +1279,9 @@ puffs_vnop_rename(struct vop_nrename_args *ap) int error; boolean_t doabort = TRUE; + if (!EXISTSOP(pmp, RENAME)) + return EOPNOTSUPP; + error = vget(tdvp, LK_EXCLUSIVE); if (error != 0) { DPRINTF(("puffs_vnop_rename: EAGAIN on tdvp vnode %p %s\n", @@ -1327,6 +1360,9 @@ puffs_vnop_read(struct vop_read_args *ap) struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); int error; + if (!EXISTSOP(pmp, READ)) + return EOPNOTSUPP; + if (vp->v_type == VDIR) return EISDIR; else if (vp->v_type != VREG) @@ -1350,6 +1386,9 @@ puffs_vnop_write(struct vop_write_args *ap) struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); int error; + if (!EXISTSOP(pmp, WRITE)) + return EOPNOTSUPP; + if (vp->v_type == VDIR) return EISDIR; else if (vp->v_type != VREG) @@ -1400,6 +1439,9 @@ puffs_vnop_pathconf(struct vop_pathconf_args *ap) struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); int error; + if (!EXISTSOP(pmp, PATHCONF)) + return EOPNOTSUPP; + PUFFS_MSG_ALLOC(vn, pathconf); pathconf_msg->pvnr_name = ap->a_name; puffs_msg_setinfo(park_pathconf, PUFFSOP_VN, -- 2.41.0