if (r) return(EINVAL);
}
- update_times(pn, CTIME | MTIME, 0);
+ update_timens(pn, CTIME | MTIME, NULL);
return(r);
}
char string[NAME_MAX + 1];
phys_bytes len;
struct puffs_node *pn, *pn_dir, *new_pn;
- time_t cur_time;
+ struct timespec cur_time;
struct puffs_kcn pkcnp;
PUFFS_MAKECRED(pcr, &global_kcred);
struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
if (r != OK) return(EINVAL);
- cur_time = clock_time();
- update_times(pn, CTIME, cur_time);
- update_times(pn_dir, MTIME | CTIME, cur_time);
+ cur_time = clock_timespec();
+ update_timens(pn, CTIME, &cur_time);
+ update_timens(pn_dir, MTIME | CTIME, &cur_time);
return(OK);
}
int odir, ndir; /* TRUE iff {old|new} file is dir */
int same_pdir; /* TRUE iff parent dirs are the same */
phys_bytes len;
- time_t cur_time;
+ struct timespec cur_time;
if (global_pu->pu_ops.puffs_node_rename == NULL)
return(EINVAL);
}
rename_out:
- cur_time = clock_time();
- update_times(old_dirp, MTIME | CTIME, cur_time);
- update_times(new_dirp, MTIME | CTIME, cur_time);
+ cur_time = clock_timespec();
+ update_timens(old_dirp, MTIME | CTIME, &cur_time);
+ update_timens(new_dirp, MTIME | CTIME, &cur_time);
/* XXX see release_node comment in fs_unlink */
if (new_ip && new_ip->pn_count == 0) {
*/
int r;
struct puffs_node *pn, *pn_dir;
- time_t cur_time;
+ struct timespec cur_time;
struct puffs_kcn pkcnp;
struct puffs_cn pcn = {&pkcnp, 0, {0,0,0}};
PUFFS_KCREDTOCRED(pcn.pcn_cred, &global_kcred);
}
if (pn->pn_va.va_nlink != 0) {
- cur_time = clock_time();
- update_times(pn, CTIME, cur_time);
- update_times(pn_dir, MTIME | CTIME, cur_time);
+ cur_time = clock_timespec();
+ update_timens(pn, CTIME, &cur_time);
+ update_timens(pn_dir, MTIME | CTIME, &cur_time);
}
/* XXX Ideally, we should check pn->pn_flags & PUFFS_NODE_REMOVED, but
PUFFS_MAKECRED(pcr, &global_kcred);
struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
struct vattr va;
- time_t cur_time;
+ struct timespec cur_time;
int len;
if (global_pu->pu_ops.puffs_node_create == NULL) {
memset(&pni, 0, sizeof(pni));
pni.pni_cookie = (void** )&pn;
- cur_time = clock_time();
+ cur_time = clock_timespec();
memset(&va, 0, sizeof(va));
va.va_type = VREG;
va.va_mode = omode;
va.va_uid = caller_uid;
va.va_gid = caller_gid;
- va.va_atime.tv_sec = va.va_mtime.tv_sec = va.va_ctime.tv_sec = cur_time;
+ va.va_atime = va.va_mtime = va.va_ctime = cur_time;
if (buildpath) {
r = puffs_path_pcnbuild(global_pu, &pcn, pn_dir);
/* Open pnode */
pn->pn_count++;
- update_times(pn_dir, MTIME | CTIME, cur_time);
+ update_timens(pn_dir, MTIME | CTIME, &cur_time);
/* Reply message */
fs_m_out.RES_INODE_NR = pn->pn_va.va_fileid;
PUFFS_MAKECRED(pcr, &global_kcred);
struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
struct vattr va;
- time_t cur_time;
+ struct timespec cur_time;
int len;
if (global_pu->pu_ops.puffs_node_mknod == NULL) {
memset(&pni, 0, sizeof(pni));
pni.pni_cookie = (void** )&pn;
- cur_time = clock_time();
+ cur_time = clock_timespec();
memset(&va, 0, sizeof(va));
va.va_type = VDIR;
va.va_uid = caller_uid;
va.va_gid = caller_gid;
va.va_rdev = (dev_t) fs_m_in.REQ_DEV;
- va.va_atime.tv_sec = va.va_mtime.tv_sec = va.va_ctime.tv_sec = cur_time;
+ va.va_atime = va.va_mtime = va.va_ctime = cur_time;
if (buildpath) {
if (puffs_path_pcnbuild(global_pu, &pcn, pn_dir) != 0) {
return(r);
}
- update_times(pn_dir, MTIME | CTIME, cur_time);
+ update_timens(pn_dir, MTIME | CTIME, &cur_time);
return(OK);
}
PUFFS_MAKECRED(pcr, &global_kcred);
struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
struct vattr va;
- time_t cur_time;
+ struct timespec cur_time;
int len;
if (global_pu->pu_ops.puffs_node_mkdir == NULL) {
if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.REQ_INODE_NR)) == NULL)
return(ENOENT);
- cur_time = clock_time();
+ cur_time = clock_timespec();
memset(&pni, 0, sizeof(pni));
pni.pni_cookie = (void** )&pn;
va.va_mode = (mode_t) fs_m_in.REQ_MODE;
va.va_uid = caller_uid;
va.va_gid = caller_gid;
- va.va_atime.tv_sec = va.va_mtime.tv_sec = va.va_ctime.tv_sec = cur_time;
+ va.va_atime = va.va_mtime = va.va_ctime = cur_time;
if (buildpath) {
r = puffs_path_pcnbuild(global_pu, &pcn, pn_dir);
return(r);
}
- update_times(pn_dir, MTIME | CTIME, cur_time);
+ update_timens(pn_dir, MTIME | CTIME, &cur_time);
return(OK);
}
va.va_mode = (mode_t) (I_SYMBOLIC_LINK | RWX_MODES);
va.va_uid = caller_uid;
va.va_gid = caller_gid;
- va.va_atime.tv_sec = va.va_mtime.tv_sec = va.va_ctime.tv_sec = clock_time();
+ va.va_atime = va.va_mtime = va.va_ctime = clock_timespec();
if (buildpath) {
r = puffs_path_pcnbuild(global_pu, &pcn, pn_dir);
puffs_vattr_null(&va);
/* Clear setgid bit if file is not in caller's grp */
va.va_mode = (pn->pn_va.va_mode & ~ALL_MODES) | (mode & ALL_MODES);
- va.va_ctime.tv_nsec = 0;
- va.va_ctime.tv_sec = clock_time();
+ va.va_ctime = clock_timespec();
if (global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr) != 0)
return(EINVAL);
va.va_uid = fs_m_in.REQ_UID;
va.va_gid = fs_m_in.REQ_GID;
va.va_mode = pn->pn_va.va_mode & ~(I_SET_UID_BIT | I_SET_GID_BIT);
- va.va_ctime.tv_nsec = 0;
- va.va_ctime.tv_sec = clock_time();
+ va.va_ctime = clock_timespec();
if (global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr) != 0)
return(EINVAL);
struct puffs_usermount;
struct puffs_node;
+struct timespec;
/* Function prototypes. */
int no_sys(void);
void mfs_nul_f(const char *file, int line, char *str, unsigned int len,
unsigned int maxlen);
-time_t clock_time(void);
-int update_times(struct puffs_node *pn, int fl, time_t t);
+struct timespec clock_timespec(void);
+int update_timens(struct puffs_node *pn, int fl, struct timespec *);
void lpuffs_debug(const char *format, ...);
#endif /* PUFFS_PROTO_H */
if (bytes_done) {
r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) 0,
(vir_bytes) rw_buf, bytes_done);
- update_times(pn, ATIME, 0);
+ update_timens(pn, ATIME, NULL);
}
} else if (rw_flag == WRITING) {
/* At first try to change vattr */
puffs_vattr_null(&va);
if ( (pos + bytes_left) > pn->pn_va.va_size)
va.va_size = bytes_left + pos;
- va.va_ctime.tv_sec = va.va_mtime.tv_sec = clock_time();
- va.va_atime.tv_sec = pn->pn_va.va_atime.tv_sec;
+ va.va_ctime = va.va_mtime = clock_timespec();
+ va.va_atime = pn->pn_va.va_atime;
r = global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr);
if (r) return(EINVAL);
if (r != OK) return(r);
}
- update_times(pn, ATIME, 0);
+ update_timens(pn, ATIME, NULL);
fs_m_out.RES_NBYTES = written;
fs_m_out.RES_SEEK_POS_LO = pos;
statbuf.st_gid = va.va_gid;
statbuf.st_rdev = (s ? va.va_rdev : NO_DEV);
statbuf.st_size = va.va_size;
- statbuf.st_atime = va.va_atime.tv_sec;
- statbuf.st_mtime = va.va_mtime.tv_sec;
- statbuf.st_ctime = va.va_ctime.tv_sec;
+ statbuf.st_atimespec = va.va_atime;
+ statbuf.st_mtimespec = va.va_mtime;
+ statbuf.st_ctimespec = va.va_ctime;
+
+ statbuf.st_birthtimespec = va.va_birthtime;
+ statbuf.st_blksize = va.va_blocksize;
+ statbuf.st_blocks = va.va_bytes / va.va_blocksize;
+ statbuf.st_flags = va.va_flags;
+ statbuf.st_gen = va.va_gen;
/* Copy the struct to user space. */
r = sys_safecopyto(fs_m_in.m_source, (cp_grant_id_t) fs_m_in.REQ_GRANT,
va->va_fsid = sb->st_dev;
va->va_fileid = sb->st_ino;
va->va_size = sb->st_size;
- va->va_atime.tv_nsec = va->va_mtime.tv_nsec = va->va_ctime.tv_nsec = 0;
- va->va_atime.tv_sec = sb->st_atime;
- va->va_ctime.tv_sec = sb->st_ctime;
- va->va_mtime.tv_sec = sb->st_mtime;
+ va->va_atime = sb->st_atimespec;
+ va->va_ctime = sb->st_ctimespec;
+ va->va_mtime = sb->st_mtimespec;
va->va_blocksize = sb->st_blksize;
va->va_birthtime = sb->st_birthtimespec;
va->va_gen = sb->st_gen;
return(EINVAL);
puffs_vattr_null(&va);
- va.va_atime.tv_nsec = va.va_mtime.tv_nsec = va.va_ctime.tv_nsec = 0;
+ va.va_atime.tv_nsec = va.va_mtime.tv_nsec = 0;
va.va_atime.tv_sec = fs_m_in.REQ_ACTIME;
va.va_mtime.tv_sec = fs_m_in.REQ_MODTIME;
- va.va_ctime.tv_sec = clock_time();
+ va.va_ctime = clock_timespec();
if (global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr) != 0)
return(EINVAL);
#include "fs.h"
+#include <assert.h>
#include <stdarg.h>
#include "puffs.h"
/*===========================================================================*
- * clock_time *
+ * clock_timespec *
*===========================================================================*/
-time_t clock_time()
+struct timespec clock_timespec()
{
/* This routine returns the time in seconds since 1.1.1970. MINIX is an
* astrophysically naive system that assumes the earth rotates at a constant
* rate and that such things as leap seconds do not exist.
*/
+ static long system_hz = 0;
register int k;
+ struct timespec tv;
clock_t uptime;
clock_t realtime;
time_t boottime;
+ if (system_hz == 0) system_hz = sys_hz();
if ((k=getuptime(&uptime, &realtime, &boottime)) != OK)
- panic("clock_time: getuptme2 failed: %d", k);
+ panic("clock_timespec: getuptime failed: %d", k);
- return( (time_t) (boottime + (realtime/sys_hz())));
+ tv.tv_sec = (time_t) (boottime + (realtime/system_hz));
+ /* We do not want to overflow, and system_hz can be as high as 50kHz */
+ assert(system_hz < LONG_MAX/40000);
+ tv.tv_nsec = (realtime%system_hz) * 40000 / system_hz * 25000;
+ return tv;
}
/*===========================================================================*
- * update_times *
+ * update_timens *
*===========================================================================*/
-int update_times(struct puffs_node *pn, int flags, time_t t)
+int update_timens(struct puffs_node *pn, int flags, struct timespec *t)
{
int r;
struct vattr va;
- time_t new_time;
+ struct timespec new_time;
PUFFS_MAKECRED(pcr, &global_kcred);
if (!flags)
if (global_pu->pu_ops.puffs_node_setattr == NULL)
return EINVAL;
- new_time = t != 0 ? t : clock_time();
+ new_time = t != NULL ? *t : clock_timespec();
puffs_vattr_null(&va);
/* librefuse modifies atime and mtime together,
* so set old values to avoid setting either one
* to PUFFS_VNOVAL (set by puffs_vattr_null).
*/
- va.va_atime.tv_sec = pn->pn_va.va_atime.tv_sec;
- va.va_mtime.tv_sec = pn->pn_va.va_mtime.tv_sec;
-
- if (flags & ATIME) {
- va.va_atime.tv_sec = new_time;
- va.va_atime.tv_nsec = 0;
- }
- if (flags & MTIME) {
- va.va_mtime.tv_sec = new_time;
- va.va_mtime.tv_nsec = 0;
- }
- if (flags & CTIME) {
- va.va_ctime.tv_sec = new_time;
- va.va_ctime.tv_nsec = 0;
- }
+ va.va_atime = pn->pn_va.va_atime;
+ va.va_mtime = pn->pn_va.va_mtime;
+
+ if (flags & ATIME)
+ va.va_atime = new_time;
+ if (flags & MTIME)
+ va.va_mtime = new_time;
+ if (flags & CTIME)
+ va.va_ctime = new_time;
r = global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr);