statfs improvement

This commit is contained in:
Miklos Szeredi
2006-08-18 18:43:50 +00:00
parent 63d3c40e1f
commit 3ded1a3176
8 changed files with 63 additions and 14 deletions
+4
View File
@@ -4,6 +4,10 @@
initialization. Bug found and original patch from Alexander
Zarochentsev
* For linux kernels >=2.6.18 (2.6.19 if using the fuse module from
the kernel tree) the statfs method will receive the path within
the filesystem on which the stat(v)fs syscall was called.
2006-07-30 Miklos Szeredi <miklos@szeredi.hu>
* fusermount: if selinux is active, restore the original file's
+24 -3
View File
@@ -68,9 +68,9 @@ typedef int (*fuse_dirfil_t) (fuse_dirh_t h, const char *name, int type,
*
* All methods are optional, but some are essential for a useful
* filesystem (e.g. getattr). Open, flush, release, fsync, opendir,
* releasedir, fsyncdir, access, create, ftruncate, fgetattr, init and
* destroy are special purpose methods, without which a full featured
* filesystem can still be implemented.
* releasedir, fsyncdir, access, create, ftruncate, fgetattr, lock,
* init and destroy are special purpose methods, without which a full
* featured filesystem can still be implemented.
*/
struct fuse_operations {
/** Get file attributes.
@@ -363,6 +363,27 @@ struct fuse_operations {
*/
int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *);
/**
* Perform POSIX file locking operation
*
* The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW.
*
* For the meaning of fields in 'struct flock' see the man page
* for fcntl(2). The l_whence field will always be set to
* SEEK_SET.
*
* Unlike fcntl, the l_pid will be set in F_SETLK and F_SETLKW,
* and should be used by the filesystem to initialize this field
* in F_GETLK.
*
* For checking lock ownership, the 'owner' argument must be used.
*
* Note: if this method is not implemented, the kernel will still
* allow file locking to work locally. Hence it is only
* interesting for network filesystems and similar.
*
* Introduced in version 2.6
*/
int (*lock) (const char *, struct fuse_file_info *, int cmd,
struct flock *, uint64_t owner);
};
+6 -1
View File
@@ -600,8 +600,9 @@ struct fuse_lowlevel_ops {
* fuse_reply_err
*
* @param req request handle
* @param ino the inode number, zero means "undefined"
*/
void (*statfs) (fuse_req_t req);
void (*statfs) (fuse_req_t req, fuse_ino_t ino);
/**
* Set an extended attribute
@@ -754,6 +755,10 @@ struct fuse_lowlevel_ops {
* 'struct flock' should only be used to fill in this field in
* getlk().
*
* Note: if the locking methods are not implemented, the kernel
* will still allow file locking to work locally. Hence these are
* only interesting for network filesystems and similar.
*
* Valid replies:
* fuse_reply_err
*
+1
View File
@@ -9,3 +9,4 @@ config.*
*.s
.tmp_versions
.*.d
*.symvers
+3 -1
View File
@@ -76,8 +76,10 @@ if test "$ENABLE_FUSE_MODULE" = y; then
AC_MSG_RESULT([$kernelbuild])
AC_MSG_CHECKING([kernel source version])
if test -r $kernelbuild/include/linux/version.h; then
if test -r $kernelbuild/include/linux/version.h && fgrep -q UTS_RELEASE $kernelbuild/include/linux/version.h; then
kernsrcver=`(echo "#include <linux/version.h>"; echo "kernsrcver=UTS_RELEASE") | cpp -I $kernelbuild/include | grep "^kernsrcver=" | cut -d \" -f 2`
elif test -r $kernelbuild/include/linux/utsrelease.h && fgrep -q UTS_RELEASE $kernelbuild/include/linux/utsrelease.h; then
kernsrcver=`(echo "#include <linux/utsrelease.h>"; echo "kernsrcver=UTS_RELEASE") | cpp -I $kernelbuild/include | grep "^kernsrcver=" | cut -d \" -f 2`
fi
if test -z "$kernsrcver"; then
AC_MSG_RESULT([Not found])
+6 -1
View File
@@ -74,7 +74,12 @@ static struct dentry *fuse_ctl_add_dentry(struct dentry *parent,
const char *name,
int mode, int nlink,
struct inode_operations *iop,
struct file_operations *fop)
#ifdef KERNEL_2_6_17_PLUS
const struct file_operations *fop
#else
struct file_operations *fop
#endif
)
{
struct dentry *dentry;
struct inode *inode;
+18 -7
View File
@@ -108,7 +108,7 @@ static struct fuse_context *(*fuse_getcontext)(void) = NULL;
static int fuse_do_open(struct fuse *, char *, struct fuse_file_info *);
static void fuse_do_release(struct fuse *, char *, struct fuse_file_info *);
static int fuse_do_opendir(struct fuse *, char *, struct fuse_file_info *);
static int fuse_do_statfs(struct fuse *, char *, struct statvfs *);
static int fuse_do_statfs(struct fuse *, struct statvfs *);
#ifndef USE_UCLIBC
#define mutex_init(mut) pthread_mutex_init(mut, NULL)
@@ -1669,7 +1669,7 @@ static int default_statfs(struct statvfs *buf)
return 0;
}
static void fuse_statfs(fuse_req_t req)
static void fuse_statfs(fuse_req_t req, fuse_ino_t ino)
{
struct fuse *f = req_fuse_prepare(req);
struct statvfs buf;
@@ -1677,7 +1677,18 @@ static void fuse_statfs(fuse_req_t req)
memset(&buf, 0, sizeof(buf));
if (f->op.statfs) {
err = fuse_do_statfs(f, "/", &buf);
if (ino && (!f->compat || f->compat >= 26)) {
char *path;
pthread_rwlock_rdlock(&f->tree_lock);
err = -ENOENT;
path = get_path(f, ino);
if (path) {
err = f->op.statfs(path, &buf);
free(path);
}
pthread_rwlock_unlock(&f->tree_lock);
} else
err = fuse_do_statfs(f, &buf);
} else
err = default_statfs(&buf);
@@ -2294,12 +2305,12 @@ static void convert_statfs_old(struct statfs *oldbuf, struct statvfs *stbuf)
stbuf->f_namemax = oldbuf->f_namelen;
}
static int fuse_do_statfs(struct fuse *f, char *path, struct statvfs *buf)
static int fuse_do_statfs(struct fuse *f, struct statvfs *buf)
{
int err;
if (!f->compat || f->compat >= 25) {
err = f->op.statfs(path, buf);
err = f->op.statfs("/", buf);
} else if (f->compat > 11) {
struct statfs oldbuf;
err = ((struct fuse_operations_compat22 *) &f->op)->statfs("/", &oldbuf);
@@ -2386,9 +2397,9 @@ static int fuse_do_opendir(struct fuse *f, char *path,
return f->op.opendir(path, fi);
}
static int fuse_do_statfs(struct fuse *f, char *path, struct statvfs *buf)
static int fuse_do_statfs(struct fuse *f, struct statvfs *buf)
{
return f->op.statfs(path, buf);
return f->op.statfs("/", buf);
}
#endif /* __FreeBSD__ */
+1 -1
View File
@@ -719,7 +719,7 @@ static void do_statfs(fuse_req_t req, fuse_ino_t nodeid, const void *inarg)
(void) inarg;
if (req->f->op.statfs)
req->f->op.statfs(req);
req->f->op.statfs(req, nodeid);
else {
struct statvfs buf = {
.f_namemax = 255,