From f43f06394ff53c2cb36a6843298fe36900cd902c Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Mon, 28 Feb 2005 11:46:56 +0000 Subject: [PATCH] fixes --- ChangeLog | 11 +++++++++++ include/fuse.h | 10 +++++++++- kernel/dir.c | 1 + kernel/file.c | 1 + kernel/inode.c | 22 +++++++++++++++------- lib/Makefile.am | 2 +- lib/fuse.c | 26 +++++++++++++++++--------- 7 files changed, 55 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7acdc08..4622dbe 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-02-28 Miklos Szeredi + + * libfuse: added opendir() operation. This can be used in case + permission checking in getdir() is too late. Thanks to Usarin + Heininga for pointing out this deficiency + + * kernel: llseek() method for files and directories made explicit + + * kernel: fixed inode leak in NFS export in case of nodeid + wrapping + 2005-02-15 Miklos Szeredi * libfuse: clean up some unitialized memory found with valgrind diff --git a/include/fuse.h b/include/fuse.h index fffca2e..5b9df10 100644 --- a/include/fuse.h +++ b/include/fuse.h @@ -24,7 +24,7 @@ #define FUSE_MAJOR_VERSION 2 /** Minor version of FUSE library interface */ -#define FUSE_MINOR_VERSION 2 +#define FUSE_MINOR_VERSION 3 /* This interface uses 64 bit off_t */ #if _FILE_OFFSET_BITS != 64 @@ -241,6 +241,14 @@ struct fuse_operations { /** Remove extended attributes */ int (*removexattr) (const char *, const char *); + + /** Open direcory + * + * This method should check if the open operation is permitted for + * this directory. The fuse_file_info parameter is currently + * unused. This method is optional. + */ + int (*opendir) (const char *, struct fuse_file_info *); }; /** Extra context that may be needed by some filesystems diff --git a/kernel/dir.c b/kernel/dir.c index 7903a66..be51309 100644 --- a/kernel/dir.c +++ b/kernel/dir.c @@ -1016,6 +1016,7 @@ static struct inode_operations fuse_dir_inode_operations = { }; static struct file_operations fuse_dir_operations = { + .llseek = generic_file_llseek, .read = generic_read_dir, .readdir = fuse_readdir, .open = fuse_dir_open, diff --git a/kernel/file.c b/kernel/file.c index 3adcb30..74921d6 100644 --- a/kernel/file.c +++ b/kernel/file.c @@ -641,6 +641,7 @@ static int fuse_set_page_dirty(struct page *page) #endif static struct file_operations fuse_file_operations = { + .llseek = generic_file_llseek, .read = fuse_file_read, .write = fuse_file_write, .mmap = fuse_file_mmap, diff --git a/kernel/inode.c b/kernel/inode.c index 67bc755..f702a4a 100644 --- a/kernel/inode.c +++ b/kernel/inode.c @@ -520,26 +520,34 @@ static struct inode *get_root_inode(struct super_block *sb, unsigned mode) #ifdef KERNEL_2_6 static struct dentry *fuse_get_dentry(struct super_block *sb, void *vobjp) { + int err; __u32 *objp = vobjp; unsigned long nodeid = objp[0]; __u32 generation = objp[1]; struct inode *inode; struct dentry *entry; + err = -ESTALE; if (nodeid == 0) - return ERR_PTR(-ESTALE); + goto error; inode = ilookup5(sb, nodeid, fuse_inode_eq, &nodeid); - if (!inode || inode->i_generation != generation) - return ERR_PTR(-ESTALE); + if (!inode) + goto error; + if (inode->i_generation != generation) + goto error_iput; + err = -ENOMEM; entry = d_alloc_anon(inode); - if (!entry) { - iput(inode); - return ERR_PTR(-ENOMEM); - } + if (!entry) + goto error_iput; return entry; + + error_iput: + iput(inode); + error: + return ERR_PTR(err); } static int fuse_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, diff --git a/lib/Makefile.am b/lib/Makefile.am index 952dcd8..b344ef3 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -9,7 +9,7 @@ libfuse_la_SOURCES = \ mount.c \ fuse_i.h -libfuse_la_LDFLAGS = -lpthread -version-number 2:2:0 \ +libfuse_la_LDFLAGS = -lpthread -version-number 2:3:0 \ -Wl,--version-script,fuse_versionscript EXTRA_DIST = fuse_versionscript diff --git a/lib/fuse.c b/lib/fuse.c index 72fd59a..64696b8 100644 --- a/lib/fuse.c +++ b/lib/fuse.c @@ -73,13 +73,6 @@ struct fuse_cmd { static struct fuse_context *(*fuse_getcontext)(void) = NULL; -/* Compatibility with kernel ABI version 5.1 */ -struct fuse_getdir_out { - __u32 fd; -}; - -#define FUSE_GETDIR 7 - static const char *opname(enum fuse_opcode opcode) { switch (opcode) { @@ -89,7 +82,6 @@ static const char *opname(enum fuse_opcode opcode) case FUSE_SETATTR: return "SETATTR"; case FUSE_READLINK: return "READLINK"; case FUSE_SYMLINK: return "SYMLINK"; - case FUSE_GETDIR: return "GETDIR"; case FUSE_MKNOD: return "MKNOD"; case FUSE_MKDIR: return "MKDIR"; case FUSE_UNLINK: return "UNLINK"; @@ -1523,7 +1515,23 @@ static void do_opendir(struct fuse *f, struct fuse_in_header *in, struct fuse_open_out outarg; struct fuse_dirhandle *dh; - (void) arg; + if (f->op.opendir) { + char *path; + res = -ENOENT; + path = get_path(f, in->nodeid); + if (path != NULL) { + struct fuse_file_info fi; + memset(&fi, 0, sizeof(fi)); + fi.flags = arg->flags; + res = f->op.opendir(path, &fi); + free(path); + } + if (res != 0) { + send_reply(f, in, res, NULL, 0); + return; + } + } + memset(&outarg, 0, sizeof(outarg)); res = -ENOMEM; dh = (struct fuse_dirhandle *) malloc(sizeof(struct fuse_dirhandle)); -- 2.30.2