mirror of
https://github.com/trapexit/mergerfs.git
synced 2025-04-24 22:14:05 +08:00
commit
43ddff6ca9
@ -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];
|
||||
};
|
||||
|
||||
|
@ -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 *
|
||||
* ----------------------------------------------------------- */
|
||||
|
@ -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)
|
||||
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};
|
||||
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);
|
||||
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));
|
||||
|
||||
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) ?
|
||||
fuse_fs_chmod(f->fs,path,attr->st_mode) :
|
||||
fuse_fs_fchmod(f->fs,fi,attr->st_mode));
|
||||
|
||||
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);
|
||||
|
||||
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));
|
||||
|
||||
#ifdef HAVE_UTIMENSAT
|
||||
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 & (FATTR_ATIME|FATTR_MTIME)) == (FATTR_ATIME|FATTR_MTIME)))
|
||||
{
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
|
||||
path = NULL;
|
||||
if(!err)
|
||||
err = ((fi == NULL) ?
|
||||
get_path(f,ino,&path) :
|
||||
get_path_nullok(f,ino,&path));
|
||||
fuse_fs_getattr(f->fs,path,&buf) :
|
||||
fuse_fs_fgetattr(f->fs,path,&buf,fi));
|
||||
|
||||
if (!err) {
|
||||
struct fuse_intr_data d;
|
||||
fuse_finish_interrupt(f,req,&d);
|
||||
free_path(f,ino,path);
|
||||
}
|
||||
|
||||
fuse_prepare_interrupt(f, req, &d);
|
||||
|
||||
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
|
||||
#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)
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -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)
|
||||
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);
|
||||
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)
|
||||
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);
|
||||
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)
|
||||
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;
|
||||
struct stat stbuf;
|
||||
struct fuse_file_info *fi;
|
||||
struct fuse_file_info fi_store;
|
||||
struct fuse_setattr_in *arg;
|
||||
|
||||
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;
|
||||
if(req_->f->op.setattr == NULL)
|
||||
return (void)fuse_reply_err(req_,ENOSYS);
|
||||
|
||||
req->f->op.setattr(req, nodeid, &stbuf, arg->valid, fi);
|
||||
} else
|
||||
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)
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user