aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/vfs_syscalls.c
diff options
context:
space:
mode:
authorKirk McKusick <mckusick@FreeBSD.org>2002-07-17 02:03:19 +0000
committerKirk McKusick <mckusick@FreeBSD.org>2002-07-17 02:03:19 +0000
commitfb36a3d8472e3b7c446b5501635ec34eb1ebaa00 (patch)
tree5b5d1d91499a541486f56f84b49c10edeafd66b2 /sys/kern/vfs_syscalls.c
parenta1dc2096387101165d53fe98677d3e4e1d0557ad (diff)
downloadsrc-fb36a3d8472e3b7c446b5501635ec34eb1ebaa00.tar.gz
src-fb36a3d8472e3b7c446b5501635ec34eb1ebaa00.zip
Change utimes to set the file creation time (for filesystems that
support creation times such as UFS2) to the value of the modification time if the value of the modification time is older than the current creation time. See utimes(2) for further details. Sponsored by: DARPA & NAI Labs.
Notes
Notes: svn path=/head/; revision=100207
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r--sys/kern/vfs_syscalls.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 5fc565255d47..b787bc230432 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -82,7 +82,7 @@ static int setfown(struct thread *td, struct vnode *, uid_t, gid_t);
static int setfmode(struct thread *td, struct vnode *, int);
static int setfflags(struct thread *td, struct vnode *, int);
static int setutimes(struct thread *td, struct vnode *,
- const struct timespec *, int);
+ const struct timespec *, int, int);
static int vn_access(struct vnode *vp, int user_flags, struct ucred *cred,
struct thread *td);
@@ -2116,13 +2116,14 @@ getutimes(usrtvp, tsp)
* Common implementation code for utimes(), lutimes(), and futimes().
*/
static int
-setutimes(td, vp, ts, nullflag)
+setutimes(td, vp, ts, numtimes, nullflag)
struct thread *td;
struct vnode *vp;
const struct timespec *ts;
+ int numtimes;
int nullflag;
{
- int error;
+ int error, setbirthtime;
struct mount *mp;
struct vattr vattr;
@@ -2130,9 +2131,17 @@ setutimes(td, vp, ts, nullflag)
return (error);
VOP_LEASE(vp, td, td->td_ucred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
+ setbirthtime = 0;
+ if (numtimes < 3 && VOP_GETATTR(vp, &vattr, td->td_ucred, td) == 0 &&
+ timespeccmp(&ts[1], &vattr.va_birthtime, < ))
+ setbirthtime = 1;
VATTR_NULL(&vattr);
vattr.va_atime = ts[0];
vattr.va_mtime = ts[1];
+ if (setbirthtime)
+ vattr.va_birthtime = ts[1];
+ if (numtimes > 2)
+ vattr.va_birthtime = ts[2];
if (nullflag)
vattr.va_vaflags |= VA_UTIMES_NULL;
error = VOP_SETATTR(vp, &vattr, td->td_ucred, td);
@@ -2171,7 +2180,7 @@ utimes(td, uap)
if ((error = namei(&nd)) != 0)
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
- error = setutimes(td, nd.ni_vp, ts, usrtvp == NULL);
+ error = setutimes(td, nd.ni_vp, ts, 2, usrtvp == NULL);
vrele(nd.ni_vp);
return (error);
}
@@ -2206,7 +2215,7 @@ lutimes(td, uap)
if ((error = namei(&nd)) != 0)
return (error);
NDFREE(&nd, NDF_ONLY_PNBUF);
- error = setutimes(td, nd.ni_vp, ts, usrtvp == NULL);
+ error = setutimes(td, nd.ni_vp, ts, 2, usrtvp == NULL);
vrele(nd.ni_vp);
return (error);
}
@@ -2239,7 +2248,7 @@ futimes(td, uap)
return (error);
if ((error = getvnode(td->td_proc->p_fd, SCARG(uap, fd), &fp)) != 0)
return (error);
- error = setutimes(td, (struct vnode *)fp->f_data, ts, usrtvp == NULL);
+ error = setutimes(td, (struct vnode *)fp->f_data, ts, 2, usrtvp==NULL);
fdrop(fp, td);
return (error);
}