Changeset View
Changeset View
Standalone View
Standalone View
sys/ufs/ufs/ufs_vnops.c
Show First 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | |||||
VFS_SMR_DECLARE; | VFS_SMR_DECLARE; | ||||
#include <ufs/ffs/ffs_extern.h> | #include <ufs/ffs/ffs_extern.h> | ||||
static vop_accessx_t ufs_accessx; | static vop_accessx_t ufs_accessx; | ||||
static vop_fplookup_vexec_t ufs_fplookup_vexec; | static vop_fplookup_vexec_t ufs_fplookup_vexec; | ||||
static int ufs_chmod(struct vnode *, int, struct ucred *, struct thread *); | static int ufs_chmod(struct vnode *, int, struct ucred *, struct thread *); | ||||
static int ufs_chown(struct vnode *, uid_t, gid_t, struct ucred *, struct thread *); | static int ufs_chown(struct vnode *, uid_t, gid_t, struct ucred *, | ||||
struct thread *); | |||||
static vop_close_t ufs_close; | static vop_close_t ufs_close; | ||||
static vop_create_t ufs_create; | static vop_create_t ufs_create; | ||||
static vop_stat_t ufs_stat; | static vop_stat_t ufs_stat; | ||||
static vop_getattr_t ufs_getattr; | static vop_getattr_t ufs_getattr; | ||||
static vop_ioctl_t ufs_ioctl; | static vop_ioctl_t ufs_ioctl; | ||||
static vop_link_t ufs_link; | static vop_link_t ufs_link; | ||||
static int ufs_makeinode(int mode, struct vnode *, struct vnode **, struct componentname *, const char *); | static int ufs_makeinode(int mode, struct vnode *, struct vnode **, | ||||
struct componentname *, const char *); | |||||
static vop_mmapped_t ufs_mmapped; | static vop_mmapped_t ufs_mmapped; | ||||
static vop_mkdir_t ufs_mkdir; | static vop_mkdir_t ufs_mkdir; | ||||
static vop_mknod_t ufs_mknod; | static vop_mknod_t ufs_mknod; | ||||
static vop_open_t ufs_open; | static vop_open_t ufs_open; | ||||
static vop_pathconf_t ufs_pathconf; | static vop_pathconf_t ufs_pathconf; | ||||
static vop_print_t ufs_print; | static vop_print_t ufs_print; | ||||
static vop_readlink_t ufs_readlink; | static vop_readlink_t ufs_readlink; | ||||
static vop_remove_t ufs_remove; | static vop_remove_t ufs_remove; | ||||
▲ Show 20 Lines • Show All 879 Lines • ▼ Show 20 Lines | ufs_remove(ap) | ||||
struct thread *td; | struct thread *td; | ||||
td = curthread; | td = curthread; | ||||
ip = VTOI(vp); | ip = VTOI(vp); | ||||
if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) || | if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) || | ||||
(VTOI(dvp)->i_flags & APPEND)) | (VTOI(dvp)->i_flags & APPEND)) | ||||
return (EPERM); | return (EPERM); | ||||
if (DOINGSUJ(dvp)) { | if (DOINGSUJ(dvp)) { | ||||
error = softdep_prelink(dvp, vp); | error = softdep_prelink(dvp, vp, ap->a_cnp); | ||||
if (error != 0) { | if (error != 0) { | ||||
MPASS(error == ERELOOKUP); | MPASS(error == ERELOOKUP); | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
#ifdef UFS_GJOURNAL | #ifdef UFS_GJOURNAL | ||||
ufs_gjournal_orphan(vp); | ufs_gjournal_orphan(vp); | ||||
▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | ufs_link(ap) | ||||
int error; | int error; | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
if ((cnp->cn_flags & HASBUF) == 0) | if ((cnp->cn_flags & HASBUF) == 0) | ||||
panic("ufs_link: no name"); | panic("ufs_link: no name"); | ||||
#endif | #endif | ||||
if (DOINGSUJ(tdvp)) { | if (DOINGSUJ(tdvp)) { | ||||
error = softdep_prelink(tdvp, vp); | error = softdep_prelink(tdvp, vp, cnp); | ||||
if (error != 0) { | if (error != 0) { | ||||
MPASS(error == ERELOOKUP); | MPASS(error == ERELOOKUP); | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
if (VTOI(tdvp)->i_effnlink < 2) { | if (VTOI(tdvp)->i_effnlink < 2) { | ||||
print_bad_link_count("ufs_link", tdvp); | print_bad_link_count("ufs_link", tdvp); | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
struct vnode *dvp = ap->a_dvp; | struct vnode *dvp = ap->a_dvp; | ||||
struct componentname *cnp = ap->a_cnp; | struct componentname *cnp = ap->a_cnp; | ||||
struct direct newdir; | struct direct newdir; | ||||
int error = 0; | int error = 0; | ||||
if (DOINGSUJ(dvp) && (ap->a_flags == CREATE || | if (DOINGSUJ(dvp) && (ap->a_flags == CREATE || | ||||
ap->a_flags == DELETE)) { | ap->a_flags == DELETE)) { | ||||
error = softdep_prelink(dvp, NULL); | error = softdep_prelink(dvp, NULL, cnp); | ||||
if (error != 0) { | if (error != 0) { | ||||
MPASS(error == ERELOOKUP); | MPASS(error == ERELOOKUP); | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
switch (ap->a_flags) { | switch (ap->a_flags) { | ||||
case LOOKUP: | case LOOKUP: | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | ufs_rename(ap) | ||||
struct thread *td = fcnp->cn_thread; | struct thread *td = fcnp->cn_thread; | ||||
struct inode *fip, *tip, *tdp, *fdp; | struct inode *fip, *tip, *tdp, *fdp; | ||||
struct direct newdir; | struct direct newdir; | ||||
off_t endoff; | off_t endoff; | ||||
int doingdirectory, newparent; | int doingdirectory, newparent; | ||||
int error = 0; | int error = 0; | ||||
struct mount *mp; | struct mount *mp; | ||||
ino_t ino; | ino_t ino; | ||||
seqc_t fdvp_s, fvp_s, tdvp_s, tvp_s; | |||||
bool want_seqc_end; | bool want_seqc_end; | ||||
want_seqc_end = false; | want_seqc_end = false; | ||||
#ifdef INVARIANTS | #ifdef INVARIANTS | ||||
if ((tcnp->cn_flags & HASBUF) == 0 || | if ((tcnp->cn_flags & HASBUF) == 0 || | ||||
(fcnp->cn_flags & HASBUF) == 0) | (fcnp->cn_flags & HASBUF) == 0) | ||||
panic("ufs_rename: no name"); | panic("ufs_rename: no name"); | ||||
#endif | #endif | ||||
endoff = 0; | endoff = 0; | ||||
mp = tdvp->v_mount; | mp = tdvp->v_mount; | ||||
VOP_UNLOCK(tdvp); | VOP_UNLOCK(tdvp); | ||||
if (tvp && tvp != tdvp) | if (tvp && tvp != tdvp) | ||||
VOP_UNLOCK(tvp); | VOP_UNLOCK(tvp); | ||||
/* | /* | ||||
* Check for cross-device rename. | * Check for cross-device rename. | ||||
*/ | */ | ||||
if ((fvp->v_mount != tdvp->v_mount) || | if ((fvp->v_mount != tdvp->v_mount) || | ||||
(tvp && (fvp->v_mount != tvp->v_mount))) { | (tvp && (fvp->v_mount != tvp->v_mount))) { | ||||
error = EXDEV; | error = EXDEV; | ||||
mp = NULL; | mp = NULL; | ||||
goto releout; | goto releout; | ||||
} | } | ||||
fdvp_s = fvp_s = tdvp_s = tvp_s = SEQC_MOD; | |||||
relock: | relock: | ||||
/* | /* | ||||
* We need to acquire 2 to 4 locks depending on whether tvp is NULL | * We need to acquire 2 to 4 locks depending on whether tvp is NULL | ||||
* and fdvp and tdvp are the same directory. Subsequently we need | * and fdvp and tdvp are the same directory. Subsequently we need | ||||
* to double-check all paths and in the directory rename case we | * to double-check all paths and in the directory rename case we | ||||
* need to verify that we are not creating a directory loop. To | * need to verify that we are not creating a directory loop. To | ||||
* handle this we acquire all but fdvp using non-blocking | * handle this we acquire all but fdvp using non-blocking | ||||
* acquisitions. If we fail to acquire any lock in the path we will | * acquisitions. If we fail to acquire any lock in the path we will | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | if (error) { | ||||
if (error != 0) | if (error != 0) | ||||
goto releout; | goto releout; | ||||
vput(nvp); | vput(nvp); | ||||
atomic_add_int(&rename_restarts, 1); | atomic_add_int(&rename_restarts, 1); | ||||
goto relock; | goto relock; | ||||
} | } | ||||
} | } | ||||
if (DOINGSOFTDEP(fdvp)) { | if (DOINGSUJ(fdvp) && | ||||
(seqc_in_modify(fdvp_s) || !vn_seqc_consistent(fdvp, fdvp_s) || | |||||
seqc_in_modify(fvp_s) || !vn_seqc_consistent(fvp, fvp_s) || | |||||
seqc_in_modify(tdvp_s) || !vn_seqc_consistent(tdvp, tdvp_s) || | |||||
(tvp != NULL && (seqc_in_modify(tvp_s) || | |||||
!vn_seqc_consistent(tvp, tvp_s))))) { | |||||
error = softdep_prerename(fdvp, fvp, tdvp, tvp); | error = softdep_prerename(fdvp, fvp, tdvp, tvp); | ||||
if (error != 0) { | if (error != 0) { | ||||
if (error == ERELOOKUP) { | if (error == ERELOOKUP) { | ||||
fdvp_s = vn_seqc_read_any(fdvp); | |||||
fvp_s = vn_seqc_read_any(fvp); | |||||
tdvp_s = vn_seqc_read_any(tdvp); | |||||
if (tvp != NULL) | |||||
tvp_s = vn_seqc_read_any(tvp); | |||||
atomic_add_int(&rename_restarts, 1); | atomic_add_int(&rename_restarts, 1); | ||||
goto relock; | goto relock; | ||||
} | } | ||||
goto releout; | goto releout; | ||||
} | } | ||||
} | } | ||||
fdp = VTOI(fdvp); | fdp = VTOI(fdvp); | ||||
▲ Show 20 Lines • Show All 565 Lines • ▼ Show 20 Lines | #endif | ||||
*/ | */ | ||||
if (dp->i_effnlink < 2) { | if (dp->i_effnlink < 2) { | ||||
print_bad_link_count("ufs_mkdir", dvp); | print_bad_link_count("ufs_mkdir", dvp); | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
if (DOINGSUJ(dvp)) { | if (DOINGSUJ(dvp)) { | ||||
error = softdep_prelink(dvp, NULL); | error = softdep_prelink(dvp, NULL, cnp); | ||||
if (error != 0) { | if (error != 0) { | ||||
MPASS(error == ERELOOKUP); | MPASS(error == ERELOOKUP); | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
error = UFS_VALLOC(dvp, dmode, cnp->cn_cred, &tvp); | error = UFS_VALLOC(dvp, dmode, cnp->cn_cred, &tvp); | ||||
if (error) | if (error) | ||||
▲ Show 20 Lines • Show All 247 Lines • ▼ Show 20 Lines | if ((dp->i_flags & APPEND) | ||||
error = EPERM; | error = EPERM; | ||||
goto out; | goto out; | ||||
} | } | ||||
if (vp->v_mountedhere != 0) { | if (vp->v_mountedhere != 0) { | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
if (DOINGSUJ(dvp)) { | if (DOINGSUJ(dvp)) { | ||||
error = softdep_prelink(dvp, vp); | error = softdep_prelink(dvp, vp, cnp); | ||||
if (error != 0) { | if (error != 0) { | ||||
MPASS(error == ERELOOKUP); | MPASS(error == ERELOOKUP); | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
#ifdef UFS_GJOURNAL | #ifdef UFS_GJOURNAL | ||||
ufs_gjournal_orphan(vp); | ufs_gjournal_orphan(vp); | ||||
▲ Show 20 Lines • Show All 508 Lines • ▼ Show 20 Lines | #endif | ||||
if ((mode & IFMT) == 0) | if ((mode & IFMT) == 0) | ||||
mode |= IFREG; | mode |= IFREG; | ||||
if (pdir->i_effnlink < 2) { | if (pdir->i_effnlink < 2) { | ||||
print_bad_link_count(callfunc, dvp); | print_bad_link_count(callfunc, dvp); | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
if (DOINGSUJ(dvp)) { | if (DOINGSUJ(dvp)) { | ||||
error = softdep_prelink(dvp, NULL); | error = softdep_prelink(dvp, NULL, cnp); | ||||
if (error != 0) { | if (error != 0) { | ||||
MPASS(error == ERELOOKUP); | MPASS(error == ERELOOKUP); | ||||
return (error); | return (error); | ||||
} | } | ||||
} | } | ||||
error = UFS_VALLOC(dvp, mode, cnp->cn_cred, &tvp); | error = UFS_VALLOC(dvp, mode, cnp->cn_cred, &tvp); | ||||
if (error) | if (error) | ||||
return (error); | return (error); | ||||
▲ Show 20 Lines • Show All 267 Lines • Show Last 20 Lines |