mirror of
https://github.com/libfuse/libfuse.git
synced 2024-11-27 06:04:27 +08:00
Pass fuse_file_info to getattr, chown, chmod, truncate, utimens handlers
This obsoletes the ftruncate & fgetattr handlers. Fixes #58.
This commit is contained in:
parent
d49f2e77b4
commit
73b6ff4b75
@ -1,6 +1,13 @@
|
||||
Unreleased Changes
|
||||
==================
|
||||
|
||||
* The chmod, chown, truncate, utimens and getattr handlers of the
|
||||
high-level API now all receive an additional struct fuse_file_info
|
||||
pointer. This pointer is NULL if the file is not currently open.
|
||||
|
||||
The fgetattr and ftruncate handlers have become obsolote and have
|
||||
been removed.
|
||||
|
||||
* The `fuse_session_new` function no longer accepts the ``-o
|
||||
clone_fd`` option. Instead, this has become a parameter of the
|
||||
`fuse_session_loop_mt` and ``fuse_loop_mt` functions.
|
||||
|
@ -68,8 +68,10 @@ static const struct fuse_opt option_spec[] = {
|
||||
FUSE_OPT_END
|
||||
};
|
||||
|
||||
static int hello_getattr(const char *path, struct stat *stbuf)
|
||||
static int hello_getattr(const char *path, struct stat *stbuf,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
(void) fi;
|
||||
int res = 0;
|
||||
|
||||
memset(stbuf, 0, sizeof(struct stat));
|
||||
|
@ -83,8 +83,10 @@ static int fioc_file_type(const char *path)
|
||||
return FIOC_NONE;
|
||||
}
|
||||
|
||||
static int fioc_getattr(const char *path, struct stat *stbuf)
|
||||
static int fioc_getattr(const char *path, struct stat *stbuf,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
(void) fi;
|
||||
stbuf->st_uid = getuid();
|
||||
stbuf->st_gid = getgid();
|
||||
stbuf->st_atime = stbuf->st_mtime = time(NULL);
|
||||
@ -160,8 +162,10 @@ static int fioc_write(const char *path, const char *buf, size_t size,
|
||||
return fioc_do_write(buf, size, offset);
|
||||
}
|
||||
|
||||
static int fioc_truncate(const char *path, off_t size)
|
||||
static int fioc_truncate(const char *path, off_t size,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
(void) fi;
|
||||
if (fioc_file_type(path) != FIOC_FILE)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -48,8 +48,10 @@
|
||||
#include <sys/xattr.h>
|
||||
#endif
|
||||
|
||||
static int xmp_getattr(const char *path, struct stat *stbuf)
|
||||
static int xmp_getattr(const char *path, struct stat *stbuf,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
(void) fi;
|
||||
int res;
|
||||
|
||||
res = lstat(path, stbuf);
|
||||
@ -200,8 +202,10 @@ static int xmp_link(const char *from, const char *to)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xmp_chmod(const char *path, mode_t mode)
|
||||
static int xmp_chmod(const char *path, mode_t mode,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
(void) fi;
|
||||
int res;
|
||||
|
||||
res = chmod(path, mode);
|
||||
@ -211,8 +215,10 @@ static int xmp_chmod(const char *path, mode_t mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xmp_chown(const char *path, uid_t uid, gid_t gid)
|
||||
static int xmp_chown(const char *path, uid_t uid, gid_t gid,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
(void) fi;
|
||||
int res;
|
||||
|
||||
res = lchown(path, uid, gid);
|
||||
@ -222,8 +228,10 @@ static int xmp_chown(const char *path, uid_t uid, gid_t gid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xmp_truncate(const char *path, off_t size)
|
||||
static int xmp_truncate(const char *path, off_t size,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
(void) fi;
|
||||
int res;
|
||||
|
||||
res = truncate(path, size);
|
||||
@ -234,8 +242,10 @@ static int xmp_truncate(const char *path, off_t size)
|
||||
}
|
||||
|
||||
#ifdef HAVE_UTIMENSAT
|
||||
static int xmp_utimens(const char *path, const struct timespec ts[2])
|
||||
static int xmp_utimens(const char *path, const struct timespec ts[2],
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
(void) fi;
|
||||
int res;
|
||||
|
||||
/* don't use utime/utimes since they follow symlinks */
|
||||
|
@ -52,25 +52,17 @@
|
||||
#endif
|
||||
#include <sys/file.h> /* flock(2) */
|
||||
|
||||
static int xmp_getattr(const char *path, struct stat *stbuf)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = lstat(path, stbuf);
|
||||
if (res == -1)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xmp_fgetattr(const char *path, struct stat *stbuf,
|
||||
static int xmp_getattr(const char *path, struct stat *stbuf,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
int res;
|
||||
|
||||
(void) path;
|
||||
|
||||
if(fi)
|
||||
res = fstat(fi->fh, stbuf);
|
||||
else
|
||||
res = lstat(path, stbuf);
|
||||
if (res == -1)
|
||||
return -errno;
|
||||
|
||||
@ -272,10 +264,14 @@ static int xmp_link(const char *from, const char *to)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xmp_chmod(const char *path, mode_t mode)
|
||||
static int xmp_chmod(const char *path, mode_t mode,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
int res;
|
||||
|
||||
if(fi)
|
||||
res = fchmod(fi->fh, mode);
|
||||
else
|
||||
res = chmod(path, mode);
|
||||
if (res == -1)
|
||||
return -errno;
|
||||
@ -283,10 +279,14 @@ static int xmp_chmod(const char *path, mode_t mode)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xmp_chown(const char *path, uid_t uid, gid_t gid)
|
||||
static int xmp_chown(const char *path, uid_t uid, gid_t gid,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (fi)
|
||||
res = fchown(fi->fh, uid, gid);
|
||||
else
|
||||
res = lchown(path, uid, gid);
|
||||
if (res == -1)
|
||||
return -errno;
|
||||
@ -294,25 +294,16 @@ static int xmp_chown(const char *path, uid_t uid, gid_t gid)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xmp_truncate(const char *path, off_t size)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = truncate(path, size);
|
||||
if (res == -1)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xmp_ftruncate(const char *path, off_t size,
|
||||
static int xmp_truncate(const char *path, off_t size,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
int res;
|
||||
|
||||
(void) path;
|
||||
|
||||
if(fi)
|
||||
res = ftruncate(fi->fh, size);
|
||||
else
|
||||
res = truncate(path, size);
|
||||
|
||||
if (res == -1)
|
||||
return -errno;
|
||||
|
||||
@ -320,11 +311,15 @@ static int xmp_ftruncate(const char *path, off_t size,
|
||||
}
|
||||
|
||||
#ifdef HAVE_UTIMENSAT
|
||||
static int xmp_utimens(const char *path, const struct timespec ts[2])
|
||||
static int xmp_utimens(const char *path, const struct timespec ts[2],
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
int res;
|
||||
|
||||
/* don't use utime/utimes since they follow symlinks */
|
||||
if (fi)
|
||||
res = futimens(fi->fh, ts);
|
||||
else
|
||||
res = utimensat(0, path, ts, AT_SYMLINK_NOFOLLOW);
|
||||
if (res == -1)
|
||||
return -errno;
|
||||
@ -550,7 +545,6 @@ static int xmp_flock(const char *path, struct fuse_file_info *fi, int op)
|
||||
|
||||
static struct fuse_operations xmp_oper = {
|
||||
.getattr = xmp_getattr,
|
||||
.fgetattr = xmp_fgetattr,
|
||||
.access = xmp_access,
|
||||
.readlink = xmp_readlink,
|
||||
.opendir = xmp_opendir,
|
||||
@ -566,7 +560,6 @@ static struct fuse_operations xmp_oper = {
|
||||
.chmod = xmp_chmod,
|
||||
.chown = xmp_chown,
|
||||
.truncate = xmp_truncate,
|
||||
.ftruncate = xmp_ftruncate,
|
||||
#ifdef HAVE_UTIMENSAT
|
||||
.utimens = xmp_utimens,
|
||||
#endif
|
||||
|
@ -64,8 +64,10 @@ static int fsel_path_index(const char *path)
|
||||
return ch <= '9' ? ch - '0' : ch - 'A' + 10;
|
||||
}
|
||||
|
||||
static int fsel_getattr(const char *path, struct stat *stbuf)
|
||||
static int fsel_getattr(const char *path, struct stat *stbuf,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
(void) fi;
|
||||
int idx;
|
||||
|
||||
memset(stbuf, 0, sizeof(struct stat));
|
||||
|
@ -105,7 +105,13 @@ struct fuse_operations {
|
||||
* the following operations:
|
||||
*
|
||||
* read, write, flush, release, fsync, readdir, releasedir,
|
||||
* fsyncdir, ftruncate, fgetattr, lock, ioctl and poll
|
||||
* fsyncdir, lock, ioctl and poll
|
||||
*
|
||||
* For the following operations, the path will not be
|
||||
* calculated only if the file is currently open (i.e., the
|
||||
* struct fuse_file_info argument is non-NULL):
|
||||
*
|
||||
* truncate, getattr, chmod, chown, utimens
|
||||
*
|
||||
* If this flag is set then the path will not be calculaged even if the
|
||||
* file wasn't unlinked. However the path can still be non-NULL if it
|
||||
@ -123,8 +129,10 @@ struct fuse_operations {
|
||||
* Similar to stat(). The 'st_dev' and 'st_blksize' fields are
|
||||
* ignored. The 'st_ino' field is ignored except if the 'use_ino'
|
||||
* mount option is given.
|
||||
*
|
||||
* *fi* will be NULL if the file is not currenly opened.
|
||||
*/
|
||||
int (*getattr) (const char *, struct stat *);
|
||||
int (*getattr) (const char *, struct stat *, struct fuse_file_info *fi);
|
||||
|
||||
/** Read the target of a symbolic link
|
||||
*
|
||||
@ -167,14 +175,23 @@ struct fuse_operations {
|
||||
/** Create a hard link to a file */
|
||||
int (*link) (const char *, const char *);
|
||||
|
||||
/** Change the permission bits of a file */
|
||||
int (*chmod) (const char *, mode_t);
|
||||
/** Change the permission bits of a file
|
||||
*
|
||||
* *fi* will be NULL if the file is not currenly opened.
|
||||
*/
|
||||
int (*chmod) (const char *, mode_t, struct fuse_file_info *fi);
|
||||
|
||||
/** Change the owner and group of a file */
|
||||
int (*chown) (const char *, uid_t, gid_t);
|
||||
/** Change the owner and group of a file
|
||||
*
|
||||
* *fi* will be NULL if the file is not currenly opened.
|
||||
*/
|
||||
int (*chown) (const char *, uid_t, gid_t, struct fuse_file_info *fi);
|
||||
|
||||
/** Change the size of a file */
|
||||
int (*truncate) (const char *, off_t);
|
||||
/** Change the size of a file
|
||||
*
|
||||
* *fi* will be NULL if the file is not currenly opened.
|
||||
*/
|
||||
int (*truncate) (const char *, off_t, struct fuse_file_info *fi);
|
||||
|
||||
/** File open operation
|
||||
*
|
||||
@ -387,34 +404,6 @@ struct fuse_operations {
|
||||
*/
|
||||
int (*create) (const char *, mode_t, struct fuse_file_info *);
|
||||
|
||||
/**
|
||||
* Change the size of an open file
|
||||
*
|
||||
* This method is called instead of the truncate() method if the
|
||||
* truncation was invoked from an ftruncate() system call.
|
||||
*
|
||||
* If this method is not implemented or under Linux kernel
|
||||
* versions earlier than 2.6.15, the truncate() method will be
|
||||
* called instead.
|
||||
*
|
||||
* Introduced in version 2.5
|
||||
*/
|
||||
int (*ftruncate) (const char *, off_t, struct fuse_file_info *);
|
||||
|
||||
/**
|
||||
* Get attributes from an open file
|
||||
*
|
||||
* This method is called instead of the getattr() method if the
|
||||
* file information is available.
|
||||
*
|
||||
* Currently this is only called after the create() method if that
|
||||
* is implemented (see above). Later it may be called for
|
||||
* invocations of fstat() too.
|
||||
*
|
||||
* Introduced in version 2.5
|
||||
*/
|
||||
int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *);
|
||||
|
||||
/**
|
||||
* Perform POSIX file locking operation
|
||||
*
|
||||
@ -457,11 +446,14 @@ struct fuse_operations {
|
||||
* This supersedes the old utime() interface. New applications
|
||||
* should use this.
|
||||
*
|
||||
* *fi* will be NULL if the file is not currenly opened.
|
||||
*
|
||||
* See the utimensat(2) man page for details.
|
||||
*
|
||||
* Introduced in version 2.6
|
||||
*/
|
||||
int (*utimens) (const char *, const struct timespec tv[2]);
|
||||
int (*utimens) (const char *, const struct timespec tv[2],
|
||||
struct fuse_file_info *fi);
|
||||
|
||||
/**
|
||||
* Map block index within file to block index within device
|
||||
@ -849,8 +841,7 @@ struct fuse_fs;
|
||||
* fuse_fs_releasedir and fuse_fs_statfs, which return 0.
|
||||
*/
|
||||
|
||||
int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf);
|
||||
int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf,
|
||||
int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf,
|
||||
struct fuse_file_info *fi);
|
||||
int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
|
||||
const char *newpath, unsigned int flags);
|
||||
@ -893,13 +884,14 @@ int fuse_fs_lock(struct fuse_fs *fs, const char *path,
|
||||
struct fuse_file_info *fi, int cmd, struct flock *lock);
|
||||
int fuse_fs_flock(struct fuse_fs *fs, const char *path,
|
||||
struct fuse_file_info *fi, int op);
|
||||
int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode);
|
||||
int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid);
|
||||
int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size);
|
||||
int fuse_fs_ftruncate(struct fuse_fs *fs, const char *path, off_t size,
|
||||
int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode,
|
||||
struct fuse_file_info *fi);
|
||||
int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid,
|
||||
struct fuse_file_info *fi);
|
||||
int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size,
|
||||
struct fuse_file_info *fi);
|
||||
int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
|
||||
const struct timespec tv[2]);
|
||||
const struct timespec tv[2], struct fuse_file_info *fi);
|
||||
int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask);
|
||||
int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
|
||||
size_t len);
|
||||
|
115
lib/fuse.c
115
lib/fuse.c
@ -1537,34 +1537,15 @@ static inline void fuse_prepare_interrupt(struct fuse *f, fuse_req_t req,
|
||||
fuse_do_prepare_interrupt(req, d);
|
||||
}
|
||||
|
||||
int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf)
|
||||
int fuse_fs_getattr(struct fuse_fs *fs, const char *path, struct stat *buf,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
fuse_get_context()->private_data = fs->user_data;
|
||||
if (fs->op.getattr) {
|
||||
if (fs->debug)
|
||||
fprintf(stderr, "getattr %s\n", path);
|
||||
|
||||
return fs->op.getattr(path, buf);
|
||||
} else {
|
||||
return -ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
int fuse_fs_fgetattr(struct fuse_fs *fs, const char *path, struct stat *buf,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
fuse_get_context()->private_data = fs->user_data;
|
||||
if (fs->op.fgetattr) {
|
||||
if (fs->debug)
|
||||
fprintf(stderr, "fgetattr[%llu] %s\n",
|
||||
fprintf(stderr, "getattr[%llu] %s\n",
|
||||
(unsigned long long) fi->fh, path);
|
||||
|
||||
return fs->op.fgetattr(path, buf, fi);
|
||||
} else if (path && fs->op.getattr) {
|
||||
if (fs->debug)
|
||||
fprintf(stderr, "getattr %s\n", path);
|
||||
|
||||
return fs->op.getattr(path, buf);
|
||||
return fs->op.getattr(path, buf, fi);
|
||||
} else {
|
||||
return -ENOSYS;
|
||||
}
|
||||
@ -2023,67 +2004,50 @@ int fuse_fs_flock(struct fuse_fs *fs, const char *path,
|
||||
}
|
||||
}
|
||||
|
||||
int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid)
|
||||
int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid,
|
||||
gid_t gid, struct fuse_file_info *fi)
|
||||
{
|
||||
fuse_get_context()->private_data = fs->user_data;
|
||||
if (fs->op.chown) {
|
||||
if (fs->debug)
|
||||
fprintf(stderr, "chown %s %lu %lu\n", path,
|
||||
fprintf(stderr, "chown[%llu] %s %lu %lu\n",
|
||||
(unsigned long long) fi->fh, path,
|
||||
(unsigned long) uid, (unsigned long) gid);
|
||||
|
||||
return fs->op.chown(path, uid, gid);
|
||||
return fs->op.chown(path, uid, gid, fi);
|
||||
} else {
|
||||
return -ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size)
|
||||
int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
fuse_get_context()->private_data = fs->user_data;
|
||||
if (fs->op.truncate) {
|
||||
if (fs->debug)
|
||||
fprintf(stderr, "truncate %s %llu\n", path,
|
||||
(unsigned long long) size);
|
||||
|
||||
return fs->op.truncate(path, size);
|
||||
} else {
|
||||
return -ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
int fuse_fs_ftruncate(struct fuse_fs *fs, const char *path, off_t size,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
fuse_get_context()->private_data = fs->user_data;
|
||||
if (fs->op.ftruncate) {
|
||||
if (fs->debug)
|
||||
fprintf(stderr, "ftruncate[%llu] %llu\n",
|
||||
fprintf(stderr, "truncate[%llu] %llu\n",
|
||||
(unsigned long long) fi->fh,
|
||||
(unsigned long long) size);
|
||||
|
||||
return fs->op.ftruncate(path, size, fi);
|
||||
} else if (path && fs->op.truncate) {
|
||||
if (fs->debug)
|
||||
fprintf(stderr, "truncate %s %llu\n", path,
|
||||
(unsigned long long) size);
|
||||
|
||||
return fs->op.truncate(path, size);
|
||||
return fs->op.truncate(path, size, fi);
|
||||
} else {
|
||||
return -ENOSYS;
|
||||
}
|
||||
}
|
||||
|
||||
int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
|
||||
const struct timespec tv[2])
|
||||
const struct timespec tv[2], struct fuse_file_info *fi)
|
||||
{
|
||||
fuse_get_context()->private_data = fs->user_data;
|
||||
if (fs->op.utimens) {
|
||||
if (fs->debug)
|
||||
fprintf(stderr, "utimens %s %li.%09lu %li.%09lu\n",
|
||||
path, tv[0].tv_sec, tv[0].tv_nsec,
|
||||
fprintf(stderr, "utimens[%llu] %s %li.%09lu %li.%09lu\n",
|
||||
(unsigned long long) fi->fh, path,
|
||||
tv[0].tv_sec, tv[0].tv_nsec,
|
||||
tv[1].tv_sec, tv[1].tv_nsec);
|
||||
|
||||
return fs->op.utimens(path, tv);
|
||||
return fs->op.utimens(path, tv, fi);
|
||||
} else {
|
||||
return -ENOSYS;
|
||||
}
|
||||
@ -2318,7 +2282,7 @@ static char *hidden_name(struct fuse *f, fuse_ino_t dir, const char *oldname,
|
||||
break;
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
res = fuse_fs_getattr(f->fs, newpath, &buf);
|
||||
res = fuse_fs_getattr(f->fs, newpath, &buf, NULL);
|
||||
if (res == -ENOENT)
|
||||
break;
|
||||
free(newpath);
|
||||
@ -2409,10 +2373,7 @@ static int lookup_path(struct fuse *f, fuse_ino_t nodeid,
|
||||
int res;
|
||||
|
||||
memset(e, 0, sizeof(struct fuse_entry_param));
|
||||
if (fi)
|
||||
res = fuse_fs_fgetattr(f->fs, path, &e->attr, fi);
|
||||
else
|
||||
res = fuse_fs_getattr(f->fs, path, &e->attr);
|
||||
res = fuse_fs_getattr(f->fs, path, &e->attr, fi);
|
||||
if (res == 0) {
|
||||
res = do_lookup(f, nodeid, name, e);
|
||||
if (res == 0 && f->conf.debug) {
|
||||
@ -2652,17 +2613,14 @@ static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
|
||||
if (fi != NULL && f->fs->op.fgetattr)
|
||||
if (fi != NULL)
|
||||
err = get_path_nullok(f, ino, &path);
|
||||
else
|
||||
err = get_path(f, ino, &path);
|
||||
if (!err) {
|
||||
struct fuse_intr_data d;
|
||||
fuse_prepare_interrupt(f, req, &d);
|
||||
if (fi)
|
||||
err = fuse_fs_fgetattr(f->fs, path, &buf, fi);
|
||||
else
|
||||
err = fuse_fs_getattr(f->fs, path, &buf);
|
||||
err = fuse_fs_getattr(f->fs, path, &buf, fi);
|
||||
fuse_finish_interrupt(f, req, &d);
|
||||
free_path(f, ino, path);
|
||||
}
|
||||
@ -2682,11 +2640,12 @@ static void fuse_lib_getattr(fuse_req_t req, fuse_ino_t ino,
|
||||
reply_err(req, err);
|
||||
}
|
||||
|
||||
int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode)
|
||||
int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
fuse_get_context()->private_data = fs->user_data;
|
||||
if (fs->op.chmod)
|
||||
return fs->op.chmod(path, mode);
|
||||
return fs->op.chmod(path, mode, fi);
|
||||
else
|
||||
return -ENOSYS;
|
||||
}
|
||||
@ -2700,8 +2659,7 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
|
||||
int err;
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
if (valid == FUSE_SET_ATTR_SIZE && fi != NULL &&
|
||||
f->fs->op.ftruncate && f->fs->op.fgetattr)
|
||||
if (fi != NULL)
|
||||
err = get_path_nullok(f, ino, &path);
|
||||
else
|
||||
err = get_path(f, ino, &path);
|
||||
@ -2710,21 +2668,17 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
|
||||
fuse_prepare_interrupt(f, req, &d);
|
||||
err = 0;
|
||||
if (!err && (valid & FUSE_SET_ATTR_MODE))
|
||||
err = fuse_fs_chmod(f->fs, path, attr->st_mode);
|
||||
err = fuse_fs_chmod(f->fs, path, attr->st_mode, fi);
|
||||
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 = fuse_fs_chown(f->fs, path, uid, gid);
|
||||
err = fuse_fs_chown(f->fs, path, uid, gid, fi);
|
||||
}
|
||||
if (!err && (valid & FUSE_SET_ATTR_SIZE)) {
|
||||
if (fi)
|
||||
err = fuse_fs_ftruncate(f->fs, path,
|
||||
attr->st_size, fi);
|
||||
else
|
||||
err = fuse_fs_truncate(f->fs, path,
|
||||
attr->st_size);
|
||||
attr->st_size, fi);
|
||||
}
|
||||
#ifdef HAVE_UTIMENSAT
|
||||
if (!err &&
|
||||
@ -2746,7 +2700,7 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
|
||||
else if (valid & FUSE_SET_ATTR_MTIME)
|
||||
tv[1] = attr->st_mtim;
|
||||
|
||||
err = fuse_fs_utimens(f->fs, path, tv);
|
||||
err = fuse_fs_utimens(f->fs, path, tv, fi);
|
||||
} else
|
||||
#endif
|
||||
if (!err &&
|
||||
@ -2757,13 +2711,10 @@ static void fuse_lib_setattr(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
|
||||
tv[0].tv_nsec = ST_ATIM_NSEC(attr);
|
||||
tv[1].tv_sec = attr->st_mtime;
|
||||
tv[1].tv_nsec = ST_MTIM_NSEC(attr);
|
||||
err = fuse_fs_utimens(f->fs, path, tv);
|
||||
err = fuse_fs_utimens(f->fs, path, tv, fi);
|
||||
}
|
||||
if (!err) {
|
||||
if (fi)
|
||||
err = fuse_fs_fgetattr(f->fs, path, &buf, fi);
|
||||
else
|
||||
err = fuse_fs_getattr(f->fs, path, &buf);
|
||||
err = fuse_fs_getattr(f->fs, path, &buf, fi);
|
||||
}
|
||||
fuse_finish_interrupt(f, req, &d);
|
||||
free_path(f, ino, path);
|
||||
@ -3116,7 +3067,7 @@ static void open_auto_cache(struct fuse *f, fuse_ino_t ino, const char *path,
|
||||
struct stat stbuf;
|
||||
int err;
|
||||
pthread_mutex_unlock(&f->lock);
|
||||
err = fuse_fs_fgetattr(f->fs, path, &stbuf, fi);
|
||||
err = fuse_fs_getattr(f->fs, path, &stbuf, fi);
|
||||
pthread_mutex_lock(&f->lock);
|
||||
if (!err)
|
||||
update_stat(node, &stbuf);
|
||||
|
@ -101,26 +101,14 @@ err:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int iconv_getattr(const char *path, struct stat *stbuf)
|
||||
{
|
||||
struct iconv *ic = iconv_get();
|
||||
char *newpath;
|
||||
int err = iconv_convpath(ic, path, &newpath, 0);
|
||||
if (!err) {
|
||||
err = fuse_fs_getattr(ic->next, newpath, stbuf);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int iconv_fgetattr(const char *path, struct stat *stbuf,
|
||||
static int iconv_getattr(const char *path, struct stat *stbuf,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct iconv *ic = iconv_get();
|
||||
char *newpath;
|
||||
int err = iconv_convpath(ic, path, &newpath, 0);
|
||||
if (!err) {
|
||||
err = fuse_fs_fgetattr(ic->next, newpath, stbuf, fi);
|
||||
err = fuse_fs_getattr(ic->next, newpath, stbuf, fi);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
@ -315,62 +303,53 @@ static int iconv_link(const char *from, const char *to)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int iconv_chmod(const char *path, mode_t mode)
|
||||
{
|
||||
struct iconv *ic = iconv_get();
|
||||
char *newpath;
|
||||
int err = iconv_convpath(ic, path, &newpath, 0);
|
||||
if (!err) {
|
||||
err = fuse_fs_chmod(ic->next, newpath, mode);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int iconv_chown(const char *path, uid_t uid, gid_t gid)
|
||||
{
|
||||
struct iconv *ic = iconv_get();
|
||||
char *newpath;
|
||||
int err = iconv_convpath(ic, path, &newpath, 0);
|
||||
if (!err) {
|
||||
err = fuse_fs_chown(ic->next, newpath, uid, gid);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int iconv_truncate(const char *path, off_t size)
|
||||
{
|
||||
struct iconv *ic = iconv_get();
|
||||
char *newpath;
|
||||
int err = iconv_convpath(ic, path, &newpath, 0);
|
||||
if (!err) {
|
||||
err = fuse_fs_truncate(ic->next, newpath, size);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int iconv_ftruncate(const char *path, off_t size,
|
||||
static int iconv_chmod(const char *path, mode_t mode,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct iconv *ic = iconv_get();
|
||||
char *newpath;
|
||||
int err = iconv_convpath(ic, path, &newpath, 0);
|
||||
if (!err) {
|
||||
err = fuse_fs_ftruncate(ic->next, newpath, size, fi);
|
||||
err = fuse_fs_chmod(ic->next, newpath, mode, fi);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int iconv_utimens(const char *path, const struct timespec ts[2])
|
||||
static int iconv_chown(const char *path, uid_t uid, gid_t gid,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct iconv *ic = iconv_get();
|
||||
char *newpath;
|
||||
int err = iconv_convpath(ic, path, &newpath, 0);
|
||||
if (!err) {
|
||||
err = fuse_fs_utimens(ic->next, newpath, ts);
|
||||
err = fuse_fs_chown(ic->next, newpath, uid, gid, fi);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int iconv_truncate(const char *path, off_t size,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct iconv *ic = iconv_get();
|
||||
char *newpath;
|
||||
int err = iconv_convpath(ic, path, &newpath, 0);
|
||||
if (!err) {
|
||||
err = fuse_fs_truncate(ic->next, newpath, size, fi);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int iconv_utimens(const char *path, const struct timespec ts[2],
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct iconv *ic = iconv_get();
|
||||
char *newpath;
|
||||
int err = iconv_convpath(ic, path, &newpath, 0);
|
||||
if (!err) {
|
||||
err = fuse_fs_utimens(ic->next, newpath, ts, fi);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
@ -600,7 +579,6 @@ static const struct fuse_operations iconv_oper = {
|
||||
.destroy = iconv_destroy,
|
||||
.init = iconv_init,
|
||||
.getattr = iconv_getattr,
|
||||
.fgetattr = iconv_fgetattr,
|
||||
.access = iconv_access,
|
||||
.readlink = iconv_readlink,
|
||||
.opendir = iconv_opendir,
|
||||
@ -616,7 +594,6 @@ static const struct fuse_operations iconv_oper = {
|
||||
.chmod = iconv_chmod,
|
||||
.chown = iconv_chown,
|
||||
.truncate = iconv_truncate,
|
||||
.ftruncate = iconv_ftruncate,
|
||||
.utimens = iconv_utimens,
|
||||
.create = iconv_create,
|
||||
.open = iconv_open_file,
|
||||
|
@ -52,26 +52,14 @@ static int subdir_addpath(struct subdir *d, const char *path, char **newpathp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int subdir_getattr(const char *path, struct stat *stbuf)
|
||||
{
|
||||
struct subdir *d = subdir_get();
|
||||
char *newpath;
|
||||
int err = subdir_addpath(d, path, &newpath);
|
||||
if (!err) {
|
||||
err = fuse_fs_getattr(d->next, newpath, stbuf);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int subdir_fgetattr(const char *path, struct stat *stbuf,
|
||||
static int subdir_getattr(const char *path, struct stat *stbuf,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct subdir *d = subdir_get();
|
||||
char *newpath;
|
||||
int err = subdir_addpath(d, path, &newpath);
|
||||
if (!err) {
|
||||
err = fuse_fs_fgetattr(d->next, newpath, stbuf, fi);
|
||||
err = fuse_fs_getattr(d->next, newpath, stbuf, fi);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
@ -301,62 +289,53 @@ static int subdir_link(const char *from, const char *to)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int subdir_chmod(const char *path, mode_t mode)
|
||||
{
|
||||
struct subdir *d = subdir_get();
|
||||
char *newpath;
|
||||
int err = subdir_addpath(d, path, &newpath);
|
||||
if (!err) {
|
||||
err = fuse_fs_chmod(d->next, newpath, mode);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int subdir_chown(const char *path, uid_t uid, gid_t gid)
|
||||
{
|
||||
struct subdir *d = subdir_get();
|
||||
char *newpath;
|
||||
int err = subdir_addpath(d, path, &newpath);
|
||||
if (!err) {
|
||||
err = fuse_fs_chown(d->next, newpath, uid, gid);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int subdir_truncate(const char *path, off_t size)
|
||||
{
|
||||
struct subdir *d = subdir_get();
|
||||
char *newpath;
|
||||
int err = subdir_addpath(d, path, &newpath);
|
||||
if (!err) {
|
||||
err = fuse_fs_truncate(d->next, newpath, size);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int subdir_ftruncate(const char *path, off_t size,
|
||||
static int subdir_chmod(const char *path, mode_t mode,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct subdir *d = subdir_get();
|
||||
char *newpath;
|
||||
int err = subdir_addpath(d, path, &newpath);
|
||||
if (!err) {
|
||||
err = fuse_fs_ftruncate(d->next, newpath, size, fi);
|
||||
err = fuse_fs_chmod(d->next, newpath, mode, fi);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int subdir_utimens(const char *path, const struct timespec ts[2])
|
||||
static int subdir_chown(const char *path, uid_t uid, gid_t gid,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct subdir *d = subdir_get();
|
||||
char *newpath;
|
||||
int err = subdir_addpath(d, path, &newpath);
|
||||
if (!err) {
|
||||
err = fuse_fs_utimens(d->next, newpath, ts);
|
||||
err = fuse_fs_chown(d->next, newpath, uid, gid, fi);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int subdir_truncate(const char *path, off_t size,
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct subdir *d = subdir_get();
|
||||
char *newpath;
|
||||
int err = subdir_addpath(d, path, &newpath);
|
||||
if (!err) {
|
||||
err = fuse_fs_truncate(d->next, newpath, size, fi);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
static int subdir_utimens(const char *path, const struct timespec ts[2],
|
||||
struct fuse_file_info *fi)
|
||||
{
|
||||
struct subdir *d = subdir_get();
|
||||
char *newpath;
|
||||
int err = subdir_addpath(d, path, &newpath);
|
||||
if (!err) {
|
||||
err = fuse_fs_utimens(d->next, newpath, ts, fi);
|
||||
free(newpath);
|
||||
}
|
||||
return err;
|
||||
@ -582,7 +561,6 @@ static const struct fuse_operations subdir_oper = {
|
||||
.destroy = subdir_destroy,
|
||||
.init = subdir_init,
|
||||
.getattr = subdir_getattr,
|
||||
.fgetattr = subdir_fgetattr,
|
||||
.access = subdir_access,
|
||||
.readlink = subdir_readlink,
|
||||
.opendir = subdir_opendir,
|
||||
@ -598,7 +576,6 @@ static const struct fuse_operations subdir_oper = {
|
||||
.chmod = subdir_chmod,
|
||||
.chown = subdir_chown,
|
||||
.truncate = subdir_truncate,
|
||||
.ftruncate = subdir_ftruncate,
|
||||
.utimens = subdir_utimens,
|
||||
.create = subdir_create,
|
||||
.open = subdir_open,
|
||||
|
Loading…
Reference in New Issue
Block a user