From 52cb09d16ed7e233c35c0c33e72a952211a056b3 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 7 Nov 2005 11:59:00 +0000 Subject: [PATCH] fix up statfs interface --- ChangeLog | 6 ++++++ example/fusexmp.c | 5 ++--- example/fusexmp_fh.c | 5 ++--- include/fuse.h | 18 +++++++++++------ include/fuse_compat.h | 2 ++ include/fuse_lowlevel.h | 4 ++-- kernel/dir.c | 2 ++ kernel/fuse_i.h | 3 +++ lib/fuse.c | 45 +++++++++++++++++++++++++++-------------- lib/fuse_lowlevel.c | 6 +++--- 10 files changed, 64 insertions(+), 32 deletions(-) diff --git a/ChangeLog b/ChangeLog index c361a4e..17f24c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2005-11-06 Miklos Szeredi + + * Change ->statfs() method to use 'struct statvfs' instead of + 'struct statfs'. This makes the API more portable since statvfs() + is defined by POSIX. + 2005-10-28 Miklos Szeredi * Add fgetattr() method, which currently will only be called after diff --git a/example/fusexmp.c b/example/fusexmp.c index 1732556..5a2e9a0 100644 --- a/example/fusexmp.c +++ b/example/fusexmp.c @@ -20,7 +20,6 @@ #include #include #include -#include #ifdef HAVE_SETXATTR #include #endif @@ -258,11 +257,11 @@ static int xmp_write(const char *path, const char *buf, size_t size, return res; } -static int xmp_statfs(const char *path, struct statfs *stbuf) +static int xmp_statfs(const char *path, struct statvfs *stbuf) { int res; - res = statfs(path, stbuf); + res = statvfs(path, stbuf); if(res == -1) return -errno; diff --git a/example/fusexmp_fh.c b/example/fusexmp_fh.c index 764ba91..93bd843 100644 --- a/example/fusexmp_fh.c +++ b/example/fusexmp_fh.c @@ -17,7 +17,6 @@ #include #include #include -#include #ifdef HAVE_SETXATTR #include #endif @@ -293,11 +292,11 @@ static int xmp_write(const char *path, const char *buf, size_t size, return res; } -static int xmp_statfs(const char *path, struct statfs *stbuf) +static int xmp_statfs(const char *path, struct statvfs *stbuf) { int res; - res = statfs(path, stbuf); + res = statvfs(path, stbuf); if(res == -1) return -errno; diff --git a/include/fuse.h b/include/fuse.h index 329fd5e..831dbff 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -20,7 +20,7 @@ #include #include -#include +#include #include #ifdef __cplusplus @@ -162,11 +162,8 @@ struct fuse_operations { int (*write) (const char *, const char *, size_t, off_t, struct fuse_file_info *); - /** Get file system statistics - * - * The 'f_type' and 'f_fsid' fields are ignored - */ - int (*statfs) (const char *, struct statfs *); + /** Old statfs interface, deprecated */ + int (*statfs_old) (const char *, void *stbuf); /** Possibly flush cached data * @@ -352,6 +349,15 @@ struct fuse_operations { * Introduced in version 2.5 */ int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *); + + /** Get file system statistics + * + * The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored + * + * Replaced 'struct statfs' parameter with 'struct statvfs' in + * version 2.5 + */ + int (*statfs) (const char *, struct statvfs *stbuf); }; /** Extra context that may be needed by some filesystems diff --git a/include/fuse_compat.h b/include/fuse_compat.h index af7aecf..08d391a 100644 --- a/include/fuse_compat.h +++ b/include/fuse_compat.h @@ -9,6 +9,8 @@ /* these definitions provide source compatibility to prior versions. Do not include this file directly! */ +#include + typedef int (*fuse_dirfil_t_compat) (fuse_dirh_t h, const char *name, int type); struct fuse_operations_compat2 { int (*getattr) (const char *, struct stat *); diff --git a/include/fuse_lowlevel.h b/include/fuse_lowlevel.h index a027163..f90d021 100644 --- a/include/fuse_lowlevel.h +++ b/include/fuse_lowlevel.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #ifdef __cplusplus @@ -840,7 +840,7 @@ int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size); * @param stbuf filesystem statistics * @return zero for success, -errno for failure to send reply */ -int fuse_reply_statfs(fuse_req_t req, const struct statfs *stbuf); +int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf); /** * Reply with needed buffer size diff --git a/kernel/dir.c b/kernel/dir.c index 48df469..bfec288 100644 --- a/kernel/dir.c +++ b/kernel/dir.c @@ -659,9 +659,11 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) return err; } else { int mode = inode->i_mode; +#ifndef KERNEL_2_6_11_PLUS if ((mask & MAY_WRITE) && IS_RDONLY(inode) && (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) return -EROFS; +#endif if ((mask & MAY_EXEC) && !S_ISDIR(mode) && !(mode & S_IXUGO)) return -EACCES; diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h index dced449..fbebe7f 100644 --- a/kernel/fuse_i.h +++ b/kernel/fuse_i.h @@ -31,6 +31,9 @@ # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) # define KERNEL_2_6_10_PLUS # endif +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) +# define KERNEL_2_6_11_PLUS +# endif # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) # define KERNEL_2_6_12_PLUS # endif diff --git a/lib/fuse.c b/lib/fuse.c index 9cc7028..3557c3b 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -77,9 +77,9 @@ struct fuse { pthread_mutex_t lock; pthread_rwlock_t tree_lock; void *user_data; - uid_t uid; - gid_t gid; - mode_t umask; + unsigned int uid; + unsigned int gid; + unsigned int umask; double entry_timeout; double attr_timeout; }; @@ -1527,15 +1527,15 @@ static void fuse_fsyncdir(fuse_req_t req, fuse_ino_t ino, int datasync, reply_err(req, err); } -static int default_statfs(struct statfs *buf) +static int default_statfs(struct statvfs *buf) { - buf->f_namelen = 255; + buf->f_namemax = 255; buf->f_bsize = 512; return 0; } static void convert_statfs_compat(struct fuse_statfs_compat1 *compatbuf, - struct statfs *stbuf) + struct statvfs *stbuf) { stbuf->f_bsize = compatbuf->block_size; stbuf->f_blocks = compatbuf->blocks; @@ -1543,28 +1543,43 @@ static void convert_statfs_compat(struct fuse_statfs_compat1 *compatbuf, stbuf->f_bavail = compatbuf->blocks_free; stbuf->f_files = compatbuf->files; stbuf->f_ffree = compatbuf->files_free; - stbuf->f_namelen = compatbuf->namelen; + stbuf->f_namemax = compatbuf->namelen; +} + +static void convert_statfs_old(struct statfs *oldbuf, struct statvfs *stbuf) +{ + stbuf->f_bsize = oldbuf->f_bsize; + stbuf->f_blocks = oldbuf->f_blocks; + stbuf->f_bfree = oldbuf->f_bfree; + stbuf->f_bavail = oldbuf->f_bavail; + stbuf->f_files = oldbuf->f_files; + stbuf->f_ffree = oldbuf->f_ffree; + stbuf->f_namemax = oldbuf->f_namelen; } static void fuse_statfs(fuse_req_t req) { struct fuse *f = req_fuse_prepare(req); - struct statfs buf; + struct statvfs buf; int err; - memset(&buf, 0, sizeof(struct statfs)); + memset(&buf, 0, sizeof(buf)); if (f->op.statfs) { - if (!f->compat || f->compat > 11) - err = f->op.statfs("/", &buf); - else { + err = f->op.statfs("/", &buf); + } else if (f->op.statfs_old) { + if (!f->compat || f->compat > 11) { + struct statfs oldbuf; + err = f->op.statfs_old("/", &oldbuf); + if (!err) + convert_statfs_old(&oldbuf, &buf); + } else { struct fuse_statfs_compat1 compatbuf; memset(&compatbuf, 0, sizeof(struct fuse_statfs_compat1)); err = ((struct fuse_operations_compat1 *) &f->op)->statfs(&compatbuf); if (!err) convert_statfs_compat(&compatbuf, &buf); - } - } - else + } + } else err = default_statfs(&buf); if (!err) diff --git a/lib/fuse_lowlevel.c b/lib/fuse_lowlevel.c index b546312..9edef54 100644 --- a/lib/fuse_lowlevel.c +++ b/lib/fuse_lowlevel.c @@ -185,7 +185,7 @@ char *fuse_add_dirent(char *buf, const char *name, const struct stat *stbuf, return buf + entsize; } -static void convert_statfs(const struct statfs *stbuf, +static void convert_statfs(const struct statvfs *stbuf, struct fuse_kstatfs *kstatfs) { kstatfs->bsize = stbuf->f_bsize; @@ -194,7 +194,7 @@ static void convert_statfs(const struct statfs *stbuf, kstatfs->bavail = stbuf->f_bavail; kstatfs->files = stbuf->f_files; kstatfs->ffree = stbuf->f_ffree; - kstatfs->namelen = stbuf->f_namelen; + kstatfs->namelen = stbuf->f_namemax; } static int send_reply_ok(fuse_req_t req, const void *arg, size_t argsize) @@ -320,7 +320,7 @@ int fuse_reply_buf(fuse_req_t req, const char *buf, size_t size) return send_reply_ok(req, buf, size); } -int fuse_reply_statfs(fuse_req_t req, const struct statfs *stbuf) +int fuse_reply_statfs(fuse_req_t req, const struct statvfs *stbuf) { struct fuse_statfs_out arg; -- 2.30.2