From: Miklos Szeredi Date: Tue, 2 Mar 2004 11:11:24 +0000 (+0000) Subject: kernel interface changes X-Git-Tag: fuse_1_9~83 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=254d5edabb677d1ad3d4c1423b26a5337657f0e7;p=qemu-gpiodev%2Flibfuse.git kernel interface changes --- diff --git a/ChangeLog b/ChangeLog index f2325b9..051ab94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2004-03-02 Miklos Szeredi + + * More kernel interface changes: + + * Lookup/getattr return cache timeout values + 2004-02-25 Miklos Szeredi * Clean up option parsing in fuse_main() diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 834c1be..d5fd357 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -119,9 +119,14 @@ enum fuse_opcode { /* Conservative buffer size for the client */ #define FUSE_MAX_IN 8192 -struct fuse_lookup_out { - unsigned long ino; - unsigned long generation; +struct fuse_entry_out { + unsigned long ino; /* Inode number */ + unsigned long generation; /* Inode generation: ino:gen must + be unique for the fs's lifetime */ + unsigned long entry_valid; /* Cache timeout for the name */ + unsigned long entry_valid_nsec; + unsigned long attr_valid; /* Cache timeout for the attributes */ + unsigned long attr_valid_nsec; struct fuse_attr attr; }; @@ -129,13 +134,14 @@ struct fuse_forget_in { int version; }; -struct fuse_getattr_out { +struct fuse_attr_out { + unsigned long attr_valid; /* Cache timeout for the attributes */ + unsigned long attr_valid_nsec; struct fuse_attr attr; }; struct fuse_getdir_out { int fd; - void *file; /* Used by kernel only */ }; struct fuse_mknod_in { @@ -160,10 +166,6 @@ struct fuse_setattr_in { unsigned int valid; }; -struct fuse_setattr_out { - struct fuse_attr attr; -}; - struct fuse_open_in { unsigned int flags; }; diff --git a/kernel/dev.c b/kernel/dev.c index 43af356..f0733d0 100644 --- a/kernel/dev.c +++ b/kernel/dev.c @@ -334,8 +334,8 @@ static struct fuse_req *request_find(struct fuse_conn *fc, unsigned int unique) static void process_getdir(struct fuse_req *req) { - struct fuse_getdir_out *arg; - arg = (struct fuse_getdir_out *) req->out->args[0].value; + struct fuse_getdir_out_i *arg; + arg = (struct fuse_getdir_out_i *) req->out->args[0].value; arg->file = fget(arg->fd); } diff --git a/kernel/dir.c b/kernel/dir.c index c5810e9..4051d07 100644 --- a/kernel/dir.c +++ b/kernel/dir.c @@ -20,9 +20,6 @@ static struct file_operations fuse_dir_operations; static struct dentry_operations fuse_dentry_operations; -/* FIXME: This should be user configurable */ -#define FUSE_REVALIDATE_TIME (1 * HZ) - #ifndef KERNEL_2_6 #define new_decode_dev(x) (x) #define new_encode_dev(x) (x) @@ -106,7 +103,7 @@ struct inode *fuse_iget(struct super_block *sb, ino_t ino, int generation, } static int fuse_do_lookup(struct inode *dir, struct dentry *entry, - struct fuse_lookup_out *outarg, int *version) + struct fuse_entry_out *outarg, int *version) { struct fuse_conn *fc = INO_FC(dir); struct fuse_in in = FUSE_IN_INIT; @@ -118,7 +115,7 @@ static int fuse_do_lookup(struct inode *dir, struct dentry *entry, in.args[0].size = entry->d_name.len + 1; in.args[0].value = entry->d_name.name; out.numargs = 1; - out.args[0].size = sizeof(struct fuse_lookup_out); + out.args[0].size = sizeof(struct fuse_entry_out); out.args[0].value = outarg; request_send(fc, &in, &out); @@ -126,11 +123,21 @@ static int fuse_do_lookup(struct inode *dir, struct dentry *entry, return out.h.error; } +static inline unsigned long time_to_jiffies(unsigned long sec, + unsigned long nsec) +{ + /* prevent wrapping of jiffies */ + if(sec + 1 >= LONG_MAX / HZ) + return 0; + + return jiffies + sec * HZ + nsec / (1000000000 / HZ); +} + static int fuse_lookup_iget(struct inode *dir, struct dentry *entry, struct inode **inodep) { int err; - struct fuse_lookup_out outarg; + struct fuse_entry_out outarg; int version; struct inode *inode = NULL; @@ -143,14 +150,15 @@ static int fuse_lookup_iget(struct inode *dir, struct dentry *entry, } else if(err != -ENOENT) return err; - entry->d_time = jiffies; + entry->d_time = time_to_jiffies(outarg.entry_valid, + outarg.entry_valid_nsec); entry->d_op = &fuse_dentry_operations; *inodep = inode; return 0; } static int lookup_new_entry(struct inode *dir, struct dentry *entry, - struct fuse_lookup_out *outarg, int version, + struct fuse_entry_out *outarg, int version, int mode) { struct inode *inode; @@ -178,7 +186,7 @@ static int _fuse_mknod(struct inode *dir, struct dentry *entry, int mode, struct fuse_in in = FUSE_IN_INIT; struct fuse_out out = FUSE_OUT_INIT; struct fuse_mknod_in inarg; - struct fuse_lookup_out outarg; + struct fuse_entry_out outarg; memset(&inarg, 0, sizeof(inarg)); inarg.mode = mode; @@ -214,7 +222,7 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, int mode) struct fuse_in in = FUSE_IN_INIT; struct fuse_out out = FUSE_OUT_INIT; struct fuse_mkdir_in inarg; - struct fuse_lookup_out outarg; + struct fuse_entry_out outarg; memset(&inarg, 0, sizeof(inarg)); inarg.mode = mode; @@ -242,7 +250,7 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry, struct fuse_conn *fc = INO_FC(dir); struct fuse_in in = FUSE_IN_INIT; struct fuse_out out = FUSE_OUT_INIT; - struct fuse_lookup_out outarg; + struct fuse_entry_out outarg; in.h.opcode = FUSE_SYMLINK; in.h.ino = dir->i_ino; @@ -336,7 +344,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, struct fuse_in in = FUSE_IN_INIT; struct fuse_out out = FUSE_OUT_INIT; struct fuse_link_in inarg; - struct fuse_lookup_out outarg; + struct fuse_entry_out outarg; memset(&inarg, 0, sizeof(inarg)); inarg.newdir = newdir->i_ino; @@ -366,7 +374,7 @@ int fuse_do_getattr(struct inode *inode) struct fuse_conn *fc = INO_FC(inode); struct fuse_in in = FUSE_IN_INIT; struct fuse_out out = FUSE_OUT_INIT; - struct fuse_getattr_out arg; + struct fuse_attr_out arg; in.h.opcode = FUSE_GETATTR; in.h.ino = inode->i_ino; @@ -390,7 +398,7 @@ static int fuse_revalidate(struct dentry *entry) if(!(fc->flags & FUSE_ALLOW_OTHER) && current->fsuid != fc->uid) return -EACCES; - } else if(time_before_eq(jiffies, entry->d_time + FUSE_REVALIDATE_TIME)) + } else if(!entry->d_time || time_before_eq(jiffies, entry->d_time)) return 0; return fuse_do_getattr(inode); @@ -541,12 +549,12 @@ static int fuse_dir_open(struct inode *inode, struct file *file) struct fuse_conn *fc = INO_FC(inode); struct fuse_in in = FUSE_IN_INIT; struct fuse_out out = FUSE_OUT_INIT; - struct fuse_getdir_out outarg; + struct fuse_getdir_out_i outarg; in.h.opcode = FUSE_GETDIR; in.h.ino = inode->i_ino; out.numargs = 1; - out.args[0].size = sizeof(outarg); + out.args[0].size = sizeof(struct fuse_getdir_out); out.args[0].value = &outarg; request_send(fc, &in, &out); if(!out.h.error) { @@ -617,7 +625,7 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr) struct fuse_in in = FUSE_IN_INIT; struct fuse_out out = FUSE_OUT_INIT; struct fuse_setattr_in inarg; - struct fuse_setattr_out outarg; + struct fuse_attr_out outarg; memset(&inarg, 0, sizeof(inarg)); inarg.valid = iattr_to_fattr(attr, &inarg.attr); @@ -646,9 +654,9 @@ static int _fuse_dentry_revalidate(struct dentry *entry) { if(!entry->d_inode) return 0; - else if(time_after(jiffies, entry->d_time + FUSE_REVALIDATE_TIME)) { + else if(entry->d_time && time_after(jiffies, entry->d_time)) { struct inode *inode = entry->d_inode; - struct fuse_lookup_out outarg; + struct fuse_entry_out outarg; int version; int ret; @@ -662,7 +670,8 @@ static int _fuse_dentry_revalidate(struct dentry *entry) change_attributes(inode, &outarg.attr); inode->i_version = version; - entry->d_time = jiffies; + entry->d_time = time_to_jiffies(outarg.entry_valid, + outarg.entry_valid_nsec); } return 1; } diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h index 48e52c9..2443efe 100644 --- a/kernel/fuse_i.h +++ b/kernel/fuse_i.h @@ -151,6 +151,11 @@ struct fuse_req { void *data; }; +struct fuse_getdir_out_i { + int fd; + void *file; /* Used by kernel only */ +}; + #ifdef KERNEL_2_6 #define SB_FC(sb) ((struct fuse_conn *) (sb)->s_fs_info) #else diff --git a/lib/fuse.c b/lib/fuse.c index 9d0783d..27e331a 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -19,6 +19,9 @@ #define FUSE_MAX_PATH 4096 #define PARAM(inarg) (((char *)(inarg)) + sizeof(*inarg)) +#define ENTRY_REVALIDATE_TIME 1 /* sec */ +#define ATTR_REVALIDATE_TIME 1 /* sec */ + static const char *opname(enum fuse_opcode opcode) { switch(opcode) { @@ -407,7 +410,7 @@ static int send_reply(struct fuse *f, struct fuse_in_header *in, int error, } static int lookup_path(struct fuse *f, fino_t ino, int version, char *name, - const char *path, struct fuse_lookup_out *arg) + const char *path, struct fuse_entry_out *arg) { int res; struct stat buf; @@ -416,11 +419,15 @@ static int lookup_path(struct fuse *f, fino_t ino, int version, char *name, if(res == 0) { struct node *node; - memset(arg, 0, sizeof(struct fuse_lookup_out)); + memset(arg, 0, sizeof(struct fuse_entry_out)); convert_stat(&buf, &arg->attr); node = find_node(f, ino, name, &arg->attr, version); arg->ino = node->ino; arg->generation = node->generation; + arg->entry_valid = ENTRY_REVALIDATE_TIME; + arg->entry_valid_nsec = 0; + arg->attr_valid = ATTR_REVALIDATE_TIME; + arg->attr_valid_nsec = 0; if(f->flags & FUSE_DEBUG) { printf(" INO: %li\n", arg->ino); fflush(stdout); @@ -433,7 +440,7 @@ static void do_lookup(struct fuse *f, struct fuse_in_header *in, char *name) { int res; char *path; - struct fuse_lookup_out arg; + struct fuse_entry_out arg; res = -ENOENT; path = get_path_name(f, in->ino, name); @@ -465,7 +472,7 @@ static void do_getattr(struct fuse *f, struct fuse_in_header *in) int res; char *path; struct stat buf; - struct fuse_getattr_out arg; + struct fuse_attr_out arg; res = -ENOENT; path = get_path(f, in->ino); @@ -477,7 +484,9 @@ static void do_getattr(struct fuse *f, struct fuse_in_header *in) } if(res == 0) { - memset(&arg, 0, sizeof(struct fuse_getattr_out)); + memset(&arg, 0, sizeof(struct fuse_attr_out)); + arg.attr_valid = ATTR_REVALIDATE_TIME; + arg.attr_valid_nsec = 0; convert_stat(&buf, &arg.attr); } @@ -541,7 +550,7 @@ static void do_setattr(struct fuse *f, struct fuse_in_header *in, char *path; int valid = arg->valid; struct fuse_attr *attr = &arg->attr; - struct fuse_setattr_out outarg; + struct fuse_attr_out outarg; res = -ENOENT; path = get_path(f, in->ino); @@ -562,7 +571,9 @@ static void do_setattr(struct fuse *f, struct fuse_in_header *in, struct stat buf; res = f->op.getattr(path, &buf); if(!res) { - memset(&outarg, 0, sizeof(struct fuse_setattr_out)); + memset(&outarg, 0, sizeof(struct fuse_attr_out)); + outarg.attr_valid = ATTR_REVALIDATE_TIME; + outarg.attr_valid_nsec = 0; convert_stat(&buf, &outarg.attr); } } @@ -622,7 +633,7 @@ static void do_mknod(struct fuse *f, struct fuse_in_header *in, int res; char *path; char *name = PARAM(inarg); - struct fuse_lookup_out outarg; + struct fuse_entry_out outarg; res = -ENOENT; path = get_path_name(f, in->ino, name); @@ -648,7 +659,7 @@ static void do_mkdir(struct fuse *f, struct fuse_in_header *in, int res; char *path; char *name = PARAM(inarg); - struct fuse_lookup_out outarg; + struct fuse_entry_out outarg; res = -ENOENT; path = get_path_name(f, in->ino, name); @@ -711,7 +722,7 @@ static void do_symlink(struct fuse *f, struct fuse_in_header *in, char *name, { int res; char *path; - struct fuse_lookup_out outarg; + struct fuse_entry_out outarg; res = -ENOENT; path = get_path_name(f, in->ino, name); @@ -766,7 +777,7 @@ static void do_link(struct fuse *f, struct fuse_in_header *in, char *oldpath; char *newpath; char *name = PARAM(arg); - struct fuse_lookup_out outarg; + struct fuse_entry_out outarg; res = -ENOENT; oldpath = get_path(f, in->ino);