diff --git a/libfuse/include/fuse_kernel.h b/libfuse/include/fuse_kernel.h index 2ac59861..373cada8 100644 --- a/libfuse/include/fuse_kernel.h +++ b/libfuse/include/fuse_kernel.h @@ -38,12 +38,50 @@ * * Protocol changelog: * + * 7.1: + * - add the following messages: + * FUSE_SETATTR, FUSE_SYMLINK, FUSE_MKNOD, FUSE_MKDIR, FUSE_UNLINK, + * FUSE_RMDIR, FUSE_RENAME, FUSE_LINK, FUSE_OPEN, FUSE_READ, FUSE_WRITE, + * FUSE_RELEASE, FUSE_FSYNC, FUSE_FLUSH, FUSE_SETXATTR, FUSE_GETXATTR, + * FUSE_LISTXATTR, FUSE_REMOVEXATTR, FUSE_OPENDIR, FUSE_READDIR, + * FUSE_RELEASEDIR + * - add padding to messages to accommodate 32-bit servers on 64-bit kernels + * + * 7.2: + * - add FOPEN_DIRECT_IO and FOPEN_KEEP_CACHE flags + * - add FUSE_FSYNCDIR message + * + * 7.3: + * - add FUSE_ACCESS message + * - add FUSE_CREATE message + * - add filehandle to fuse_setattr_in + * + * 7.4: + * - add frsize to fuse_kstatfs + * - clean up request size limit checking + * + * 7.5: + * - add flags and max_write to fuse_init_out + * + * 7.6: + * - add max_readahead to fuse_init_in and fuse_init_out + * + * 7.7: + * - add FUSE_INTERRUPT message + * - add POSIX file lock support + * + * 7.8: + * - add lock_owner and flags fields to fuse_release_in + * - add FUSE_BMAP message + * - add FUSE_DESTROY message + * * 7.9: * - new fuse_getattr_in input argument of GETATTR * - add lk_flags in fuse_lk_in * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in * - add blksize field to fuse_attr * - add file flags field to fuse_read_in and fuse_write_in + * - Add ATIME_NOW and MTIME_NOW flags to fuse_setattr_in * * 7.10 * - add nonseekable open flag @@ -54,7 +92,7 @@ * - add POLL message and NOTIFY_POLL notification * * 7.12 - * - add umask flag to input argument of open, mknod and mkdir + * - add umask flag to input argument of create, mknod and mkdir * - add notification messages for invalidation of inodes and * directory entries * @@ -125,6 +163,15 @@ * * 7.29 * - add FUSE_NO_OPENDIR_SUPPORT flag + * + * 7.30 + * - add FUSE_EXPLICIT_INVAL_DATA + * - add FUSE_IOCTL_COMPAT_X32 + * + * 7.31 + * - add FUSE_WRITE_KILL_PRIV flag + * - add FUSE_SETUPMAPPING and FUSE_REMOVEMAPPING + * - add map_alignment to fuse_init_out, add FUSE_MAP_ALIGNMENT flag */ #ifndef _LINUX_FUSE_H @@ -160,7 +207,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 29 +#define FUSE_KERNEL_MINOR_VERSION 31 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -229,11 +276,13 @@ struct fuse_file_lock { * FOPEN_KEEP_CACHE: don't invalidate the data cache on open * FOPEN_NONSEEKABLE: the file is not seekable * FOPEN_CACHE_DIR: allow caching this directory + * FOPEN_STREAM: the file is stream-like (no file position at all) */ #define FOPEN_DIRECT_IO (1 << 0) #define FOPEN_KEEP_CACHE (1 << 1) #define FOPEN_NONSEEKABLE (1 << 2) #define FOPEN_CACHE_DIR (1 << 3) +#define FOPEN_STREAM (1 << 4) /** * INIT request/reply flags @@ -263,6 +312,8 @@ struct fuse_file_lock { * FUSE_MAX_PAGES: init_out.max_pages contains the max number of req pages * FUSE_CACHE_SYMLINKS: cache READLINK responses * FUSE_NO_OPENDIR_SUPPORT: kernel supports zero-message opendir + * FUSE_EXPLICIT_INVAL_DATA: only invalidate cached pages on explicit request + * FUSE_MAP_ALIGNMENT: map_alignment field is valid */ #define FUSE_ASYNC_READ (1 << 0) #define FUSE_POSIX_LOCKS (1 << 1) @@ -289,6 +340,8 @@ struct fuse_file_lock { #define FUSE_MAX_PAGES (1 << 22) #define FUSE_CACHE_SYMLINKS (1 << 23) #define FUSE_NO_OPENDIR_SUPPORT (1 << 24) +#define FUSE_EXPLICIT_INVAL_DATA (1 << 25) +#define FUSE_MAP_ALIGNMENT (1 << 26) /** * CUSE INIT request/reply flags @@ -318,9 +371,11 @@ struct fuse_file_lock { * * FUSE_WRITE_CACHE: delayed write from page cache, file handle is guessed * FUSE_WRITE_LOCKOWNER: lock_owner field is valid + * FUSE_WRITE_KILL_PRIV: kill suid and sgid bits */ #define FUSE_WRITE_CACHE (1 << 0) #define FUSE_WRITE_LOCKOWNER (1 << 1) +#define FUSE_WRITE_KILL_PRIV (1 << 2) /** * Read flags @@ -335,6 +390,7 @@ struct fuse_file_lock { * FUSE_IOCTL_RETRY: retry with new iovecs * FUSE_IOCTL_32BIT: 32bit ioctl * FUSE_IOCTL_DIR: is a directory + * FUSE_IOCTL_COMPAT_X32: x32 compat ioctl on 64bit machine (64bit time_t) * * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs */ @@ -343,6 +399,7 @@ struct fuse_file_lock { #define FUSE_IOCTL_RETRY (1 << 2) #define FUSE_IOCTL_32BIT (1 << 3) #define FUSE_IOCTL_DIR (1 << 4) +#define FUSE_IOCTL_COMPAT_X32 (1 << 5) #define FUSE_IOCTL_MAX_IOV 256 @@ -353,6 +410,13 @@ struct fuse_file_lock { */ #define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0) +/** + * Fsync flags + * + * FUSE_FSYNC_FDATASYNC: Sync data only, not metadata + */ +#define FUSE_FSYNC_FDATASYNC (1 << 0) + enum fuse_opcode { FUSE_LOOKUP = 1, FUSE_FORGET = 2, /* no reply */ @@ -399,9 +463,15 @@ enum fuse_opcode { FUSE_RENAME2 = 45, FUSE_LSEEK = 46, FUSE_COPY_FILE_RANGE = 47, + FUSE_SETUPMAPPING = 48, + FUSE_REMOVEMAPPING = 49, /* CUSE specific operations */ CUSE_INIT = 4096, + + /* Reserved opcodes: helpful to detect structure endian-ness */ + CUSE_INIT_BSWAP_RESERVED = 1048576, /* CUSE_INIT << 8 */ + FUSE_INIT_BSWAP_RESERVED = 436207616, /* FUSE_INIT << 24 */ }; enum fuse_notify_code { @@ -629,7 +699,7 @@ struct fuse_init_out { uint32_t max_write; uint32_t time_gran; uint16_t max_pages; - uint16_t padding; + uint16_t map_alignment; uint32_t unused[8]; }; diff --git a/libfuse/include/fuse_lowlevel.h b/libfuse/include/fuse_lowlevel.h index bed7afd9..c9e34d1f 100644 --- a/libfuse/include/fuse_lowlevel.h +++ b/libfuse/include/fuse_lowlevel.h @@ -128,16 +128,6 @@ struct fuse_forget_data { uint64_t nlookup; }; -/* 'to_set' flags in setattr */ -#define FUSE_SET_ATTR_MODE (1 << 0) -#define FUSE_SET_ATTR_UID (1 << 1) -#define FUSE_SET_ATTR_GID (1 << 2) -#define FUSE_SET_ATTR_SIZE (1 << 3) -#define FUSE_SET_ATTR_ATIME (1 << 4) -#define FUSE_SET_ATTR_MTIME (1 << 5) -#define FUSE_SET_ATTR_ATIME_NOW (1 << 7) -#define FUSE_SET_ATTR_MTIME_NOW (1 << 8) - /* ----------------------------------------------------------- * * Request methods and replies * * ----------------------------------------------------------- */ diff --git a/libfuse/lib/fuse.c b/libfuse/lib/fuse.c index 39cb42ea..aba3379c 100644 --- a/libfuse/lib/fuse.c +++ b/libfuse/lib/fuse.c @@ -2735,120 +2735,126 @@ fuse_fs_fchmod(struct fuse_fs *fs_, return -ENOSYS; } -static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, - int valid, struct fuse_file_info *fi) -{ - struct fuse *f = req_fuse_prepare(req); - struct stat buf; - char *path; - int err; - struct node *node; - struct fuse_file_info ffi = {0}; +static +void +fuse_lib_setattr(fuse_req_t req, + fuse_ino_t ino, + struct stat *attr, + int valid, + struct fuse_file_info *fi) +{ + struct fuse *f = req_fuse_prepare(req); + struct stat buf; + char *path; + int err; + struct node *node; + struct fuse_file_info ffi = {0}; - if(fi == NULL) - { - pthread_mutex_lock(&f->lock); - node = get_node(f,ino); - if(node->is_hidden) - { - fi = &ffi; - fi->fh = node->hidden_fh; - } - pthread_mutex_unlock(&f->lock); - } + if(fi == NULL) + { + pthread_mutex_lock(&f->lock); + node = get_node(f,ino); + if(node->is_hidden) + { + fi = &ffi; + fi->fh = node->hidden_fh; + } + pthread_mutex_unlock(&f->lock); + } - memset(&buf, 0, sizeof(buf)); + memset(&buf,0,sizeof(buf)); - path = NULL; + path = NULL; + err = ((fi == NULL) ? + get_path(f,ino,&path) : + get_path_nullok(f,ino,&path)); + + if(!err) + { + struct fuse_intr_data d; + + fuse_prepare_interrupt(f,req,&d); + + err = 0; + if (!err && (valid & FATTR_MODE)) err = ((fi == NULL) ? - get_path(f,ino,&path) : - get_path_nullok(f,ino,&path)); + fuse_fs_chmod(f->fs,path,attr->st_mode) : + fuse_fs_fchmod(f->fs,fi,attr->st_mode)); - if (!err) { - struct fuse_intr_data d; + if(!err && (valid & (FATTR_UID | FATTR_GID))) + { + uid_t uid = ((valid & FATTR_UID) ? attr->st_uid : (uid_t) -1); + gid_t gid = ((valid & FATTR_GID) ? attr->st_gid : (gid_t) -1); - fuse_prepare_interrupt(f, req, &d); + err = ((fi == NULL) ? + fuse_fs_chown(f->fs,path,uid,gid) : + fuse_fs_fchown(f->fs,fi,uid,gid)); + } + + if(!err && (valid & FATTR_SIZE)) + err = ((fi == NULL) ? + fuse_fs_truncate(f->fs,path,attr->st_size) : + fuse_fs_ftruncate(f->fs,path,attr->st_size,fi)); - err = 0; - if (!err && (valid & FUSE_SET_ATTR_MODE)) - err = ((fi == NULL) ? - fuse_fs_chmod(f->fs, path, attr->st_mode) : - fuse_fs_fchmod(f->fs, fi, attr->st_mode)); - - if (!err && (valid & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID))) - { - uid_t uid = (valid & FUSE_SET_ATTR_UID) ? - attr->st_uid : (uid_t) -1; - gid_t gid = (valid & FUSE_SET_ATTR_GID) ? - attr->st_gid : (gid_t) -1; - - err = ((fi == NULL) ? - fuse_fs_chown(f->fs, path, uid, gid) : - fuse_fs_fchown(f->fs, fi, uid, gid)); - } - - if (!err && (valid & FUSE_SET_ATTR_SIZE)) - { - err = ((fi == NULL) ? - fuse_fs_truncate(f->fs, path, attr->st_size) : - fuse_fs_ftruncate(f->fs, path, attr->st_size, fi)); - } #ifdef HAVE_UTIMENSAT - if (!err && f->utime_omit_ok && - (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) { - struct timespec tv[2]; - - tv[0].tv_sec = 0; - tv[1].tv_sec = 0; - tv[0].tv_nsec = UTIME_OMIT; - tv[1].tv_nsec = UTIME_OMIT; - - if (valid & FUSE_SET_ATTR_ATIME_NOW) - tv[0].tv_nsec = UTIME_NOW; - else if (valid & FUSE_SET_ATTR_ATIME) - tv[0] = attr->st_atim; - - if (valid & FUSE_SET_ATTR_MTIME_NOW) - tv[1].tv_nsec = UTIME_NOW; - else if (valid & FUSE_SET_ATTR_MTIME) - tv[1] = attr->st_mtim; - - err = ((fi == NULL) ? - fuse_fs_utimens(f->fs, path, tv) : - fuse_fs_futimens(f->fs, fi, tv)); - } else + if(!err && f->utime_omit_ok && (valid & (FATTR_ATIME | FATTR_MTIME))) + { + struct timespec tv[2]; + + tv[0].tv_sec = 0; + tv[1].tv_sec = 0; + tv[0].tv_nsec = UTIME_OMIT; + tv[1].tv_nsec = UTIME_OMIT; + + if(valid & FATTR_ATIME_NOW) + tv[0].tv_nsec = UTIME_NOW; + else if(valid & FATTR_ATIME) + tv[0] = attr->st_atim; + + if(valid & FATTR_MTIME_NOW) + tv[1].tv_nsec = UTIME_NOW; + else if(valid & FATTR_MTIME) + tv[1] = attr->st_mtim; + + err = ((fi == NULL) ? + fuse_fs_utimens(f->fs,path,tv) : + fuse_fs_futimens(f->fs,fi,tv)); + } + else #endif - if (!err && - (valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) == - (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) { - struct timespec tv[2]; - tv[0].tv_sec = attr->st_atime; - tv[0].tv_nsec = ST_ATIM_NSEC(attr); - tv[1].tv_sec = attr->st_mtime; - tv[1].tv_nsec = ST_MTIM_NSEC(attr); - err = ((fi == NULL) ? - fuse_fs_utimens(f->fs, path, tv) : - fuse_fs_futimens(f->fs, fi, tv)); - } + if(!err && ((valid & (FATTR_ATIME|FATTR_MTIME)) == (FATTR_ATIME|FATTR_MTIME))) + { + struct timespec tv[2]; + tv[0].tv_sec = attr->st_atime; + tv[0].tv_nsec = ST_ATIM_NSEC(attr); + tv[1].tv_sec = attr->st_mtime; + tv[1].tv_nsec = ST_MTIM_NSEC(attr); + err = ((fi == NULL) ? + fuse_fs_utimens(f->fs,path,tv) : + fuse_fs_futimens(f->fs,fi,tv)); + } - if (!err) - err = ((fi == NULL) ? - fuse_fs_getattr(f->fs, path, &buf) : - fuse_fs_fgetattr(f->fs, path, &buf, fi)); + if(!err) + err = ((fi == NULL) ? + fuse_fs_getattr(f->fs,path,&buf) : + fuse_fs_fgetattr(f->fs,path,&buf,fi)); - fuse_finish_interrupt(f, req, &d); - free_path(f, ino, path); - } + fuse_finish_interrupt(f,req,&d); + free_path(f,ino,path); + } - if (!err) { - pthread_mutex_lock(&f->lock); - update_stat(get_node(f, ino), &buf); - pthread_mutex_unlock(&f->lock); - set_stat(f, ino, &buf); - fuse_reply_attr(req, &buf, f->conf.attr_timeout); - } else { - reply_err(req, err); - } + if(!err) + { + pthread_mutex_lock(&f->lock); + update_stat(get_node(f,ino),&buf); + pthread_mutex_unlock(&f->lock); + set_stat(f,ino,&buf); + fuse_reply_attr(req,&buf,f->conf.attr_timeout); + } + else + { + reply_err(req,err); + } } static void fuse_lib_access(fuse_req_t req, fuse_ino_t ino, int mask) diff --git a/libfuse/lib/fuse_lowlevel.c b/libfuse/lib/fuse_lowlevel.c index 01f35b45..816a6cb8 100644 --- a/libfuse/lib/fuse_lowlevel.c +++ b/libfuse/lib/fuse_lowlevel.c @@ -54,35 +54,43 @@ static __attribute__((constructor)) void fuse_ll_init_pagesize(void) pagesize = getpagesize(); } -static void convert_stat(const struct stat *stbuf, struct fuse_attr *attr) -{ - attr->ino = stbuf->st_ino; - attr->mode = stbuf->st_mode; - attr->nlink = stbuf->st_nlink; - attr->uid = stbuf->st_uid; - attr->gid = stbuf->st_gid; - attr->rdev = stbuf->st_rdev; - attr->size = stbuf->st_size; - attr->blksize = stbuf->st_blksize; - attr->blocks = stbuf->st_blocks; - attr->atime = stbuf->st_atime; - attr->mtime = stbuf->st_mtime; - attr->ctime = stbuf->st_ctime; - attr->atimensec = ST_ATIM_NSEC(stbuf); - attr->mtimensec = ST_MTIM_NSEC(stbuf); - attr->ctimensec = ST_CTIM_NSEC(stbuf); -} - -static void convert_attr(const struct fuse_setattr_in *attr, struct stat *stbuf) -{ - stbuf->st_mode = attr->mode; - stbuf->st_uid = attr->uid; - stbuf->st_gid = attr->gid; - stbuf->st_size = attr->size; - stbuf->st_atime = attr->atime; - stbuf->st_mtime = attr->mtime; - ST_ATIM_NSEC_SET(stbuf, attr->atimensec); - ST_MTIM_NSEC_SET(stbuf, attr->mtimensec); +static +void +convert_stat(const struct stat *stbuf_, + struct fuse_attr *attr_) +{ + attr_->ino = stbuf_->st_ino; + attr_->mode = stbuf_->st_mode; + attr_->nlink = stbuf_->st_nlink; + attr_->uid = stbuf_->st_uid; + attr_->gid = stbuf_->st_gid; + attr_->rdev = stbuf_->st_rdev; + attr_->size = stbuf_->st_size; + attr_->blksize = stbuf_->st_blksize; + attr_->blocks = stbuf_->st_blocks; + attr_->atime = stbuf_->st_atime; + attr_->mtime = stbuf_->st_mtime; + attr_->ctime = stbuf_->st_ctime; + attr_->atimensec = ST_ATIM_NSEC(stbuf_); + attr_->mtimensec = ST_MTIM_NSEC(stbuf_); + attr_->ctimensec = ST_CTIM_NSEC(stbuf_); +} + +static +void +convert_attr(const struct fuse_setattr_in *attr_, + struct stat *stbuf_) +{ + stbuf_->st_mode = attr_->mode; + stbuf_->st_uid = attr_->uid; + stbuf_->st_gid = attr_->gid; + stbuf_->st_size = attr_->size; + stbuf_->st_atime = attr_->atime; + stbuf_->st_mtime = attr_->mtime; + stbuf_->st_ctime = attr_->ctime; + ST_ATIM_NSEC_SET(stbuf_,attr_->atimensec); + ST_MTIM_NSEC_SET(stbuf_,attr_->mtimensec); + ST_CTIM_NSEC_SET(stbuf_,attr_->ctimensec); } static size_t iov_length(const struct iovec *iov, size_t count) @@ -297,9 +305,11 @@ static int send_reply_ok(fuse_req_t req, const void *arg, size_t argsize) return send_reply(req, 0, arg, argsize); } -int fuse_reply_err(fuse_req_t req, int err) +int +fuse_reply_err(fuse_req_t req_, + int err_) { - return send_reply(req, -err, NULL, 0); + return send_reply(req_,-err_,NULL,0); } void fuse_reply_none(fuse_req_t req) @@ -1053,35 +1063,46 @@ static void do_getattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) fuse_reply_err(req, ENOSYS); } -static void do_setattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) -{ - struct fuse_setattr_in *arg = (struct fuse_setattr_in *) inarg; - - if (req->f->op.setattr) { - struct fuse_file_info *fi = NULL; - struct fuse_file_info fi_store; - struct stat stbuf; - memset(&stbuf, 0, sizeof(stbuf)); - convert_attr(arg, &stbuf); - if (arg->valid & FATTR_FH) { - arg->valid &= ~FATTR_FH; - memset(&fi_store, 0, sizeof(fi_store)); - fi = &fi_store; - fi->fh = arg->fh; - } - arg->valid &= - FUSE_SET_ATTR_MODE | - FUSE_SET_ATTR_UID | - FUSE_SET_ATTR_GID | - FUSE_SET_ATTR_SIZE | - FUSE_SET_ATTR_ATIME | - FUSE_SET_ATTR_MTIME | - FUSE_SET_ATTR_ATIME_NOW | - FUSE_SET_ATTR_MTIME_NOW; - - req->f->op.setattr(req, nodeid, &stbuf, arg->valid, fi); - } else - fuse_reply_err(req, ENOSYS); +static +void +do_setattr(fuse_req_t req_, + fuse_ino_t nodeid_, + const void *inarg_) +{ + struct stat stbuf; + struct fuse_file_info *fi; + struct fuse_file_info fi_store; + struct fuse_setattr_in *arg; + + if(req_->f->op.setattr == NULL) + return (void)fuse_reply_err(req_,ENOSYS); + + fi = NULL; + arg = (struct fuse_setattr_in*)inarg_; + + memset(&stbuf,0,sizeof(stbuf)); + convert_attr(arg,&stbuf); + + if(arg->valid & FATTR_FH) + { + arg->valid &= ~FATTR_FH; + memset(&fi_store,0,sizeof(fi_store)); + fi = &fi_store; + fi->fh = arg->fh; + } + + arg->valid &= + (FATTR_MODE | + FATTR_UID | + FATTR_GID | + FATTR_SIZE | + FATTR_ATIME | + FATTR_MTIME | + FATTR_CTIME | + FATTR_ATIME_NOW | + FATTR_MTIME_NOW); + + req_->f->op.setattr(req_,nodeid_,&stbuf,arg->valid,fi); } static void do_access(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) diff --git a/libfuse/lib/fuse_misc.h b/libfuse/lib/fuse_misc.h index eedf0e0f..5fa14675 100644 --- a/libfuse/lib/fuse_misc.h +++ b/libfuse/lib/fuse_misc.h @@ -36,22 +36,25 @@ static inline void fuse_mutex_init(pthread_mutex_t *mut) #ifdef HAVE_STRUCT_STAT_ST_ATIM /* Linux */ -#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec) -#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctim.tv_nsec) -#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtim.tv_nsec) -#define ST_ATIM_NSEC_SET(stbuf, val) (stbuf)->st_atim.tv_nsec = (val) -#define ST_MTIM_NSEC_SET(stbuf, val) (stbuf)->st_mtim.tv_nsec = (val) +#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec) +#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctim.tv_nsec) +#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtim.tv_nsec) +#define ST_ATIM_NSEC_SET(stbuf,val) ((stbuf)->st_atim.tv_nsec = (val)) +#define ST_CTIM_NSEC_SET(stbuf,val) ((stbuf)->st_ctim.tv_nsec = (val)) +#define ST_MTIM_NSEC_SET(stbuf,val) ((stbuf)->st_mtim.tv_nsec = (val)) #elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC) /* FreeBSD */ -#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atimespec.tv_nsec) -#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctimespec.tv_nsec) -#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtimespec.tv_nsec) -#define ST_ATIM_NSEC_SET(stbuf, val) (stbuf)->st_atimespec.tv_nsec = (val) -#define ST_MTIM_NSEC_SET(stbuf, val) (stbuf)->st_mtimespec.tv_nsec = (val) +#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atimespec.tv_nsec) +#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctimespec.tv_nsec) +#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtimespec.tv_nsec) +#define ST_ATIM_NSEC_SET(stbuf,val) ((stbuf)->st_atimespec.tv_nsec = (val)) +#define ST_CTIM_NSEC_SET(stbuf,val) ((stbuf)->st_ctimespec.tv_nsec = (val)) +#define ST_MTIM_NSEC_SET(stbuf,val) ((stbuf)->st_mtimespec.tv_nsec = (val)) #else #define ST_ATIM_NSEC(stbuf) 0 #define ST_CTIM_NSEC(stbuf) 0 #define ST_MTIM_NSEC(stbuf) 0 -#define ST_ATIM_NSEC_SET(stbuf, val) do { } while (0) -#define ST_MTIM_NSEC_SET(stbuf, val) do { } while (0) +#define ST_ATIM_NSEC_SET(stbuf,val) do { } while (0) +#define ST_CTIM_NSEC_SET(stbuf,val) do { } while (0) +#define ST_MTIM_NSEC_SET(stbuf,val) do { } while (0) #endif