From owner-p4-projects@FreeBSD.ORG Mon Jun 13 15:33:43 2011 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 7D918106576E; Mon, 13 Jun 2011 15:33:43 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2571F1065674 for ; Mon, 13 Jun 2011 15:33:43 +0000 (UTC) (envelope-from ilya@FreeBSD.org) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:4f8:fff6::2d]) by mx1.freebsd.org (Postfix) with ESMTP id 134E18FC15 for ; Mon, 13 Jun 2011 15:33:43 +0000 (UTC) Received: from skunkworks.freebsd.org (localhost [127.0.0.1]) by skunkworks.freebsd.org (8.14.4/8.14.4) with ESMTP id p5DFXgcS074435 for ; Mon, 13 Jun 2011 15:33:42 GMT (envelope-from ilya@FreeBSD.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.4/8.14.4/Submit) id p5DFXgkM074432 for perforce@freebsd.org; Mon, 13 Jun 2011 15:33:42 GMT (envelope-from ilya@FreeBSD.org) Date: Mon, 13 Jun 2011 15:33:42 GMT Message-Id: <201106131533.p5DFXgkM074432@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to ilya@FreeBSD.org using -f From: Ilya Putsikau To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 194682 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 13 Jun 2011 15:33:43 -0000 http://p4web.freebsd.org/@@194682?ac=10 Change 194682 by ilya@ilya_triton2011 on 2011/06/13 15:33:26 Restore vfs_hash and original node creations on FreeBSD Affected files ... .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.c#2 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#4 edit Differences ... ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.c#2 (text+ko) ==== @@ -3,173 +3,165 @@ * Amit Singh */ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "fuse.h" +#include "fuse_node.h" +#include "fuse_internal.h" #include "fuse_ipc.h" -#include "fuse_locking.h" -#include "fuse_node.h" + +#include +#include + +static void +fuse_vnode_init(struct vnode *vp, struct fuse_vnode_data *fvdat, + uint64_t nodeid, enum vtype vtyp) +{ + fvdat->nid = nodeid; + if (nodeid == FUSE_ROOT_ID) { + vp->v_vflag |= VV_ROOT; + } + vp->v_type = vtyp; + vp->v_data = fvdat; + mtx_init(&fvdat->createlock, "fuse node create mutex", NULL, MTX_DEF); + sx_init(&fvdat->nodelock, "fuse node sx lock"); + sx_init(&fvdat->truncatelock, "fuse node truncate sx lock"); +} void -FSNodeScrub(struct fuse_vnode_data *fvdat) +fuse_vnode_destroy(struct vnode *vp) { - lck_mtx_destroy(fvdat->createlock, fuse_lock_group); - lck_rw_destroy(fvdat->nodelock, fuse_lock_group); - lck_rw_destroy(fvdat->truncatelock, fuse_lock_group); - fvdat->fMagic = kFSNodeBadMagic; -} + struct fuse_vnode_data *fvdat = vp->v_data; + + vp->v_data = NULL; + mtx_destroy(&fvdat->createlock); + sx_destroy(&fvdat->nodelock); + sx_destroy(&fvdat->truncatelock); + free(fvdat, M_FUSEVN); +} -errno_t -FSNodeGetOrCreateFileVNodeByID(mount_t mp, - uint64_t nodeid, - vnode_t dvp, - enum vtype vtyp, - uint64_t insize, - vnode_t *vnPtr, - int flags) +static int +fuse_vnode_cmp(struct vnode *vp, void *nidp) { - int err; - int junk; - vnode_t vn; - HNodeRef hn; - vnode_t dirVN; - dev_t dummy_device; - struct fuse_vnode_data *fvdat = NULL; - struct fuse_data *mntdata; - int markroot = FALSE; - uint64_t size = 0; + return (VTOI(vp) != *((uint64_t *)nidp)); +} - if (insize == 0xffffffff) { - markroot = TRUE; - } else { - size = insize; - } +static uint32_t __inline +fuse_vnode_hash(uint64_t id) +{ + return (fnv_32_buf(&id, sizeof(id), FNV1_32_INIT)); +} - hn = NULL; - vn = NULL; - dirVN = NULL; +static int +fuse_vnode_alloc(struct mount *mp, + struct thread *td, + uint64_t nodeid, + enum vtype vtyp, + int lkflags, + struct vnode **vpp) +{ + struct fuse_vnode_data *fvdat; + struct vnode *vp2; + int err = 0; - mntdata = vfs_fsprivate(mp); - dummy_device = (dev_t)mntdata->fdev; + DEBUG("been asked for vno #%ju\n", (uintmax_t)nodeid); - err = HNodeLookupCreatingIfNecessary(dummy_device, - (ino_t)nodeid, // XXXXXXXX - 0 /* fork index */, - &hn, - &vn); - if ((err == 0) && (vn == NULL)) { + if (vtyp == VNON) { + return EINVAL; + } - struct vnode_fsparam params; - fvdat = (struct fuse_vnode_data *)FSNodeGenericFromHNode(hn); - if (!fvdat->fInitialised) { - int k; - fvdat->fMagic = kFSNodeMagic; - fvdat->fInitialised = TRUE; - fvdat->nid = nodeid; - fvdat->vtype = vtyp; - fvdat->parent = NULL; - fvdat->filesize = size; - fvdat->newfilesize = 0; - fvdat->nlookup = 0; - if (dvp) { - fvdat->parent_nid = VTOFUD(dvp)->nid; - } else { - fvdat->parent_nid = 0; - } - for (k = 0; k < FUFH_MAXTYPE; k++) { - fvdat->fufh[k].fufh_flags = 0; - } - fvdat->createlock = lck_mtx_alloc_init(fuse_lock_group, fuse_lock_attr); - fvdat->nodelock = lck_rw_alloc_init(fuse_lock_group, fuse_lock_attr); - fvdat->truncatelock = lck_rw_alloc_init(fuse_lock_group, fuse_lock_attr); - fvdat->creator = current_thread(); - fvdat->flag = flags; - //LIST_INIT(&fvdat->fh_head); - } + *vpp = NULL; + err = vfs_hash_get(mp, fuse_vnode_hash(nodeid), lkflags, td, vpp, + fuse_vnode_cmp, &nodeid); + if (err) + return (err); - if (err == 0) { - params.vnfs_mp = mp; - params.vnfs_vtype = vtyp; - params.vnfs_str = NULL; - params.vnfs_dvp = NULL; // dvp; XXXXXXXXXXXXXXXXXXXXXXXXXX - params.vnfs_fsnode = hn; - params.vnfs_vops = fuse_vnode_operations; - params.vnfs_marksystem = FALSE; - params.vnfs_rdev = 0; - params.vnfs_cnp = NULL; - params.vnfs_flags = VNFS_NOCACHE | VNFS_CANTCACHE; - params.vnfs_filesize = size; - params.vnfs_markroot = markroot; + if (*vpp) { + MPASS((*vpp)->v_type == vtyp && (*vpp)->v_data != NULL); + DEBUG("vnode taken from hash\n"); + return (0); + } - err = vnode_create(VNCREATE_FLAVOR, sizeof(params), ¶ms, &vn); - } + lkflags = LK_EXCLUSIVE | LK_RETRY; /* XXXIP don't loose other flags */ - if (err == 0) { - HNodeAttachVNodeSucceeded(hn, 0 /* forkIndex */, vn); - if (markroot == TRUE) { - fvdat->parent = vn; - } - } else { - if (HNodeAttachVNodeFailed(hn, 0 /* forkIndex */)) { - FSNodeScrub(fvdat); - HNodeScrubDone(hn); - } - } + fvdat = malloc(sizeof(*fvdat), M_FUSEVN, M_WAITOK | M_ZERO); + err = getnewvnode("fuse", mp, &fuse_vnops, vpp); + if (err) { + free(fvdat, M_FUSEVN); + return (err); } - if (err == 0) { - *vnPtr = vn; - vnode_settag(vn, VT_KERNFS); + vn_lock(*vpp, lkflags); + err = insmntque(*vpp, mp); + if (err) { + free(fvdat, M_FUSEVN); + return (err); } - if (dirVN != NULL) { - junk = vnode_put(dirVN); - /* assert(junk == 0); */ + fuse_vnode_init(*vpp, fvdat, nodeid, vtyp); + err = vfs_hash_insert(*vpp, fuse_vnode_hash(nodeid), lkflags, + td, &vp2, fuse_vnode_cmp, &nodeid); + + if (err) { + fuse_vnode_destroy(*vpp); + *vpp = NULL; + return (err); } - /* assert((err == 0) == (*vnPtr != NULL); */ + /* + * XXXIP: Prevent silent vnode reuse. It may happen because several fuse + * filesystems ignore inode numbers + */ + KASSERT(vp2 == NULL, + ("vfs hash collision for node #%ju\n", (uintmax_t)nodeid)); - return err; + return (0); } int -fuse_vget_i(mount_t mp, - uint64_t nodeid, - vfs_context_t context, - vnode_t dvp, - vnode_t *vpp, - struct componentname *cnp, - enum vtype vtyp, - uint64_t size, - enum vget_mode mode, - uint64_t parentid) +fuse_vnode_get(struct mount *mp, + uint64_t nodeid, + struct vnode *dvp, + struct vnode **vpp, + struct componentname *cnp, + enum vtype vtyp, + uint64_t size) { + struct thread *td = (cnp != NULL ? cnp->cn_thread : curthread); int err = 0; debug_printf("dvp=%p\n", dvp); - if (vtyp == VNON) { - return EINVAL; - } - -#if 0 //XROOT - if (nodeid == FUSE_ROOT_ID) { - *vpp = fusefs_get_data(mp)->rvp; //XROOT - err = vnode_get(*vpp); - if (err) { - *vpp = NULLVP; - return err; - } - goto found; - } -#endif - - err = FSNodeGetOrCreateFileVNodeByID(mp, nodeid, dvp, vtyp, size, vpp, 0); + err = fuse_vnode_alloc(mp, td, nodeid, vtyp, LK_EXCLUSIVE | LK_RETRY, vpp); if (err) { return err; } - cache_enter(dvp, *vpp, cnp); + if (cnp != NULL) { + cache_enter(dvp, *vpp, cnp); + } -found: VTOFUD(*vpp)->nlookup++; return 0; ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#4 (text+ko) ==== @@ -10,22 +10,14 @@ #include #include "fuse_file.h" -#include "fuse_nodehash.h" -enum { - kFSNodeMagic = 1, - kFSNodeBadMagic = 2, - kHNodeMagic = 3, -}; - #define FN_CREATING 0x00000001 struct fuse_vnode_data { - uint32_t fMagic; - boolean_t fInitialised; uint64_t nid; uint64_t nlookup; enum vtype vtype; + /* XXXIP very likely to be stale, it's not updated in rename() */ uint64_t parent_nid; struct mtx createlock; @@ -40,16 +32,17 @@ * modified. Typically, we would take this lock at the beginning of a * vnop and drop it at the end of the vnop. */ - struct sx *nodelock; + struct sx nodelock; void *nodelockowner; /* * The truncatelock guards against the EOF changing on us (that is, a * file resize) unexpectedly. */ - struct sx *truncatelock; + struct sx truncatelock; struct vnode *c_vp; + /* XXXIP reference is very likely to be stale, it's not updated in rename() */ struct vnode *parent; off_t filesize; off_t newfilesize; @@ -59,13 +52,11 @@ struct vattr cached_attrs; struct timespec cached_attrs_valid; }; -typedef struct fuse_vnode_data * fusenode_t; -#define VTOFUD(vp) \ - ((struct fuse_vnode_data *)FSNodeGenericFromHNode((vp)->v_data)) +#define VTOFUD(vp) ((struct fuse_vnode_data *)((vp)->v_data)) #define VTOI(vp) (VTOFUD(vp)->nid) #define VTOVA(vp) (&(VTOFUD(vp)->cached_attrs)) -#define VTOILLU(vp) ((unsigned long long)(VTOFUD(vp) ? VTOI(vp) : 0)) +#define VTOILLU(vp) ((uint64_t)(VTOFUD(vp) ? VTOI(vp) : 0)) #define FUSE_NULL_ID 0 @@ -79,17 +70,6 @@ MALLOC_DECLARE(M_FUSEVN); -vfs_hash_cmp_t fuse_vnode_cmp; -vfs_hash_cmp_t fuse_vnode_setparent_cmp; - -void fuse_vnode_init(struct vnode *vp, struct fuse_vnode_data *fvdat, - uint64_t nodeid, enum vtype vtyp, uint64_t parentid); -void fuse_vnode_ditch(struct vnode *vp, struct thread *td); -void fuse_vnode_teardown(struct vnode *vp, struct thread *td, - struct ucred *cred, enum vtype vtyp); - -enum vget_mode { VG_NORMAL, VG_WANTNEW, VG_FORCENEW }; - struct get_filehandle_param { enum fuse_opcode opcode; uint8_t do_gc:1; @@ -116,37 +96,17 @@ #define C_CREATING 0x04000 #define C_ACCESS_NOOP 0x08000 -int -FSNodeGetOrCreateFileVNodeByID(struct mount *mp, - uint64_t nodeid, - struct vnode *dvp, - enum vtype vtyp, - uint64_t insize, - struct vnode **vnPtr, - int flags); +extern struct vop_vector fuse_vnops; -void FSNodeScrub(struct fuse_vnode_data *fvdat); +void fuse_vnode_destroy(struct vnode *vp); int -fuse_vget_i(struct mount *mp, - struct thread *td, - uint64_t nodeid, - enum vtype vtyp, - struct vnode **vpp, - enum vget_mode vmod, - uint64_t parentid); -#ifdef XXXIP -int -fuse_vget_i(struct mount *mp, - uint64_t nodeid, - vfs_context_t context, - struct vnode *dvp, - struct vnode *vpp, - struct componentname *cnp, - enum vtype vtyp, - uint64_t size, - enum vget_mode mode, - uint64_t parentid); -#endif +fuse_vnode_get(struct mount *mp, + uint64_t nodeid, + struct vnode *dvp, + struct vnode **vpp, + struct componentname *cnp, + enum vtype vtyp, + uint64_t size); #endif /* _FUSE_NODE_H_ */