fixes
authorMiklos Szeredi <miklos@szeredi.hu>
Mon, 28 Feb 2005 11:46:56 +0000 (11:46 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Mon, 28 Feb 2005 11:46:56 +0000 (11:46 +0000)
ChangeLog
include/fuse.h
kernel/dir.c
kernel/file.c
kernel/inode.c
lib/Makefile.am
lib/fuse.c

index 7acdc08c68bcb7ba390294364b83482f5695c8eb..4622dbe4220703ee3897d41ded8a515c86af35de 100644 (file)
--- 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
index fffca2e97f29913ddbd71dc2f56073c0974f0f9d..5b9df10c63f700d3dd631d714fa0d871e7852b76 100644 (file)
@@ -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
index 7903a6675c89072509002a44032911a54682dd20..be513093a013591537fdfe34b689940ddd5b4d15 100644 (file)
@@ -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,
index 3adcb3055869c6d41f99e11225fafd35b93ccc95..74921d63864ff2a59eed2ba2bc42f4219b556f09 100644 (file)
@@ -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,
index 67bc755432e7d2ba875306a60a62d9c091a6f796..f702a4a1f8514d83d7661a66833b83c333ef3a3b 100644 (file)
@@ -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,
index 952dcd8ef678d0d60f843aefa9303994b693cfec..b344ef3eaaebbfb4b9906bffd83bdeb9116d5761 100644 (file)
@@ -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
index 72fd59a02ac894b591a0d1cd3add4630a3d73e13..64696b8c2ed4edf9d76af2e50942f5f1fe60c59f 100644 (file)
@@ -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));