2005-04-21 16:53:53 +02:00
|
|
|
/* This file takes care of those system calls that deal with time.
|
|
|
|
*
|
|
|
|
* The entry points into this file are
|
|
|
|
* do_utime: perform the UTIME system call
|
2011-12-24 15:02:54 +01:00
|
|
|
* do_utimens: perform the UTIMENS system call
|
2005-04-21 16:53:53 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "fs.h"
|
|
|
|
#include <minix/callnr.h>
|
|
|
|
#include <minix/com.h>
|
2011-12-21 23:29:29 +01:00
|
|
|
#include <time.h>
|
2013-04-12 18:41:23 +02:00
|
|
|
#include <string.h>
|
2011-12-24 15:02:54 +01:00
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
2005-04-21 16:53:53 +02:00
|
|
|
#include "file.h"
|
|
|
|
#include "fproc.h"
|
2012-02-13 16:28:04 +01:00
|
|
|
#include "path.h"
|
2005-04-21 16:53:53 +02:00
|
|
|
#include "param.h"
|
2007-08-07 14:52:47 +02:00
|
|
|
#include "vnode.h"
|
2006-10-25 15:40:36 +02:00
|
|
|
#include <minix/vfsif.h>
|
|
|
|
#include "vmnt.h"
|
|
|
|
|
2011-12-24 15:02:54 +01:00
|
|
|
#define UTIMENS_STYLE 0 /* utimes(2)/utimensat(2) style, named file */
|
|
|
|
#define FUTIMENS_STYLE 1 /* futimens(2)/futimes(2) style, file desc. */
|
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/*===========================================================================*
|
|
|
|
* do_utime *
|
|
|
|
*===========================================================================*/
|
2013-04-12 18:41:23 +02:00
|
|
|
int do_utime(message *UNUSED(m_out))
|
2005-04-21 16:53:53 +02:00
|
|
|
{
|
|
|
|
/* Perform the utime(name, timep) system call. */
|
2006-10-25 15:40:36 +02:00
|
|
|
int r;
|
2011-12-21 23:29:29 +01:00
|
|
|
struct timespec actim, modtim, newactim, newmodtim;
|
2007-08-07 14:52:47 +02:00
|
|
|
struct vnode *vp;
|
2012-02-13 16:28:04 +01:00
|
|
|
struct vmnt *vmp;
|
|
|
|
char fullpath[PATH_MAX];
|
|
|
|
struct lookup resolve;
|
2012-04-13 14:50:38 +02:00
|
|
|
vir_bytes vname;
|
|
|
|
size_t vname_length, len;
|
2012-02-13 16:28:04 +01:00
|
|
|
|
2012-04-13 14:50:38 +02:00
|
|
|
vname = (vir_bytes) job_m_in.utime_file;
|
|
|
|
vname_length = (size_t) job_m_in.utime_length;
|
2011-12-21 23:29:29 +01:00
|
|
|
actim.tv_sec = job_m_in.utime_actime;
|
|
|
|
modtim.tv_sec = job_m_in.utime_modtime;
|
|
|
|
actim.tv_nsec = modtim.tv_nsec = 0;
|
2012-02-13 16:28:04 +01:00
|
|
|
|
2005-04-21 16:53:53 +02:00
|
|
|
/* Adjust for case of 'timep' being NULL;
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
* utime_strlen then holds the actual size: strlen(name)+1 */
|
2012-04-13 14:50:38 +02:00
|
|
|
len = vname_length;
|
|
|
|
if (len == 0) len = (size_t) job_m_in.utime_strlen;
|
|
|
|
|
|
|
|
lookup_init(&resolve, fullpath, PATH_NOFLAGS, &vmp, &vp);
|
VFS: fix locking bugs
.sync and fsync used unnecessarily restrictive locking type
.fsync violated locking order by obtaining a vmnt lock after a filp lock
.fsync contained a TOCTOU bug
.new_node violated locking rules (didn't upgrade lock upon file creation)
.do_pipe used unnecessarily restrictive locking type
.always lock pipes exclusively; even a read operation might require to do
a write on a vnode object (update pipe size)
.when opening a file with O_TRUNC, upgrade vnode lock when truncating
.utime used unnecessarily restrictive locking type
.path parsing:
.always acquire VMNT_WRITE or VMNT_EXCL on vmnt and downgrade to
VMNT_READ if that was what was actually requested. This prevents the
following deadlock scenario:
thread A:
lock_vmnt(vmp, TLL_READSER);
lock_vnode(vp, TLL_READSER);
upgrade_vmnt_lock(vmp, TLL_WRITE);
thread B:
lock_vmnt(vmp, TLL_READ);
lock_vnode(vp, TLL_READSER);
thread A will be stuck in upgrade_vmnt_lock and thread B is stuck in
lock_vnode. This happens when, for example, thread A tries create a
new node (open.c:new_node) and thread B tries to do eat_path to
change dir (stadir.c:do_chdir). When the path is being resolved, a
vnode is always locked with VNODE_OPCL (TLL_READSER) and then
downgraded to VNODE_READ if read-only is actually requested. Thread
A locks the vmnt with VMNT_WRITE (TLL_READSER) which still allows
VMNT_READ locks. Thread B can't acquire a lock on the vnode because
thread A has it; Thread A can't upgrade its vmnt lock to VMNT_WRITE
(TLL_WRITE) because thread B has a VMNT_READ lock on it.
By serializing vmnt locks during path parsing, thread B can only
acquire a lock on vmp when thread A has completely finished its
operation.
2012-11-30 13:49:53 +01:00
|
|
|
resolve.l_vmnt_lock = VMNT_READ;
|
2012-04-13 14:50:38 +02:00
|
|
|
resolve.l_vnode_lock = VNODE_READ;
|
2005-04-21 16:53:53 +02:00
|
|
|
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
/* Temporarily open the file */
|
2012-04-13 14:50:38 +02:00
|
|
|
if (fetch_name(vname, len, fullpath) != OK) return(err_code);
|
2012-02-13 16:28:04 +01:00
|
|
|
if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code);
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
|
2011-12-21 23:29:29 +01:00
|
|
|
/* Only the owner of a file or the super user can change timestamps. */
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
r = OK;
|
|
|
|
if (vp->v_uid != fp->fp_effuid && fp->fp_effuid != SU_UID) r = EPERM;
|
2012-04-13 14:50:38 +02:00
|
|
|
if (vname_length == 0 && r != OK) r = forbidden(fp, vp, W_BIT);
|
2012-02-13 16:28:04 +01:00
|
|
|
if (read_only(vp) != OK) r = EROFS; /* Not even su can touch if R/O */
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
if (r == OK) {
|
|
|
|
/* Issue request */
|
2012-04-13 14:50:38 +02:00
|
|
|
if (vname_length == 0) {
|
2011-12-21 23:29:29 +01:00
|
|
|
newactim = newmodtim = clock_timespec();
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
} else {
|
2011-12-21 23:29:29 +01:00
|
|
|
newactim = actim;
|
|
|
|
newmodtim = modtim;
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
}
|
2011-12-21 23:29:29 +01:00
|
|
|
r = req_utime(vp->v_fs_e, vp->v_inode_nr, &newactim, &newmodtim);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
|
|
|
|
2012-02-13 16:28:04 +01:00
|
|
|
unlock_vnode(vp);
|
|
|
|
unlock_vmnt(vmp);
|
|
|
|
|
2007-08-07 14:52:47 +02:00
|
|
|
put_vnode(vp);
|
- Introduce support for sticky bit.
- Revise VFS-FS protocol and update VFS/MFS/ISOFS accordingly.
- Clean up MFS by removing old, dead code (backwards compatibility is broken by
the new VFS-FS protocol, anyway) and rewrite other parts. Also, make sure all
functions have proper banners and prototypes.
- VFS should always provide a (syntactically) valid path to the FS; no need for
the FS to do sanity checks when leaving/entering mount points.
- Fix several bugs in MFS:
- Several path lookup bugs in MFS.
- A link can be too big for the path buffer.
- A mountpoint can become inaccessible when the creation of a new inode
fails, because the inode already exists and is a mountpoint.
- Introduce support for supplemental groups.
- Add test 46 to test supplemental group functionality (and removed obsolete
suppl. tests from test 2).
- Clean up VFS (not everything is done yet).
- ISOFS now opens device read-only. This makes the -r flag in the mount command
unnecessary (but will still report to be mounted read-write).
- Introduce PipeFS. PipeFS is a new FS that handles all anonymous and
named pipes. However, named pipes still reside on the (M)FS, as they are part
of the file system on disk. To make this work VFS now has a concept of
'mapped' inodes, which causes read, write, truncate and stat requests to be
redirected to the mapped FS, and all other requests to the original FS.
2009-12-20 21:27:14 +01:00
|
|
|
return(r);
|
2005-04-21 16:53:53 +02:00
|
|
|
}
|
2011-12-24 15:02:54 +01:00
|
|
|
|
|
|
|
|
|
|
|
/*===========================================================================*
|
|
|
|
* do_utimens *
|
|
|
|
*===========================================================================*/
|
2013-04-12 18:41:23 +02:00
|
|
|
int do_utimens(message *UNUSED(m_out))
|
2011-12-24 15:02:54 +01:00
|
|
|
{
|
|
|
|
/* Perform the utimens(name, times, flag) system call, and its friends.
|
|
|
|
* Implement a very large but not complete subset of the utimensat()
|
|
|
|
* Posix:2008/XOpen-7 function.
|
|
|
|
* Are handled all the following cases:
|
|
|
|
* . utimensat(AT_FDCWD, "/some/absolute/path", , )
|
|
|
|
* . utimensat(AT_FDCWD, "some/path", , )
|
|
|
|
* . utimens("anything", ) really special case of the above two
|
|
|
|
* . lutimens("anything", ) also really special case of the above
|
|
|
|
* . utimensat(fd, "/some/absolute/path", , ) although fd is useless here
|
|
|
|
* . futimens(fd, )
|
|
|
|
* Are not handled the following cases:
|
|
|
|
* . utimensat(fd, "some/path", , ) path to a file relative to some open fd
|
|
|
|
*/
|
|
|
|
int r, kind, lookup_flags;
|
|
|
|
struct vnode *vp;
|
|
|
|
struct filp *filp = NULL; /* initialization required by clueless GCC */
|
|
|
|
struct vmnt *vmp;
|
|
|
|
struct timespec actim, modtim, now, newactim, newmodtim;
|
|
|
|
char fullpath[PATH_MAX];
|
|
|
|
struct lookup resolve;
|
|
|
|
vir_bytes vname;
|
|
|
|
size_t vname_length;
|
|
|
|
|
2013-04-12 18:41:23 +02:00
|
|
|
memset(&now, 0, sizeof(now));
|
|
|
|
|
2011-12-24 15:02:54 +01:00
|
|
|
/* The case times==NULL is handled by the caller, replaced with UTIME_NOW */
|
|
|
|
actim.tv_sec = job_m_in.utime_actime;
|
|
|
|
actim.tv_nsec = job_m_in.utimens_ansec;
|
|
|
|
modtim.tv_sec = job_m_in.utime_modtime;
|
|
|
|
modtim.tv_nsec = job_m_in.utimens_mnsec;
|
|
|
|
|
|
|
|
if (job_m_in.utime_file != NULL) {
|
|
|
|
kind = UTIMENS_STYLE;
|
|
|
|
if (job_m_in.utimens_flags & ~AT_SYMLINK_NOFOLLOW)
|
|
|
|
return EINVAL; /* unknown flag */
|
|
|
|
/* Temporarily open the file */
|
|
|
|
vname = (vir_bytes) job_m_in.utime_file;
|
|
|
|
vname_length = (size_t) job_m_in.utime_length;
|
|
|
|
if (job_m_in.utimens_flags & AT_SYMLINK_NOFOLLOW)
|
|
|
|
lookup_flags = PATH_RET_SYMLINK;
|
|
|
|
else
|
|
|
|
lookup_flags = PATH_NOFLAGS;
|
|
|
|
lookup_init(&resolve, fullpath, lookup_flags, &vmp, &vp);
|
|
|
|
resolve.l_vmnt_lock = VMNT_READ;
|
|
|
|
resolve.l_vnode_lock = VNODE_READ;
|
|
|
|
/* Temporarily open the file */
|
|
|
|
if (fetch_name(vname, vname_length, fullpath) != OK) return(err_code);
|
|
|
|
if ((vp = eat_path(&resolve, fp)) == NULL) return(err_code);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
kind = FUTIMENS_STYLE;
|
|
|
|
/* Change timestamps on already-opened fd. Is it valid? */
|
|
|
|
if (job_m_in.utimens_flags != 0)
|
|
|
|
return EINVAL; /* unknown flag */
|
|
|
|
if ((filp = get_filp(job_m_in.utimens_fd, VNODE_READ)) == NULL)
|
|
|
|
return err_code;
|
|
|
|
vp = filp->filp_vno;
|
|
|
|
}
|
|
|
|
|
|
|
|
r = OK;
|
|
|
|
/* Only the owner of a file or the super user can change timestamps. */
|
|
|
|
if (vp->v_uid != fp->fp_effuid && fp->fp_effuid != SU_UID) r = EPERM;
|
|
|
|
/* Need write permission (or super user) to 'touch' the file */
|
|
|
|
if (r != OK && actim.tv_nsec == UTIME_NOW
|
|
|
|
&& modtim.tv_nsec == UTIME_NOW) r = forbidden(fp, vp, W_BIT);
|
|
|
|
if (read_only(vp) != OK) r = EROFS; /* Not even su can touch if R/O */
|
|
|
|
|
|
|
|
if (r == OK) {
|
|
|
|
/* Do we need to ask for current time? */
|
|
|
|
if (actim.tv_nsec == UTIME_NOW
|
|
|
|
|| actim.tv_nsec == UTIME_OMIT
|
|
|
|
|| modtim.tv_nsec == UTIME_NOW
|
|
|
|
|| modtim.tv_nsec == UTIME_OMIT) {
|
|
|
|
now = clock_timespec();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Build the request */
|
|
|
|
switch (actim.tv_nsec) {
|
|
|
|
case UTIME_NOW:
|
|
|
|
newactim = now;
|
|
|
|
break;
|
|
|
|
case UTIME_OMIT:
|
|
|
|
newactim.tv_nsec = UTIME_OMIT;
|
|
|
|
/* Be nice with old FS, put a sensible value in
|
|
|
|
* otherwise not used field for seconds
|
|
|
|
*/
|
|
|
|
newactim.tv_sec = now.tv_sec;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if ( (unsigned)actim.tv_nsec >= 1000000000)
|
|
|
|
r = EINVAL;
|
|
|
|
else
|
|
|
|
newactim = actim;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch (modtim.tv_nsec) {
|
|
|
|
case UTIME_NOW:
|
|
|
|
newmodtim = now;
|
|
|
|
break;
|
|
|
|
case UTIME_OMIT:
|
|
|
|
newmodtim.tv_nsec = UTIME_OMIT;
|
|
|
|
/* Be nice with old FS, put a sensible value */
|
|
|
|
newmodtim.tv_sec = now.tv_sec;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if ( (unsigned)modtim.tv_nsec >= 1000000000)
|
|
|
|
r = EINVAL;
|
|
|
|
else
|
|
|
|
newmodtim = modtim;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (r == OK)
|
|
|
|
/* Issue request */
|
|
|
|
r = req_utime(vp->v_fs_e, vp->v_inode_nr, &newactim, &newmodtim);
|
|
|
|
|
|
|
|
if (kind == UTIMENS_STYLE) {
|
|
|
|
/* Close the temporary */
|
|
|
|
unlock_vnode(vp);
|
|
|
|
unlock_vmnt(vmp);
|
|
|
|
put_vnode(vp);
|
|
|
|
}
|
|
|
|
else { /* Change timestamps on opened fd. */
|
|
|
|
unlock_filp(filp);
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|