fix
authorMiklos Szeredi <miklos@szeredi.hu>
Fri, 28 Oct 2005 13:09:50 +0000 (13:09 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Fri, 28 Oct 2005 13:09:50 +0000 (13:09 +0000)
ChangeLog
README
example/fusexmp_fh.c
include/fuse.h
kernel/configure.ac
lib/fuse.c

index c6dfda43933ea509c758846012701c588038c09f..c361a4e7aadad1ad6a2f26bd21c9916bce6391fc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2005-10-28  Miklos Szeredi <miklos@szeredi.hu>
+
+       * Add fgetattr() method, which currently will only be called after
+       a successful call to a create() method.
+
 2005-10-26  Miklos Szeredi <miklos@szeredi.hu>
 
        * Change kernel ABI version to 7.3
diff --git a/README b/README
index a37044ac6fc978b9b4e681e668cb11e4a1eaed27..4c5517aa7827c72656da606bf23b73a9e9f690c4 100644 (file)
--- a/README
+++ b/README
@@ -41,6 +41,21 @@ FUSE support is detected, the kernel module in this package will not
 be compiled.  It is possible to override this with the
 '--enable-kernel-module' configure option.
 
+If './configure' cannot find the kernel source or it says the kernel
+source should be prepared, you may either try
+
+  ./configure--disable-kernel-module
+
+or if your kernel does not already contain FUSE support, do the
+following:
+
+  - Extract the kernel source to some directory
+
+  - Copy the running kernel's config (usually found in
+    /boot/config-X.Y.Z) to .config at the top of the source tree
+
+  - Run 'make prepare'
+
 For more details see the file 'INSTALL'
 
 How To Use
index 2f4b1875512fe795a2efd64bfc64fb3e257c1bb4..764ba914f21849232f2388cda1fe3f89838720d5 100644 (file)
@@ -33,6 +33,20 @@ static int xmp_getattr(const char *path, struct stat *stbuf)
     return 0;
 }
 
+static int xmp_fgetattr(const char *path, struct stat *stbuf,
+                        struct fuse_file_info *fi)
+{
+    int res;
+
+    (void) path;
+
+    res = fstat(fi->fh, stbuf);
+    if(res == -1)
+        return -errno;
+
+    return 0;
+}
+
 static int xmp_access(const char *path, int mask)
 {
     int res;
@@ -353,6 +367,7 @@ static int xmp_removexattr(const char *path, const char *name)
 
 static struct fuse_operations xmp_oper = {
     .getattr   = xmp_getattr,
+    .fgetattr  = xmp_fgetattr,
     .access    = xmp_access,
     .readlink  = xmp_readlink,
     .opendir   = xmp_opendir,
index 6d7e54b432c49281a418c8eaa55b15f81ebac482..329fd5eed27281f411611bd459b052b5677822a9 100644 (file)
@@ -63,8 +63,8 @@ typedef int (*fuse_dirfil_t) (fuse_dirh_t h, const char *name, int type,
  *
  * All methods are optional, but some are essential for a useful
  * filesystem (e.g. getattr).  Open, flush, release, fsync, opendir,
- * releasedir, fsyncdir, access, create, ftruncate, init and destroy
- * are special purpose methods, without which a full featured
+ * releasedir, fsyncdir, access, create, ftruncate, fgetattr, init and
+ * destroy are special purpose methods, without which a full featured
  * filesystem can still be implemented.
  */
 struct fuse_operations {
@@ -338,6 +338,20 @@ struct fuse_operations {
      * Introduced in version 2.5
      */
     int (*ftruncate) (const char *, off_t, struct fuse_file_info *);
+
+    /**
+     * Get attributes from an open file
+     *
+     * This method is called instead of the getattr() method if the
+     * file information is available.
+     *
+     * Currently this is only called after the create() method if that
+     * is implemented (see above).  Later it may be called for
+     * invocations of fstat() too.
+     *
+     * Introduced in version 2.5
+     */
+    int (*fgetattr) (const char *, struct stat *, struct fuse_file_info *);
 };
 
 /** Extra context that may be needed by some filesystems
index 41ebafc2478400fc351e03b6b5d1e3572437933a..40f0725ef3819ef6c3ecd63cf1374f3d82e05bc9 100644 (file)
@@ -50,7 +50,7 @@ if test -z "$kernsrcver"; then
        AC_MSG_RESULT([Not found])
        AC_MSG_ERROR([
 *** Cannot determine the version of the linux kernel source. Please
-*** configure the kernel before running this script])
+*** prepare the kernel before running this script])
 fi
 AC_MSG_RESULT([$kernsrcver])
 majver=`echo "$kernsrcver" | cut -f-2 -d.`
index 1399dfdd66956931b41f4dc0f2633ca1140693b5..9cc70288e8f28d6b69721a491e689af28039f0cb 100644 (file)
@@ -501,12 +501,16 @@ static int hide_node(struct fuse *f, const char *oldpath, fuse_ino_t dir,
 }
 
 static int lookup_path(struct fuse *f, fuse_ino_t nodeid, const char *name,
-                       const char *path, struct fuse_entry_param *e)
+                       const char *path, struct fuse_entry_param *e,
+                       struct fuse_file_info *fi)
 {
     int res;
 
     memset(e, 0, sizeof(struct fuse_entry_param));
-    res = f->op.getattr(path, &e->attr);
+    if (fi && f->op.fgetattr)
+        res = f->op.fgetattr(path, &e->attr, fi);
+    else
+        res = f->op.getattr(path, &e->attr);
     if (res == 0) {
         struct node *node;
 
@@ -604,7 +608,7 @@ static void fuse_lookup(fuse_req_t req, fuse_ino_t parent, const char *name)
         }
         err = -ENOSYS;
         if (f->op.getattr)
-            err = lookup_path(f, parent, name, path, &e);
+            err = lookup_path(f, parent, name, path, &e, NULL);
         free(path);
     }
     pthread_rwlock_unlock(&f->tree_lock);
@@ -804,7 +808,7 @@ static void fuse_mknod(fuse_req_t req, fuse_ino_t parent, const char *name,
         if (f->op.mknod && f->op.getattr) {
             err = f->op.mknod(path, mode, rdev);
             if (!err)
-                err = lookup_path(f, parent, name, path, &e);
+                err = lookup_path(f, parent, name, path, &e, NULL);
         }
         free(path);
     }
@@ -832,7 +836,7 @@ static void fuse_mkdir(fuse_req_t req, fuse_ino_t parent, const char *name,
         if (f->op.mkdir && f->op.getattr) {
             err = f->op.mkdir(path, mode);
             if (!err)
-                err = lookup_path(f, parent, name, path, &e);
+                err = lookup_path(f, parent, name, path, &e, NULL);
         }
         free(path);
     }
@@ -916,7 +920,7 @@ static void fuse_symlink(fuse_req_t req, const char *linkname,
         if (f->op.symlink && f->op.getattr) {
             err = f->op.symlink(linkname, path);
             if (!err)
-                err = lookup_path(f, parent, name, path, &e);
+                err = lookup_path(f, parent, name, path, &e, NULL);
         }
         free(path);
     }
@@ -985,7 +989,7 @@ static void fuse_link(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
             if (f->op.link && f->op.getattr) {
                 err = f->op.link(oldpath, newpath);
                 if (!err)
-                    err = lookup_path(f, newparent, newname, newpath, &e);
+                    err = lookup_path(f, newparent, newname, newpath, &e, NULL);
             }
             free(newpath);
         }
@@ -1016,7 +1020,7 @@ static void fuse_create(fuse_req_t req, fuse_ino_t parent, const char *name,
                            path);
                     fflush(stdout);
                 }
-                err = lookup_path(f, parent, name, path, &e);
+                err = lookup_path(f, parent, name, path, &e, fi);
                 if (err) {
                     if (f->op.release)
                         f->op.release(path, fi);