From: Flávio Cruz <flavioc...@gmail.com> Hello
These two patches allow the glibc and the hurd servers to handle UTIME_OMIT and UTIME_NOW in futimens. The file_utimes RPC now uses a struct timespec instead of a timeval. --- console-client/trans.c | 8 ++------ console/console.c | 8 ++------ ext2fs/pager.c | 3 +++ ftpfs/netfs.c | 8 ++------ hostmux/node.c | 8 ++------ hurd/fs.defs | 4 ++-- libdiskfs/file-utimes.c | 20 +++++++++++-------- libnetfs/file-utimes.c | 40 +++++++++++++++++++------------------ libnetfs/init-init.c | 6 ++++++ libnetfs/netfs.h | 2 +- libnetfs/priv.h | 2 ++ libtreefs/s-file.c | 2 +- libtreefs/treefs-s-hooks.h | 2 +- libtrivfs/file-utimes.c | 2 +- libtrivfs/times.c | 24 +++++++++++----------- nfs/nfs.c | 50 ++++++++++++++++++++++++++++++++++++---------- nfs/ops.c | 14 ++++--------- nfsd/ops.c | 46 +++++++++++++++++++++--------------------- trans/fakeroot.c | 29 +++++++++++++-------------- usermux/node.c | 8 ++------ 20 files changed, 153 insertions(+), 133 deletions(-) diff --git a/console-client/trans.c b/console-client/trans.c index 224229e..4c78e46 100644 --- a/console-client/trans.c +++ b/console-client/trans.c @@ -186,14 +186,10 @@ netfs_attempt_utimes (struct iouser *cred, struct node *np, if (! err) { if (mtime) - np->nn_stat.st_mtim = *mtime; - else - flags |= TOUCH_MTIME; + np->nn_stat.st_mtim = *mtime; if (atime) - np->nn_stat.st_atim = *atime; - else - flags |= TOUCH_ATIME; + np->nn_stat.st_atim = *atime; fshelp_touch (&np->nn_stat, flags, console_maptime); } diff --git a/console/console.c b/console/console.c index 57ae813..1be1112 100644 --- a/console/console.c +++ b/console/console.c @@ -506,14 +506,10 @@ netfs_attempt_utimes (struct iouser *cred, struct node *node, if (! err) { if (mtime) - node->nn_stat.st_mtim = *mtime; - else - flags |= TOUCH_MTIME; + node->nn_stat.st_mtim = *mtime; if (atime) - node->nn_stat.st_atim = *atime; - else - flags |= TOUCH_ATIME; + node->nn_stat.st_atim = *atime; fshelp_touch (&node->nn_stat, flags, console_maptime); } diff --git a/ext2fs/pager.c b/ext2fs/pager.c index b56c923..4f56743 100644 --- a/ext2fs/pager.c +++ b/ext2fs/pager.c @@ -1220,6 +1220,9 @@ create_disk_pager (void) err = pager_start_workers (file_pager_bucket); if (err) ext2_panic ("can't create libpager worker threads: %s", strerror (err)); +#ifdef STAT + +#endif } /* Call this to create a FILE_DATA pager and return a send right. diff --git a/ftpfs/netfs.c b/ftpfs/netfs.c index cf5d907..b0c80db 100644 --- a/ftpfs/netfs.c +++ b/ftpfs/netfs.c @@ -77,14 +77,10 @@ netfs_attempt_utimes (struct iouser *cred, struct node *node, if (! err) { if (atime) - node->nn_stat.st_atim = *atime; - else - flags |= TOUCH_ATIME; + node->nn_stat.st_atim = *atime; if (mtime) - node->nn_stat.st_mtim = *mtime; - else - flags |= TOUCH_MTIME; + node->nn_stat.st_mtim = *mtime; fshelp_touch (&node->nn_stat, flags, ftpfs_maptime); } diff --git a/hostmux/node.c b/hostmux/node.c index 7167300..0724d35 100644 --- a/hostmux/node.c +++ b/hostmux/node.c @@ -79,14 +79,10 @@ netfs_attempt_utimes (struct iouser *cred, struct node *node, if (! err) { if (mtime) - node->nn_stat.st_mtim = *mtime; - else - flags |= TOUCH_MTIME; + node->nn_stat.st_mtim = *mtime; if (atime) - node->nn_stat.st_atim = *atime; - else - flags |= TOUCH_ATIME; + node->nn_stat.st_atim = *atime; fshelp_touch (&node->nn_stat, flags, hostmux_maptime); } diff --git a/hurd/fs.defs b/hurd/fs.defs index a4a48cc..1514a84 100644 --- a/hurd/fs.defs +++ b/hurd/fs.defs @@ -99,8 +99,8 @@ routine file_chflags ( routine file_utimes ( utimes_file: file_t; RPT - new_atime: time_value_t; - new_mtime: time_value_t); + new_atime: timespec_t; + new_mtime: timespec_t); /* Change the size of the file. If the size increases, new blocks are zero-filled. After successful return, it is safe to reference mapped diff --git a/libdiskfs/file-utimes.c b/libdiskfs/file-utimes.c index 39fac50..d525e81 100644 --- a/libdiskfs/file-utimes.c +++ b/libdiskfs/file-utimes.c @@ -21,28 +21,32 @@ /* Implement file_utimes as described in <hurd/fs.defs>. */ kern_return_t diskfs_S_file_utimes (struct protid *cred, - time_value_t atime, - time_value_t mtime) + struct timespec atime, + struct timespec mtime) { CHANGE_NODE_FIELD (cred, ({ if (!(err = fshelp_isowner (&np->dn_stat, cred->user))) { - if (atime.microseconds == -1) + if (atime.tv_nsec == UTIME_NOW) np->dn_set_atime = 1; + else if(atime.tv_nsec == UTIME_OMIT) + np->dn_set_atime = 0; else { - np->dn_stat.st_atim.tv_sec = atime.seconds; - np->dn_stat.st_atim.tv_nsec = atime.microseconds * 1000; + np->dn_stat.st_atim.tv_sec = atime.tv_sec; + np->dn_stat.st_atim.tv_nsec = atime.tv_nsec; np->dn_set_atime = 0; } - if (mtime.microseconds == -1) + if (mtime.tv_nsec == UTIME_NOW) np->dn_set_mtime = 1; + else if(mtime.tv_nsec == UTIME_OMIT) + np->dn_set_mtime = 0; else { - np->dn_stat.st_mtim.tv_sec = mtime.seconds; - np->dn_stat.st_mtim.tv_nsec = mtime.microseconds * 1000; + np->dn_stat.st_mtim.tv_sec = mtime.tv_sec; + np->dn_stat.st_mtim.tv_nsec = mtime.tv_nsec; np->dn_set_mtime = 0; } diff --git a/libnetfs/file-utimes.c b/libnetfs/file-utimes.c index 1915609..2c49cfa 100644 --- a/libnetfs/file-utimes.c +++ b/libnetfs/file-utimes.c @@ -23,31 +23,33 @@ error_t netfs_S_file_utimes (struct protid *user, - time_value_t atimein, - time_value_t mtimein) + struct timespec atimein, + struct timespec mtimein) { - struct timespec atime, mtime; error_t err; + struct timeval t; - if (atimein.microseconds != -1) - { - atime.tv_sec = atimein.seconds; - atime.tv_nsec = atimein.microseconds * 1000; - } - - if (mtimein.microseconds != -1) - { - mtime.tv_sec = mtimein.seconds; - mtime.tv_nsec = mtimein.microseconds * 1000; - } - if (!user) return EOPNOTSUPP; - + + if (atimein.tv_nsec == UTIME_NOW || mtimein.tv_nsec == UTIME_NOW) + maptime_read (netfs_mtime, &t); + + if (atimein.tv_nsec == UTIME_NOW) + { + atimein.tv_sec = t.tv_sec; + atimein.tv_nsec = t.tv_usec * 1000; + } + if (mtimein.tv_nsec == UTIME_NOW) + { + mtimein.tv_nsec = t.tv_sec; + mtimein.tv_nsec = t.tv_usec * 1000; + } + pthread_mutex_lock (&user->po->np->lock); - err = netfs_attempt_utimes (user->user, user->po->np, - atimein.microseconds != -1 ? &atime : 0, - mtimein.microseconds != -1 ? &mtime : 0); + err = netfs_attempt_utimes (user->user, user->po->np, + (atimein.tv_nsec == UTIME_OMIT) ? 0 : &atimein, + (mtimein.tv_nsec == UTIME_OMIT) ? 0 : &mtimein); pthread_mutex_unlock (&user->po->np->lock); return err; } diff --git a/libnetfs/init-init.c b/libnetfs/init-init.c index a088ad5..4b749f5 100644 --- a/libnetfs/init-init.c +++ b/libnetfs/init-init.c @@ -32,11 +32,17 @@ struct port_class *netfs_protid_class = 0; struct port_class *netfs_control_class = 0; auth_t netfs_auth_server_port = 0; mach_port_t netfs_fsys_identity; +volatile struct mapped_time_value *netfs_mtime; void netfs_init () { + error_t err; + err = maptime_map (0, 0, &netfs_mtime); + if (err) + error (2, err, "mapping time"); + netfs_protid_class = ports_create_class (netfs_release_protid, 0); netfs_control_class = ports_create_class (0, 0); netfs_port_bucket = ports_create_bucket (); diff --git a/libnetfs/netfs.h b/libnetfs/netfs.h index fbe2c60..3774070 100644 --- a/libnetfs/netfs.h +++ b/libnetfs/netfs.h @@ -173,7 +173,7 @@ error_t netfs_attempt_chflags (struct iouser *cred, struct node *np, /* The user must define this function. This should attempt a utimes call for the user specified by CRED on locked node NP, to change the atime to ATIME and the mtime to MTIME. If ATIME or MTIME is - null, then set to the current time. */ + null, then do not change it. */ error_t netfs_attempt_utimes (struct iouser *cred, struct node *np, struct timespec *atime, struct timespec *mtime); diff --git a/libnetfs/priv.h b/libnetfs/priv.h index 3c5bcd4..3871da8 100644 --- a/libnetfs/priv.h +++ b/libnetfs/priv.h @@ -25,6 +25,8 @@ #include "netfs.h" +volatile struct mapped_time_value *netfs_mtime; + static inline struct protid * __attribute__ ((unused)) begin_using_protid_port (file_t port) { diff --git a/libtreefs/s-file.c b/libtreefs/s-file.c index c24d645..120258f 100644 --- a/libtreefs/s-file.c +++ b/libtreefs/s-file.c @@ -227,7 +227,7 @@ treefs_S_file_set_size (struct treefs_protid *cred, off_t size) error_t treefs_S_file_utimes (struct treefs_protid *cred, - time_value_t atime, time_value_t mtime) + struct timespec atime, struct timespec mtime) { if (!cred) return EOPNOTSUPP; diff --git a/libtreefs/treefs-s-hooks.h b/libtreefs/treefs-s-hooks.h index 2ea9e7a..d637459 100644 --- a/libtreefs/treefs-s-hooks.h +++ b/libtreefs/treefs-s-hooks.h @@ -53,7 +53,7 @@ DHH(s_file_chmod, error_t, mode_t) DHH(s_file_chflags, error_t, int) #define treefs_s_file_chflags(h, args...) \ _TREEFS_CHH(h, S_FILE_CHFLAGS, s_file_chflags , ##args) -DHH(s_file_utimes, error_t, time_value_t, time_value_t) +DHH(s_file_utimes, error_t, struct timespec, struct timespec) #define treefs_s_file_utimes(h, args...) \ _TREEFS_CHH(h, S_FILE_UTIMES, s_file_utimes , ##args) DHH(s_file_truncate, error_t, off_t) diff --git a/libtrivfs/file-utimes.c b/libtrivfs/file-utimes.c index 827c055..92b906d 100644 --- a/libtrivfs/file-utimes.c +++ b/libtrivfs/file-utimes.c @@ -21,7 +21,7 @@ kern_return_t trivfs_S_file_utimes (struct trivfs_protid *cred, mach_port_t reply, mach_msg_type_name_t reply_type, - time_value_t atime, time_value_t mtime) + struct timespec atime, struct timespec mtime) { return cred ? file_utimes (cred->realnode, atime, mtime) : EOPNOTSUPP; } diff --git a/libtrivfs/times.c b/libtrivfs/times.c index 5f08cb1..3bc07c3 100644 --- a/libtrivfs/times.c +++ b/libtrivfs/times.c @@ -21,13 +21,13 @@ error_t trivfs_set_atime (struct trivfs_control *cntl) { struct stat st; - time_value_t atime; - time_value_t mtime; + struct timespec mtime; + struct timespec atime; - io_stat (cntl->underlying, &st); - mtime.seconds = st.st_mtim.tv_sec; - mtime.microseconds = st.st_mtim.tv_nsec / 1000; - atime.microseconds = -1; + mtime.tv_sec =0; + mtime.tv_nsec = UTIME_OMIT; + atime.tv_sec = 0; + atime.tv_nsec = UTIME_NOW; file_utimes (cntl->underlying, atime, mtime); return 0; } @@ -36,13 +36,13 @@ error_t trivfs_set_mtime (struct trivfs_control *cntl) { struct stat st; - time_value_t atime; - time_value_t mtime; + struct timespec atime; + struct timespec mtime; - io_stat (cntl->underlying, &st); - atime.seconds = st.st_atim.tv_sec; - atime.microseconds = st.st_atim.tv_nsec / 1000; - mtime.microseconds = -1; + atime.tv_sec = 0; + atime.tv_nsec = UTIME_OMIT; + mtime.tv_sec = 0; + mtime.tv_nsec = UTIME_NOW; file_utimes (cntl->underlying, atime, mtime); return 0; } diff --git a/nfs/nfs.c b/nfs/nfs.c index 4916df6..e743d40 100644 --- a/nfs/nfs.c +++ b/nfs/nfs.c @@ -273,10 +273,26 @@ xdr_encode_sattr_times (int *p, struct timespec *atime, struct timespec *mtime) *(p++) = -1; /* uid */ *(p++) = -1; /* gid */ *(p++) = -1; /* size */ - *(p++) = htonl (atime->tv_sec); - *(p++) = htonl (atime->tv_nsec / 1000); - *(p++) = htonl (mtime->tv_sec); - *(p++) = htonl (mtime->tv_nsec / 1000); + if (atime) + { + *(p++) = htonl (atime->tv_sec); + *(p++) = htonl (atime->tv_nsec / 1000); + } + else + { + *(p++) = -1; /* no atime */ + *(p++) = -1; + } + if (mtime) + { + *(p++) = htonl (mtime->tv_sec); + *(p++) = htonl (mtime->tv_nsec / 1000); + } + else + { + *(p++) = -1; /* no mtime */ + *(p++) = -1; + } } else { @@ -284,12 +300,26 @@ xdr_encode_sattr_times (int *p, struct timespec *atime, struct timespec *mtime) *(p++) = 0; /* no uid */ *(p++) = 0; /* no gid */ *(p++) = 0; /* no size */ - *(p++) = htonl (SET_TO_CLIENT_TIME); /* atime */ - *(p++) = htonl (atime->tv_sec); - *(p++) = htonl (atime->tv_nsec); - *(p++) = htonl (SET_TO_CLIENT_TIME); /* mtime */ - *(p++) = htonl (mtime->tv_sec); - *(p++) = htonl (mtime->tv_nsec); + if (atime) + { + *(p++) = htonl (SET_TO_CLIENT_TIME); /* atime */ + *(p++) = htonl (atime->tv_sec); + *(p++) = htonl (atime->tv_nsec); + } + else + { + *(p++) = DONT_CHANGE; /* no atime */ + } + if (mtime) + { + *(p++) = htonl (SET_TO_CLIENT_TIME); /* mtime */ + *(p++) = htonl (mtime->tv_sec); + *(p++) = htonl (mtime->tv_nsec); + } + else + { + *(p++) = DONT_CHANGE; /* no mtime */ + } } return p; } diff --git a/nfs/ops.c b/nfs/ops.c index a4d6ac7..faae658 100644 --- a/nfs/ops.c +++ b/nfs/ops.c @@ -298,17 +298,13 @@ netfs_attempt_utimes (struct iouser *cred, struct node *np, int *p; void *rpcbuf; error_t err; - struct timeval tv; struct timespec current; + if (!atime && !mtime) + return 0; /* nothing to update */ + /* XXX For version 3 we can actually do this right, but we don't just yet. */ - if (!atime || !mtime) - { - maptime_read (mapped_time, &tv); - current.tv_sec = tv.tv_sec; - current.tv_nsec = tv.tv_usec * 1000; - } p = nfs_initialize_rpc (NFSPROC_SETATTR (protocol_version), cred, 0, &rpcbuf, np, -1); @@ -316,9 +312,7 @@ netfs_attempt_utimes (struct iouser *cred, struct node *np, return errno; p = xdr_encode_fhandle (p, &np->nn->handle); - p = xdr_encode_sattr_times (p, - atime ?: ¤t, - mtime ?: ¤t); + p = xdr_encode_sattr_times (p, atime, mtime); if (protocol_version == 3) *(p++) = 0; /* guard check == 0 */ diff --git a/nfsd/ops.c b/nfsd/ops.c index 6e2cbb1..a83859e 100644 --- a/nfsd/ops.c +++ b/nfsd/ops.c @@ -63,7 +63,7 @@ complete_setattr (mach_port_t port, { uid_t uid, gid; off_t size; - time_value_t atime, mtime; + struct timespec atime, mtime; struct stat st; error_t err; @@ -91,33 +91,33 @@ complete_setattr (mach_port_t port, if (err) return err; - atime.seconds = ntohl (*p); + atime.tv_sec = ntohl (*p); p++; - atime.microseconds = ntohl (*p); + atime.tv_nsec = ntohl (*p) * 1000; p++; - mtime.seconds = ntohl (*p); + mtime.tv_sec = ntohl (*p); p++; - mtime.microseconds = ntohl (*p); + mtime.tv_nsec = ntohl (*p) * 1000; p++; - if (atime.seconds != -1 && atime.microseconds == -1) - atime.microseconds = 0; - if (mtime.seconds != -1 && mtime.microseconds == -1) - mtime.microseconds = 0; - - if (atime.seconds == -1) - atime.seconds = st.st_atim.tv_sec; - if (atime.microseconds == -1) - atime.microseconds = st.st_atim.tv_nsec / 1000; - if (mtime.seconds == -1) - mtime.seconds = st.st_mtim.tv_sec; - if (mtime.microseconds == -1) - mtime.microseconds = st.st_mtim.tv_nsec / 1000; - - if (atime.seconds != st.st_atim.tv_sec - || atime.microseconds != st.st_atim.tv_nsec / 1000 - || mtime.seconds != st.st_mtim.tv_sec - || mtime.microseconds != st.st_mtim.tv_nsec / 1000) + if (atime.tv_sec != -1 && atime.tv_nsec == -1) + atime.tv_nsec = 0; + if (mtime.tv_sec != -1 && mtime.tv_nsec == -1) + mtime.tv_nsec = 0; + + if (atime.tv_nsec == -1) + atime.tv_sec = st.st_atim.tv_sec; + if (atime.tv_nsec == -1) + atime.tv_nsec = st.st_atim.tv_nsec; + if (mtime.tv_sec == -1) + mtime.tv_sec = st.st_mtim.tv_sec; + if (mtime.tv_nsec == -1) + mtime.tv_nsec = st.st_mtim.tv_nsec; + + if (atime.tv_sec != st.st_atim.tv_sec + || atime.tv_nsec != st.st_atim.tv_nsec + || mtime.tv_sec != st.st_mtim.tv_sec + || mtime.tv_nsec != st.st_mtim.tv_nsec) err = file_utimes (port, atime, mtime); return err; diff --git a/trans/fakeroot.c b/trans/fakeroot.c index 76fc901..8cd7119 100644 --- a/trans/fakeroot.c +++ b/trans/fakeroot.c @@ -618,26 +618,25 @@ error_t netfs_attempt_utimes (struct iouser *cred, struct node *np, struct timespec *atime, struct timespec *mtime) { - union tv - { - struct timeval tv; - time_value_t tvt; - }; - union tv a, m; + struct timespec tatime, tmtime; + if (atime) - { - TIMESPEC_TO_TIMEVAL (&a.tv, atime); - } + tatime = *atime; else - a.tv.tv_sec = a.tv.tv_usec = -1; + { + tatime.tv_sec = 0; + tatime.tv_nsec = UTIME_OMIT; + } + if (mtime) - { - TIMESPEC_TO_TIMEVAL (&m.tv, mtime); - } + tmtime = *mtime; else - m.tv.tv_sec = m.tv.tv_usec = -1; + { + tmtime.tv_sec = 0; + tmtime.tv_nsec = UTIME_OMIT; + } - return file_utimes (netfs_node_netnode (np)->file, a.tvt, m.tvt); + return file_utimes (netfs_node_netnode (np)->file, tatime, tmtime); } error_t diff --git a/usermux/node.c b/usermux/node.c index 2341714..66bf79b 100644 --- a/usermux/node.c +++ b/usermux/node.c @@ -81,14 +81,10 @@ netfs_attempt_utimes (struct iouser *cred, struct node *node, if (! err) { if (mtime) - node->nn_stat.st_mtim = *mtime; - else - flags |= TOUCH_MTIME; + node->nn_stat.st_mtim = *mtime; if (atime) - node->nn_stat.st_atim = *atime; - else - flags |= TOUCH_ATIME; + node->nn_stat.st_atim = *atime; fshelp_touch (&node->nn_stat, flags, usermux_maptime); } -- 2.5.0