1fab63cc4SDoug Rabson.\" -*- nroff -*- 2fab63cc4SDoug Rabson.\" 3fab63cc4SDoug Rabson.\" Copyright (c) 1996 Doug Rabson 4fab63cc4SDoug Rabson.\" 5fab63cc4SDoug Rabson.\" All rights reserved. 6fab63cc4SDoug Rabson.\" 7fab63cc4SDoug Rabson.\" This program is free software. 8fab63cc4SDoug Rabson.\" 9fab63cc4SDoug Rabson.\" Redistribution and use in source and binary forms, with or without 10fab63cc4SDoug Rabson.\" modification, are permitted provided that the following conditions 11fab63cc4SDoug Rabson.\" are met: 12fab63cc4SDoug Rabson.\" 1. Redistributions of source code must retain the above copyright 13fab63cc4SDoug Rabson.\" notice, this list of conditions and the following disclaimer. 14fab63cc4SDoug Rabson.\" 2. Redistributions in binary form must reproduce the above copyright 15fab63cc4SDoug Rabson.\" notice, this list of conditions and the following disclaimer in the 16fab63cc4SDoug Rabson.\" documentation and/or other materials provided with the distribution. 17fab63cc4SDoug Rabson.\" 18fab63cc4SDoug Rabson.\" THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY EXPRESS OR 19fab63cc4SDoug Rabson.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20fab63cc4SDoug Rabson.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21fab63cc4SDoug Rabson.\" IN NO EVENT SHALL THE DEVELOPERS BE LIABLE FOR ANY DIRECT, INDIRECT, 22fab63cc4SDoug Rabson.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23fab63cc4SDoug Rabson.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24fab63cc4SDoug Rabson.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25fab63cc4SDoug Rabson.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26fab63cc4SDoug Rabson.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27fab63cc4SDoug Rabson.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28fab63cc4SDoug Rabson.\" 297f3dea24SPeter Wemm.\" $FreeBSD$ 30fab63cc4SDoug Rabson.\" 31fab63cc4SDoug Rabson.Dd July 24, 1996 32fab63cc4SDoug Rabson.Os 33fab63cc4SDoug Rabson.Dt VOP_RENAME 9 34fab63cc4SDoug Rabson.Sh NAME 35fab63cc4SDoug Rabson.Nm VOP_RENAME 36fab63cc4SDoug Rabson.Nd rename a file 37fab63cc4SDoug Rabson.Sh SYNOPSIS 3832eef9aeSRuslan Ermilov.In sys/param.h 3932eef9aeSRuslan Ermilov.In sys/vnode.h 40fab63cc4SDoug Rabson.Ft int 41fab63cc4SDoug Rabson.Fn VOP_RENAME "struct vnode *fdvp" "struct vnode *fvp" "struct componentname *fcnp" "struct vnode *tdvp" "struct vnode *tvp" "struct componentname *tcnp" 42fab63cc4SDoug Rabson.Sh DESCRIPTION 43fab63cc4SDoug RabsonThis renames a file and possibly changes its parent directory. 44fab63cc4SDoug RabsonIf the destination object exists, it will be removed first. 45fab63cc4SDoug Rabson.Pp 46fab63cc4SDoug RabsonIts arguments are: 47fab63cc4SDoug Rabson.Bl -tag -width fdvp 480640e9e0SHiten Pandya.It Fa fdvp 490a57ea7dSRuslan ErmilovThe vnode of the old parent directory. 500640e9e0SHiten Pandya.It Fa fvp 510a57ea7dSRuslan ErmilovThe vnode of the file to be renamed. 520640e9e0SHiten Pandya.It Fa fcnp 530a57ea7dSRuslan ErmilovPathname information about the file's current name. 540640e9e0SHiten Pandya.It Fa tdvp 550a57ea7dSRuslan ErmilovThe vnode of the new parent directory. 560640e9e0SHiten Pandya.It Fa tvp 570a57ea7dSRuslan ErmilovThe vnode of the target file (if it exists). 580640e9e0SHiten Pandya.It Fa tcnp 590a57ea7dSRuslan ErmilovPathname information about the file's new name. 60fab63cc4SDoug Rabson.El 61fab63cc4SDoug Rabson.Sh LOCKS 6237af2883SMatthew DillonThe source directory and file are unlocked but are expected to have their 63c1c03d49SHiten Pandyaref count bumped on entry. 64c1c03d49SHiten PandyaThe VOP routine is expected to 652cb869e0SHiten Pandya.Xr vrele 9 6687b0140cSMatthew Dillonboth prior 6737af2883SMatthew Dillonto returning. 6837af2883SMatthew Dillon.Pp 6937af2883SMatthew DillonThe destination directory and file are locked as well as having their ref 70c1c03d49SHiten Pandyacount bumped. 71c1c03d49SHiten PandyaThe VOP routine is expected to 722cb869e0SHiten Pandya.Xr vput 9 7387b0140cSMatthew Dillonboth prior to 7437af2883SMatthew Dillonreturning. 75fab63cc4SDoug Rabson.Sh PSEUDOCODE 76fab63cc4SDoug Rabson.Bd -literal 77fab63cc4SDoug Rabsonint 78fab63cc4SDoug Rabsonvop_rename(struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp, 79fab63cc4SDoug Rabson struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp) 80fab63cc4SDoug Rabson{ 81fab63cc4SDoug Rabson int doingdirectory = 0; 82fab63cc4SDoug Rabson int error = 0; 83fab63cc4SDoug Rabson 84fab63cc4SDoug Rabson /* 85fab63cc4SDoug Rabson * Check for cross-device rename. 86fab63cc4SDoug Rabson */ 87fab63cc4SDoug Rabson if (fvp->v_mount != tdvp->v_mount) { 88fab63cc4SDoug Rabson error = EXDEV; 89fab63cc4SDoug Rabson abortit: 90fab63cc4SDoug Rabson if (tdvp == tvp) 91fab63cc4SDoug Rabson vrele(tdvp); 92fab63cc4SDoug Rabson else 93fab63cc4SDoug Rabson vput(tdvp); 94fab63cc4SDoug Rabson if (tvp) 95fab63cc4SDoug Rabson vput(tvp); 96fab63cc4SDoug Rabson vrele(fdvp); 97fab63cc4SDoug Rabson vrele(fvp); 98fab63cc4SDoug Rabson return error; 99fab63cc4SDoug Rabson } 100fab63cc4SDoug Rabson 101fab63cc4SDoug Rabson if (tvp exists and is immutable) { 102fab63cc4SDoug Rabson error = EPERM; 103fab63cc4SDoug Rabson goto abortit; 104fab63cc4SDoug Rabson } 105fab63cc4SDoug Rabson 106fab63cc4SDoug Rabson /* 107fab63cc4SDoug Rabson * Check if just deleting a link name. 108fab63cc4SDoug Rabson */ 109fab63cc4SDoug Rabson if (fvp == tvp) { 110fab63cc4SDoug Rabson if (fvp->v_type == VDIR) { 111fab63cc4SDoug Rabson error = EINVAL; 112fab63cc4SDoug Rabson goto abortit; 113fab63cc4SDoug Rabson } 114fab63cc4SDoug Rabson 115fab63cc4SDoug Rabson /* 116fab63cc4SDoug Rabson * Release destination. 117fab63cc4SDoug Rabson */ 118fab63cc4SDoug Rabson vput(tdvp); 119fab63cc4SDoug Rabson vput(tvp); 120fab63cc4SDoug Rabson 121fab63cc4SDoug Rabson /* 122fab63cc4SDoug Rabson * Delete source. Pretty bizarre stuff. 123fab63cc4SDoug Rabson */ 124fab63cc4SDoug Rabson vrele(fdvp); 125fab63cc4SDoug Rabson vrele(fvp); 126fab63cc4SDoug Rabson fcnp->cn_flags &= ~MODMASK; 127fab63cc4SDoug Rabson fcnp->cn_flags |= LOCKPARENT | LOCKLEAF; 128fab63cc4SDoug Rabson fcnp->cn_nameiop = DELETE; 129fab63cc4SDoug Rabson VREF(fdvp); 130fab63cc4SDoug Rabson error = relookup(fdvp, &fvp, fcnp); 131fab63cc4SDoug Rabson if (error == 0) 132fab63cc4SDoug Rabson vrele(fdvp); 133fab63cc4SDoug Rabson return VOP_REMOVE(fdvp, fvp, fcnp); 134fab63cc4SDoug Rabson } 135fab63cc4SDoug Rabson 136fab63cc4SDoug Rabson if (fvp is immutable) { 137fab63cc4SDoug Rabson error = EPERM; 138fab63cc4SDoug Rabson goto abortit; 139fab63cc4SDoug Rabson } 140fab63cc4SDoug Rabson 141fab63cc4SDoug Rabson error = VOP_LOCK(fvp); 142fab63cc4SDoug Rabson if (error) 143fab63cc4SDoug Rabson goto abortit; 144fab63cc4SDoug Rabson 145fab63cc4SDoug Rabson if (vp is a directory) { 146fab63cc4SDoug Rabson /* 147fab63cc4SDoug Rabson * Avoid ".", "..", and aliases of "." for obvious reasons. 148fab63cc4SDoug Rabson */ 149fab63cc4SDoug Rabson if ((fcnp->cn_namelen == 1 && fcnp->cn_nameptr[0] == '.') 150fab63cc4SDoug Rabson || fdvp == fvp 151fab63cc4SDoug Rabson || ((fcnp->cn_flags | tcnp->cn_flags) & ISDOTDOT)) { 152fab63cc4SDoug Rabson VOP_UNLOCK(fvp); 153fab63cc4SDoug Rabson error = EINVAL; 154fab63cc4SDoug Rabson goto abortit; 155fab63cc4SDoug Rabson } 156fab63cc4SDoug Rabson doingdirectory = 1; 157fab63cc4SDoug Rabson } 158fab63cc4SDoug Rabson vrele(fdvp); 159fab63cc4SDoug Rabson 160fab63cc4SDoug Rabson /* 161fab63cc4SDoug Rabson * Bump link count on fvp while we are moving stuff around. If we 162fab63cc4SDoug Rabson * crash before completing the work, the link count may be wrong 163fab63cc4SDoug Rabson * but correctable. 164fab63cc4SDoug Rabson */ 165fab63cc4SDoug Rabson ...; 166fab63cc4SDoug Rabson 167fab63cc4SDoug Rabson /* 168fab63cc4SDoug Rabson * If ".." must be changed (ie the directory gets a new 169fab63cc4SDoug Rabson * parent) then the source directory must not be in the 1703a9c9c6eSMike Pritchard * directory hierarchy above the target, as this would 171fab63cc4SDoug Rabson * orphan everything below the source directory. Also 172fab63cc4SDoug Rabson * the user must have write permission in the source so 173fab63cc4SDoug Rabson * as to be able to change "..". 174fab63cc4SDoug Rabson */ 175ad5d91b7SAlfred Perlstein error = VOP_ACCESS(fvp, VWRITE, tcnp->cn_cred, tcnp->cn_thread); 176fab63cc4SDoug Rabson VOP_UNLOCK(fvp); 177fab63cc4SDoug Rabson if (doingdirectory && fdvp != tdvp) { 178fab63cc4SDoug Rabson /* 179fab63cc4SDoug Rabson * Check for pathname conflict. 180fab63cc4SDoug Rabson */ 181fab63cc4SDoug Rabson ...; 182fab63cc4SDoug Rabson } 183fab63cc4SDoug Rabson 184fab63cc4SDoug Rabson /* 185fab63cc4SDoug Rabson * If the target doesn't exist, link the target to the source and 186fab63cc4SDoug Rabson * unlink the source. Otherwise, rewrite the target directory to 187fab63cc4SDoug Rabson * reference the source and remove the original entry. 188fab63cc4SDoug Rabson */ 189fab63cc4SDoug Rabson if (tvp == NULL) { 190fab63cc4SDoug Rabson /* 191fab63cc4SDoug Rabson * Account for ".." in new directory. 192fab63cc4SDoug Rabson */ 193fab63cc4SDoug Rabson if (doingdirectory && fdvp != tdvp) { 194fab63cc4SDoug Rabson /* 195fab63cc4SDoug Rabson * Increase link count of tdvp. 196fab63cc4SDoug Rabson */ 197fab63cc4SDoug Rabson ...; 198fab63cc4SDoug Rabson } 199fab63cc4SDoug Rabson 200fab63cc4SDoug Rabson /* 201fab63cc4SDoug Rabson * Add name in new directory. 202fab63cc4SDoug Rabson */ 203fab63cc4SDoug Rabson ...; 204fab63cc4SDoug Rabson 205fab63cc4SDoug Rabson if (error) { 206fab63cc4SDoug Rabson if (doingdirectory && fdvp != tdvp) { 207fab63cc4SDoug Rabson /* 208fab63cc4SDoug Rabson * Decrease link count if tdvp. 209fab63cc4SDoug Rabson */ 210fab63cc4SDoug Rabson ...; 211fab63cc4SDoug Rabson } 212fab63cc4SDoug Rabson goto bad; 213fab63cc4SDoug Rabson } 214fab63cc4SDoug Rabson vput(tdvp); 215fab63cc4SDoug Rabson } else { 216fab63cc4SDoug Rabson /* 217fab63cc4SDoug Rabson * Target must be empty if a directory and have no links 218fab63cc4SDoug Rabson * to it. Also, ensure source and target are compatible 219fab63cc4SDoug Rabson * (both directories, or both not directories). 220fab63cc4SDoug Rabson */ 221fab63cc4SDoug Rabson if (tvp is a directory) { 222fab63cc4SDoug Rabson if (tvp is not empty) { 223fab63cc4SDoug Rabson error = ENOTEMPTY; 224fab63cc4SDoug Rabson goto bad; 225fab63cc4SDoug Rabson } 226fab63cc4SDoug Rabson if (!doingdirectory) { 227fab63cc4SDoug Rabson error = ENOTDIR; 228fab63cc4SDoug Rabson goto bad; 229fab63cc4SDoug Rabson } 230fab63cc4SDoug Rabson /* 231fab63cc4SDoug Rabson * Update name cache since directory is going away. 232fab63cc4SDoug Rabson */ 233fab63cc4SDoug Rabson cache_purge(tdvp); 234fab63cc4SDoug Rabson } else if (doingdirectory) { 235fab63cc4SDoug Rabson error = ENOTDIR; 236fab63cc4SDoug Rabson goto bad; 237fab63cc4SDoug Rabson } 238fab63cc4SDoug Rabson 239fab63cc4SDoug Rabson /* 240fab63cc4SDoug Rabson * Change name tcnp in tdvp to point at fvp. 241fab63cc4SDoug Rabson */ 242fab63cc4SDoug Rabson ...; 243fab63cc4SDoug Rabson 244fab63cc4SDoug Rabson /* 245fab63cc4SDoug Rabson * If the target directory is in same directory as the source 246fab63cc4SDoug Rabson * directory, decrement the link count on the parent of the 247fab63cc4SDoug Rabson * target directory. This accounts for the fact that a 248fab63cc4SDoug Rabson * directory links back to its parent with "..". 249fab63cc4SDoug Rabson */ 250fab63cc4SDoug Rabson if (doingdirectory && fdvp == tdvp) { 251fab63cc4SDoug Rabson /* 252fab63cc4SDoug Rabson * Decrement link count of tdvp. 253fab63cc4SDoug Rabson */ 254fab63cc4SDoug Rabson ...; 255fab63cc4SDoug Rabson } 256fab63cc4SDoug Rabson vput(tdvp); 257fab63cc4SDoug Rabson 258fab63cc4SDoug Rabson /* 259fab63cc4SDoug Rabson * Decrement the link count of tvp since the directory no 260fab63cc4SDoug Rabson * longer points at it. 261fab63cc4SDoug Rabson */ 262fab63cc4SDoug Rabson ...; 263fab63cc4SDoug Rabson if (doingdirectory) { 264fab63cc4SDoug Rabson /* 265fab63cc4SDoug Rabson * Clean up the old directory tvp. 266fab63cc4SDoug Rabson */ 267fab63cc4SDoug Rabson ...; 268fab63cc4SDoug Rabson } 269fab63cc4SDoug Rabson vput(tvp); 270fab63cc4SDoug Rabson } 271fab63cc4SDoug Rabson 272fab63cc4SDoug Rabson /* 273fab63cc4SDoug Rabson * Unlink the source. If a directory was moved to a new parent, 274fab63cc4SDoug Rabson * update its ".." entry. Gobs of ugly UFS code omitted here. 275fab63cc4SDoug Rabson */ 276fab63cc4SDoug Rabson ...; 277fab63cc4SDoug Rabson 278fab63cc4SDoug Rabsonbad: 279fab63cc4SDoug Rabson if (tvp) 280fab63cc4SDoug Rabson vput(tvp); 281fab63cc4SDoug Rabson vput(tdvp); 282fab63cc4SDoug Rabsonout: 283fab63cc4SDoug Rabson if (VOP_LOCK(fvp) == 0) { 284fab63cc4SDoug Rabson /* 285fab63cc4SDoug Rabson * Decrement link count of fvp. 286fab63cc4SDoug Rabson */ 287fab63cc4SDoug Rabson ...; 288fab63cc4SDoug Rabson vput(fvp); 289fab63cc4SDoug Rabson } else 290fab63cc4SDoug Rabson vrele(fvp); 291fab63cc4SDoug Rabson 292fab63cc4SDoug Rabson return error; 293fab63cc4SDoug Rabson} 294fab63cc4SDoug Rabson.Ed 295fab63cc4SDoug Rabson.Sh ERRORS 296eaa8b244SMike Pritchard.Bl -tag -width Er 297fab63cc4SDoug Rabson.It Bq Er EPERM 298cc258457SDon LewisThe file is immutable. 299fab63cc4SDoug Rabson.It Bq Er EXDEV 30081f8d226SDon LewisIt is not possible to rename a file between different file systems. 301fab63cc4SDoug Rabson.It Bq Er EINVAL 30281f8d226SDon LewisAn attempt was made to rename 303d962d52aSRuslan Ermilov.Pa \&. 30481f8d226SDon Lewisor 305d962d52aSRuslan Ermilov.Pa .. , 306d962d52aSRuslan Ermilovor to perform an operation which would break the directory tree structure. 307fab63cc4SDoug Rabson.It Bq Er ENOTDIR 30881f8d226SDon LewisAn attempt was made to rename a directory to a file or vice versa. 309fab63cc4SDoug Rabson.It Bq Er ENOTEMPTY 31081f8d226SDon LewisAn attempt was made to remove a directory which is not empty. 311fab63cc4SDoug Rabson.El 312fab63cc4SDoug Rabson.Sh SEE ALSO 313fab63cc4SDoug Rabson.Xr vnode 9 314fab63cc4SDoug Rabson.Sh AUTHORS 3152cb869e0SHiten PandyaThis manual page was written by 316aaf1f16eSPhilippe Charnier.An Doug Rabson . 317