PERFORCE change 194682 for review
Ilya Putsikau
ilya at FreeBSD.org
Mon Jun 13 15:33:43 UTC 2011
http://p4web.freebsd.org/@@194682?ac=10
Change 194682 by ilya at 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 <singh@>
*/
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+#include <sys/errno.h>
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/uio.h>
+#include <sys/malloc.h>
+#include <sys/queue.h>
+#include <sys/lock.h>
+#include <sys/sx.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/vnode.h>
+#include <sys/namei.h>
+#include <sys/mount.h>
+#include <sys/sysctl.h>
+#include <sys/fcntl.h>
+#include <sys/fnv_hash.h>
+
#include "fuse.h"
+#include "fuse_node.h"
+#include "fuse_internal.h"
#include "fuse_ipc.h"
-#include "fuse_locking.h"
-#include "fuse_node.h"
+
+#include <sys/priv.h>
+#include <security/mac/mac_framework.h>
+
+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 <sys/mutex.h>
#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_ */
More information about the p4-projects
mailing list