Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_syscalls.c
Show First 20 Lines • Show All 3,762 Lines • ▼ Show 20 Lines | sys_mkdirat(struct thread *td, struct mkdirat_args *uap) | ||||
return (kern_mkdirat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode)); | return (kern_mkdirat(td, uap->fd, uap->path, UIO_USERSPACE, uap->mode)); | ||||
} | } | ||||
int | int | ||||
kern_mkdirat(struct thread *td, int fd, const char *path, enum uio_seg segflg, | kern_mkdirat(struct thread *td, int fd, const char *path, enum uio_seg segflg, | ||||
int mode) | int mode) | ||||
{ | { | ||||
struct mount *mp; | struct mount *mp; | ||||
struct vnode *vp; | |||||
struct vattr vattr; | struct vattr vattr; | ||||
struct nameidata nd; | struct nameidata nd; | ||||
int error; | int error; | ||||
AUDIT_ARG_MODE(mode); | AUDIT_ARG_MODE(mode); | ||||
restart: | restart: | ||||
bwillwrite(); | bwillwrite(); | ||||
NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 | | NDINIT_ATRIGHTS(&nd, CREATE, LOCKPARENT | SAVENAME | AUDITVNODE1 | | ||||
NC_NOMAKEENTRY | NC_KEEPPOSENTRY, segflg, path, fd, | NC_NOMAKEENTRY | NC_KEEPPOSENTRY | FAILIFEXISTS, segflg, path, fd, | ||||
&cap_mkdirat_rights, td); | &cap_mkdirat_rights, td); | ||||
nd.ni_cnd.cn_flags |= WILLBEDIR; | nd.ni_cnd.cn_flags |= WILLBEDIR; | ||||
if ((error = namei(&nd)) != 0) | if ((error = namei(&nd)) != 0) | ||||
return (error); | return (error); | ||||
vp = nd.ni_vp; | |||||
if (vp != NULL) { | |||||
NDFREE(&nd, NDF_ONLY_PNBUF); | |||||
/* | |||||
* XXX namei called with LOCKPARENT but not LOCKLEAF has | |||||
* the strange behaviour of leaving the vnode unlocked | |||||
* if the target is the same vnode as the parent. | |||||
kib: I think this comment should be moved into the herald of the bad_eexist block. | |||||
*/ | |||||
if (vp == nd.ni_dvp) | |||||
vrele(nd.ni_dvp); | |||||
else | |||||
vput(nd.ni_dvp); | |||||
vrele(vp); | |||||
return (EEXIST); | |||||
} | |||||
if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { | if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { | ||||
NDFREE(&nd, NDF_ONLY_PNBUF); | NDFREE(&nd, NDF_ONLY_PNBUF); | ||||
vput(nd.ni_dvp); | vput(nd.ni_dvp); | ||||
if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) | if ((error = vn_start_write(NULL, &mp, V_XSLEEP | PCATCH)) != 0) | ||||
return (error); | return (error); | ||||
goto restart; | goto restart; | ||||
} | } | ||||
VATTR_NULL(&vattr); | VATTR_NULL(&vattr); | ||||
▲ Show 20 Lines • Show All 1,157 Lines • Show Last 20 Lines |
I think this comment should be moved into the herald of the bad_eexist block.