From: Antoine Leca Date: Sun, 7 Apr 2013 08:42:26 +0000 (+0200) Subject: Libpuffs: use struct timespec instead of time_t X-Git-Tag: v3.3.0~1042 X-Git-Url: http://zhaoyanbai.com/repos/man.host.html?a=commitdiff_plain;h=df9d28ebe7ab955e1e8e8b6d3cb97846f755bb41;p=minix.git Libpuffs: use struct timespec instead of time_t --- diff --git a/lib/libpuffs/link.c b/lib/libpuffs/link.c index e797f2102..039e820b1 100644 --- a/lib/libpuffs/link.c +++ b/lib/libpuffs/link.c @@ -59,7 +59,7 @@ int fs_ftrunc(void) if (r) return(EINVAL); } - update_times(pn, CTIME | MTIME, 0); + update_timens(pn, CTIME | MTIME, NULL); return(r); } @@ -76,7 +76,7 @@ int fs_link() 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}}; @@ -141,9 +141,9 @@ int fs_link() 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); } @@ -208,7 +208,7 @@ int fs_rename() 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); @@ -373,9 +373,9 @@ int fs_rename() } 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) { @@ -401,7 +401,7 @@ int fs_unlink() */ 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); @@ -447,9 +447,9 @@ int fs_unlink() } 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 diff --git a/lib/libpuffs/open.c b/lib/libpuffs/open.c index d520ac973..0a858ce1b 100644 --- a/lib/libpuffs/open.c +++ b/lib/libpuffs/open.c @@ -27,7 +27,7 @@ int fs_create() 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) { @@ -59,14 +59,14 @@ int fs_create() 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); @@ -96,7 +96,7 @@ int fs_create() /* 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; @@ -124,7 +124,7 @@ int fs_mknod() 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) { @@ -154,7 +154,7 @@ int fs_mknod() 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; @@ -162,7 +162,7 @@ int fs_mknod() 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) { @@ -188,7 +188,7 @@ int fs_mknod() return(r); } - update_times(pn_dir, MTIME | CTIME, cur_time); + update_timens(pn_dir, MTIME | CTIME, &cur_time); return(OK); } @@ -207,7 +207,7 @@ int fs_mkdir() 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) { @@ -234,7 +234,7 @@ int fs_mkdir() 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; @@ -244,7 +244,7 @@ int fs_mkdir() 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); @@ -271,7 +271,7 @@ int fs_mkdir() return(r); } - update_times(pn_dir, MTIME | CTIME, cur_time); + update_timens(pn_dir, MTIME | CTIME, &cur_time); return(OK); } @@ -341,7 +341,7 @@ int fs_slink() 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); diff --git a/lib/libpuffs/protect.c b/lib/libpuffs/protect.c index f4abe5b11..0c46dc74d 100644 --- a/lib/libpuffs/protect.c +++ b/lib/libpuffs/protect.c @@ -33,8 +33,7 @@ int fs_chmod() 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); @@ -64,8 +63,7 @@ int fs_chown() 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); diff --git a/lib/libpuffs/proto.h b/lib/libpuffs/proto.h index 41da711be..c3758a7b7 100644 --- a/lib/libpuffs/proto.h +++ b/lib/libpuffs/proto.h @@ -3,6 +3,7 @@ struct puffs_usermount; struct puffs_node; +struct timespec; /* Function prototypes. */ @@ -67,8 +68,8 @@ int fs_utime(void); 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 */ diff --git a/lib/libpuffs/read.c b/lib/libpuffs/read.c index 10d83f5f0..641a41972 100644 --- a/lib/libpuffs/read.c +++ b/lib/libpuffs/read.c @@ -68,7 +68,7 @@ int fs_readwrite(void) 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 */ @@ -78,8 +78,8 @@ int fs_readwrite(void) 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); @@ -169,7 +169,7 @@ int fs_getdents(void) 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; diff --git a/lib/libpuffs/stadir.c b/lib/libpuffs/stadir.c index ddf9acf9b..a22faa773 100644 --- a/lib/libpuffs/stadir.c +++ b/lib/libpuffs/stadir.c @@ -81,9 +81,15 @@ int fs_stat() 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, diff --git a/lib/libpuffs/subr.c b/lib/libpuffs/subr.c index c48b2fe0f..3ccd7be33 100644 --- a/lib/libpuffs/subr.c +++ b/lib/libpuffs/subr.c @@ -292,10 +292,9 @@ puffs_stat2vattr(struct vattr *va, const struct stat *sb) 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; diff --git a/lib/libpuffs/time.c b/lib/libpuffs/time.c index df986277f..a5a26727f 100644 --- a/lib/libpuffs/time.c +++ b/lib/libpuffs/time.c @@ -30,10 +30,10 @@ int fs_utime() 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); diff --git a/lib/libpuffs/utility.c b/lib/libpuffs/utility.c index 401df9c2e..03667561a 100644 --- a/lib/libpuffs/utility.c +++ b/lib/libpuffs/utility.c @@ -4,6 +4,7 @@ #include "fs.h" +#include #include #include "puffs.h" @@ -35,35 +36,42 @@ void mfs_nul_f(const char *file, int line, char *str, unsigned int len, /*===========================================================================* - * 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) @@ -72,28 +80,22 @@ int update_times(struct puffs_node *pn, int flags, time_t t) 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);