PERFORCE change 194685 for review

Ilya Putsikau ilya at FreeBSD.org
Mon Jun 13 15:38:07 UTC 2011


http://p4web.freebsd.org/@@194685?ac=10

Change 194685 by ilya at ilya_triton2011 on 2011/06/13 15:37:47

	Simplify fuse_vfs_root, root vnode is handed by fuse_vnode_get
	Simplify fuse_vfs_statfs, merge macfuse
	Remove VFS hash comparators

Affected files ...

.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vfsops.c#10 edit

Differences ...

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vfsops.c#10 (text+ko) ====

@@ -40,9 +40,6 @@
 #define PRIV_VFS_FUSE_SYNC_UNMOUNT PRIV_VFS_MOUNT_NONUSER
 #endif
 
-
-static vfs_hash_cmp_t fuse_vnode_bgdrop_cmp;
-
 static vfs_mount_t fuse_vfs_mount;
 static vfs_unmount_t fuse_vfs_unmount;
 static vfs_root_t fuse_vfs_root;
@@ -69,57 +66,6 @@
 
 extern struct vop_vector fuse_vnops;
 
-/******************
- *
- * >>> VFS hash comparators
- *
- ******************/
-
-int
-fuse_vnode_cmp(struct vnode *vp, void *nidp)
-{
-	return (VTOI(vp) != *((uint64_t *)nidp));
-}
-
-/*
- * This comparator is used for safely setting the parent_nid.
- */
-
-int
-fuse_vnode_setparent_cmp(struct vnode *vp, void *param)
-{
-	struct parentmanager_param *pmp = param;
-
-	if (VTOI(vp) == pmp->nodeid) {
-		KASSERT(! pmp->valid,
-		        ("more than one vnode seems to match #%llu",
-			 (unsigned long long)pmp->nodeid));
-		VTOFUD(vp)->parent_nid = pmp->parent_nid;
-		pmp->valid = 1;
-	}
-
-	return (1);
-}
-
-/*
- * Vnode comparison function which expicitly marks
- * clashing vnodes as unhashed (via setting id to 0)
- * before dropping them. So at gc time we'll know if
- * we have to remove the node from the hash.
- */
-
-static int
-fuse_vnode_bgdrop_cmp(struct vnode *vp, void *param)
-{
-	struct fuse_vnode_data *fvdat = param;
-
-	if (VTOI(vp) != fvdat->nid)
-		return (1);
-
-	fvdat->nid = FUSE_NULL_ID;
-	return (0);
-}
-
 /*************
  *
  * >>> VFS ops
@@ -541,309 +487,68 @@
     return (0);
 }        
 
-/* stolen from portalfs */
 static int
-fuse_vfs_root(struct mount *mp, int flags, struct vnode **vpp)
+fuse_vfs_root(struct mount *mp, int lkflags, struct vnode **vpp)
 {
-	/*
-	 * Return locked reference to root.
-	 */
-	struct thread *td = curthread;
-	struct fuse_data *data = fusefs_get_data(mp);
-	struct vnode *vp;
+    int err;
 
-	DEBUG2G("mp %p: %s\n", mp, mp->mnt_stat.f_mntfromname);
-
-	if (! data) {
-		struct fuse_secondary_data *fsdat = fusefs_get_secdata(mp);
-		int err;
-
-		data = fsdat->master;
-		sx_slock(&data->mhierlock);
-		if (data->mpri == FM_PRIMARY)
-			err = fuse_vfs_root(data->mp, flags, vpp);
-		else
-			err = ENXIO;
-		sx_sunlock(&data->mhierlock);
-		return (err);
-	}
-
-	vp = data->rvp;
-	vref(vp);
-	vn_lock(vp, flags | LK_RETRY);
-	if (vp->v_type == VNON) {
-		struct vattr va;
-
-		(void)VOP_GETATTR(vp, &va, td->td_ucred);
-	}
-	*vpp = vp;
-#if _DEBUG2G
-	DEBUG2G("root node:\n");
-	vn_printf(vp, " * ");
-#endif
-	return (0);
+    err = fuse_vnode_get(mp, FUSE_ROOT_ID, NULL, vpp, NULL, VDIR, 0);
+    return (err);
 }
 
 static int
 fuse_vfs_statfs(struct mount *mp, struct statfs *sbp)
 {
-	struct thread *td = curthread;
-	struct fuse_dispatcher fdi;
-	struct fuse_statfs_out *fsfo;
-	struct fuse_data *data;
-	int err = 0;	
+    struct fuse_dispatcher fdi;
+    struct fuse_statfs_out *fsfo;
+    struct fuse_data *data;
+    int err = 0;	
 
-	DEBUG2G("mp %p: %s\n", mp, mp->mnt_stat.f_mntfromname);
-	data = fusefs_get_data(mp);
+    DEBUG2G("mp %p: %s\n", mp, mp->mnt_stat.f_mntfromname);
+    data = fusefs_get_data(mp);
 
-	if (! data) {
-		struct fuse_secondary_data *fsdat;
+    if (!(data->dataflag & FSESS_INITED))
+        goto fake;
 
-		fsdat = fusefs_get_secdata(mp);
-		data = fsdat->master;
+    if ((err = fdisp_simple_vfs_statfs(&fdi, mp))) {
+        if (err == ENOTCONN) {
+            /*
+             * We want to seem a legitimate fs even if the daemon
+             * is stiff dead... (so that, eg., we can still do path
+             * based unmounting after the daemon dies).
+             */
+            goto fake;
+        }
+        return (err);
+    }
 
-		sx_slock(&data->mhierlock);
-		if (data->mpri == FM_PRIMARY)
-			err = fuse_vfs_statfs(data->mp, sbp);
-		else
-			err = ENXIO;
-		sx_sunlock(&data->mhierlock);
-		return (err);
-	}
+    fsfo = fdi.answ;
 
-	if (! (data->dataflag & FSESS_INITED))
-		goto fake;
+    sbp->f_blocks  = fsfo->st.blocks;
+    sbp->f_bfree   = fsfo->st.bfree;
+    sbp->f_bavail  = fsfo->st.bavail;
+    sbp->f_files   = fsfo->st.files;
+    sbp->f_ffree   = fsfo->st.ffree; /* cast from uint64_t to int64_t */
+    sbp->f_namemax = fsfo->st.namelen;
+    sbp->f_bsize   = fsfo->st.frsize; /* cast from uint32_t to uint64_t */
 
-	if ((err = fdisp_simple_putget(&fdi, FUSE_STATFS, data->rvp, td,
-	    NULL))) {
-		if (err == ENOTCONN)
-			/*
-			 * We want to seem a legitimate fs even if the daemon
-			 * is stiff dead... (so that, eg., we can still do path
-			 * based unmounting after the daemon dies).
-			 */
-			goto fake;
+    DEBUG("fuse_statfs_out -- blocks: %llu, bfree: %llu, bavail: %llu, "
+        "files: %llu, ffree: %llu, bsize: %i, namelen: %i\n",
+        (unsigned long long)fsfo->st.blocks, (unsigned long long)fsfo->st.bfree,
+        (unsigned long long)fsfo->st.bavail, (unsigned long long)fsfo->st.files,
+        (unsigned long long)fsfo->st.ffree, fsfo->st.bsize, fsfo->st.namelen);
 
-		return (err);
-	}
+    fuse_ticket_drop(fdi.tick);
 
-	fsfo = fdi.answ;
-
-	sbp->f_blocks  = fsfo->st.blocks;
-	sbp->f_bfree   = fsfo->st.bfree;
-	sbp->f_bavail  = fsfo->st.bavail;
-	sbp->f_files   = fsfo->st.files;
-	sbp->f_ffree   = fsfo->st.ffree; /* cast from uint64_t to int64_t */
-	sbp->f_namemax = fsfo->st.namelen;
-	if (fuse_libabi_geq(fusefs_get_data(mp), 7, 3)) {
-		/*
-		 * fuse_kstatfs is created from a struct statvfs, we can fill
-		 * the statfs struct by inverting sfs2svfs() of lib/libc/gen/statvfs.c
-		 */
-#if 0
-		/*
-		 * This would pretty much **ck up buffered IO,
-		 * since this would overwrite mnt_stat.f_iosize
-		 */
-		sbp->f_iosize  = fsfo->st.bsize; /* cast from uint32_t to uint64_t */
-#endif
-		sbp->f_bsize = 0; /* userspace data is broken ... */
-#if FUSE_KERNELABI_GEQ(7, 4)
-		if (fuse_libabi_geq(fusefs_get_data(mp), 7, 4))
-			/* ... unless both kernel and userspace speak 7.4 */
-			sbp->f_bsize = fsfo->st.frsize; /* cast from uint32_t to uint64_t */
-#endif
-	} else
-		/*
-		 * fuse_kstatfs is also created from a struct statfs,
-		 * conversion is direct
-		 */
-		sbp->f_bsize = fsfo->st.bsize; /* cast from uint32_t to uint64_t */
-
-	DEBUG("fuse_statfs_out -- blocks: %llu, bfree: %llu, bavail: %llu, files: %llu, ffree: %llu, bsize: %i, namelen: %i\n",
-	(unsigned long long)fsfo->st.blocks, (unsigned long long)fsfo->st.bfree, (unsigned long long)fsfo->st.bavail, (unsigned long long)fsfo->st.files, (unsigned long long)fsfo->st.ffree, fsfo->st.bsize, fsfo->st.namelen);
-
-	fuse_ticket_drop(fdi.tick);
-
-	return (0);
+    return (0);
 fake:
-        sbp->f_blocks  = 0;
-	sbp->f_bfree   = 0;
-	sbp->f_bavail  = 0;
-	sbp->f_files   = 0;
-	sbp->f_ffree   = 0;
-	sbp->f_namemax = 0;
-	sbp->f_bsize   = 0;
+    sbp->f_blocks  = 0;
+    sbp->f_bfree   = 0;
+    sbp->f_bavail  = 0;
+    sbp->f_files   = 0;
+    sbp->f_ffree   = 0;
+    sbp->f_namemax = 0;
+    sbp->f_bsize   = 0;
 
-	return (0);
-}
-
-/*
- *  ..._i, as "internal" -- we don't need to register it as a VFS op,
- *  so we might alter from the VFS_VGET signature
- */
-
-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)
-{
-#define myflags LK_EXCLUSIVE | LK_RETRY
-	int err = 0;
-	struct fuse_vnode_data *fvdat;
-	struct vnode *vp2;
-
-	DEBUG("been asked for vno #%llu, parent #%llu\n",
-	        (long long unsigned)nodeid, (long long unsigned)parentid);
-
-	if (vtyp == VNON)
-		return (EINVAL);
-
-	if (nodeid == FUSE_ROOT_ID) {
-		if (parentid != FUSE_NULL_ID)
-			return (ENOENT);
-		err = VFS_ROOT(mp, myflags, vpp);
-		if (err)
-			return (err);
-		KASSERT(*vpp, ("we neither err'd nor found the root node"));
-		goto found;
-	}
-
-	/*
-	 * With vmod == VG_WANTNEW, caller wants to get a vnode for the id
-	 * only if it's a new one. Hence, no use of trying to get
-	 * to get one with the given id.
-	 */
-	if (vmod == VG_WANTNEW)
-		*vpp = NULL;
-	else if ((err = vfs_hash_get(mp, nodeid, /*flags*/ myflags, td, vpp,
-		                     fuse_vnode_cmp, &nodeid)))
-		return (err);
-
-	/*
-	 * If vmod == VG_FORCENEW, we also want a new vnode, but instead of
-	 * just bitching when there is an old one with the given id, we
-	 * go and search & destroy those ones...
-	 */
-	 if (*vpp && vmod == VG_FORCENEW) {
-		fuse_vnode_teardown(*vpp, td, NULL, vtyp);
-		*vpp = NULL;
-	}
-
-audit:
-	if (*vpp) {
-		DEBUG("vnode taken from hash\n");
-		if ((*vpp)->v_type == vtyp) {
-			if (vtyp == VDIR && parentid != FUSE_NULL_ID &&
-			    VTOFUD(*vpp)->parent_nid != parentid) {
-				DEBUG("parent mismatch\n");
-				if (VTOFUD(*vpp)->parent_nid == FUSE_NULL_ID) {
-					/*
-					 * Deleted directory is to be reused.
-					 * We adjust the nodeid to the new scenario.
-					 */
-					struct parentmanager_param pmp;
-					struct vnode *xvp;
-
-					DEBUG("dir has no parent, pushing in required\n");
-					pmp.nodeid = nodeid;
-					pmp.parent_nid = parentid;
-					pmp.valid = 0;
-					err = vfs_hash_get(mp, pmp.nodeid, 0,
-					                   td, &xvp,
-					                   fuse_vnode_setparent_cmp,
-					                   &pmp);
-					KASSERT(xvp == NULL,
-					        ("findparent routine has fetched a vnode"));
-				} else
-					/* parent mismatch for a directory */
-					err = EIO;
-
-				if (err) {
-					vput(*vpp);
-					*vpp = NULL;
-					return (err);
-				}
-			}
-			goto found;
-		} else if ((*vpp)->v_type == VNON) {
-			DEBUG2G("vnode #%llu with no type\n", VTOILLU(*vpp));
-			(*vpp)->v_type = vtyp;
-			goto found;
-		} else {
-			fuse_vnode_ditch(*vpp, td);
-			vput(*vpp);
-		}
-	} else if (parentid == FUSE_NULL_ID) {
-		DEBUG("no vpp, no parentid => ENOENT\n");
-		*vpp = NULL;
-		return (ENOENT);
-	}
-
-	/* as the big guys say, malloc for your data before getnewvnode() */
-
-	fvdat = malloc(sizeof(*fvdat), M_FUSEVN, M_WAITOK | M_ZERO);
-	err = getnewvnode("fuse", mp, &fuse_vnops, vpp);
-#if _DEBUG
-	DEBUG2G("allocated new vnode:\n");
-	vn_printf(*vpp, " * ");
-#endif
-
-	if (err) {
-	        free(fvdat, M_FUSEVN);
-		VNASSERT(! *vpp, *vpp,
-		         ("Maybe I misunderstood how getnewvnode() works..."));
-	        return (err);
-	}
-
-	err = vn_lock(*vpp, myflags);
-	if (err)
-		printf("fuse4bsd: leaking vnode %p\n", *vpp);
-	else
-		err = insmntque(*vpp, mp);
-	if (err) {
-	        free(fvdat, M_FUSEVN);
-	        return (err);
-	}
-
-	/*
-	 * There is no harm in fully initializing the vnode before trying
-	 * at insertion, because vnodes are gc-d anyway. For the same reason,
-	 * they _do_ have to be fully initialized here -- the gc routines should
-	 * get the node in an as much predictable state as it's possible.
-	 */
-	fuse_vnode_init(*vpp, fvdat, nodeid, vtyp, parentid);
-	err = vfs_hash_insert(*vpp, nodeid, /*flags*/ myflags, td, &vp2,
-	                      fuse_vnode_bgdrop_cmp, fvdat);
-
-	if (err) {
-		free(fvdat, M_FUSEVN);
-		/* XXX do something to tear down allocated inode?
-		 * (other fss' code doesn't, so neither I...)
-		 */ 
-		return (err);
-	}
-
-	if (vp2) {
-		DEBUG("gee, vfs hash collision for node #%llu\n", (unsigned long long)nodeid);
-		if (vmod == VG_WANTNEW) {
-			vput(vp2);
-			*vpp = NULL;
-			return (EEXIST);
-		} else if (vmod == VG_FORCENEW) {
-			fuse_vnode_teardown(vp2, td, NULL, vtyp);
-			*vpp = NULL;
-			goto audit;
-		}
-		vpp = &vp2;
-		goto audit;
-	}
-
-found:
-#if _DEBUG
-	DEBUG2G("\n");
-	vn_printf(*vpp, " * ");
-#endif
-	return (0);
-#undef myflags
+    return (0);
 }


More information about the p4-projects mailing list