From 85801bbad1b3f1160bd35608f30048faa8d94995 Mon Sep 17 00:00:00 2001 From: Mark Glines Date: Sun, 17 Mar 2002 06:58:33 +0000 Subject: [PATCH] 'struct statfs' changes size, and entries within it change position, depending on which headerfiles are included and which macros are defined. Because its unreliable, we now use struct fuse_statfs everywhere except in the kernel. Also fixed some perl fuse_main semantics - it now works much better when multithreading is disabled. --- example/fusexmp.c | 12 ++++++++--- example/null.c | 6 +++--- include/fuse.h | 4 ++-- include/fusestat.h | 14 ++++++++++++ include/linux/fuse.h | 10 +-------- lib/fuse.c | 15 +------------ perl/Fuse.xs | 16 ++++++++------ perl/loopback.pl | 51 ++++++++++++++++++++++++++++++++------------ 8 files changed, 76 insertions(+), 52 deletions(-) create mode 100644 include/fusestat.h diff --git a/example/fusexmp.c b/example/fusexmp.c index f237667..8b48af6 100644 --- a/example/fusexmp.c +++ b/example/fusexmp.c @@ -233,12 +233,18 @@ static int xmp_write(const char *path, const char *buf, size_t size, return res; } -static int xmp_statfs(struct statfs *fst) +static int xmp_statfs(struct fuse_statfs *fst) { struct statfs st; int rv = statfs("/",&st); - if(!rv) - memcpy(fst,&st,sizeof(st)); + if(!rv) { + fst->block_size = st.f_bsize; + fst->blocks = st.f_blocks; + fst->blocks_free = st.f_bavail; + fst->files = st.f_files; + fst->files_free = st.f_ffree; + fst->namelen = st.f_namelen; + } return rv; } diff --git a/example/null.c b/example/null.c index 3a948f2..6b2c1b6 100644 --- a/example/null.c +++ b/example/null.c @@ -64,10 +64,10 @@ static int null_write(const char *path, const char *UNUSED(buf), size_t size, return size; } -static int null_statfs(struct statfs *st) +static int null_statfs(struct fuse_statfs *st) { - return st->f_blocks = st->f_bavail = st->f_bsize = st->f_files = - st->f_ffree = st->f_namelen = 0; + return st->block_size = st->blocks = st->blocks_free = st->files = + st->files_free = st->namelen = 0; } static struct fuse_operations null_oper = { diff --git a/include/fuse.h b/include/fuse.h index 46fc87b..451e163 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -13,9 +13,9 @@ #include #include -#include #include +#include "fusestat.h" /* ----------------------------------------------------------- * * Basic FUSE API * * ----------------------------------------------------------- */ @@ -82,7 +82,7 @@ struct fuse_operations { int (*open) (const char *, int); int (*read) (const char *, char *, size_t, off_t); int (*write) (const char *, const char *, size_t, off_t); - int (*statfs) (struct statfs *); + int (*statfs) (struct fuse_statfs *); }; /** Extra context that may be needed by some filesystems */ diff --git a/include/fusestat.h b/include/fusestat.h new file mode 100644 index 0000000..a18509c --- /dev/null +++ b/include/fusestat.h @@ -0,0 +1,14 @@ +#ifndef __FUSESTAT_H_ +#define __FUSESTAT_H_ +/* this is seperated out into its own file because both + * kernel and lib use it, but neither can #include the + * other's headerfile */ +typedef struct fuse_statfs { + long block_size; + long blocks; + long blocks_free; + long files; + long files_free; + long namelen; +} fuse_statfs_t; +#endif diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 40f3950..539ebce 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -8,6 +8,7 @@ /* This file defines the kernel interface of FUSE */ +#include "fusestat.h" /** Version number of this interface */ #define FUSE_KERNEL_VERSION 2 @@ -157,15 +158,6 @@ struct fuse_write_in { char buf[0]; }; -typedef struct fuse_statfs { - long block_size; - long blocks; - long blocks_free; - long files; - long files_free; - long namelen; -} fuse_statfs_t; - struct fuse_statfs_out { struct fuse_statfs st; }; diff --git a/lib/fuse.c b/lib/fuse.c index 63dadf5..2ac7386 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -306,16 +306,6 @@ static void convert_stat(struct stat *stbuf, struct fuse_attr *attr) attr->_dummy = 4096; } -static void convert_statfs(struct statfs *st, struct fuse_statfs *fst) -{ - fst->block_size = st->f_bsize; - fst->blocks = st->f_blocks; - fst->blocks_free = st->f_bavail; - fst->files = st->f_files; - fst->files_free = st->f_ffree; - fst->namelen = st->f_namelen; -} - static int fill_dir(struct fuse_dirhandle *dh, char *name, int type) { struct fuse_dirent dirent; @@ -806,14 +796,11 @@ static void do_write(struct fuse *f, struct fuse_in_header *in, static void do_statfs(struct fuse *f, struct fuse_in_header *in) { int res; - struct statfs sbuf; struct fuse_statfs_out arg; res = -ENOSYS; if(f->op.statfs) - res = f->op.statfs(&sbuf); - if(res == 0) - convert_statfs(&sbuf,&arg.st); + res = f->op.statfs(&arg.st); send_reply(f, in, res, &arg, sizeof(arg)); } diff --git a/perl/Fuse.xs b/perl/Fuse.xs index f197449..6e8a5c6 100644 --- a/perl/Fuse.xs +++ b/perl/Fuse.xs @@ -32,6 +32,7 @@ int _PLfuse_getattr(const char *file, struct stat *result) { else rv = -ENOENT; } else { + DEBUGf("populating\n"); result->st_blocks = POPi; result->st_blksize = POPi; result->st_ctime = POPi; @@ -50,6 +51,7 @@ int _PLfuse_getattr(const char *file, struct stat *result) { FREETMPS; LEAVE; PUTBACK; + DEBUGf("getattr end %i %o\n",rv,result->st_mode); return rv; } @@ -473,7 +475,7 @@ int _PLfuse_write (const char *file, const char *buf, size_t buflen, off_t off) return rv; } -int _PLfuse_statfs (struct statfs *st) { +int _PLfuse_statfs (struct fuse_statfs *st) { int rv; char *rvstr; dSP; @@ -485,12 +487,12 @@ int _PLfuse_statfs (struct statfs *st) { rv = call_sv(_PLfuse_callbacks[17],G_ARRAY); SPAGAIN; if(rv > 5) { - st->f_bsize = POPi; - st->f_bavail = st->f_bfree = POPi; - st->f_blocks = POPi; - st->f_ffree = POPi; - st->f_files = POPi; - st->f_namelen = POPi; + st->block_size = POPi; + st->blocks_free = POPi; + st->blocks = POPi; + st->files_free = POPi; + st->files = POPi; + st->namelen = POPi; if(rv > 6) rv = POPi; else diff --git a/perl/loopback.pl b/perl/loopback.pl index c055db5..e58d90a 100644 --- a/perl/loopback.pl +++ b/perl/loopback.pl @@ -14,8 +14,9 @@ sub fixup { return "/tmp/test" . shift } sub x_getattr { my ($file) = fixup(shift); - return -ENOENT() unless -e $file; - return (lstat($file)); + my (@list) = lstat($file); + return -$! unless @list; + return @list; } sub x_getdir { @@ -53,7 +54,7 @@ sub x_read { sub x_write { my ($file,$buf,$off) = @_; - debug("write",@_); + debug("write",$file,length($buf),$off); my ($rv); return -ENOENT() unless -e ($file = fixup($file)); return -ENOSYS() unless sysopen(FILE,$file,O_RDWR()|O_APPEND()|O_CREAT()); @@ -67,16 +68,36 @@ sub x_write { sub err { return (-shift || -$!) } sub x_readlink { return readlink(fixup(shift) ); } -sub x_unlink { return unlink(fixup(shift)) ? 0 : -$!; } -sub x_rmdir { return err(rmdir(fixup(shift)) ); } -sub x_symlink { return err(symlink(fixup(shift),fixup(shift))); } -sub x_rename { return err(rename(fixup(shift),fixup(shift)) ); } -sub x_link { return err(link(fixup(shift),fixup(shift)) ); } -sub x_chmod { return err(chmod(fixup(shift),shift) ); } -sub x_chown { return err(chown(fixup(shift),shift,shift) ); } -sub x_chmod { return err(chmod(fixup(shift),shift) ); } +sub x_unlink { return unlink(fixup(shift)) ? 0 : -$!; } +sub x_rmdir { return err(rmdir(fixup(shift)) ); } +sub x_symlink { return err(symlink(fixup(shift),fixup(shift))); } +sub x_rename { + debug("rename",@_); + my ($old) = fixup(shift); + my ($new) = fixup(shift); + my ($err) = rename($old,$new) ? 0 : -ENOENT(); + debug("old=$old,new=$new,err=$err"); + return $err; +} +sub x_link { return err(link(fixup(shift),fixup(shift)) ); } +sub x_chown { + debug("chown",@_); + my ($fn) = fixup(shift); + my ($uid,$gid) = @_; + my ($err) = chown($uid,$gid,$fn) ? 0 : -$!; + debug("fn=$fn,uid=$uid,gid=$gid,err=$err"); + return $err; +} +sub x_chmod { + debug("chmod",@_); + my ($fn) = fixup(shift); + my ($mode) = shift; + my ($err) = chmod($mode,$fn) ? 0 : -$!; + debug("fn=$fn,mode=$mode,err=$err"); + return $err; +} sub x_truncate { return truncate(fixup(shift),shift) ? 0 : -$! ; } -sub x_utime { return utime($_[1],$_[2],fixup($_[0])) ? 0:-$!; } +sub x_utime { return utime($_[1],$_[2],fixup($_[0])) ? 0:-$!; } sub x_mkdir { my ($name, $perm) = @_; return 0 if mkdir(fixup($name),$perm); return -$!; } sub x_rmdir { return 0 if rmdir fixup(shift); return -$!; } @@ -102,11 +123,12 @@ sub x_mknod { } } +# kludge +sub x_statfs {return 255,1000000,500000,1000000,500000,4096} my ($mountpoint) = ""; $mountpoint = shift(@ARGV) if @ARGV; Fuse::main( unthreaded=>1, - debug=>1, mountpoint=>$mountpoint, getattr=>\&x_getattr, readlink=>\&x_readlink, @@ -124,5 +146,6 @@ Fuse::main( utime=>\&x_utime, open=>\&x_open, read=>\&x_read, - write=>\&x_write + write=>\&x_write, + statfs=>\&x_statfs ); -- 2.30.2