Browse Source

Merge pull request #706 from trapexit/ctime

ctime
pull/710/head
trapexit 5 years ago
committed by GitHub
parent
commit
43ddff6ca9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 76
      libfuse/include/fuse_kernel.h
  2. 10
      libfuse/include/fuse_lowlevel.h
  3. 210
      libfuse/lib/fuse.c
  4. 141
      libfuse/lib/fuse_lowlevel.c
  5. 27
      libfuse/lib/fuse_misc.h

76
libfuse/include/fuse_kernel.h

@ -38,12 +38,50 @@
* *
* Protocol changelog: * 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: * 7.9:
* - new fuse_getattr_in input argument of GETATTR * - new fuse_getattr_in input argument of GETATTR
* - add lk_flags in fuse_lk_in * - add lk_flags in fuse_lk_in
* - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in
* - add blksize field to fuse_attr * - add blksize field to fuse_attr
* - add file flags field to fuse_read_in and fuse_write_in * - 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 * 7.10
* - add nonseekable open flag * - add nonseekable open flag
@ -54,7 +92,7 @@
* - add POLL message and NOTIFY_POLL notification * - add POLL message and NOTIFY_POLL notification
* *
* 7.12 * 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 * - add notification messages for invalidation of inodes and
* directory entries * directory entries
* *
@ -125,6 +163,15 @@
* *
* 7.29 * 7.29
* - add FUSE_NO_OPENDIR_SUPPORT flag * - 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 #ifndef _LINUX_FUSE_H
@ -160,7 +207,7 @@
#define FUSE_KERNEL_VERSION 7 #define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */ /** 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 */ /** The node ID of the root inode */
#define FUSE_ROOT_ID 1 #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_KEEP_CACHE: don't invalidate the data cache on open
* FOPEN_NONSEEKABLE: the file is not seekable * FOPEN_NONSEEKABLE: the file is not seekable
* FOPEN_CACHE_DIR: allow caching this directory * 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_DIRECT_IO (1 << 0)
#define FOPEN_KEEP_CACHE (1 << 1) #define FOPEN_KEEP_CACHE (1 << 1)
#define FOPEN_NONSEEKABLE (1 << 2) #define FOPEN_NONSEEKABLE (1 << 2)
#define FOPEN_CACHE_DIR (1 << 3) #define FOPEN_CACHE_DIR (1 << 3)
#define FOPEN_STREAM (1 << 4)
/** /**
* INIT request/reply flags * 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_MAX_PAGES: init_out.max_pages contains the max number of req pages
* FUSE_CACHE_SYMLINKS: cache READLINK responses * FUSE_CACHE_SYMLINKS: cache READLINK responses
* FUSE_NO_OPENDIR_SUPPORT: kernel supports zero-message opendir * 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_ASYNC_READ (1 << 0)
#define FUSE_POSIX_LOCKS (1 << 1) #define FUSE_POSIX_LOCKS (1 << 1)
@ -289,6 +340,8 @@ struct fuse_file_lock {
#define FUSE_MAX_PAGES (1 << 22) #define FUSE_MAX_PAGES (1 << 22)
#define FUSE_CACHE_SYMLINKS (1 << 23) #define FUSE_CACHE_SYMLINKS (1 << 23)
#define FUSE_NO_OPENDIR_SUPPORT (1 << 24) #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 * 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_CACHE: delayed write from page cache, file handle is guessed
* FUSE_WRITE_LOCKOWNER: lock_owner field is valid * 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_CACHE (1 << 0)
#define FUSE_WRITE_LOCKOWNER (1 << 1) #define FUSE_WRITE_LOCKOWNER (1 << 1)
#define FUSE_WRITE_KILL_PRIV (1 << 2)
/** /**
* Read flags * Read flags
@ -335,6 +390,7 @@ struct fuse_file_lock {
* FUSE_IOCTL_RETRY: retry with new iovecs * FUSE_IOCTL_RETRY: retry with new iovecs
* FUSE_IOCTL_32BIT: 32bit ioctl * FUSE_IOCTL_32BIT: 32bit ioctl
* FUSE_IOCTL_DIR: is a directory * 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 * 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_RETRY (1 << 2)
#define FUSE_IOCTL_32BIT (1 << 3) #define FUSE_IOCTL_32BIT (1 << 3)
#define FUSE_IOCTL_DIR (1 << 4) #define FUSE_IOCTL_DIR (1 << 4)
#define FUSE_IOCTL_COMPAT_X32 (1 << 5)
#define FUSE_IOCTL_MAX_IOV 256 #define FUSE_IOCTL_MAX_IOV 256
@ -353,6 +410,13 @@ struct fuse_file_lock {
*/ */
#define FUSE_POLL_SCHEDULE_NOTIFY (1 << 0) #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 { enum fuse_opcode {
FUSE_LOOKUP = 1, FUSE_LOOKUP = 1,
FUSE_FORGET = 2, /* no reply */ FUSE_FORGET = 2, /* no reply */
@ -399,9 +463,15 @@ enum fuse_opcode {
FUSE_RENAME2 = 45, FUSE_RENAME2 = 45,
FUSE_LSEEK = 46, FUSE_LSEEK = 46,
FUSE_COPY_FILE_RANGE = 47, FUSE_COPY_FILE_RANGE = 47,
FUSE_SETUPMAPPING = 48,
FUSE_REMOVEMAPPING = 49,
/* CUSE specific operations */ /* CUSE specific operations */
CUSE_INIT = 4096, 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 { enum fuse_notify_code {
@ -629,7 +699,7 @@ struct fuse_init_out {
uint32_t max_write; uint32_t max_write;
uint32_t time_gran; uint32_t time_gran;
uint16_t max_pages; uint16_t max_pages;
uint16_t padding; uint16_t map_alignment;
uint32_t unused[8]; uint32_t unused[8];
}; };

10
libfuse/include/fuse_lowlevel.h

@ -128,16 +128,6 @@ struct fuse_forget_data {
uint64_t nlookup; 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 * * Request methods and replies *
* ----------------------------------------------------------- */ * ----------------------------------------------------------- */

210
libfuse/lib/fuse.c

@ -2735,120 +2735,126 @@ fuse_fs_fchmod(struct fuse_fs *fs_,
return -ENOSYS; return -ENOSYS;
} }
static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr, static
int valid, struct fuse_file_info *fi) void
{ fuse_lib_setattr(fuse_req_t req,
struct fuse *f = req_fuse_prepare(req); fuse_ino_t ino,
struct stat buf; struct stat *attr,
char *path; int valid,
int err; struct fuse_file_info *fi)
struct node *node; {
struct fuse_file_info ffi = {0}; 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) if(fi == NULL)
{ {
pthread_mutex_lock(&f->lock); pthread_mutex_lock(&f->lock);
node = get_node(f,ino); node = get_node(f,ino);
if(node->is_hidden) if(node->is_hidden)
{ {
fi = &ffi; fi = &ffi;
fi->fh = node->hidden_fh; fi->fh = node->hidden_fh;
} }
pthread_mutex_unlock(&f->lock); 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) ? err = ((fi == NULL) ?
get_path(f,ino,&path) : fuse_fs_chmod(f->fs,path,attr->st_mode) :
get_path_nullok(f,ino,&path)); fuse_fs_fchmod(f->fs,fi,attr->st_mode));
if (!err) { if(!err && (valid & (FATTR_UID | FATTR_GID)))
struct fuse_intr_data d; {
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 #ifdef HAVE_UTIMENSAT
if (!err && f->utime_omit_ok && if(!err && f->utime_omit_ok && (valid & (FATTR_ATIME | FATTR_MTIME)))
(valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME))) { {
struct timespec tv[2]; struct timespec tv[2];
tv[0].tv_sec = 0;
tv[0].tv_sec = 0; tv[1].tv_sec = 0;
tv[1].tv_sec = 0; tv[0].tv_nsec = UTIME_OMIT;
tv[0].tv_nsec = UTIME_OMIT; tv[1].tv_nsec = UTIME_OMIT;
tv[1].tv_nsec = UTIME_OMIT; if(valid & FATTR_ATIME_NOW)
tv[0].tv_nsec = UTIME_NOW;
if (valid & FUSE_SET_ATTR_ATIME_NOW) else if(valid & FATTR_ATIME)
tv[0].tv_nsec = UTIME_NOW; tv[0] = attr->st_atim;
else if (valid & FUSE_SET_ATTR_ATIME) if(valid & FATTR_MTIME_NOW)
tv[0] = attr->st_atim; tv[1].tv_nsec = UTIME_NOW;
else if(valid & FATTR_MTIME)
if (valid & FUSE_SET_ATTR_MTIME_NOW) tv[1] = attr->st_mtim;
tv[1].tv_nsec = UTIME_NOW; err = ((fi == NULL) ?
else if (valid & FUSE_SET_ATTR_MTIME) fuse_fs_utimens(f->fs,path,tv) :
tv[1] = attr->st_mtim; fuse_fs_futimens(f->fs,fi,tv));
}
err = ((fi == NULL) ? else
fuse_fs_utimens(f->fs, path, tv) :
fuse_fs_futimens(f->fs, fi, tv));
} else
#endif #endif
if (!err && if(!err && ((valid & (FATTR_ATIME|FATTR_MTIME)) == (FATTR_ATIME|FATTR_MTIME)))
(valid & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) == {
(FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) { struct timespec tv[2];
struct timespec tv[2]; tv[0].tv_sec = attr->st_atime;
tv[0].tv_sec = attr->st_atime; tv[0].tv_nsec = ST_ATIM_NSEC(attr);
tv[0].tv_nsec = ST_ATIM_NSEC(attr); tv[1].tv_sec = attr->st_mtime;
tv[1].tv_sec = attr->st_mtime; tv[1].tv_nsec = ST_MTIM_NSEC(attr);
tv[1].tv_nsec = ST_MTIM_NSEC(attr); err = ((fi == NULL) ?
err = ((fi == NULL) ? fuse_fs_utimens(f->fs,path,tv) :
fuse_fs_utimens(f->fs, path, tv) : fuse_fs_futimens(f->fs,fi,tv));
fuse_fs_futimens(f->fs, fi, tv)); }
}
if (!err) if(!err)
err = ((fi == NULL) ? err = ((fi == NULL) ?
fuse_fs_getattr(f->fs, path, &buf) : fuse_fs_getattr(f->fs,path,&buf) :
fuse_fs_fgetattr(f->fs, path, &buf, fi)); fuse_fs_fgetattr(f->fs,path,&buf,fi));
fuse_finish_interrupt(f, req, &d); fuse_finish_interrupt(f,req,&d);
free_path(f, ino, path); free_path(f,ino,path);
} }
if (!err) { if(!err)
pthread_mutex_lock(&f->lock); {
update_stat(get_node(f, ino), &buf); pthread_mutex_lock(&f->lock);
pthread_mutex_unlock(&f->lock); update_stat(get_node(f,ino),&buf);
set_stat(f, ino, &buf); pthread_mutex_unlock(&f->lock);
fuse_reply_attr(req, &buf, f->conf.attr_timeout); set_stat(f,ino,&buf);
} else { fuse_reply_attr(req,&buf,f->conf.attr_timeout);
reply_err(req, err); }
} else
{
reply_err(req,err);
}
} }
static void fuse_lib_access(fuse_req_t req, fuse_ino_t ino, int mask) static void fuse_lib_access(fuse_req_t req, fuse_ino_t ino, int mask)

141
libfuse/lib/fuse_lowlevel.c

@ -54,35 +54,43 @@ static __attribute__((constructor)) void fuse_ll_init_pagesize(void)
pagesize = getpagesize(); pagesize = getpagesize();
} }
static void convert_stat(const struct stat *stbuf, struct fuse_attr *attr) static
{ void
attr->ino = stbuf->st_ino; convert_stat(const struct stat *stbuf_,
attr->mode = stbuf->st_mode; struct fuse_attr *attr_)
attr->nlink = stbuf->st_nlink; {
attr->uid = stbuf->st_uid; attr_->ino = stbuf_->st_ino;
attr->gid = stbuf->st_gid; attr_->mode = stbuf_->st_mode;
attr->rdev = stbuf->st_rdev; attr_->nlink = stbuf_->st_nlink;
attr->size = stbuf->st_size; attr_->uid = stbuf_->st_uid;
attr->blksize = stbuf->st_blksize; attr_->gid = stbuf_->st_gid;
attr->blocks = stbuf->st_blocks; attr_->rdev = stbuf_->st_rdev;
attr->atime = stbuf->st_atime; attr_->size = stbuf_->st_size;
attr->mtime = stbuf->st_mtime; attr_->blksize = stbuf_->st_blksize;
attr->ctime = stbuf->st_ctime; attr_->blocks = stbuf_->st_blocks;
attr->atimensec = ST_ATIM_NSEC(stbuf); attr_->atime = stbuf_->st_atime;
attr->mtimensec = ST_MTIM_NSEC(stbuf); attr_->mtime = stbuf_->st_mtime;
attr->ctimensec = ST_CTIM_NSEC(stbuf); attr_->ctime = stbuf_->st_ctime;
} attr_->atimensec = ST_ATIM_NSEC(stbuf_);
attr_->mtimensec = ST_MTIM_NSEC(stbuf_);
static void convert_attr(const struct fuse_setattr_in *attr, struct stat *stbuf) attr_->ctimensec = ST_CTIM_NSEC(stbuf_);
{ }
stbuf->st_mode = attr->mode; static
stbuf->st_uid = attr->uid; void
stbuf->st_gid = attr->gid; convert_attr(const struct fuse_setattr_in *attr_,
stbuf->st_size = attr->size; struct stat *stbuf_)
stbuf->st_atime = attr->atime; {
stbuf->st_mtime = attr->mtime; stbuf_->st_mode = attr_->mode;
ST_ATIM_NSEC_SET(stbuf, attr->atimensec); stbuf_->st_uid = attr_->uid;
ST_MTIM_NSEC_SET(stbuf, attr->mtimensec); 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) 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); 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) 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); fuse_reply_err(req, ENOSYS);
} }
static void do_setattr(fuse_req_t req, fuse_ino_t nodeid, const void *inarg) static
{ void
struct fuse_setattr_in *arg = (struct fuse_setattr_in *) inarg; do_setattr(fuse_req_t req_,
fuse_ino_t nodeid_,
if (req->f->op.setattr) { const void *inarg_)
struct fuse_file_info *fi = NULL; {
struct fuse_file_info fi_store; struct stat stbuf;
struct stat stbuf; struct fuse_file_info *fi;
memset(&stbuf, 0, sizeof(stbuf)); struct fuse_file_info fi_store;
convert_attr(arg, &stbuf); struct fuse_setattr_in *arg;
if (arg->valid & FATTR_FH) { if(req_->f->op.setattr == NULL)
arg->valid &= ~FATTR_FH; return (void)fuse_reply_err(req_,ENOSYS);
memset(&fi_store, 0, sizeof(fi_store)); fi = NULL;
fi = &fi_store; arg = (struct fuse_setattr_in*)inarg_;
fi->fh = arg->fh; memset(&stbuf,0,sizeof(stbuf));
} convert_attr(arg,&stbuf);
arg->valid &= if(arg->valid & FATTR_FH)
FUSE_SET_ATTR_MODE | {
FUSE_SET_ATTR_UID | arg->valid &= ~FATTR_FH;
FUSE_SET_ATTR_GID | memset(&fi_store,0,sizeof(fi_store));
FUSE_SET_ATTR_SIZE | fi = &fi_store;
FUSE_SET_ATTR_ATIME | fi->fh = arg->fh;
FUSE_SET_ATTR_MTIME | }
FUSE_SET_ATTR_ATIME_NOW | arg->valid &=
FUSE_SET_ATTR_MTIME_NOW; (FATTR_MODE |
FATTR_UID |
req->f->op.setattr(req, nodeid, &stbuf, arg->valid, fi); FATTR_GID |
} else FATTR_SIZE |
fuse_reply_err(req, ENOSYS); 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) static void do_access(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)

27
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 #ifdef HAVE_STRUCT_STAT_ST_ATIM
/* Linux */ /* Linux */
#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec) #define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec)
#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctim.tv_nsec) #define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctim.tv_nsec)
#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtim.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_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_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) #elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC)
/* FreeBSD */ /* FreeBSD */
#define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atimespec.tv_nsec) #define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atimespec.tv_nsec)
#define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctimespec.tv_nsec) #define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctimespec.tv_nsec)
#define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtimespec.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_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_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 #else
#define ST_ATIM_NSEC(stbuf) 0 #define ST_ATIM_NSEC(stbuf) 0
#define ST_CTIM_NSEC(stbuf) 0 #define ST_CTIM_NSEC(stbuf) 0
#define ST_MTIM_NSEC(stbuf) 0 #define ST_MTIM_NSEC(stbuf) 0
#define ST_ATIM_NSEC_SET(stbuf, val) do { } while (0) #define ST_ATIM_NSEC_SET(stbuf,val) do { } while (0)
#define ST_MTIM_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 #endif
|||||||
100:0
Loading…
Cancel
Save