From owner-p4-projects@FreeBSD.ORG Wed May 26 21:06:27 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 58D7B1065677; Wed, 26 May 2010 21:06:27 +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 1CDF81065675 for ; Wed, 26 May 2010 21:06:27 +0000 (UTC) (envelope-from gpf@FreeBSD.org) Received: from repoman.freebsd.org (unknown [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 09A8D8FC1A for ; Wed, 26 May 2010 21:06:27 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o4QL6RuM019239 for ; Wed, 26 May 2010 21:06:27 GMT (envelope-from gpf@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o4QL6QvV019237 for perforce@freebsd.org; Wed, 26 May 2010 21:06:26 GMT (envelope-from gpf@FreeBSD.org) Date: Wed, 26 May 2010 21:06:26 GMT Message-Id: <201005262106.o4QL6QvV019237@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gpf@FreeBSD.org using -f From: Efstratios Karatzas To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 178836 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: Wed, 26 May 2010 21:06:27 -0000 http://p4web.freebsd.org/@@178836?ac=10 Change 178836 by gpf@gpf_desktop on 2010/05/26 21:05:34 - changed how vn_fullpath_nocache(9) works internally. now the fs specific part whose job is to find a parent directory for our file has broken off to its own VOP(), VOP_GETPARENT. VOP_GETPARENT works for UFS & ZFS. Please refer to the comment headers above the functions in question for more information on how to use them. UFS: use directory inode hint or do an exhaustive search. (exhaustive search still kernel panics) ZFS: use the directory znode number that is stored inside the physical part of the znode. note: there are other ways we could do this such as zfs_obj_to_path() but there's no documentation to be found and my zfs magic is limited for the time being. Still, vn_fullpath_nocache() performs well under UFS & ZFS - any feedback welcome. - oh and removed a trailing white space in praudit.c Affected files ... .. //depot/projects/soc2010/gpf_audit/freebsd/src/contrib/openbsm/bin/praudit/praudit.c#3 edit .. //depot/projects/soc2010/gpf_audit/freebsd/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c#2 edit .. //depot/projects/soc2010/gpf_audit/freebsd/src/sys/kern/vfs_default.c#2 edit .. //depot/projects/soc2010/gpf_audit/freebsd/src/sys/kern/vnode_if.src#3 edit .. //depot/projects/soc2010/gpf_audit/freebsd/src/sys/sys/vnode.h#2 edit .. //depot/projects/soc2010/gpf_audit/freebsd/src/sys/ufs/ffs/ffs_vnops.c#3 edit .. //depot/projects/soc2010/gpf_audit/vn_fullpath_nocache.c#4 edit Differences ... ==== //depot/projects/soc2010/gpf_audit/freebsd/src/contrib/openbsm/bin/praudit/praudit.c#3 (text) ==== @@ -152,7 +152,7 @@ case 'x': xml = 1; - break; + break; case '?': default: ==== //depot/projects/soc2010/gpf_audit/freebsd/src/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c#2 (text+ko) ==== @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -3772,6 +3773,12 @@ ZFS_ENTER(zfsvfs); ZFS_VERIFY_ZP(zp); gen = (uint32_t)zp->z_gen; + + printf("EIMAI H VOP_VPTOFH TOU KWLOZFS\n"); + printf("ID %llu\n", zp->z_id); + printf("PARENT ID %llu\n", zp->z_phys->zp_parent); + /* gpf shit */ + size = (zfsvfs->z_parent != zfsvfs) ? LONG_FID_LEN : SHORT_FID_LEN; fidp->fid_len = size; @@ -4963,6 +4970,151 @@ return (EOPNOTSUPP); } +/* + * XXXgpf: should relocate them someplace else + * I just dont know where:S + */ +#define PARENTHINT 0x0001 +#define EXHAUSTSEARCH 0x0002 +#define WANTNAME 0x0004 + +/* + * VOP_GETPARENT + * + * int VOP_GETPARENT(struct vnode *vp, struct vnode **dvp, uint64_t hint, + * int flags, char *buf, int *buflen); + * + * Find a parent directory -dvp- with vp as a child. The parent hint is used to + * facilitate the search. + * + * Flags should be set to: + * - PARENTHIT: if a hint ino_t of a directory is supplied to facilitate the search + * - EXHAUSTSEARCH: if we are willing to search the whole filesystem to find the directory + * - WANTNAME: if we want to copy the name used to reference the file inside the dir, to buf + * + * ZFS note: only WANTNAME is actually checked in ZFS code + * + * Locks: vp should be locked on entry and will still be locked on exit. + * On success, dvp will be locked and have its reference count incremented. + * + */ +int +zfs_freebsd_getparent(struct vop_getparent_args *ap) +/* +vop_getparent { + IN struct vnode *a_vp; + OUT struct vnode **a_vpp; + IN uint64_t a_hint; + IN int a_flags; + INOUT char *a_buf; + INOUT int *a_buflen; +}; +*/ +{ + znode_t *zp; + struct mount *mp; + struct vnode *dvp; + int error; + + zp = VTOZ(ap->a_vp); + mp = ap->a_vp->v_mount; + dvp = NULL; + + if (zp->z_phys == NULL) { + error = ENOENT; + goto out; + } + /* grab directory vnode that should contain this znode */ + error = VFS_VGET(mp, zp->z_phys->zp_parent, LK_SHARED, &dvp); + if (error) { + error = ENOENT; + goto out; + } + else if (ap->a_flags & WANTNAME) { + struct uio io; + struct iovec iov; + struct dirent *dp, *edp; + struct thread *td; + char *dirbuf; + u_int64_t dirbuflen; + int error, eofflag; + char foundit; + + foundit = 0; + dirbuflen = ((struct znode *)dvp->v_data)->z_blksz; + dirbuf = malloc(dirbuflen, M_TEMP, M_WAITOK); + td = curthread; + + /* prep the call to VOP_READDIR() */ + iov.iov_base = dirbuf; + iov.iov_len = dirbuflen; + io.uio_iov = &iov; + io.uio_iovcnt = 1; + io.uio_offset = 0; + io.uio_resid = dirbuflen; + io.uio_segflg = UIO_SYSSPACE; + io.uio_rw = UIO_READ; + io.uio_td = td; + eofflag = 0; + + error = VOP_READDIR(dvp, &io, td->td_ucred, &eofflag, NULL, NULL); + if (error) { + error = EIO; + goto out; + } + + /* search for the correct znode number inside the directory */ + edp = (struct dirent *)&dirbuf[dirbuflen - io.uio_resid]; + for (dp = (struct dirent *)dirbuf; dp < edp; ) { + if (dp->d_reclen > 0) { + /* found it */ + if (zp->z_id == ((struct dirent *)dp)->d_fileno) { + char *pch; + int len; + + pch = ((struct dirent *)dp)->d_name; + len = strlen(pch); + + if (len >= *(ap->a_buflen)) { + error = EOVERFLOW; + goto out; + } + + strlcpy(ap->a_buf, ((struct dirent *)dp)->d_name, *(ap->a_buflen)); + *(ap->a_buflen) -= len + 1; + foundit = 1; + break; + } + dp = (struct dirent *)((char *)dp + dp->d_reclen); + } + else { + error = EIO; + break; + } + } + + if (dirbuf != NULL) { + free(dirbuf, M_TEMP); + } + + if (foundit == 0 && error != 0) { + error = ENOENT; + if (dvp) + vput(dvp); + } + } /* WANTNAME */ + +out: + if (error == 0 && dvp != NULL) { + *(ap->a_vpp) = dvp; + } + else if (error) { + *(ap->a_vpp) = NULL; + } + + return (error); +} + struct vop_vector zfs_vnodeops; struct vop_vector zfs_fifoops; @@ -5005,6 +5157,7 @@ .vop_getacl = zfs_freebsd_getacl, .vop_setacl = zfs_freebsd_setacl, .vop_aclcheck = zfs_freebsd_aclcheck, + .vop_getparent = zfs_freebsd_getparent, }; struct vop_vector zfs_fifoops = { ==== //depot/projects/soc2010/gpf_audit/freebsd/src/sys/kern/vfs_default.c#2 (text+ko) ==== @@ -120,6 +120,7 @@ .vop_unlock = vop_stdunlock, .vop_vptocnp = vop_stdvptocnp, .vop_vptofh = vop_stdvptofh, + .vop_getparent = vop_stdgetparent, }; /* @@ -841,6 +842,12 @@ return (error); } +int +vop_stdgetparent(struct vop_getparent_args *ap) +{ + return (EOPNOTSUPP); +} + /* * vfs default ops * used to fill the vfs function table to get reasonable default return values. ==== //depot/projects/soc2010/gpf_audit/freebsd/src/sys/kern/vnode_if.src#3 (text+ko) ==== @@ -612,3 +612,15 @@ INOUT char *buf; INOUT int *buflen; }; + +%% getparent vp L L L +%% getparent vpp - L - + +vop_getparent { + IN struct vnode *vp; + OUT struct vnode **vpp; + IN uint64_t hint; + IN int flags; + INOUT char *buf; + INOUT int *buflen; +}; ==== //depot/projects/soc2010/gpf_audit/freebsd/src/sys/sys/vnode.h#2 (text+ko) ==== @@ -693,6 +693,7 @@ int vop_stdpoll(struct vop_poll_args *); int vop_stdvptocnp(struct vop_vptocnp_args *ap); int vop_stdvptofh(struct vop_vptofh_args *ap); +int vop_stdgetparent(struct vop_getparent_args *ap); int vop_eopnotsupp(struct vop_generic_args *ap); int vop_ebadf(struct vop_generic_args *ap); int vop_einval(struct vop_generic_args *ap); ==== //depot/projects/soc2010/gpf_audit/freebsd/src/sys/ufs/ffs/ffs_vnops.c#3 (text+ko) ==== @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include @@ -119,8 +120,8 @@ static vop_openextattr_t ffs_openextattr; static vop_setextattr_t ffs_setextattr; static vop_vptofh_t ffs_vptofh; +static vop_getparent_t ffs_getparent; - /* Global vfs data structures for ufs. */ struct vop_vector ffs_vnodeops1 = { .vop_default = &ufs_vnodeops, @@ -131,6 +132,7 @@ .vop_reallocblks = ffs_reallocblks, .vop_write = ffs_write, .vop_vptofh = ffs_vptofh, + .vop_getparent = ffs_getparent, }; struct vop_vector ffs_fifoops1 = { @@ -156,6 +158,7 @@ .vop_openextattr = ffs_openextattr, .vop_setextattr = ffs_setextattr, .vop_vptofh = ffs_vptofh, + .vop_getparent = ffs_getparent, }; struct vop_vector ffs_fifoops2 = { @@ -1789,3 +1792,228 @@ } return (0); } + +/* + * XXXgpf: should relocate them someplace else + * I just dont know where:S + */ +#define PARENTHINT 0x0001 +#define EXHAUSTSEARCH 0x0002 +#define WANTNAME 0x0004 + +/* + * XXXgpf: used by VOP_GETPARENT + * + * find the name that is used to reference vp inside the directory vnode dvp. + * flags should be set to WANTNAME if the filename should be copied to + * the supplied buffer. + * + * locks: dvp must be locked on entry and will still be locked on exit + * + * returns: + * - ENOENT a file that corresponds to vp was not found inside dvp, + * or dvp is not a directory vnode + * - EIO error occured while reading the directory + * - EOVERFLOW result does not fit in buffer "name" + */ +static int +dir_ilookup(struct vnode *vp, struct vnode *dvp, char *name, int *namelen, int flags) +{ + struct uio io; + struct iovec iov; + struct dirent *dp, *edp; + struct thread *td; + char *dirbuf; + u_int64_t dirbuflen; + int error, eofflag; + char foundit; + + if (dvp->v_type != VDIR) { + return ENOENT; + } + + foundit = 0; + dirbuflen = ((struct inode *)dvp->v_data)->i_size; + dirbuf = malloc(dirbuflen, M_TEMP, M_WAITOK); + td = curthread; + + /* prep the call to VOP_READDIR() */ + iov.iov_base = dirbuf; + iov.iov_len = dirbuflen; + io.uio_iov = &iov; + io.uio_iovcnt = 1; + io.uio_offset = 0; + io.uio_resid = dirbuflen; + io.uio_segflg = UIO_SYSSPACE; + io.uio_rw = UIO_READ; + io.uio_td = td; + eofflag = 0; + + error = VOP_READDIR(dvp, &io, td->td_ucred, &eofflag, NULL, NULL); + if (error) { + error = EIO; + goto out; + } + + /* search for the correct inode number inside the directory */ + edp = (struct dirent *)&dirbuf[dirbuflen - io.uio_resid]; + for (dp = (struct dirent *)dirbuf; dp < edp; ) { + if (dp->d_reclen > 0) { + /* found it */ + if ( ((struct inode *)vp->v_data)->i_number == ((struct dirent *)dp)->d_fileno) { + char *pch; + int len; + + if (flags & WANTNAME) { + pch = ((struct dirent *)dp)->d_name; + len = strlen(pch); + + if (len >= *namelen) { + error = EOVERFLOW; + goto out; + } + + strlcpy(name, ((struct dirent *)dp)->d_name, *namelen); + *namelen -= len + 1; + } + + foundit = 1; + break; + } + dp = (struct dirent *)((char *)dp + dp->d_reclen); + } + else { + error = EIO; + break; + } + } + +out: + if (dirbuf != NULL) { + free(dirbuf, M_TEMP); + } + + if (foundit == 0 && error != 0) { + error = ENOENT; + } + + return error; +} + +/* + * VOP_GETPARENT + * + * int VOP_GETPARENT(struct vnode *vp, struct vnode **dvp, uint64_t hint, + * int flags, char *buf, int *buflen); + * + * Find a parent directory -dvp- with vp as a child. The parent hint is used to + * facilitate the search. + * + * Flags should be set to: + * - PARENTHIT: if a hint ino_t of a directory is supplied to facilitate the search + * - EXHAUSTSEARCH: if we are willing to search the whole filesystem to find the directory + * - WANTNAME: if we want to copy the name used to reference the file inside the dir, to buf + * + * Locks: vp should be locked on entry and will still be locked on exit. + * On success, dvp will be locked and have its reference count incremented. + * + */ +static int +ffs_getparent(struct vop_getparent_args *ap) +/* +vop_getparent { + IN struct vnode *a_vp; + OUT struct vnode **a_vpp; + IN uint64_t a_hint; + IN int a_flags; + INOUT char *a_buf; + INOUT int *a_buflen; +}; +*/ +{ + struct mount *mp; + struct vnode *vp, *dvp; + int error, flags; + + error = 0; + vp = ap->a_vp; + mp = vp->v_mount; + flags = ap->a_flags; + + /* XXXgpf:is this check necessary? */ + if (vp->v_type == VBAD) { + error = ENOENT; + dvp = NULL; + goto out; + } + + /* grab the parent directory using the directory_hint */ + if (flags & PARENTHINT) { + error = VFS_VGET(mp, ap->a_hint, LK_SHARED, &dvp); + /* in case of failure, proceed to exhaustive search */ + if (error) { + dvp = NULL; + } + else if (flags & WANTNAME) { + /* grab the name that is being used to reference vp */ + error = dir_ilookup(vp, dvp, ap->a_buf, ap->a_buflen, flags); + if (error) { + vput(dvp); + dvp = NULL; + } + } + } + + /* + * if our target is not a directory and we haven't found 'a' parent directory, + * do an exhaustive search on the filesystem + */ + if ((flags & EXHAUSTSEARCH) && dvp == NULL) { + /* + * XXXgpf: this actually does not work because when the thread will try to sleep, + * e.g. in VOP_READDIR, the kernel will panic because we have ilocked mp >.< + * + * Not, it also kernel panics because we have locked vp >.<' + */ + MNT_ILOCK(mp); + if (!TAILQ_EMPTY(&mp->mnt_nvnodelist)) { + struct vnode *tvp; + + TAILQ_FOREACH(tvp, &mp->mnt_nvnodelist, v_nmntvnodes) { + if (tvp->v_type == VDIR) { + vn_lock(tvp, LK_SHARED); + /* grab the name that is being used to reference vp */ + error = dir_ilookup(vp, tvp, ap->a_buf, ap->a_buflen, flags); + + /* found it */ + if (error == 0) { + dvp = tvp; + vref(dvp); + break; + } + VOP_UNLOCK(tvp, 0); + } + } + } + MNT_IUNLOCK(mp); + + /* we failed to find a directory that contains the vnode, exit */ + if (error != 0) { + error = ENOENT; + } + } + /* we failed to find a directory that contains the vnode, exit */ + else if (dvp == NULL) { + error = ENOENT; + } + +out: + if (error == 0 && dvp != NULL) { + *(ap->a_vpp) = dvp; + } + else if (error) { + *(ap->a_vpp) = NULL; + } + + return error; +} ==== //depot/projects/soc2010/gpf_audit/vn_fullpath_nocache.c#4 (text+ko) ==== @@ -45,108 +45,14 @@ #include #include -#define PARENT_HINT 0x0001 -#define EXHAUSTIVE_SEARCH 0x0002 - -/* - * find the name that is used to reference vp inside the directory vnode dvp - * locks: dvp must be locked on entry and will still be locked on exit - * - * works for UFS - * - * returns: - * - ENOENT a file that corresponds to vp was not found inside dvp - * - EIO error occured while reading the directory - * - EOVERFLOW result does not fit in buffer "name" +/* + * XXXgpf: should relocate them someplace else + * I just dont know where:S */ -static int -dir_ilookup(struct vnode *vp, struct vnode *dvp, char *name, int *namelen) -{ - struct uio io; - struct iovec iov; - struct dirent *dp, *edp; - struct thread *td; - char *dirbuf; - u_int64_t dirbuflen; - int error, eofflag; - char foundit; - - KASSERT("vp != NULL", "dir_ilookup: vp == NULL"); - KASSERT("dvp != NULL", "dir_ilookup: dvp == NULL"); - KASSERT("name != NULL", "dir_ilookup: name == NULL"); - - /* XXXgpf: temporary, must be a better way to check this than f_type or f_fstypename */ - if (strcmp(vp->v_mount->mnt_stat.f_fstypename, "ufs")) { - uprintf("only ufs supported\n"); - return 1; - } - - foundit = 0; - dirbuflen = ((struct inode *)dvp->v_data)->i_size; - dirbuf = malloc(dirbuflen, M_TEMP, M_WAITOK); - td = curthread; - - /* prep the call to VOP_READDIR() */ - iov.iov_base = dirbuf; - iov.iov_len = dirbuflen; - io.uio_iov = &iov; - io.uio_iovcnt = 1; - io.uio_offset = 0; - io.uio_resid = dirbuflen; - io.uio_segflg = UIO_SYSSPACE; - io.uio_rw = UIO_READ; - io.uio_td = td; - eofflag = 0; - - error = VOP_READDIR(dvp, &io, td->td_ucred, &eofflag, NULL, NULL); - if (error) { - uprintf("VOP_READDIR failure %d\n", error); - error = EIO; - goto out; - } - - /* search for the correct inode number inside the directory */ - edp = (struct dirent *)&dirbuf[dirbuflen - io.uio_resid]; - for (dp = (struct dirent *)dirbuf; dp < edp; ) { - if (dp->d_reclen > 0) { - /* found it */ - if ( ((struct inode *)vp->v_data)->i_number == ((struct dirent *)dp)->d_fileno) { - char *pch; - int len; - - pch = ((struct dirent *)dp)->d_name; - len = strlen(pch); - - if (len >= *namelen) { - error = EOVERFLOW; - goto out; - } - - strlcpy(name, ((struct dirent *)dp)->d_name, *namelen); - *namelen -= len + 1; - foundit = 1; - break; - } - dp = (struct dirent *)((char *)dp + dp->d_reclen); - } - else { - error = EIO; - break; - } - } +#define PARENTHINT 0x0001 +#define EXHAUSTSEARCH 0x0002 +#define WANTNAME 0x0004 -out: - if (dirbuf != NULL) { - free(dirbuf, M_TEMP); - } - - if (foundit == 0 && error != 0) { - error = ENOENT; - } - - return error; -} - /* * vn_fullpath_nocache * @@ -157,11 +63,13 @@ * - flags should be set to PARENT_HINT, if the directory hint is supplied * and to EXHAUSTIVE_SEARCH, if we are willing to go intro great trouble to get this path. * + * Locks: no locks required. + * * Author's note: This only works for UFS filesystems (for now). * Oh, also EXHAUSTIVE_SEARCH will kernel panic :-D */ static int -vn_fullpath_nocache(struct vnode *vp, char **fullpath, char **freepath, ino_t directory_hint, char flags) +vn_fullpath_nocache(struct vnode *vp, char **fullpath, char **freepath, uint64_t directory_hint, char flags) { struct vnode *dvp, *upper_dvp; struct mount *mp; @@ -192,68 +100,15 @@ /* * - If our target is a directory, move on to the part where we traverse the '..' entries. - * - If not, either use the directory_hint if it's available or do an exhaustive search on the fs (xD) so - * that we can connect the vp with 'a' parent directory. + * - If not, try to find its' parent through VOP_GETPARENT */ if (vp->v_type != VDIR) { - /* grab the parent directory using the directory_hint */ - if ((flags & PARENT_HINT) && vp->v_type != VDIR) { - error = VFS_VGET(vp->v_mount, directory_hint, LK_SHARED, &dvp); - /* in case of failure, proceed to exhaustive search */ - if (error) { - uprintf("VFS_VGET failure %d\n", error); - dvp = NULL; - } - else { - /* grab the name that is being used to reference vp */ - error = dir_ilookup(vp, dvp, fname, &fnamelen); - if (error) { - vput(dvp); - goto out; - } - } - } - - /* - * if our target is not a directory and we haven't found 'a' parent directory, - * do an exhaustive search on the filesystem - */ - if ((flags & EXHAUSTIVE_SEARCH) && dvp == NULL) { - /* - * XXXgpf: this actually does not work because when the thread will try to sleep, - * e.g. in VOP_READDIR, the kernel will panic because we have ilocked mp >.< - */ - MNT_ILOCK(mp); - if (!TAILQ_EMPTY(&mp->mnt_nvnodelist)) { - struct vnode *tvp; - - TAILQ_FOREACH(tvp, &mp->mnt_nvnodelist, v_nmntvnodes) { - if (tvp->v_type == VDIR) { - vn_lock(tvp, LK_SHARED); - /* grab the name that is being used to reference vp */ - error = dir_ilookup(vp, tvp, fname, &fnamelen); - - /* found it */ - if (error == 0) { - dvp = tvp; - vref(dvp); - break; - } - VOP_UNLOCK(tvp, 0); - } - } - } - MNT_IUNLOCK(mp); - - /* we failed to find a directory that contains the vnode, exit */ - if (error != 0) { - error = ENOENT; - goto out; - } - } - /* we failed to find a directory that contains the vnode, exit */ - else if (dvp == NULL) { - error = ENOENT; + /* XXXgpf: perhaps locking vp is redundant */ + vn_lock(vp, LK_SHARED); + error = VOP_GETPARENT(vp, &dvp, directory_hint, flags, fname, &fnamelen); + VOP_UNLOCK(vp, 0); + if (error) { + dvp = NULL; goto out; } @@ -268,7 +123,7 @@ strcpy(pch, fname); buflen -= strlen(fname); buf[--buflen] = '/'; - } /* if not VDIR */ + } /* if our target is a dir, do the initial preparation */ else { dvp = vp; @@ -355,11 +210,13 @@ struct nameidata nd; struct vnode *vp, *dvp; char *freepath, *fullpath; - char *path = "/usr/home/gpf/Desktop/gsoc/example"; - //char *path = "/usr/home/gpf/Desktop/usb/abc/file"; + //char *path = "/usr/home/gpf/Desktop/gsoc/example"; + //char *path = "/usr/home/gpf/Desktop/"; + char *path = "/example/test/test.sh"; ino_t directory_hint; int vfslocked; int error; + int flags; /* use the namei interface to get something that we can work on */ NDINIT(&nd, LOOKUP, FOLLOW | WANTPARENT, UIO_SYSSPACE, path, curthread); @@ -372,11 +229,6 @@ vp = nd.ni_vp; dvp = nd.ni_dvp; - - #if defined DEBUG - uprintf("inode number of the file %u\n", ((struct inode *)vp->v_data)->i_number); - uprintf("inode number of the dir that contains the file %u\n", ((struct inode *)dvp->v_data)->i_number); - #endif vrele(vp); vrele(dvp); @@ -384,14 +236,19 @@ /* preping the call to vn_fullpath_nocache() */ freepath = NULL; - /* careful, should not reference the i_number like that when vp is the root of a fs */ - if (dvp != NULL && dvp->v_data != NULL) - directory_hint = ((struct inode *)dvp->v_data)->i_number; - - error = vn_fullpath_nocache(vp, &fullpath, &freepath, directory_hint, PARENT_HINT); + if (!strcmp(vp->v_mount->mnt_stat.f_fstypename, "ufs")) { + flags = PARENTHINT | WANTNAME; + /* careful, should not reference the i_number like that when vp is the root of a fs */ + if (dvp != NULL && dvp->v_data != NULL) + directory_hint = ((struct inode *)dvp->v_data)->i_number; + } + else if (!strcmp(vp->v_mount->mnt_stat.f_fstypename, "zfs")) { + flags = WANTNAME; + } + error = vn_fullpath_nocache(vp, &fullpath, &freepath, directory_hint, flags); uprintf("vn_fullpath_nocache() returned %d\n", error); - if (freepath != NULL) { + if (freepath != NULL) { uprintf("path: %s\n", fullpath); free(freepath, M_TEMP); }