Hi Andrew!
Patches 1 and 2 are bugfixes, and should go into 2.6.15.
The others are cleanups and new features, which can wait for 2.6.16.
Thanks,
Miklos
Check the created directory inode for aliases in the mkdir() method.
Signed-off-by: Miklos Szeredi <[email protected]>
---
Index: linux/fs/fuse/dir.c
===================================================================
--- linux.orig/fs/fuse/dir.c 2005-11-28 14:01:08.000000000 +0100
+++ linux/fs/fuse/dir.c 2005-11-28 14:01:52.000000000 +0100
@@ -74,6 +74,19 @@ static int fuse_dentry_revalidate(struct
return 1;
}
+static int dir_alias(struct inode *inode)
+{
+ if (S_ISDIR(inode->i_mode)) {
+ /* Don't allow creating an alias to a directory */
+ struct dentry *alias = d_find_alias(inode);
+ if (alias) {
+ dput(alias);
+ return 1;
+ }
+ }
+ return 0;
+}
+
static struct dentry_operations fuse_dentry_operations = {
.d_revalidate = fuse_dentry_revalidate,
};
@@ -263,7 +276,7 @@ static int create_new_entry(struct fuse_
fuse_put_request(fc, req);
/* Don't allow userspace to do really stupid things... */
- if ((inode->i_mode ^ mode) & S_IFMT) {
+ if (((inode->i_mode ^ mode) & S_IFMT) || dir_alias(inode)) {
iput(inode);
return -EIO;
}
@@ -874,14 +887,9 @@ static struct dentry *fuse_lookup(struct
err = fuse_lookup_iget(dir, entry, &inode);
if (err)
return ERR_PTR(err);
- if (inode && S_ISDIR(inode->i_mode)) {
- /* Don't allow creating an alias to a directory */
- struct dentry *alias = d_find_alias(inode);
- if (alias) {
- dput(alias);
- iput(inode);
- return ERR_PTR(-EIO);
- }
+ if (inode && dir_alias(inode)) {
+ iput(inode);
+ return ERR_PTR(-EIO);
}
d_add(entry, inode);
return NULL;
Check for invalid node ID values in the new atomic create+open method.
Signed-off-by: Miklos Szeredi <[email protected]>
---
Index: linux/fs/fuse/dir.c
===================================================================
--- linux.orig/fs/fuse/dir.c 2005-11-28 17:24:22.000000000 +0100
+++ linux/fs/fuse/dir.c 2005-11-28 17:24:26.000000000 +0100
@@ -87,6 +87,11 @@ static int dir_alias(struct inode *inode
return 0;
}
+static inline int invalid_nodeid(u64 nodeid)
+{
+ return !nodeid || nodeid == FUSE_ROOT_ID;
+}
+
static struct dentry_operations fuse_dentry_operations = {
.d_revalidate = fuse_dentry_revalidate,
};
@@ -110,7 +115,7 @@ static int fuse_lookup_iget(struct inode
fuse_lookup_init(req, dir, entry, &outarg);
request_send(fc, req);
err = req->out.h.error;
- if (!err && (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID))
+ if (!err && invalid_nodeid(outarg.nodeid))
err = -EIO;
if (!err) {
inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
@@ -206,7 +211,7 @@ static int fuse_create_open(struct inode
}
err = -EIO;
- if (!S_ISREG(outentry.attr.mode))
+ if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
goto out_free_ff;
inode = fuse_iget(dir->i_sb, outentry.nodeid, outentry.generation,
@@ -263,7 +268,7 @@ static int create_new_entry(struct fuse_
fuse_put_request(fc, req);
return err;
}
- if (!outarg.nodeid || outarg.nodeid == FUSE_ROOT_ID) {
+ if (invalid_nodeid(outarg.nodeid)) {
fuse_put_request(fc, req);
return -EIO;
}
Simplify fuse_lookup() and related functions.
Signed-off-by: Miklos Szeredi <[email protected]>
---
Index: linux/fs/fuse/dir.c
===================================================================
--- linux.orig/fs/fuse/dir.c 2005-11-28 17:24:26.000000000 +0100
+++ linux/fs/fuse/dir.c 2005-11-28 17:26:51.000000000 +0100
@@ -13,7 +13,6 @@
#include <linux/gfp.h>
#include <linux/sched.h>
#include <linux/namei.h>
-#include <linux/mount.h>
static inline unsigned long time_to_jiffies(unsigned long sec,
unsigned long nsec)
@@ -22,6 +21,13 @@ static inline unsigned long time_to_jiff
return jiffies + timespec_to_jiffies(&ts);
}
+static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
+{
+ struct fuse_inode *fi = get_fuse_inode(entry->d_inode);
+ entry->d_time = time_to_jiffies(o->entry_valid, o->entry_valid_nsec);
+ fi->i_time = time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
+}
+
static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
struct dentry *entry,
struct fuse_entry_out *outarg)
@@ -66,10 +72,7 @@ static int fuse_dentry_revalidate(struct
return 0;
fuse_change_attributes(inode, &outarg.attr);
- entry->d_time = time_to_jiffies(outarg.entry_valid,
- outarg.entry_valid_nsec);
- fi->i_time = time_to_jiffies(outarg.attr_valid,
- outarg.attr_valid_nsec);
+ fuse_change_timeout(entry, &outarg);
}
return 1;
}
@@ -96,8 +99,8 @@ static struct dentry_operations fuse_den
.d_revalidate = fuse_dentry_revalidate,
};
-static int fuse_lookup_iget(struct inode *dir, struct dentry *entry,
- struct inode **inodep)
+static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
+ struct nameidata *nd)
{
int err;
struct fuse_entry_out outarg;
@@ -106,11 +109,11 @@ static int fuse_lookup_iget(struct inode
struct fuse_req *req;
if (entry->d_name.len > FUSE_NAME_MAX)
- return -ENAMETOOLONG;
+ return ERR_PTR(-ENAMETOOLONG);
req = fuse_get_request(fc);
if (!req)
- return -EINTR;
+ return ERR_PTR(-EINTR);
fuse_lookup_init(req, dir, entry, &outarg);
request_send(fc, req);
@@ -122,24 +125,22 @@ static int fuse_lookup_iget(struct inode
&outarg.attr);
if (!inode) {
fuse_send_forget(fc, req, outarg.nodeid, 1);
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
}
}
fuse_put_request(fc, req);
if (err && err != -ENOENT)
- return err;
+ return ERR_PTR(err);
- if (inode) {
- struct fuse_inode *fi = get_fuse_inode(inode);
- entry->d_time = time_to_jiffies(outarg.entry_valid,
- outarg.entry_valid_nsec);
- fi->i_time = time_to_jiffies(outarg.attr_valid,
- outarg.attr_valid_nsec);
+ if (inode && dir_alias(inode)) {
+ iput(inode);
+ return ERR_PTR(-EIO);
}
-
+ d_add(entry, inode);
entry->d_op = &fuse_dentry_operations;
- *inodep = inode;
- return 0;
+ if (inode)
+ fuse_change_timeout(entry, &outarg);
+ return NULL;
}
void fuse_invalidate_attr(struct inode *inode)
@@ -163,7 +164,6 @@ static int fuse_create_open(struct inode
struct fuse_open_in inarg;
struct fuse_open_out outopen;
struct fuse_entry_out outentry;
- struct fuse_inode *fi;
struct fuse_file *ff;
struct file *file;
int flags = nd->intent.open.flags - 1;
@@ -224,13 +224,8 @@ static int fuse_create_open(struct inode
goto out_put_request;
}
fuse_put_request(fc, req);
- entry->d_time = time_to_jiffies(outentry.entry_valid,
- outentry.entry_valid_nsec);
- fi = get_fuse_inode(inode);
- fi->i_time = time_to_jiffies(outentry.attr_valid,
- outentry.attr_valid_nsec);
-
d_instantiate(entry, inode);
+ fuse_change_timeout(entry, &outentry);
file = lookup_instantiate_filp(nd, entry, generic_file_open);
if (IS_ERR(file)) {
ff->fh = outopen.fh;
@@ -254,7 +249,6 @@ static int create_new_entry(struct fuse_
{
struct fuse_entry_out outarg;
struct inode *inode;
- struct fuse_inode *fi;
int err;
req->in.h.nodeid = get_node_id(dir);
@@ -286,14 +280,8 @@ static int create_new_entry(struct fuse_
return -EIO;
}
- entry->d_time = time_to_jiffies(outarg.entry_valid,
- outarg.entry_valid_nsec);
-
- fi = get_fuse_inode(inode);
- fi->i_time = time_to_jiffies(outarg.attr_valid,
- outarg.attr_valid_nsec);
-
d_instantiate(entry, inode);
+ fuse_change_timeout(entry, &outarg);
fuse_invalidate_attr(dir);
return 0;
}
@@ -883,23 +871,6 @@ static int fuse_getattr(struct vfsmount
return err;
}
-static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
- struct nameidata *nd)
-{
- struct inode *inode;
- int err;
-
- err = fuse_lookup_iget(dir, entry, &inode);
- if (err)
- return ERR_PTR(err);
- if (inode && dir_alias(inode)) {
- iput(inode);
- return ERR_PTR(-EIO);
- }
- d_add(entry, inode);
- return NULL;
-}
-
static int fuse_setxattr(struct dentry *entry, const char *name,
const void *value, size_t size, int flags)
{
Use page_offset() instead of doing page offset calculation by hand.
Signed-off-by: Miklos Szeredi <[email protected]>
---
Index: linux/fs/fuse/file.c
===================================================================
--- linux.orig/fs/fuse/file.c 2005-11-28 14:01:07.000000000 +0100
+++ linux/fs/fuse/file.c 2005-11-28 14:02:07.000000000 +0100
@@ -272,7 +272,6 @@ static int fuse_readpage(struct file *fi
{
struct inode *inode = page->mapping->host;
struct fuse_conn *fc = get_fuse_conn(inode);
- loff_t pos = (loff_t) page->index << PAGE_CACHE_SHIFT;
struct fuse_req *req = fuse_get_request(fc);
int err = -EINTR;
if (!req)
@@ -281,7 +280,7 @@ static int fuse_readpage(struct file *fi
req->out.page_zeroing = 1;
req->num_pages = 1;
req->pages[0] = page;
- fuse_send_read(req, file, inode, pos, PAGE_CACHE_SIZE);
+ fuse_send_read(req, file, inode, page_offset(page), PAGE_CACHE_SIZE);
err = req->out.h.error;
fuse_put_request(fc, req);
if (!err)
@@ -295,7 +294,7 @@ static int fuse_readpage(struct file *fi
static int fuse_send_readpages(struct fuse_req *req, struct file *file,
struct inode *inode)
{
- loff_t pos = (loff_t) req->pages[0]->index << PAGE_CACHE_SHIFT;
+ loff_t pos = page_offset(req->pages[0]);
size_t count = req->num_pages << PAGE_CACHE_SHIFT;
unsigned i;
req->out.page_zeroing = 1;
@@ -402,7 +401,7 @@ static int fuse_commit_write(struct file
unsigned count = to - offset;
struct inode *inode = page->mapping->host;
struct fuse_conn *fc = get_fuse_conn(inode);
- loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + offset;
+ loff_t pos = page_offset(page) + offset;
struct fuse_req *req = fuse_get_request(fc);
if (!req)
return -EINTR;
Change interface version to 7.4.
Following changes will need backward compatibility support, so store
the minor version returned by userspace.
Signed-off-by: Miklos Szeredi <[email protected]>
---
Index: linux/fs/fuse/dev.c
===================================================================
--- linux.orig/fs/fuse/dev.c 2005-11-22 14:45:54.000000000 +0100
+++ linux/fs/fuse/dev.c 2005-11-28 12:02:10.000000000 +0100
@@ -178,6 +178,8 @@ static void request_end(struct fuse_conn
if (req->misc.init_in_out.major != FUSE_KERNEL_VERSION)
fc->conn_error = 1;
+ fc->minor = req->misc.init_in_out.minor;
+
/* After INIT reply is received other requests can go
out. So do (FUSE_MAX_OUTSTANDING - 1) number of
up()s on outstanding_sem. The last up() is done in
Index: linux/include/linux/fuse.h
===================================================================
--- linux.orig/include/linux/fuse.h 2005-11-22 14:45:58.000000000 +0100
+++ linux/include/linux/fuse.h 2005-11-28 11:59:01.000000000 +0100
@@ -14,7 +14,7 @@
#define FUSE_KERNEL_VERSION 7
/** Minor version number of this interface */
-#define FUSE_KERNEL_MINOR_VERSION 3
+#define FUSE_KERNEL_MINOR_VERSION 4
/** The node ID of the root inode */
#define FUSE_ROOT_ID 1
Index: linux/fs/fuse/fuse_i.h
===================================================================
--- linux.orig/fs/fuse/fuse_i.h 2005-11-22 14:45:54.000000000 +0100
+++ linux/fs/fuse/fuse_i.h 2005-11-28 12:02:36.000000000 +0100
@@ -272,6 +272,9 @@ struct fuse_conn {
/** Is create not implemented by fs? */
unsigned no_create : 1;
+ /** Negotiated minor version */
+ unsigned minor;
+
/** Backing dev info */
struct backing_dev_info bdi;
};
Add 'frsize' member to the statfs reply.
I'm not sure if sending f_fsid will ever be needed, but just in case
leave some space at the end of the structure, so less compatibility
mess would be required.
Signed-off-by: Miklos Szeredi <[email protected]>
---
Index: linux/fs/fuse/inode.c
===================================================================
--- linux.orig/fs/fuse/inode.c 2005-11-28 14:01:07.000000000 +0100
+++ linux/fs/fuse/inode.c 2005-11-28 16:45:12.000000000 +0100
@@ -218,6 +218,7 @@ static void convert_fuse_statfs(struct k
{
stbuf->f_type = FUSE_SUPER_MAGIC;
stbuf->f_bsize = attr->bsize;
+ stbuf->f_frsize = attr->frsize;
stbuf->f_blocks = attr->blocks;
stbuf->f_bfree = attr->bfree;
stbuf->f_bavail = attr->bavail;
@@ -238,10 +239,12 @@ static int fuse_statfs(struct super_bloc
if (!req)
return -EINTR;
+ memset(&outarg, 0, sizeof(outarg));
req->in.numargs = 0;
req->in.h.opcode = FUSE_STATFS;
req->out.numargs = 1;
- req->out.args[0].size = sizeof(outarg);
+ req->out.args[0].size =
+ fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg);
req->out.args[0].value = &outarg;
request_send(fc, req);
err = req->out.h.error;
Index: linux/include/linux/fuse.h
===================================================================
--- linux.orig/include/linux/fuse.h 2005-11-28 14:02:09.000000000 +0100
+++ linux/include/linux/fuse.h 2005-11-28 15:25:14.000000000 +0100
@@ -53,6 +53,9 @@ struct fuse_kstatfs {
__u64 ffree;
__u32 bsize;
__u32 namelen;
+ __u32 frsize;
+ __u32 padding;
+ __u32 spare[6];
};
#define FATTR_MODE (1 << 0)
@@ -213,6 +216,8 @@ struct fuse_write_out {
__u32 padding;
};
+#define FUSE_COMPAT_STATFS_SIZE 48
+
struct fuse_statfs_out {
struct fuse_kstatfs st;
};
Add support for caching negative dentries.
Up till now, ->d_revalidate() always forced a new lookup on these.
Now let the lookup method return a zero node ID (not used for anything
else) meaning a negative entry, but with a positive cache timeout.
The old way of signaling negative entry (replying ENOENT) still works.
Userspace should check the ABI minor version to see whether sending a
zero ID is allowed by the kernel or not.
Signed-off-by: Miklos Szeredi <[email protected]>
---
Index: linux/fs/fuse/dir.c
===================================================================
--- linux.orig/fs/fuse/dir.c 2005-11-28 17:55:27.000000000 +0100
+++ linux/fs/fuse/dir.c 2005-11-28 18:07:23.000000000 +0100
@@ -23,9 +23,26 @@ static inline unsigned long time_to_jiff
static void fuse_change_timeout(struct dentry *entry, struct fuse_entry_out *o)
{
- struct fuse_inode *fi = get_fuse_inode(entry->d_inode);
entry->d_time = time_to_jiffies(o->entry_valid, o->entry_valid_nsec);
- fi->i_time = time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
+ if (entry->d_inode)
+ get_fuse_inode(entry->d_inode)->i_time =
+ time_to_jiffies(o->attr_valid, o->attr_valid_nsec);
+}
+
+void fuse_invalidate_attr(struct inode *inode)
+{
+ get_fuse_inode(inode)->i_time = jiffies - 1;
+}
+
+static void fuse_invalidate_entry_cache(struct dentry *entry)
+{
+ entry->d_time = jiffies - 1;
+}
+
+static void fuse_invalidate_entry(struct dentry *entry)
+{
+ d_invalidate(entry);
+ fuse_invalidate_entry_cache(entry);
}
static void fuse_lookup_init(struct fuse_req *req, struct inode *dir,
@@ -45,15 +62,22 @@ static void fuse_lookup_init(struct fuse
static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd)
{
- if (!entry->d_inode || is_bad_inode(entry->d_inode))
+ struct inode *inode = entry->d_inode;
+
+ if (inode && is_bad_inode(inode))
return 0;
else if (time_after(jiffies, entry->d_time)) {
int err;
struct fuse_entry_out outarg;
- struct inode *inode = entry->d_inode;
- struct fuse_inode *fi = get_fuse_inode(inode);
- struct fuse_conn *fc = get_fuse_conn(inode);
- struct fuse_req *req = fuse_get_request(fc);
+ struct fuse_conn *fc;
+ struct fuse_req *req;
+
+ fuse_invalidate_entry_cache(entry);
+ if (!inode)
+ return 0;
+
+ fc = get_fuse_conn(inode);
+ req = fuse_get_request(fc);
if (!req)
return 0;
@@ -61,6 +85,7 @@ static int fuse_dentry_revalidate(struct
request_send(fc, req);
err = req->out.h.error;
if (!err) {
+ struct fuse_inode *fi = get_fuse_inode(inode);
if (outarg.nodeid != get_node_id(inode)) {
fuse_send_forget(fc, req, outarg.nodeid, 1);
return 0;
@@ -118,9 +143,9 @@ static struct dentry *fuse_lookup(struct
fuse_lookup_init(req, dir, entry, &outarg);
request_send(fc, req);
err = req->out.h.error;
- if (!err && invalid_nodeid(outarg.nodeid))
+ if (!err && outarg.nodeid && invalid_nodeid(outarg.nodeid))
err = -EIO;
- if (!err) {
+ if (!err && outarg.nodeid) {
inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
&outarg.attr);
if (!inode) {
@@ -138,22 +163,13 @@ static struct dentry *fuse_lookup(struct
}
d_add(entry, inode);
entry->d_op = &fuse_dentry_operations;
- if (inode)
+ if (!err)
fuse_change_timeout(entry, &outarg);
+ else
+ fuse_invalidate_entry_cache(entry);
return NULL;
}
-void fuse_invalidate_attr(struct inode *inode)
-{
- get_fuse_inode(inode)->i_time = jiffies - 1;
-}
-
-static void fuse_invalidate_entry(struct dentry *entry)
-{
- d_invalidate(entry);
- entry->d_time = jiffies - 1;
-}
-
static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode,
struct nameidata *nd)
{
@@ -387,6 +403,7 @@ static int fuse_unlink(struct inode *dir
inode->i_nlink = 0;
fuse_invalidate_attr(inode);
fuse_invalidate_attr(dir);
+ fuse_invalidate_entry_cache(entry);
} else if (err == -EINTR)
fuse_invalidate_entry(entry);
return err;
@@ -412,6 +429,7 @@ static int fuse_rmdir(struct inode *dir,
if (!err) {
entry->d_inode->i_nlink = 0;
fuse_invalidate_attr(dir);
+ fuse_invalidate_entry_cache(entry);
} else if (err == -EINTR)
fuse_invalidate_entry(entry);
return err;
@@ -447,6 +465,10 @@ static int fuse_rename(struct inode *old
fuse_invalidate_attr(olddir);
if (olddir != newdir)
fuse_invalidate_attr(newdir);
+
+ /* newent will end up negative */
+ if (newent->d_inode)
+ fuse_invalidate_entry_cache(newent);
} else if (err == -EINTR) {
/* If request was interrupted, DEITY only knows if the
rename actually took place. If the invalidation
On Mon, 2005-11-28 at 20:43 +0100, Miklos Szeredi wrote:
> Check the created directory inode for aliases in the mkdir() method.
Can't you use d_add_unique() here?
Cheers,
Trond
> Signed-off-by: Miklos Szeredi <[email protected]>
>
> ---
> Index: linux/fs/fuse/dir.c
> ===================================================================
> --- linux.orig/fs/fuse/dir.c 2005-11-28 14:01:08.000000000 +0100
> +++ linux/fs/fuse/dir.c 2005-11-28 14:01:52.000000000 +0100
> @@ -74,6 +74,19 @@ static int fuse_dentry_revalidate(struct
> return 1;
> }
>
> +static int dir_alias(struct inode *inode)
> +{
> + if (S_ISDIR(inode->i_mode)) {
> + /* Don't allow creating an alias to a directory */
> + struct dentry *alias = d_find_alias(inode);
> + if (alias) {
> + dput(alias);
> + return 1;
> + }
> + }
> + return 0;
> +}
> +
> static struct dentry_operations fuse_dentry_operations = {
> .d_revalidate = fuse_dentry_revalidate,
> };
> @@ -263,7 +276,7 @@ static int create_new_entry(struct fuse_
> fuse_put_request(fc, req);
>
> /* Don't allow userspace to do really stupid things... */
> - if ((inode->i_mode ^ mode) & S_IFMT) {
> + if (((inode->i_mode ^ mode) & S_IFMT) || dir_alias(inode)) {
> iput(inode);
> return -EIO;
> }
> @@ -874,14 +887,9 @@ static struct dentry *fuse_lookup(struct
> err = fuse_lookup_iget(dir, entry, &inode);
> if (err)
> return ERR_PTR(err);
> - if (inode && S_ISDIR(inode->i_mode)) {
> - /* Don't allow creating an alias to a directory */
> - struct dentry *alias = d_find_alias(inode);
> - if (alias) {
> - dput(alias);
> - iput(inode);
> - return ERR_PTR(-EIO);
> - }
> + if (inode && dir_alias(inode)) {
> + iput(inode);
> + return ERR_PTR(-EIO);
> }
> d_add(entry, inode);
> return NULL;
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
> > Check the created directory inode for aliases in the mkdir() method.
>
>
> Can't you use d_add_unique() here?
The patch is checking for hashed aliases of an inode. E.g. if /foo is
a directory and has a ID of 28, and mkdir /bar returns the same ID,
then the mkdir should fail.
It's an illegal for the filesystem to create two directories refering
to the same inode.
OTOH d_add_unique() is looking for unhashed aliases to resurrect,
which may or may not make sense in fuse. I'll think about it a bit
more.
Thanks,
Miklos
Miklos Szeredi <[email protected]> wrote:
>
> +void fuse_invalidate_attr(struct inode *inode)
> +{
> + get_fuse_inode(inode)->i_time = jiffies - 1;
> +}
> +
> +static void fuse_invalidate_entry_cache(struct dentry *entry)
> +{
> + entry->d_time = jiffies - 1;
> +}
> +
I'd normally have a little whine about lack of comments here - pity the
poor programmer who is trying to work out why on earth that code is doing
that.
But fuse is pretty much a comment-free zone anyway. Please don't go near
any buses.
> >
> > +void fuse_invalidate_attr(struct inode *inode)
> > +{
> > + get_fuse_inode(inode)->i_time = jiffies - 1;
> > +}
> > +
> > +static void fuse_invalidate_entry_cache(struct dentry *entry)
> > +{
> > + entry->d_time = jiffies - 1;
> > +}
> > +
>
> I'd normally have a little whine about lack of comments here - pity the
> poor programmer who is trying to work out why on earth that code is doing
> that.
Well, I thought it was evident, but it seems not. I'll add some
comments.
> But fuse is pretty much a comment-free zone anyway.
I think most of FUSE is really-really obvious. The most complex parts
are in the device handling, which is now quite well commented (thanks
to your earlier whining :).
> Please don't go near any buses.
Don't worry, I usually go by tram.
Miklos