2005-11-28 19:41:52

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 0/7] fuse updates

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


2005-11-28 19:43:36

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 1/7] fuse: check directory aliasing in mkdir

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;

2005-11-28 19:45:49

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 2/7] fuse: check for invalid node ID in fuse_create_open()

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;
}

2005-11-28 19:46:49

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 3/7] fuse: clean up fuse_lookup()

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)
{

2005-11-28 19:47:51

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 4/7] fuse: clean up page offset calculation

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;

2005-11-28 19:49:18

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 5/7] fuse: bump interface version

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;
};

2005-11-28 19:50:23

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 6/7] fuse: add frsize to statfs reply

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;
};

2005-11-28 19:51:48

by Miklos Szeredi

[permalink] [raw]
Subject: [PATCH 7/7] fuse: support caching negative dentries

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

2005-11-28 19:57:29

by Trond Myklebust

[permalink] [raw]
Subject: Re: [PATCH 1/7] fuse: check directory aliasing in mkdir

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/

2005-11-28 20:09:39

by Miklos Szeredi

[permalink] [raw]
Subject: Re: [PATCH 1/7] fuse: check directory aliasing in mkdir

> > 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

2005-11-28 20:40:20

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 7/7] fuse: support caching negative dentries

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.

2005-11-28 21:07:20

by Miklos Szeredi

[permalink] [raw]
Subject: Re: [PATCH 7/7] fuse: support caching negative dentries

> >
> > +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