PERFORCE change 194384 for review

Ilya Putsikau ilya at FreeBSD.org
Tue Jun 7 10:57:22 UTC 2011


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

Change 194384 by ilya at ilya_triton2011 on 2011/06/07 10:56:33

	fuse_vnops.c reduce diffs

Affected files ...

.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#9 edit

Differences ...

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#9 (text+ko) ====

@@ -348,18 +348,22 @@
 static int
 fuse_vnop_access(struct vop_access_args *ap)
 {
-	struct vnode *vp = ap->a_vp;
-	struct fuse_access_param facp;
-	struct fuse_vnode_data *fvdat = VTOFUD(vp);
+    struct vnode *vp = ap->a_vp;
+    struct fuse_access_param facp;
+    struct fuse_vnode_data *fvdat = VTOFUD(vp);
+
+    fuse_trace_printf_vnop();
+
+    bzero(&facp, sizeof(facp));
 
-	bzero(&facp, sizeof(facp));
-	if (fvdat->flags & FVP_ACCESS_NOOP)
-		fvdat->flags &= ~FVP_ACCESS_NOOP;
-	else
-		facp.facc_flags |= FACCESS_DO_ACCESS;
+    if (fvdat->flags & FVP_ACCESS_NOOP) {
+            fvdat->flags &= ~FVP_ACCESS_NOOP;
+    } else {
+            facp.facc_flags |= FACCESS_DO_ACCESS;
+    }
 
-	return fuse_internal_access(vp, ap->a_accmode,
-	    ap->a_cred, ap->a_td, &facp);
+    return fuse_internal_access(vp, ap->a_accmode,
+        ap->a_cred, ap->a_td, &facp);
 }
 
 /*
@@ -373,20 +377,20 @@
 static int
 fuse_vnop_close(struct vop_close_args *ap)
 {
-	struct fuse_release_param frp;
+    struct fuse_release_param frp;
 
-	DEBUG2G("vnode #%llu\n", VTOILLU(ap->a_vp));
-	frp.err = 0;
+    DEBUG2G("vnode #%llu\n", VTOILLU(ap->a_vp));
+    frp.err = 0;
 #if FUSE_HAS_FLUSH_RELEASE
-	frp.fg = 1;
-	frp.flush = 1;
+    frp.fg = 1;
+    frp.flush = 1;
 #else
-	frp.fg = 0;
-	frp.flush = 0;
+    frp.fg = 0;
+    frp.flush = 0;
 #endif
-	fuse_filehandle_gc(ap->a_vp, ap->a_td, ap->a_cred, &frp);
+    fuse_filehandle_gc(ap->a_vp, ap->a_td, ap->a_cred, &frp);
 
-	return (frp.err);
+    return (frp.err);
 }
 
 /*
@@ -400,57 +404,57 @@
 static int
 fuse_vnop_create(struct vop_create_args *ap)
 {
-	struct vnode *dvp = ap->a_dvp;
-	struct vnode **vpp = ap->a_vpp;
-	struct vattr *vap = ap->a_vap;
+    struct vnode *dvp = ap->a_dvp;
+    struct vnode **vpp = ap->a_vpp;
+    struct vattr *vap = ap->a_vap;
 #if FUSE_HAS_CREATE
-	struct fuse_vnode_data *fvdat;
-	int err;
+    struct fuse_vnode_data *fvdat;
+    int err;
 
-	if (vap->va_type != VREG ||
-	    fusefs_get_data(dvp->v_mount)->dataflag & FSESS_NOCREATE)
-		goto good_old;
+    if (vap->va_type != VREG ||
+        fusefs_get_data(dvp->v_mount)->dataflag & FSESS_NOCREATE)
+            goto good_old;
 
-	/*
-	 * We cobble together here a new vnode as the caller expects that,
-	 * but we don't yet fully initialize it (that will happen when it
-	 * will be opened). We keep it in a "germic" state.
-	 */
-	if ((err = getnewvnode("fuse", dvp->v_mount, &fuse_vnops, vpp)))
-		return (err);
+    /*
+     * We cobble together here a new vnode as the caller expects that,
+     * but we don't yet fully initialize it (that will happen when it
+     * will be opened). We keep it in a "germic" state.
+     */
+    if ((err = getnewvnode("fuse", dvp->v_mount, &fuse_vnops, vpp)))
+            return (err);
 
-	if ((err = vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY))) {
-		printf("fuse4bsd: leaking vnode %p\n", *vpp);
-		return (err);
-	}
+    if ((err = vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY))) {
+            printf("fuse4bsd: leaking vnode %p\n", *vpp);
+            return (err);
+    }
 
-	fvdat = malloc(sizeof(*fvdat), M_FUSEVN, M_WAITOK | M_ZERO);
+    fvdat = malloc(sizeof(*fvdat), M_FUSEVN, M_WAITOK | M_ZERO);
 
-	fvdat->parent_nid = VTOI(dvp);
-	/*
-	 * We overload some fields of the vnode data to carry the information
-	 * which will be needed to make the proper CREATE query in open.
-	 * germcnp is a dedicated field for this purpose though.
-	 */
-	fvdat->flags = MAKEIMODE(vap->va_type, vap->va_mode);
-	fvdat->germcnp = ap->a_cnp;
+    fvdat->parent_nid = VTOI(dvp);
+    /*
+     * We overload some fields of the vnode data to carry the information
+     * which will be needed to make the proper CREATE query in open.
+     * germcnp is a dedicated field for this purpose though.
+     */
+    fvdat->flags = MAKEIMODE(vap->va_type, vap->va_mode);
+    fvdat->germcnp = ap->a_cnp;
 
-	/*
-	 * Stub vnops, almost the same as "dead", with the exception of the
-	 * critical ones which will let the vnode get fully emerged.
-	 */
-	(*vpp)->v_op = &fuse_germ_vnops;
-	(*vpp)->v_data = fvdat;
-	(*vpp)->v_mount = dvp->v_mount;
+    /*
+     * Stub vnops, almost the same as "dead", with the exception of the
+     * critical ones which will let the vnode get fully emerged.
+     */
+    (*vpp)->v_op = &fuse_germ_vnops;
+    (*vpp)->v_data = fvdat;
+    (*vpp)->v_mount = dvp->v_mount;
 
-	fuse_invalidate_attr(dvp);
+    fuse_invalidate_attr(dvp);
 
-	return (0);
+    return (0);
 
 good_old:
 #endif
-	vap->va_rdev = 0;
-	return (VOP_MKNOD(dvp, vpp, ap->a_cnp, vap));
+    vap->va_rdev = 0;
+    return (VOP_MKNOD(dvp, vpp, ap->a_cnp, vap));
 }
 
 /*
@@ -477,84 +481,85 @@
 static int
 fuse_vnop_fsync(struct vop_fsync_args *ap)
 {
-	struct vnode *vp = ap->a_vp;
-	struct thread *td = ap->a_td;
+    struct vnode *vp = ap->a_vp;
+    struct thread *td = ap->a_td;
+    struct fuse_dispatcher fdi;
 
-	int err = 0;
-	struct fuse_dispatcher fdi;
+    int err = 0;
 
-	DEBUG("got flag %d\n", ap->a_waitfor);
+    DEBUG("got flag %d\n", ap->a_waitfor);
 
-	/*
-	 * Usually, the call to vop_stdfsync is expected to do nothing, as we
-	 * tend to leave no dirty buffers behind. However, they might show up,
-	 * eg., after an interrupted write.
-	 * To be able to release the kernel's cleanup-dirty-buffers machinery
-	 * this is advised to be inserted here.
-	 */
+    /*
+     * Usually, the call to vop_stdfsync is expected to do nothing, as we
+     * tend to leave no dirty buffers behind. However, they might show up,
+     * eg., after an interrupted write.
+     * To be able to release the kernel's cleanup-dirty-buffers machinery
+     * this is advised to be inserted here.
+     */
 
-	if ((err = vop_stdfsync(ap)))
-		return (err); 
+    if ((err = vop_stdfsync(ap)))
+        return (err); 
 
-	/*	
-	 * In Linux, the fsync syscall handler is file based.
-	 * Hence in fuse too -- and this approach does make sense,
-	 * for exapmle, when it comes to implementing things like
-	 * sshfs: the sshfs userspace fsync handler flushes data
-	 * associated with the given filehandle, ie. sftp
-	 * messaging thread.
-	 * 
-	 * On the other hand, BSD fsync is inherently not file
-	 * but vnode based: even fsync(2), to which one passes
-	 * a file descriptor, the corresponding file is used for 
-	 * nothing but looking up the vnode behind (see fsync() 
-	 * in kern/vfs_syscalls.c).
-	 *
-	 * We have thus two choices here: either grab the first
-	 * open file and use that for the fsync message or run
-	 * through all files (at least, the ones we have acces to,
-	 * ie., those belonging to the current process). The first
-	 * is bad: as we mentioned concerning sshfs, dirty data can belong
-	 * to each ssh messaging thread, being associated to file
-	 * handles independently. 
-	 *
-	 * So we wanna sync all our open files. "Nowait" sync is easy,
-	 * just walk over all the files, and send FUSE_FSYNC(DIR) with
-	 * a null callback, and leave. "Wait" sync is harder: syncing
-	 * the files linearly, one after the other would be very easy
-	 * indeed but would be far more than a lethal dose of the KISS
-	 * principle. So sending of the messages and waiting for them
-	 * should be done synchronously. The messaging backend is flexible
-	 * enough for making the implementation of this not too hard, 
-	 * but now I don't wanna go mucking with the proper handling of
-	 * interrupts, and other issues; and I don't wanna break the nice
-	 * hi-level messaging API which serves us well otherwise. So
-	 * currently I just say no here...
-	 *
-	 * Just to note: even the "nowait" type fsync could be optimized
-	 * if we went beyond the api, and lock/unlock all mutexes (tickets',
-	 * messages', callbacks') only once, and take out/put in stuff for all
-	 * files together, with one big breath. But doing not so is not as much
-	 * overhead as it would be worth for the trouble.
-	 */
+    /*	
+     * In Linux, the fsync syscall handler is file based.
+     * Hence in fuse too -- and this approach does make sense,
+     * for exapmle, when it comes to implementing things like
+     * sshfs: the sshfs userspace fsync handler flushes data
+     * associated with the given filehandle, ie. sftp
+     * messaging thread.
+     * 
+     * On the other hand, BSD fsync is inherently not file
+     * but vnode based: even fsync(2), to which one passes
+     * a file descriptor, the corresponding file is used for 
+     * nothing but looking up the vnode behind (see fsync() 
+     * in kern/vfs_syscalls.c).
+     *
+     * We have thus two choices here: either grab the first
+     * open file and use that for the fsync message or run
+     * through all files (at least, the ones we have acces to,
+     * ie., those belonging to the current process). The first
+     * is bad: as we mentioned concerning sshfs, dirty data can belong
+     * to each ssh messaging thread, being associated to file
+     * handles independently. 
+     *
+     * So we wanna sync all our open files. "Nowait" sync is easy,
+     * just walk over all the files, and send FUSE_FSYNC(DIR) with
+     * a null callback, and leave. "Wait" sync is harder: syncing
+     * the files linearly, one after the other would be very easy
+     * indeed but would be far more than a lethal dose of the KISS
+     * principle. So sending of the messages and waiting for them
+     * should be done synchronously. The messaging backend is flexible
+     * enough for making the implementation of this not too hard, 
+     * but now I don't wanna go mucking with the proper handling of
+     * interrupts, and other issues; and I don't wanna break the nice
+     * hi-level messaging API which serves us well otherwise. So
+     * currently I just say no here...
+     *
+     * Just to note: even the "nowait" type fsync could be optimized
+     * if we went beyond the api, and lock/unlock all mutexes (tickets',
+     * messages', callbacks') only once, and take out/put in stuff for all
+     * files together, with one big breath. But doing not so is not as much
+     * overhead as it would be worth for the trouble.
+     */
 
-	/*
-	 * It seemed to be a good idea to lock the filehandle lock only before
-	 * doing iterate_filehandle but that configuration is suspected to cause
-	 * LOR alerts, so now we get the filehandle lock before the fuse_data
-	 * lock.
-	 */
-	ASSERT_VOP_LOCKED__FH(vp);
+    /*
+     * It seemed to be a good idea to lock the filehandle lock only before
+     * doing iterate_filehandle but that configuration is suspected to cause
+     * LOR alerts, so now we get the filehandle lock before the fuse_data
+     * lock.
+     */
+    ASSERT_VOP_LOCKED__FH(vp);
 
-	if (fusefs_get_data(vp->v_mount)->dataflag &
-            (vp->v_type == VDIR ? FSESS_NOFSYNCDIR : FSESS_NOFSYNC))
-		goto out;
+    if (fusefs_get_data(vp->v_mount)->dataflag &
+        (vp->v_type == VDIR ? FSESS_NOFSYNCDIR : FSESS_NOFSYNC)) {
+        goto out;
+    }
 
-	fdisp_init(&fdi, 0);
-	iterate_filehandles(vp, td, NULL, fuse_fsync_filehandle, &fdi);
+    fdisp_init(&fdi, 0);
+    iterate_filehandles(vp, td, NULL, fuse_fsync_filehandle, &fdi);
 
 out:
-	return (err);
+    return (err);
 }
 
 /*
@@ -717,58 +722,62 @@
 static int
 fuse_vnop_link(struct vop_link_args *ap)
 {
-	struct vnode *dvp = ap->a_tdvp;
-	struct vnode *vp = ap->a_vp;
-	struct componentname *cnp = ap->a_cnp;
+    struct vnode *vp = ap->a_vp;
+    struct vnode *tdvp = ap->a_tdvp;
+    struct componentname *cnp = ap->a_cnp;
+
+    int err = 0;
+    struct fuse_dispatcher fdi;
+    struct fuse_entry_out *feo;
+    struct fuse_link_in    fli;
+
+    fuse_trace_printf_vnop();
 
-	struct fuse_dispatcher fdi;
-	struct fuse_link_in fli; 
-	struct fuse_entry_out *feo;
-	int err = 0;
+    if (tdvp->v_mount != vp->v_mount) {
+            return (EXDEV);
+    }
 
-	if (dvp->v_mount != vp->v_mount)
-		return (EXDEV);
+    fli.oldnodeid = VTOI(vp);
 
-	fli.oldnodeid = VTOI(vp);
+    /*
+     * Unlike Linux, we proceed here lazily: here we do nothing on
+     * the kernel side for registering the new, hardlinked entry.
+     * (That will just happen when the hardlinked entry is looked up
+     * first time). We just send the request to the daemon.
+     * This suits better for the BSD VFS.
+     */
 
-	/*
-	 * Unlike Linux, we proceed here lazily: here we do nothing on
-	 * the kernel side for registering the new, hardlinked entry.
-	 * (That will just happen when the hardlinked entry is looked up
-	 * first time). We just send the request to the daemon.
-	 * This suits better for the BSD VFS.
-	 */
+    fdisp_init(&fdi, 0);
+    fuse_internal_newentry_makerequest(tdvp->v_mount, VTOI(tdvp), cnp,
+                                       FUSE_LINK, &fli, sizeof(fli), &fdi);
+    if ((err = fdisp_wait_answ(&fdi))) {
+        return (err);
+    }
 
-	fdisp_init(&fdi, 0);
-	fuse_internal_newentry_makerequest(dvp->v_mount, VTOI(dvp), cnp, FUSE_LINK, &fli,
-	                    sizeof(fli), &fdi);
-	if ((err = fdisp_wait_answ(&fdi)))
-		return (err);
-	
-	feo = fdi.answ;
+    feo = fdi.answ;
 
-	err = fuse_internal_checkentry(feo, vp->v_type);
+    err = fuse_internal_checkentry(feo, vp->v_type);
 
-	fuse_ticket_drop(fdi.tick);
-	fuse_invalidate_attr(dvp);
-	/*
-	 * It depends on userspace if the hardlinked entry is really the
-	 * same vnode or not. Sort of unconventionally, the latter happens
-	 * if linking is managed by the hi-level FUSE library (in which case
-	 * syncing between the two nodes is up to the actual fs code).
-	 * Therefore we can't just cache the attrs we got for the hardlink node,
-	 * -- that regards to the hardlinked node and not the original.
-	 * What we do instead is invalidating cached attrs of the original so
-	 * the fs gets a chance to pass on updated attributes also for the
-	 * original node.
-	 *
-	 * See also remark at the similar place in the Linux kernel code.
-	 */
-	fuse_invalidate_attr(vp);
+    fuse_ticket_drop(fdi.tick);
+    fuse_invalidate_attr(tdvp);
+    /*
+     * It depends on userspace if the hardlinked entry is really the
+     * same vnode or not. Sort of unconventionally, the latter happens
+     * if linking is managed by the hi-level FUSE library (in which case
+     * syncing between the two nodes is up to the actual fs code).
+     * Therefore we can't just cache the attrs we got for the hardlink node,
+     * -- that regards to the hardlinked node and not the original.
+     * What we do instead is invalidating cached attrs of the original so
+     * the fs gets a chance to pass on updated attributes also for the
+     * original node.
+     *
+     * See also remark at the similar place in the Linux kernel code.
+     */
+    fuse_invalidate_attr(vp);
 
-	VTOFUD(vp)->nlookup++;
+    VTOFUD(vp)->nlookup++;
 
-	return (err);
+    return (err);
 }
 
 /*
@@ -782,412 +791,419 @@
 int
 fuse_vnop_lookup(struct vop_lookup_args *ap)
 {
-        struct vnode *dvp         = ap->a_dvp;
-        struct vnode **vpp        = ap->a_vpp;
-        struct componentname *cnp = ap->a_cnp;
-	int nameiop = cnp->cn_nameiop;
-	struct thread *td = cnp->cn_thread;
-	struct ucred *cred = cnp->cn_cred;
-	int flags = cnp->cn_flags;
-	int wantparent = flags & WANTPARENT;
-	int islastcn = flags & ISLASTCN;
+    struct componentname *cnp = ap->a_cnp;
+    int nameiop               = cnp->cn_nameiop;
+    int flags                 = cnp->cn_flags;
+    int wantparent            = flags & WANTPARENT;
+    int islastcn              = flags & ISLASTCN;
+    struct vnode *dvp         = ap->a_dvp;
+    struct vnode **vpp        = ap->a_vpp;
+    struct thread *td         = cnp->cn_thread;
+    struct ucred *cred        = cnp->cn_cred;
+
+    fuse_trace_printf_vnop();
 
-	int err = 0;
-	int lookup_err = 0;
-	struct vnode *vp = NULL;
-	struct fuse_dispatcher fdi;
-	struct fuse_attr *fattr = NULL;
-	enum fuse_opcode op;
-	uint64_t nid;
-	uint64_t parentid;
-	struct fuse_access_param facp;
+    int err                   = 0;
+    int lookup_err            = 0;
+    struct vnode *vp          = NULL;
+    struct fuse_attr *fattr   = NULL;
+    struct fuse_dispatcher fdi;
+    enum fuse_opcode op;
+    uint64_t nid, parentid;
+    struct fuse_access_param facp;
 #ifdef INVARIANTS
-	int cache_attrs_hit = 0;
+    int cache_attrs_hit = 0;
 #endif
 
-	/* general stuff, based on vfs_cache_lookup */
+    /* general stuff, based on vfs_cache_lookup */
 
 #if _DEBUG
-	DEBUG2G("root node:\n");
-	vn_printf(fusefs_get_data(dvp->v_mount)->rvp, " * ");
+    DEBUG2G("root node:\n");
+    vn_printf(fusefs_get_data(dvp->v_mount)->rvp, " * ");
 #endif
 
-	if (dvp->v_type != VDIR) {
-		DEBUG("vnode #%llu of vtype %d is not a dir\n", VTOILLU(dvp),
-		      dvp->v_type); 
-		return (ENOTDIR);
-	}
+    if (dvp->v_type != VDIR) {
+        return ENOTDIR;
+    }
 
-	if (islastcn && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
-	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
-		return (EROFS);
+    if (islastcn && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
+        (nameiop == DELETE || nameiop == RENAME)) {
+        return (EROFS);
+    }
 
-	/*
-	 * We do access check prior to doing anything else only in the case
-	 * when we are at fs root (we'd like to say, "we are at the first
-	 * component", but that's not exactly the same... nevermind).
-	 * See further comments at further access checks.
-	 */
+    /*
+     * We do access check prior to doing anything else only in the case
+     * when we are at fs root (we'd like to say, "we are at the first
+     * component", but that's not exactly the same... nevermind).
+     * See further comments at further access checks.
+     */
 
-	bzero(&facp, sizeof(facp));
-	if (
+    bzero(&facp, sizeof(facp));
+    if (
 #ifdef NO_EARLY_PERM_CHECK_HACK
-	    1
+        1
 #else
-	    dvp->v_vflag & VV_ROOT
+        dvp->v_vflag & VV_ROOT
 #endif
-	   ) {
-		if ((err = fuse_internal_access(dvp, VEXEC, cred, td, &facp)))
-			return (err);
-	}
+       ) {
+            if ((err = fuse_internal_access(dvp, VEXEC, cred, td, &facp)))
+                return err;
+    }
 
-	DEBUG2G("lookup in #%llu, nameiop %lu, with flags %#x\n",
-	        VTOILLU(dvp), cnp->cn_nameiop, flags);
+    DEBUG2G("lookup in #%llu, nameiop %lu, with flags %#x\n",
+            VTOILLU(dvp), cnp->cn_nameiop, flags);
 
-	/* fetching data from "storage" */
+    /* fetching data from "storage" */
 
-	if (flags & ISDOTDOT) {
-		DEBUG2G("dotdot lookup!\n");
-		nid = VTOFUD(dvp)->parent_nid;
-		parentid = FUSE_NULL_ID;
-		fdisp_init(&fdi, 0);
-		op = FUSE_GETATTR;
-	} else if (cnp->cn_namelen == 1 && *(cnp->cn_nameptr) == '.') {
-		DEBUG2G("dot lookup!\n");
-		nid = VTOI(dvp);
-		parentid = VTOFUD(dvp)->parent_nid; /* irrelevant */
-		fdisp_init(&fdi, 0);
-		op = FUSE_GETATTR;
-	} else {
-		nid = VTOI(dvp);
-		parentid = VTOI(dvp);
-		fdisp_init(&fdi, cnp->cn_namelen + 1);
-		op = FUSE_LOOKUP;
-	}
+    if (flags & ISDOTDOT) {
+        DEBUG2G("dotdot lookup!\n");
+        nid = VTOFUD(dvp)->parent_nid;
+        parentid = FUSE_NULL_ID;
+        fdisp_init(&fdi, 0);
+        op = FUSE_GETATTR;
+    } else if (cnp->cn_namelen == 1 && *(cnp->cn_nameptr) == '.') {
+        DEBUG2G("dot lookup!\n");
+        nid = VTOI(dvp);
+        parentid = VTOFUD(dvp)->parent_nid; /* irrelevant */
+        fdisp_init(&fdi, 0);
+        op = FUSE_GETATTR;
+    } else {
+        nid = VTOI(dvp);
+        parentid = VTOI(dvp);
+        fdisp_init(&fdi, cnp->cn_namelen + 1);
+        op = FUSE_LOOKUP;
+    }
 
-	fdisp_make(&fdi, dvp->v_mount, op, nid, td, cred);
+    fdisp_make(&fdi, dvp->v_mount, op, nid, td, cred);
 
-	if (op == FUSE_LOOKUP) {
-		memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen);
-		((char *)fdi.indata)[cnp->cn_namelen] = '\0';
-		DEBUG2G("standard lookup, looking up %s\n", (char *)fdi.indata);
-	}
+    if (op == FUSE_LOOKUP) {
+        memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen);
+        ((char *)fdi.indata)[cnp->cn_namelen] = '\0';
+        DEBUG2G("standard lookup, looking up %s\n", (char *)fdi.indata);
+    }
 
-	lookup_err = fdisp_wait_answ(&fdi);
+    lookup_err = fdisp_wait_answ(&fdi);
 
-	if (op == FUSE_LOOKUP && ! lookup_err) {
-		nid = ((struct fuse_entry_out *)fdi.answ)->nodeid;
-		if (! nid) {
-			/*
-			 * zero nodeid is the same as "not found",
-			 * but it's also cacheable (which we keep
-			 * keep on doing not as of writing this)
-			 */
-			DEBUG2G("zero nid, ie ENOENT\n");
-			lookup_err = ENOENT;
-		} else if (nid == FUSE_ROOT_ID) {
-			DEBUG2G("root inode found on lookup?!!\n");
-			lookup_err = EINVAL;
-		}
-	}
+    if (op == FUSE_LOOKUP && !lookup_err) {
+        nid = ((struct fuse_entry_out *)fdi.answ)->nodeid;
+        if (!nid) {
+            /*
+             * zero nodeid is the same as "not found",
+             * but it's also cacheable (which we keep
+             * keep on doing not as of writing this)
+             */
+            DEBUG2G("zero nid, ie ENOENT\n");
+            lookup_err = ENOENT;
+        } else if (nid == FUSE_ROOT_ID) {
+            DEBUG2G("root inode found on lookup?!!\n");
+            lookup_err = EINVAL;
+        }
+    }
 
-	if (lookup_err && (
-	     (! fdi.answ_stat) || /* this means messaging error */
-	     lookup_err != ENOENT || /* daemon reported other error than "legal" ENOENT */
-	     op != FUSE_LOOKUP /* we tolerate ENOENT only when we sent a LOOKUP */  
-            )) {
-		/*
-		 * There is error but not lookup related actually
-		 * (messaging error)
-		 */
-		DEBUG("lookup failed b/c messaging crap\n");
-		return (lookup_err);
-	}
+    if (lookup_err && (
+         (!fdi.answ_stat) || /* this means messaging error */
+         lookup_err != ENOENT || /* daemon reported other error than "legal" ENOENT */
+         op != FUSE_LOOKUP /* we tolerate ENOENT only when we sent a LOOKUP */  
+        )) {
+        /*
+         * There is error but not lookup related actually
+         * (messaging error)
+         */
+        DEBUG("lookup failed b/c messaging crap\n");
+        return (lookup_err);
+    }
 
-	/* analyzing answer */
+    /* analyzing answer */
 
-	/*
-	 * Now we got the answer and filtered out the crap, too, so we know that
-	 * "found" iff lookup_err == 0
-	 */
+    /*
+     * Now we got the answer and filtered out the crap, too, so we know that
+     * "found" iff lookup_err == 0
+     */
 
-	if (lookup_err) {
-		DEBUG("looked up thingy not found\n");
-		if ((nameiop == CREATE || nameiop == RENAME)
-		 && islastcn
-		 /* && directory dvp has not been removed */) {
+    if (lookup_err) {
+        DEBUG("looked up thingy not found\n");
+        if ((nameiop == CREATE || nameiop == RENAME)
+         && islastcn
+         /* && directory dvp has not been removed */) {
 
-			if (dvp->v_mount->mnt_flag & MNT_RDONLY) {
-				err = EROFS;
-				goto out;
-			}
+                if (dvp->v_mount->mnt_flag & MNT_RDONLY) {
+                        err = EROFS;
+                        goto out;
+                }
 
-			DEBUG("create/rename -- we have to make it\n");
-			/*
-			 * Check for write access on directory.
-			 */
-			
-			if ((err = fuse_internal_access(dvp, VWRITE, cred, td, &facp)))
-				goto out;
+                DEBUG("create/rename -- we have to make it\n");
+                /*
+                 * Check for write access on directory.
+                 */
+                
+                if ((err = fuse_internal_access(dvp, VWRITE, cred, td, &facp)))
+                        goto out;
 
-			/*
-			 * Possibly record the position of a slot in the
-			 * directory large enough for the new component name.
-			 * This can be recorded in the vnode private data for
-			 * dvp. Set the SAVENAME flag to hold onto the
-			 * pathname for use later in VOP_CREATE or VOP_RENAME.
-			 */
-			cnp->cn_flags |= SAVENAME;
-			
-			err = EJUSTRETURN;
-			goto out;
-		}
+                /*
+                 * Possibly record the position of a slot in the
+                 * directory large enough for the new component name.
+                 * This can be recorded in the vnode private data for
+                 * dvp. Set the SAVENAME flag to hold onto the
+                 * pathname for use later in VOP_CREATE or VOP_RENAME.
+                 */
+                cnp->cn_flags |= SAVENAME;
+                
+                err = EJUSTRETURN;
+                goto out;
+        }
 
-		/*
-		 * Consider inserting name into cache.
-		 */
+        /*
+         * Consider inserting name into cache.
+         */
 
-		/*
-		 * No we can't use negative caching, as the fs
-		 * changes are out of our control.
-		 * False positives' falseness turns out just as things
-		 * go by, but false negatives' falseness doesn't.
-		 * (and aiding the caching mechanism with extra control
-		 * mechanisms comes quite close to beating the whole purpose
-		 * caching...)
-		 */
+        /*
+         * No we can't use negative caching, as the fs
+         * changes are out of our control.
+         * False positives' falseness turns out just as things
+         * go by, but false negatives' falseness doesn't.
+         * (and aiding the caching mechanism with extra control
+         * mechanisms comes quite close to beating the whole purpose
+         * caching...)
+         */
 #if 0
-		if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) {
-			DEBUG("inserting NULL into cache\n");
-			cache_enter(dvp, NULL, cnp);
-		}
+        if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) {
+            DEBUG("inserting NULL into cache\n");
+            cache_enter(dvp, NULL, cnp);
+        }
 #endif
-		err = ENOENT;
-		goto out;
-	} else {
-		if (op == FUSE_GETATTR)
-			fattr = &((struct fuse_attr_out *)fdi.answ)->attr;
-		else
-			fattr = &((struct fuse_entry_out *)fdi.answ)->attr;
+        err = ENOENT;
+        goto out;
+
+    } else {
+        if (op == FUSE_GETATTR) {
+            fattr = &((struct fuse_attr_out *)fdi.answ)->attr;
+        } else {
+            fattr = &((struct fuse_entry_out *)fdi.answ)->attr;
+        }
 
-		DEBUG("we found something...\n");
-		/*
-		 * If deleting, and at end of pathname, return parameters
-		 * which can be used to remove file.  If the wantparent flag
-		 * isn't set, we return only the directory, otherwise we go on
-		 * and lock the inode, being careful with ".".
-		 */
-		if (nameiop == DELETE && islastcn) {
-			DEBUG("something to delete\n");
-			/*
-			 * Check for write access on directory.
-			 */
+        DEBUG("we found something...\n");
+        /*
+         * If deleting, and at end of pathname, return parameters
+         * which can be used to remove file.  If the wantparent flag
+         * isn't set, we return only the directory, otherwise we go on
+         * and lock the inode, being careful with ".".
+         */
+        if (nameiop == DELETE && islastcn) {
+            DEBUG("something to delete\n");
+            /*
+             * Check for write access on directory.
+             */
 
-			facp.xuid = fattr->uid;
-			facp.facc_flags |= FACCESS_STICKY;
-			err = fuse_internal_access(dvp, VWRITE, cred, td, &facp);
-			facp.facc_flags &= ~FACCESS_XQUERIES;
+            facp.xuid = fattr->uid;
+            facp.facc_flags |= FACCESS_STICKY;
+            err = fuse_internal_access(dvp, VWRITE, cred, td, &facp);
+            facp.facc_flags &= ~FACCESS_XQUERIES;
 
-			if (err)
-				goto out;
+            if (err) {
+                goto out;
+            }
 
-			if (nid == VTOI(dvp)) {
-				VREF(dvp);
-				*vpp = dvp;
-				goto out;
-			}
+            if (nid == VTOI(dvp)) {
+                VREF(dvp);
+                *vpp = dvp;
+                goto out;
+            }
 
-			err = fuse_vget_i(dvp->v_mount, td, nid,
-			                  IFTOVT(fattr->mode), &vp, VG_NORMAL,
-                                          parentid);
-			if (err)
-				goto out;
-			*vpp = vp;
+            if ((err = fuse_vget_i(dvp->v_mount, td,
+                                   nid,
+                                   IFTOVT(fattr->mode),
+                                   &vp,
+                                   VG_NORMAL,
+                                   parentid))) {
+                    goto out;
+            }
 
-			goto out;
-		}
+            *vpp = vp;
+        
+            goto out;
+            }
 
-		/*
-		 * If rewriting (RENAME), return the inode and the
-		 * information required to rewrite the present directory
-		 * Must get inode of directory entry to verify it's a
-		 * regular file, or empty directory.
-		 */
-		if (nameiop == RENAME && wantparent && islastcn) {
-			DEBUG("something to rename...\n");
+            /*
+             * If rewriting (RENAME), return the inode and the
+             * information required to rewrite the present directory
+             * Must get inode of directory entry to verify it's a
+             * regular file, or empty directory.
+             */
+            if (nameiop == RENAME && wantparent && islastcn) {
+                    DEBUG("something to rename...\n");
 
-			facp.xuid = fattr->uid;
-			facp.facc_flags |= FACCESS_STICKY;
-			err = fuse_internal_access(dvp, VWRITE, cred, td, &facp);
-			facp.facc_flags &= ~FACCESS_XQUERIES;
+                    facp.xuid = fattr->uid;
+                    facp.facc_flags |= FACCESS_STICKY;
+                    err = fuse_internal_access(dvp, VWRITE, cred, td, &facp);
+                    facp.facc_flags &= ~FACCESS_XQUERIES;
 
-			if (err)
-				goto out;
+                    if (err)
+                            goto out;
 
-			/*
-			 * Check for "."
-			 */
-			if (nid == VTOI(dvp)) {
-				err = EISDIR;
-				goto out;
-			}
+                    /*
+                     * Check for "."
+                     */
+                    if (nid == VTOI(dvp)) {
+                            err = EISDIR;
+                            goto out;
+                    }
 
-			err = fuse_vget_i(dvp->v_mount, td, nid,
-			                  IFTOVT(fattr->mode), &vp, VG_NORMAL,
-			                  parentid);
-			if (err)
-				goto out;
-			*vpp = vp;
-			/*
-			 * Save the name for use in VOP_RENAME later.
-			 */
-			cnp->cn_flags |= SAVENAME;
+                    err = fuse_vget_i(dvp->v_mount, td, nid,
+                                      IFTOVT(fattr->mode), &vp, VG_NORMAL,
+                                      parentid);
+                    if (err)
+                            goto out;
+                    *vpp = vp;
+                    /*
+                     * Save the name for use in VOP_RENAME later.
+                     */
+                    cnp->cn_flags |= SAVENAME;
 
-			goto out;
-		}
+                    goto out;
+            }
 
-		DEBUG("we peacefully found that file\n");
+            DEBUG("we peacefully found that file\n");
 
-		if (nid == VTOI(dvp)) {
-			VREF(dvp); /* We want ourself, ie "." */
-			*vpp = dvp;
-		} else {
-			if (flags & ISDOTDOT)
-				/*
-				 * If doing dotdot, we unlock dvp for vget time
-				 * to conform lock order regulations.
-				 */
-				VOP_UNLOCK(dvp, 0);
-			err = fuse_vget_i(dvp->v_mount, td, nid,
-			                  IFTOVT(fattr->mode), &vp, VG_NORMAL,
-			                  parentid);
-			if (flags & ISDOTDOT)
-				vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
-			if (err)
-				goto out;
-			*vpp = vp;
-		}
+            if (nid == VTOI(dvp)) {
+                    VREF(dvp); /* We want ourself, ie "." */
+                    *vpp = dvp;
+            } else {
+                    if (flags & ISDOTDOT)
+                            /*
+                             * If doing dotdot, we unlock dvp for vget time
+                             * to conform lock order regulations.
+                             */
+                            VOP_UNLOCK(dvp, 0);
+                    err = fuse_vget_i(dvp->v_mount, td, nid,
+                                      IFTOVT(fattr->mode), &vp, VG_NORMAL,
+                                      parentid);
+                    if (flags & ISDOTDOT)
+                            vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
+                    if (err)
+                            goto out;
+                    *vpp = vp;
+            }
 
-		if (op == FUSE_GETATTR)
-			cache_attrs(*vpp, (struct fuse_attr_out *)fdi.answ);
-		else
-			cache_attrs(*vpp, (struct fuse_entry_out *)fdi.answ);
+        if (op == FUSE_GETATTR)
+            cache_attrs(*vpp, (struct fuse_attr_out *)fdi.answ);
+        else
+            cache_attrs(*vpp, (struct fuse_entry_out *)fdi.answ);
 
 #ifdef INVARIANTS
-		cache_attrs_hit = 1;
+            cache_attrs_hit = 1;
 #endif
 
-		/* Insert name into cache if appropriate. */
+        /* Insert name into cache if appropriate. */
 
-		/*
-		 * Nooo, caching is evil. With caching, we can't avoid stale
-		 * information taking over the playground (cached info is not
-		 * just positive/negative, it does have qualitative aspects,
-		 * too). And a (VOP/FUSE)_GETATTR is always thrown anyway, when
-		 * walking down along cached path components, and that's not
-		 * any cheaper than FUSE_LOOKUP. This might change with
-		 * implementing kernel side attr caching, but... In Linux,
-		 * lookup results are not cached, and the daemon is bombarded
-		 * with FUSE_LOOKUPS on and on. This shows that by design, the
-		 * daemon is expected to handle frequent lookup queries
-		 * efficiently, do its caching in userspace, and so on.
-		 *
-		 * So just leave the name cache alone.
-		 */

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list