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
*
* 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 {
* 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
}
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;
}
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);
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);
}
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);
}
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);
}
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);
}
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);