summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_extattr.c
diff options
context:
space:
mode:
authormckusick <mckusick@FreeBSD.org>2002-07-17 02:03:19 +0000
committermckusick <mckusick@FreeBSD.org>2002-07-17 02:03:19 +0000
commit3abb526f86a27b005f352fb91f605228876fa8f7 (patch)
tree5b5d1d91499a541486f56f84b49c10edeafd66b2 /sys/kern/vfs_extattr.c
parent9498a983a938cec96851b64642f0b62bba7d1827 (diff)
downloadFreeBSD-src-3abb526f86a27b005f352fb91f605228876fa8f7.zip
FreeBSD-src-3abb526f86a27b005f352fb91f605228876fa8f7.tar.gz
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.
Diffstat (limited to 'sys/kern/vfs_extattr.c')
-rw-r--r--sys/kern/vfs_extattr.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 5fc5652..b787bc2 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.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);
}
OpenPOWER on IntegriCloud