Date: Sat, 9 Jul 2011 08:56:13 GMT From: Ilya Putsikau <ilya@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 195923 for review Message-ID: <201107090856.p698uDS1043125@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@195923?ac=10 Change 195923 by ilya@ilya_triton2011 on 2011/07/09 08:55:40 Save root vnode reference Add fuse_isvalid_attr Add sysctls to control data cache and mmap Add debug messages, remove unused code Affected files ... .. //depot/projects/soc2011/ilya_fuse/fuse_module/config.h#2 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse.h#13 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_device.c#9 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.c#11 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.h#5 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.c#16 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.h#16 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.c#14 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.h#7 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_ipc.c#10 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_ipc.h#11 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_kernel.h#2 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_main.c#7 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.c#14 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#14 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_param.h#4 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vfsops.c#19 edit .. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#35 edit Differences ... ==== //depot/projects/soc2011/ilya_fuse/fuse_module/config.h#2 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse.h#13 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_device.c#9 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.c#11 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.h#5 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.c#16 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.h#16 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.c#14 (text+ko) ==== @@ -91,7 +91,7 @@ * we hardwire it into the file's private data (similarly to Linux, * btw.). */ - directio = (flag & O_DIRECT); + directio = (flag & O_DIRECT) || !fuse_vnode_cache_enable(vp); switch (uio->uio_rw) { case UIO_READ: ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.h#7 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_ipc.c#10 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_ipc.h#11 (text+ko) ==== @@ -116,6 +116,7 @@ struct fuse_data { struct cdev *fdev; struct mount *mp; + struct vnode *vroot; enum mountpri mpri; int mntco; struct ucred *daemoncred; ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_kernel.h#2 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_main.c#7 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.c#14 (text+ko) ==== @@ -44,6 +44,14 @@ SYSCTL_INT(_vfs_fuse, OID_AUTO, node_count, CTLFLAG_RD, &fuse_node_count, 0, ""); +int fuse_data_cache_enable = 1; +SYSCTL_INT(_vfs_fuse, OID_AUTO, data_cache_enable, CTLFLAG_RW, + &fuse_data_cache_enable, 0, ""); + +int fuse_mmap_enable = 1; +SYSCTL_INT(_vfs_fuse, OID_AUTO, mmap_enable, CTLFLAG_RW, + &fuse_mmap_enable, 0, ""); + static void fuse_vnode_init(struct vnode *vp, struct fuse_vnode_data *fvdat, uint64_t nodeid, enum vtype vtyp) @@ -209,6 +217,16 @@ } } +int +fuse_isvalid_attr(struct vnode *vp) +{ + struct fuse_vnode_data *fvdat = VTOFUD(vp); + struct timespec uptsp; + + nanouptime(&uptsp); + return fuse_timespec_cmp(&uptsp, &fvdat->cached_attrs_valid, <=); +} + void fuse_vnode_setsize(struct vnode *vp, off_t newsize) { ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#14 (text+ko) ==== @@ -62,6 +62,10 @@ #define FUSE_NULL_ID 0 +extern struct vop_vector fuse_vnops; +extern int fuse_data_cache_enable; +extern int fuse_mmap_enable; + static __inline__ void fuse_invalidate_attr(struct vnode *vp) @@ -71,35 +75,19 @@ } } -struct get_filehandle_param { +static __inline int +fuse_vnode_cache_enable(struct vnode *vp) +{ + return (fuse_data_cache_enable); +} - enum fuse_opcode opcode; - uint8_t do_gc:1; - uint8_t do_new:1; +static __inline int +fuse_vnode_mmap_enable(struct vnode *vp) +{ + return (fuse_mmap_enable && fuse_data_cache_enable); +} - int explicitidentity; - pid_t pid; - uid_t uid; - gid_t gid; -}; - -#define C_NEED_RVNODE_PUT 0x00001 -#define C_NEED_DVNODE_PUT 0x00002 -#define C_ZFWANTSYNC 0x00004 -#define C_FROMSYNC 0x00008 -#define C_MODIFIED 0x00010 -#define C_NOEXISTS 0x00020 -#define C_DELETED 0x00040 -#define C_HARDLINK 0x00080 -#define C_FORCEUPDATE 0x00100 -#define C_HASXATTRS 0x00200 -#define C_NEED_DATA_SETSIZE 0x01000 -#define C_NEED_RSRC_SETSIZE 0x02000 - -#define C_CREATING 0x04000 -#define C_ACCESS_NOOP 0x08000 - -extern struct vop_vector fuse_vnops; +int fuse_isvalid_attr(struct vnode *vp); void fuse_vnode_destroy(struct vnode *vp); ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_param.h#4 (text+ko) ==== ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vfsops.c#19 (text+ko) ==== @@ -307,6 +307,14 @@ } /* There is 1 extra root vnode reference (mp->mnt_data). */ + FUSE_LOCK(); + if (data->vroot != NULL) { + struct vnode *vroot = data->vroot; + data->vroot = NULL; + FUSE_UNLOCK(); + vrele(vroot); + } else + FUSE_UNLOCK(); err = vflush(mp, 0, flags, td); if (err) { debug_printf("vflush failed"); @@ -352,9 +360,34 @@ static int fuse_vfsop_root(struct mount *mp, int lkflags, struct vnode **vpp) { + struct fuse_data *data = fuse_get_mpdata(mp); int err = 0; - err = fuse_vnode_get(mp, FUSE_ROOT_ID, NULL, vpp, NULL, VDIR, 0); + if (data->vroot != NULL) { + err = vget(data->vroot, lkflags, curthread); + if (err == 0) + *vpp = data->vroot; + } else { + err = fuse_vnode_get(mp, FUSE_ROOT_ID, NULL, vpp, NULL, VDIR, 0); + if (err == 0) { + FUSE_LOCK(); + MPASS(data->vroot == NULL || data->vroot == *vpp); + if (data->vroot == NULL) { + DEBUG("new root vnode\n"); + data->vroot = *vpp; + FUSE_UNLOCK(); + vref(*vpp); + } else if (data->vroot != *vpp) { + DEBUG("root vnode race\n"); + FUSE_UNLOCK(); + VOP_UNLOCK(*vpp, 0); + vrele(*vpp); + vrecycle(*vpp, curthread); + *vpp = data->vroot; + } else + FUSE_UNLOCK(); + } + } return err; } ==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#35 (text+ko) ==== @@ -167,7 +167,9 @@ struct fuse_vnode_data *fvdat = VTOFUD(vp); struct fuse_data *data = fuse_get_mpdata(vnode_mount(vp)); - fuse_trace_printf_vnop(); + int err; + + DEBUG2G("inode=%jd\n", VTOI(vp)); if (fuse_isdeadfs(vp)) { if (vnode_isvroot(vp)) { @@ -198,7 +200,9 @@ facp.facc_flags |= FACCESS_DO_ACCESS; } - return fuse_internal_access(vp, accmode, &facp, ap->a_td, ap->a_cred); + err = fuse_internal_access(vp, accmode, &facp, ap->a_td, ap->a_cred); + DEBUG2G("err=%d accmode=0x%x\n", err, accmode); + return err; } /* @@ -465,18 +469,16 @@ int err = 0; int dataflags; - struct timespec uptsp; struct fuse_dispatcher fdi; - fuse_trace_printf_vnop(); + DEBUG2G("inode=%jd\n", VTOI(vp)); dataflags = fuse_get_mpdata(vnode_mount(vp))->dataflags; /* Note that we are not bailing out on a dead file system just yet. */ /* look for cached attributes */ - nanouptime(&uptsp); - if (fuse_timespec_cmp(&uptsp, &VTOFUD(vp)->cached_attrs_valid, <=)) { + if (fuse_isvalid_attr(vp)) { if (vap != VTOVA(vp)) { memcpy(vap, VTOVA(vp), sizeof(*vap)); } @@ -574,7 +576,7 @@ int type; - fuse_trace_printf_vnop(); + DEBUG("inode=%jd\n", (uintmax_t)VTOI(vp)); for (type = 0; type < FUFH_MAXTYPE; type++) { fufh = &(fvdat->fufh[type]); @@ -583,7 +585,8 @@ } } - if ((fvdat->flag & FN_REVOKED) != 0 || fuse_reclaim_inactive) { + if ((fvdat->flag & FN_REVOKED) != 0 || + (fuse_reclaim_inactive && vnode_vtype(vp) != VDIR)) { vrecycle(vp, td); } @@ -683,7 +686,8 @@ uint64_t nid; struct fuse_access_param facp; - fuse_trace_printf_vnop(); + DEBUG2G("parent_inode=%jd - %*s\n", + VTOI(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr); if (fuse_isdeadfs(dvp)) { *vpp = NULL; @@ -1170,7 +1174,7 @@ int error, isdir = 0; - fuse_trace_printf_vnop(); + DEBUG2G("inode=%jd mode=0x%x\n", VTOI(vp), mode); if (fuse_isdeadfs(vp)) { return ENXIO; @@ -1214,7 +1218,8 @@ int ioflag = ap->a_ioflag; struct ucred *cred = ap->a_cred; - fuse_trace_printf_vnop(); + DEBUG2G("inode=%jd offset=%jd resid=%zd\n", + VTOI(vp), uio->uio_offset, uio->uio_resid); if (fuse_isdeadfs(vp)) { return EIO; @@ -1247,7 +1252,7 @@ int err = 0; int freefufh = 0; - fuse_trace_printf_vnop(); + DEBUG2G("inode=%jd\n", VTOI(vp)); if (fuse_isdeadfs(vp)) { return EBADF; @@ -1304,7 +1309,7 @@ struct fuse_dispatcher fdi; int err; - fuse_trace_printf_vnop(); + DEBUG2G("inode=%jd\n", VTOI(vp)); if (fuse_isdeadfs(vp)) { return EBADF; @@ -1351,12 +1356,12 @@ int type; - fuse_trace_printf_vnop(); - if (!fvdat) { panic("FUSE: no vnode data during recycling"); } + DEBUG("inode=%jd\n", (uintmax_t)VTOI(vp)); + for (type = 0; type < FUFH_MAXTYPE; type++) { fufh = &(fvdat->fufh[type]); if (FUFH_IS_VALID(fufh)) { @@ -1397,7 +1402,8 @@ int err; - fuse_trace_printf_vnop(); + DEBUG2G("inode=%jd name=%*s\n", + VTOI(vp), (int)cnp->cn_namelen, cnp->cn_nameptr); if (fuse_isdeadfs_fs(vp)) { panic("FUSE: fuse_vnop_remove(): called on a dead file system"); @@ -1441,7 +1447,10 @@ int err = 0; - fuse_trace_printf_vnop(); + DEBUG2G("from: inode=%jd name=%*s -> to: inode=%jd name=%*s\n", + VTOI(fvp), (int)fcnp->cn_namelen, fcnp->cn_nameptr, + (tvp == NULL ? (intmax_t)-1 : VTOI(tvp)), + (int)tcnp->cn_namelen, tcnp->cn_nameptr); if (fuse_isdeadfs_fs(fdvp)) { panic("FUSE: fuse_vnop_rename(): called on a dead file system"); @@ -1512,7 +1521,7 @@ int err; - fuse_trace_printf_vnop(); + DEBUG2G("inode=%jd\n", VTOI(vp)); if (fuse_isdeadfs_fs(vp)) { panic("FUSE: fuse_vnop_rmdir(): called on a dead file system"); @@ -1557,7 +1566,7 @@ int sizechanged = 0; uint64_t newsize = 0; - fuse_trace_printf_vnop(); + DEBUG2G("inode=%jd\n", VTOI(vp)); /* * XXX: Locking @@ -1588,20 +1597,18 @@ bzero(&facp, sizeof(facp)); -#define FUSEATTR(x) x - facp.xuid = vap->va_uid; facp.xgid = vap->va_gid; if (vap->va_uid != (uid_t)VNOVAL) { facp.facc_flags |= FACCESS_CHOWN; - fsai->FUSEATTR(uid) = vap->va_uid; + fsai->uid = vap->va_uid; fsai->valid |= FATTR_UID; } if (vap->va_gid != (gid_t)VNOVAL) { facp.facc_flags |= FACCESS_CHOWN; - fsai->FUSEATTR(gid) = vap->va_gid; + fsai->gid = vap->va_gid; fsai->valid |= FATTR_GID; } @@ -1610,7 +1617,7 @@ struct fuse_filehandle *fufh = NULL; // Truncate to a new value. - fsai->FUSEATTR(size) = vap->va_size; + fsai->size = vap->va_size; sizechanged = 1; newsize = vap->va_size; fsai->valid |= FATTR_SIZE; @@ -1623,24 +1630,22 @@ } if (vap->va_atime.tv_sec != VNOVAL) { - fsai->FUSEATTR(atime) = vap->va_atime.tv_sec; - fsai->FUSEATTR(atimensec) = vap->va_atime.tv_nsec; + fsai->atime = vap->va_atime.tv_sec; + fsai->atimensec = vap->va_atime.tv_nsec; fsai->valid |= FATTR_ATIME; } if (vap->va_mtime.tv_sec != VNOVAL) { - fsai->FUSEATTR(mtime) = vap->va_mtime.tv_sec; - fsai->FUSEATTR(mtimensec) = vap->va_mtime.tv_nsec; + fsai->mtime = vap->va_mtime.tv_sec; + fsai->mtimensec = vap->va_mtime.tv_nsec; fsai->valid |= FATTR_MTIME; } if (vap->va_mode != (mode_t)VNOVAL) { - fsai->FUSEATTR(mode) = vap->va_mode & ALLPERMS; + fsai->mode = vap->va_mode & ALLPERMS; fsai->valid |= FATTR_MODE; } -#undef FUSEATTR - if (!fsai->valid) { goto out; } @@ -1768,6 +1773,9 @@ int err; size_t len; + DEBUG2G("inode=%jd name=%*s\n", + VTOI(dvp), (int)cnp->cn_namelen, cnp->cn_nameptr); + if (fuse_isdeadfs_fs(dvp)) { panic("FUSE: fuse_vnop_symlink(): called on a dead file system"); } @@ -1868,6 +1876,11 @@ pages = ap->a_m; count = ap->a_count; + if (!fuse_vnode_mmap_enable(vp)) { + DEBUG("called on non-cacheable vnode??\n"); + return (VM_PAGER_ERROR); + } + npages = btoc(count); /* @@ -2058,6 +2071,10 @@ npages = btoc(count); offset = IDX_TO_OFF(pages[0]->pindex); + if (!fuse_vnode_mmap_enable(vp)) { + DEBUG("called on non-cacheable vnode??\n"); + } + for (i = 0; i < npages; i++) rtvals[i] = VM_PAGER_AGAIN;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201107090856.p698uDS1043125>