Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/vfs_syscalls.c
Show First 20 Lines • Show All 1,378 Lines • ▼ Show 20 Lines | else { | ||||
&nd.ni_cnd, &vattr); | &nd.ni_cnd, &vattr); | ||||
if (error == 0) | if (error == 0) | ||||
vput(nd.ni_vp); | vput(nd.ni_vp); | ||||
} | } | ||||
} | } | ||||
NDFREE(&nd, NDF_ONLY_PNBUF); | NDFREE(&nd, NDF_ONLY_PNBUF); | ||||
vput(nd.ni_dvp); | vput(nd.ni_dvp); | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
if (error == ERELOOKUP) | |||||
goto restart; | |||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Create a named pipe. | * Create a named pipe. | ||||
*/ | */ | ||||
#ifndef _SYS_SYSPROTO_H_ | #ifndef _SYS_SYSPROTO_H_ | ||||
struct mkfifo_args { | struct mkfifo_args { | ||||
▲ Show 20 Lines • Show All 70 Lines • ▼ Show 20 Lines | #endif | ||||
if (error == 0) | if (error == 0) | ||||
vput(nd.ni_vp); | vput(nd.ni_vp); | ||||
#ifdef MAC | #ifdef MAC | ||||
out: | out: | ||||
#endif | #endif | ||||
vput(nd.ni_dvp); | vput(nd.ni_dvp); | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
NDFREE(&nd, NDF_ONLY_PNBUF); | NDFREE(&nd, NDF_ONLY_PNBUF); | ||||
if (error == ERELOOKUP) | |||||
goto restart; | |||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Make a hard file link. | * Make a hard file link. | ||||
*/ | */ | ||||
#ifndef _SYS_SYSPROTO_H_ | #ifndef _SYS_SYSPROTO_H_ | ||||
struct link_args { | struct link_args { | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | kern_linkat(struct thread *td, int fd1, int fd2, const char *path1, | ||||
do { | do { | ||||
bwillwrite(); | bwillwrite(); | ||||
NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, segflag, | NDINIT_ATRIGHTS(&nd, LOOKUP, follow | AUDITVNODE1, segflag, | ||||
path1, fd1, &cap_linkat_source_rights, td); | path1, fd1, &cap_linkat_source_rights, td); | ||||
if ((error = namei(&nd)) != 0) | if ((error = namei(&nd)) != 0) | ||||
return (error); | return (error); | ||||
NDFREE(&nd, NDF_ONLY_PNBUF); | NDFREE(&nd, NDF_ONLY_PNBUF); | ||||
error = kern_linkat_vp(td, nd.ni_vp, fd2, path2, segflag); | error = kern_linkat_vp(td, nd.ni_vp, fd2, path2, segflag); | ||||
} while (error == EAGAIN); | } while (error == EAGAIN || error == ERELOOKUP); | ||||
return (error); | return (error); | ||||
} | } | ||||
static int | static int | ||||
kern_linkat_vp(struct thread *td, struct vnode *vp, int fd, const char *path, | kern_linkat_vp(struct thread *td, struct vnode *vp, int fd, const char *path, | ||||
enum uio_seg segflag) | enum uio_seg segflag) | ||||
{ | { | ||||
struct nameidata nd; | struct nameidata nd; | ||||
▲ Show 20 Lines • Show All 156 Lines • ▼ Show 20 Lines | #endif | ||||
if (error == 0) | if (error == 0) | ||||
vput(nd.ni_vp); | vput(nd.ni_vp); | ||||
#ifdef MAC | #ifdef MAC | ||||
out2: | out2: | ||||
#endif | #endif | ||||
NDFREE(&nd, NDF_ONLY_PNBUF); | NDFREE(&nd, NDF_ONLY_PNBUF); | ||||
vput(nd.ni_dvp); | vput(nd.ni_dvp); | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
if (error == ERELOOKUP) | |||||
goto restart; | |||||
out: | out: | ||||
if (segflg != UIO_SYSSPACE) | if (segflg != UIO_SYSSPACE) | ||||
uma_zfree(namei_zone, tmppath); | uma_zfree(namei_zone, tmppath); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Delete a whiteout from the filesystem. | * Delete a whiteout from the filesystem. | ||||
Show All 34 Lines | if (vn_start_write(nd.ni_dvp, &mp, V_NOWAIT) != 0) { | ||||
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; | ||||
} | } | ||||
error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE); | error = VOP_WHITEOUT(nd.ni_dvp, &nd.ni_cnd, DELETE); | ||||
NDFREE(&nd, NDF_ONLY_PNBUF); | NDFREE(&nd, NDF_ONLY_PNBUF); | ||||
vput(nd.ni_dvp); | vput(nd.ni_dvp); | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
if (error == ERELOOKUP) | |||||
goto restart; | |||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Delete a name from the filesystem. | * Delete a name from the filesystem. | ||||
*/ | */ | ||||
#ifndef _SYS_SYSPROTO_H_ | #ifndef _SYS_SYSPROTO_H_ | ||||
struct unlink_args { | struct unlink_args { | ||||
▲ Show 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | #endif | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
} | } | ||||
NDFREE(&nd, NDF_ONLY_PNBUF); | NDFREE(&nd, NDF_ONLY_PNBUF); | ||||
vput(nd.ni_dvp); | vput(nd.ni_dvp); | ||||
if (vp == nd.ni_dvp) | if (vp == nd.ni_dvp) | ||||
vrele(vp); | vrele(vp); | ||||
else | else | ||||
vput(vp); | vput(vp); | ||||
if (error == ERELOOKUP) | |||||
goto restart; | |||||
fdout: | fdout: | ||||
if (fp != NULL) | if (fp != NULL) | ||||
fdrop(fp, td); | fdrop(fp, td); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Reposition read/write file offset. | * Reposition read/write file offset. | ||||
▲ Show 20 Lines • Show All 1,442 Lines • ▼ Show 20 Lines | kern_truncate(struct thread *td, const char *path, enum uio_seg pathseg, | ||||
struct mount *mp; | struct mount *mp; | ||||
struct vnode *vp; | struct vnode *vp; | ||||
void *rl_cookie; | void *rl_cookie; | ||||
struct vattr vattr; | struct vattr vattr; | ||||
struct nameidata nd; | struct nameidata nd; | ||||
int error; | int error; | ||||
if (length < 0) | if (length < 0) | ||||
return(EINVAL); | return (EINVAL); | ||||
retry: | |||||
NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, td); | NDINIT(&nd, LOOKUP, FOLLOW | AUDITVNODE1, pathseg, path, td); | ||||
if ((error = namei(&nd)) != 0) | if ((error = namei(&nd)) != 0) | ||||
return (error); | return (error); | ||||
vp = nd.ni_vp; | vp = nd.ni_vp; | ||||
rl_cookie = vn_rangelock_wlock(vp, 0, OFF_MAX); | rl_cookie = vn_rangelock_wlock(vp, 0, OFF_MAX); | ||||
if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { | if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) { | ||||
vn_rangelock_unlock(vp, rl_cookie); | vn_rangelock_unlock(vp, rl_cookie); | ||||
vrele(vp); | vrele(vp); | ||||
Show All 12 Lines | else if ((error = vn_writechk(vp)) == 0 && | ||||
VATTR_NULL(&vattr); | VATTR_NULL(&vattr); | ||||
vattr.va_size = length; | vattr.va_size = length; | ||||
error = VOP_SETATTR(vp, &vattr, td->td_ucred); | error = VOP_SETATTR(vp, &vattr, td->td_ucred); | ||||
} | } | ||||
VOP_UNLOCK(vp); | VOP_UNLOCK(vp); | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
vn_rangelock_unlock(vp, rl_cookie); | vn_rangelock_unlock(vp, rl_cookie); | ||||
vrele(vp); | vrele(vp); | ||||
if (error == ERELOOKUP) | |||||
goto retry; | |||||
return (error); | return (error); | ||||
} | } | ||||
#if defined(COMPAT_43) | #if defined(COMPAT_43) | ||||
/* | /* | ||||
* Truncate a file given its path name. | * Truncate a file given its path name. | ||||
*/ | */ | ||||
#ifndef _SYS_SYSPROTO_H_ | #ifndef _SYS_SYSPROTO_H_ | ||||
Show All 39 Lines | kern_fsync(struct thread *td, int fd, bool fullsync) | ||||
error = getvnode(td, fd, &cap_fsync_rights, &fp); | error = getvnode(td, fd, &cap_fsync_rights, &fp); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
vp = fp->f_vnode; | vp = fp->f_vnode; | ||||
#if 0 | #if 0 | ||||
if (!fullsync) | if (!fullsync) | ||||
/* XXXKIB: compete outstanding aio writes */; | /* XXXKIB: compete outstanding aio writes */; | ||||
#endif | #endif | ||||
retry: | |||||
error = vn_start_write(vp, &mp, V_WAIT | PCATCH); | error = vn_start_write(vp, &mp, V_WAIT | PCATCH); | ||||
if (error != 0) | if (error != 0) | ||||
goto drop; | goto drop; | ||||
if (MNT_SHARED_WRITES(mp) || | if (MNT_SHARED_WRITES(mp) || | ||||
((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) { | ((mp == NULL) && MNT_SHARED_WRITES(vp->v_mount))) { | ||||
lock_flags = LK_SHARED; | lock_flags = LK_SHARED; | ||||
} else { | } else { | ||||
lock_flags = LK_EXCLUSIVE; | lock_flags = LK_EXCLUSIVE; | ||||
} | } | ||||
vn_lock(vp, lock_flags | LK_RETRY); | vn_lock(vp, lock_flags | LK_RETRY); | ||||
AUDIT_ARG_VNODE1(vp); | AUDIT_ARG_VNODE1(vp); | ||||
if (vp->v_object != NULL) { | if (vp->v_object != NULL) { | ||||
VM_OBJECT_WLOCK(vp->v_object); | VM_OBJECT_WLOCK(vp->v_object); | ||||
vm_object_page_clean(vp->v_object, 0, 0, 0); | vm_object_page_clean(vp->v_object, 0, 0, 0); | ||||
VM_OBJECT_WUNLOCK(vp->v_object); | VM_OBJECT_WUNLOCK(vp->v_object); | ||||
} | } | ||||
error = fullsync ? VOP_FSYNC(vp, MNT_WAIT, td) : VOP_FDATASYNC(vp, td); | error = fullsync ? VOP_FSYNC(vp, MNT_WAIT, td) : VOP_FDATASYNC(vp, td); | ||||
VOP_UNLOCK(vp); | VOP_UNLOCK(vp); | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
if (error == ERELOOKUP) | |||||
goto retry; | |||||
drop: | drop: | ||||
fdrop(fp, td); | fdrop(fp, td); | ||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Sync an open file. | * Sync an open file. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 165 Lines • ▼ Show 20 Lines | if (fvp == tdvp) { | ||||
error = EINVAL; | error = EINVAL; | ||||
goto out; | goto out; | ||||
} | } | ||||
/* | /* | ||||
* If the source is the same as the destination (that is, if they | * If the source is the same as the destination (that is, if they | ||||
* are links to the same vnode), then there is nothing to do. | * are links to the same vnode), then there is nothing to do. | ||||
*/ | */ | ||||
if (fvp == tvp) | if (fvp == tvp) | ||||
error = -1; | error = ERESTART; | ||||
#ifdef MAC | #ifdef MAC | ||||
else | else | ||||
error = mac_vnode_check_rename_to(td->td_ucred, tdvp, | error = mac_vnode_check_rename_to(td->td_ucred, tdvp, | ||||
tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); | tond.ni_vp, fromnd.ni_dvp == tdvp, &tond.ni_cnd); | ||||
#endif | #endif | ||||
out: | out: | ||||
if (error == 0) { | if (error == 0) { | ||||
error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, | error = VOP_RENAME(fromnd.ni_dvp, fromnd.ni_vp, &fromnd.ni_cnd, | ||||
Show All 12 Lines | if (error == 0) { | ||||
vrele(fromnd.ni_dvp); | vrele(fromnd.ni_dvp); | ||||
vrele(fvp); | vrele(fvp); | ||||
} | } | ||||
vrele(tond.ni_startdir); | vrele(tond.ni_startdir); | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
out1: | out1: | ||||
if (fromnd.ni_startdir) | if (fromnd.ni_startdir) | ||||
vrele(fromnd.ni_startdir); | vrele(fromnd.ni_startdir); | ||||
if (error == -1) | if (error == ERESTART) | ||||
markj: While you're here, could this use of -1 be converted to use a proper errno value? | |||||
return (0); | return (0); | ||||
if (error == ERELOOKUP) | |||||
goto again; | |||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Make a directory file. | * Make a directory file. | ||||
*/ | */ | ||||
#ifndef _SYS_SYSPROTO_H_ | #ifndef _SYS_SYSPROTO_H_ | ||||
struct mkdir_args { | struct mkdir_args { | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | |||||
#ifdef MAC | #ifdef MAC | ||||
out: | out: | ||||
#endif | #endif | ||||
NDFREE(&nd, NDF_ONLY_PNBUF); | NDFREE(&nd, NDF_ONLY_PNBUF); | ||||
vput(nd.ni_dvp); | vput(nd.ni_dvp); | ||||
if (error == 0) | if (error == 0) | ||||
vput(nd.ni_vp); | vput(nd.ni_vp); | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
if (error == ERELOOKUP) | |||||
goto restart; | |||||
return (error); | return (error); | ||||
} | } | ||||
/* | /* | ||||
* Remove a directory file. | * Remove a directory file. | ||||
*/ | */ | ||||
#ifndef _SYS_SYSPROTO_H_ | #ifndef _SYS_SYSPROTO_H_ | ||||
struct rmdir_args { | struct rmdir_args { | ||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | #endif | ||||
vn_finished_write(mp); | vn_finished_write(mp); | ||||
out: | out: | ||||
NDFREE(&nd, NDF_ONLY_PNBUF); | NDFREE(&nd, NDF_ONLY_PNBUF); | ||||
vput(vp); | vput(vp); | ||||
if (nd.ni_dvp == vp) | if (nd.ni_dvp == vp) | ||||
vrele(nd.ni_dvp); | vrele(nd.ni_dvp); | ||||
else | else | ||||
vput(nd.ni_dvp); | vput(nd.ni_dvp); | ||||
if (error == ERELOOKUP) | |||||
goto restart; | |||||
fdout: | fdout: | ||||
if (fp != NULL) | if (fp != NULL) | ||||
fdrop(fp, td); | fdrop(fp, td); | ||||
return (error); | return (error); | ||||
} | } | ||||
#if defined(COMPAT_43) || defined(COMPAT_FREEBSD11) | #if defined(COMPAT_43) || defined(COMPAT_FREEBSD11) | ||||
int | int | ||||
▲ Show 20 Lines • Show All 497 Lines • ▼ Show 20 Lines | do { | ||||
bwillwrite(); | bwillwrite(); | ||||
if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) | if ((mp = vfs_busyfs(&fh.fh_fsid)) == NULL) | ||||
return (ESTALE); | return (ESTALE); | ||||
error = VFS_FHTOVP(mp, &fh.fh_fid, LK_SHARED, &vp); | error = VFS_FHTOVP(mp, &fh.fh_fid, LK_SHARED, &vp); | ||||
vfs_unbusy(mp); | vfs_unbusy(mp); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
VOP_UNLOCK(vp); | VOP_UNLOCK(vp); | ||||
} while ((error = kern_linkat_vp(td, vp, fd, path, pathseg)) == EAGAIN); | error = kern_linkat_vp(td, vp, fd, path, pathseg); | ||||
} while (error == EAGAIN || error == ERELOOKUP); | |||||
return (error); | return (error); | ||||
} | } | ||||
#ifndef _SYS_SYSPROTO_H_ | #ifndef _SYS_SYSPROTO_H_ | ||||
struct fhreadlink_args { | struct fhreadlink_args { | ||||
fhandle_t *fhp; | fhandle_t *fhp; | ||||
char *buf; | char *buf; | ||||
size_t bufsize; | size_t bufsize; | ||||
▲ Show 20 Lines • Show All 503 Lines • Show Last 20 Lines |
While you're here, could this use of -1 be converted to use a proper errno value?