Changeset View
Changeset View
Standalone View
Standalone View
sys/fs/fuse/fuse_vnops.c
Show First 20 Lines • Show All 1,321 Lines • ▼ Show 20 Lines | fuse_vnop_link(struct vop_link_args *ap) | ||||
fdisp_init(&fdi, 0); | fdisp_init(&fdi, 0); | ||||
fuse_internal_newentry_makerequest(vnode_mount(tdvp), VTOI(tdvp), cnp, | fuse_internal_newentry_makerequest(vnode_mount(tdvp), VTOI(tdvp), cnp, | ||||
FUSE_LINK, &fli, sizeof(fli), &fdi); | FUSE_LINK, &fli, sizeof(fli), &fdi); | ||||
if ((err = fdisp_wait_answ(&fdi))) { | if ((err = fdisp_wait_answ(&fdi))) { | ||||
goto out; | goto out; | ||||
} | } | ||||
feo = fdi.answ; | feo = fdi.answ; | ||||
if (fli.oldnodeid != feo->nodeid) { | |||||
struct fuse_data *data = fuse_get_mpdata(vnode_mount(vp)); | |||||
fuse_warn(data, FSESS_WARN_ILLEGAL_INODE, | |||||
"Assigned wrong inode for a hard link."); | |||||
fuse_vnode_clear_attr_cache(vp); | |||||
fuse_vnode_clear_attr_cache(tdvp); | |||||
err = EIO; | |||||
goto out; | |||||
} | |||||
err = fuse_internal_checkentry(feo, vnode_vtype(vp)); | err = fuse_internal_checkentry(feo, vnode_vtype(vp)); | ||||
if (!err) { | if (!err) { | ||||
/* | /* | ||||
* Purge the parent's attribute cache because the daemon | * Purge the parent's attribute cache because the daemon | ||||
* should've updated its mtime and ctime | * should've updated its mtime and ctime | ||||
*/ | */ | ||||
fuse_vnode_clear_attr_cache(tdvp); | fuse_vnode_clear_attr_cache(tdvp); | ||||
fuse_internal_cache_attrs(vp, &feo->attr, feo->attr_valid, | fuse_internal_cache_attrs(vp, &feo->attr, feo->attr_valid, | ||||
▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | fuse_vnop_lookup(struct vop_lookup_args *ap) | ||||
int nameiop = cnp->cn_nameiop; | int nameiop = cnp->cn_nameiop; | ||||
int flags = cnp->cn_flags; | int flags = cnp->cn_flags; | ||||
int wantparent = flags & (LOCKPARENT | WANTPARENT); | int wantparent = flags & (LOCKPARENT | WANTPARENT); | ||||
int islastcn = flags & ISLASTCN; | int islastcn = flags & ISLASTCN; | ||||
struct mount *mp = vnode_mount(dvp); | struct mount *mp = vnode_mount(dvp); | ||||
struct fuse_data *data = fuse_get_mpdata(mp); | struct fuse_data *data = fuse_get_mpdata(mp); | ||||
int default_permissions = data->dataflags & FSESS_DEFAULT_PERMISSIONS; | int default_permissions = data->dataflags & FSESS_DEFAULT_PERMISSIONS; | ||||
bool is_dot; | |||||
int err = 0; | int err = 0; | ||||
int lookup_err = 0; | int lookup_err = 0; | ||||
struct vnode *vp = NULL; | struct vnode *vp = NULL; | ||||
struct fuse_dispatcher fdi; | struct fuse_dispatcher fdi; | ||||
bool did_lookup = false; | bool did_lookup = false; | ||||
struct fuse_entry_out *feo = NULL; | struct fuse_entry_out *feo = NULL; | ||||
Show All 11 Lines | fuse_vnop_lookup(struct vop_lookup_args *ap) | ||||
if (islastcn && vfs_isrdonly(mp) && (nameiop != LOOKUP)) | if (islastcn && vfs_isrdonly(mp) && (nameiop != LOOKUP)) | ||||
return EROFS; | return EROFS; | ||||
if ((cnp->cn_flags & NOEXECCHECK) != 0) | if ((cnp->cn_flags & NOEXECCHECK) != 0) | ||||
cnp->cn_flags &= ~NOEXECCHECK; | cnp->cn_flags &= ~NOEXECCHECK; | ||||
else if ((err = fuse_internal_access(dvp, VEXEC, td, cred))) | else if ((err = fuse_internal_access(dvp, VEXEC, td, cred))) | ||||
return err; | return err; | ||||
is_dot = cnp->cn_namelen == 1 && *(cnp->cn_nameptr) == '.'; | |||||
if ((flags & ISDOTDOT) && !(data->dataflags & FSESS_EXPORT_SUPPORT)) | if ((flags & ISDOTDOT) && !(data->dataflags & FSESS_EXPORT_SUPPORT)) | ||||
{ | { | ||||
if (!(VTOFUD(dvp)->flag & FN_PARENT_NID)) { | if (!(VTOFUD(dvp)->flag & FN_PARENT_NID)) { | ||||
/* | /* | ||||
* Since the file system doesn't support ".." lookups, | * Since the file system doesn't support ".." lookups, | ||||
* we have no way to find this entry. | * we have no way to find this entry. | ||||
*/ | */ | ||||
return ESTALE; | return ESTALE; | ||||
} | } | ||||
nid = VTOFUD(dvp)->parent_nid; | nid = VTOFUD(dvp)->parent_nid; | ||||
if (nid == 0) | if (nid == 0) | ||||
return ENOENT; | return ENOENT; | ||||
/* .. is obviously a directory */ | /* .. is obviously a directory */ | ||||
vtyp = VDIR; | vtyp = VDIR; | ||||
} else if (cnp->cn_namelen == 1 && *(cnp->cn_nameptr) == '.') { | } else if (is_dot) { | ||||
nid = VTOI(dvp); | nid = VTOI(dvp); | ||||
/* . is obviously a directory */ | /* . is obviously a directory */ | ||||
vtyp = VDIR; | vtyp = VDIR; | ||||
} else { | } else { | ||||
struct timespec timeout; | struct timespec timeout; | ||||
int ncpticks; /* here to accommodate for API contract */ | int ncpticks; /* here to accommodate for API contract */ | ||||
err = cache_lookup(dvp, vpp, cnp, &timeout, &ncpticks); | err = cache_lookup(dvp, vpp, cnp, &timeout, &ncpticks); | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | if (flags & ISDOTDOT) { | ||||
flaa.nid = nid; | flaa.nid = nid; | ||||
flaa.feo = feo; | flaa.feo = feo; | ||||
flaa.cnp = cnp; | flaa.cnp = cnp; | ||||
flaa.vtyp = vtyp; | flaa.vtyp = vtyp; | ||||
err = vn_vget_ino_gen(dvp, fuse_lookup_alloc, &flaa, 0, | err = vn_vget_ino_gen(dvp, fuse_lookup_alloc, &flaa, 0, | ||||
&vp); | &vp); | ||||
*vpp = vp; | *vpp = vp; | ||||
} else if (nid == VTOI(dvp)) { | } else if (nid == VTOI(dvp)) { | ||||
if (is_dot) { | |||||
vref(dvp); | vref(dvp); | ||||
*vpp = dvp; | *vpp = dvp; | ||||
} else { | |||||
fuse_warn(fuse_get_mpdata(mp), | |||||
FSESS_WARN_ILLEGAL_INODE, | |||||
"Assigned same inode to both parent and " | |||||
"child."); | |||||
err = EIO; | |||||
} | |||||
} else { | } else { | ||||
struct fuse_vnode_data *fvdat; | struct fuse_vnode_data *fvdat; | ||||
err = fuse_vnode_get(vnode_mount(dvp), feo, nid, dvp, | err = fuse_vnode_get(vnode_mount(dvp), feo, nid, dvp, | ||||
&vp, cnp, vtyp); | &vp, cnp, vtyp); | ||||
if (err) | if (err) | ||||
goto out; | goto out; | ||||
*vpp = vp; | *vpp = vp; | ||||
▲ Show 20 Lines • Show All 1,603 Lines • Show Last 20 Lines |