aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2005-02-28 11:46:56 +0000
committerMiklos Szeredi <miklos@szeredi.hu>2005-02-28 11:46:56 +0000
commitf43f06394ff53c2cb36a6843298fe36900cd902c (patch)
treeec83707d80bdc26ed5c82f7d492ffa77a3a08cc8
parent47c529838cde03fa23387f2bf91dfb5706a4470b (diff)
downloadlibfuse-f43f06394ff53c2cb36a6843298fe36900cd902c.tar.gz
fixes
-rw-r--r--ChangeLog11
-rw-r--r--include/fuse.h10
-rw-r--r--kernel/dir.c1
-rw-r--r--kernel/file.c1
-rw-r--r--kernel/inode.c22
-rw-r--r--lib/Makefile.am2
-rw-r--r--lib/fuse.c26
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 <miklos@szeredi.hu>
+
+ * 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 <miklos@szeredi.hu>
* 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));