* [PATCH 0/7] fuse updates @ 2005-11-28 19:41 Miklos Szeredi 2005-11-28 19:43 ` [PATCH 1/7] fuse: check directory aliasing in mkdir Miklos Szeredi 0 siblings, 1 reply; 12+ messages in thread From: Miklos Szeredi @ 2005-11-28 19:41 UTC (permalink / raw) To: akpm; +Cc: linux-kernel 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 1/7] fuse: check directory aliasing in mkdir 2005-11-28 19:41 [PATCH 0/7] fuse updates Miklos Szeredi @ 2005-11-28 19:43 ` Miklos Szeredi 2005-11-28 19:45 ` [PATCH 2/7] fuse: check for invalid node ID in fuse_create_open() Miklos Szeredi 2005-11-28 19:57 ` [PATCH 1/7] fuse: check directory aliasing in mkdir Trond Myklebust 0 siblings, 2 replies; 12+ messages in thread From: Miklos Szeredi @ 2005-11-28 19:43 UTC (permalink / raw) To: akpm; +Cc: linux-kernel Check the created directory inode for aliases in the mkdir() method. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> --- 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; ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 2/7] fuse: check for invalid node ID in fuse_create_open() 2005-11-28 19:43 ` [PATCH 1/7] fuse: check directory aliasing in mkdir Miklos Szeredi @ 2005-11-28 19:45 ` Miklos Szeredi 2005-11-28 19:46 ` [PATCH 3/7] fuse: clean up fuse_lookup() Miklos Szeredi 2005-11-28 19:57 ` [PATCH 1/7] fuse: check directory aliasing in mkdir Trond Myklebust 1 sibling, 1 reply; 12+ messages in thread From: Miklos Szeredi @ 2005-11-28 19:45 UTC (permalink / raw) To: akpm; +Cc: linux-kernel Check for invalid node ID values in the new atomic create+open method. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> --- 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; } ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 3/7] fuse: clean up fuse_lookup() 2005-11-28 19:45 ` [PATCH 2/7] fuse: check for invalid node ID in fuse_create_open() Miklos Szeredi @ 2005-11-28 19:46 ` Miklos Szeredi 2005-11-28 19:47 ` [PATCH 4/7] fuse: clean up page offset calculation Miklos Szeredi 0 siblings, 1 reply; 12+ messages in thread From: Miklos Szeredi @ 2005-11-28 19:46 UTC (permalink / raw) To: akpm; +Cc: linux-kernel Simplify fuse_lookup() and related functions. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> --- 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) { ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 4/7] fuse: clean up page offset calculation 2005-11-28 19:46 ` [PATCH 3/7] fuse: clean up fuse_lookup() Miklos Szeredi @ 2005-11-28 19:47 ` Miklos Szeredi 2005-11-28 19:49 ` [PATCH 5/7] fuse: bump interface version Miklos Szeredi 0 siblings, 1 reply; 12+ messages in thread From: Miklos Szeredi @ 2005-11-28 19:47 UTC (permalink / raw) To: akpm; +Cc: linux-kernel Use page_offset() instead of doing page offset calculation by hand. Signed-off-by: Miklos Szeredi <miklos@szeredi.hu> --- 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; ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 5/7] fuse: bump interface version 2005-11-28 19:47 ` [PATCH 4/7] fuse: clean up page offset calculation Miklos Szeredi @ 2005-11-28 19:49 ` Miklos Szeredi 2005-11-28 19:50 ` [PATCH 6/7] fuse: add frsize to statfs reply Miklos Szeredi 0 siblings, 1 reply; 12+ messages in thread From: Miklos Szeredi @ 2005-11-28 19:49 UTC (permalink / raw) To: akpm; +Cc: linux-kernel 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 <miklos@szeredi.hu> --- 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; }; ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 6/7] fuse: add frsize to statfs reply 2005-11-28 19:49 ` [PATCH 5/7] fuse: bump interface version Miklos Szeredi @ 2005-11-28 19:50 ` Miklos Szeredi 2005-11-28 19:51 ` [PATCH 7/7] fuse: support caching negative dentries Miklos Szeredi 0 siblings, 1 reply; 12+ messages in thread From: Miklos Szeredi @ 2005-11-28 19:50 UTC (permalink / raw) To: akpm; +Cc: linux-kernel 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 <miklos@szeredi.hu> --- 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; }; ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH 7/7] fuse: support caching negative dentries 2005-11-28 19:50 ` [PATCH 6/7] fuse: add frsize to statfs reply Miklos Szeredi @ 2005-11-28 19:51 ` Miklos Szeredi 2005-11-28 20:40 ` Andrew Morton 0 siblings, 1 reply; 12+ messages in thread From: Miklos Szeredi @ 2005-11-28 19:51 UTC (permalink / raw) To: akpm; +Cc: linux-kernel 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 <miklos@szeredi.hu> --- 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 7/7] fuse: support caching negative dentries 2005-11-28 19:51 ` [PATCH 7/7] fuse: support caching negative dentries Miklos Szeredi @ 2005-11-28 20:40 ` Andrew Morton 2005-11-28 21:06 ` Miklos Szeredi 0 siblings, 1 reply; 12+ messages in thread From: Andrew Morton @ 2005-11-28 20:40 UTC (permalink / raw) To: Miklos Szeredi; +Cc: linux-kernel Miklos Szeredi <miklos@szeredi.hu> 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. ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 7/7] fuse: support caching negative dentries 2005-11-28 20:40 ` Andrew Morton @ 2005-11-28 21:06 ` Miklos Szeredi 0 siblings, 0 replies; 12+ messages in thread From: Miklos Szeredi @ 2005-11-28 21:06 UTC (permalink / raw) To: akpm; +Cc: linux-kernel > > > > +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 ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/7] fuse: check directory aliasing in mkdir 2005-11-28 19:43 ` [PATCH 1/7] fuse: check directory aliasing in mkdir Miklos Szeredi 2005-11-28 19:45 ` [PATCH 2/7] fuse: check for invalid node ID in fuse_create_open() Miklos Szeredi @ 2005-11-28 19:57 ` Trond Myklebust 2005-11-28 20:09 ` Miklos Szeredi 1 sibling, 1 reply; 12+ messages in thread From: Trond Myklebust @ 2005-11-28 19:57 UTC (permalink / raw) To: Miklos Szeredi; +Cc: akpm, linux-kernel 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 <miklos@szeredi.hu> > > --- > 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 majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Please read the FAQ at http://www.tux.org/lkml/ ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/7] fuse: check directory aliasing in mkdir 2005-11-28 19:57 ` [PATCH 1/7] fuse: check directory aliasing in mkdir Trond Myklebust @ 2005-11-28 20:09 ` Miklos Szeredi 0 siblings, 0 replies; 12+ messages in thread From: Miklos Szeredi @ 2005-11-28 20:09 UTC (permalink / raw) To: trond.myklebust; +Cc: akpm, linux-kernel > > 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 ^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2005-11-28 21:07 UTC | newest] Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2005-11-28 19:41 [PATCH 0/7] fuse updates Miklos Szeredi 2005-11-28 19:43 ` [PATCH 1/7] fuse: check directory aliasing in mkdir Miklos Szeredi 2005-11-28 19:45 ` [PATCH 2/7] fuse: check for invalid node ID in fuse_create_open() Miklos Szeredi 2005-11-28 19:46 ` [PATCH 3/7] fuse: clean up fuse_lookup() Miklos Szeredi 2005-11-28 19:47 ` [PATCH 4/7] fuse: clean up page offset calculation Miklos Szeredi 2005-11-28 19:49 ` [PATCH 5/7] fuse: bump interface version Miklos Szeredi 2005-11-28 19:50 ` [PATCH 6/7] fuse: add frsize to statfs reply Miklos Szeredi 2005-11-28 19:51 ` [PATCH 7/7] fuse: support caching negative dentries Miklos Szeredi 2005-11-28 20:40 ` Andrew Morton 2005-11-28 21:06 ` Miklos Szeredi 2005-11-28 19:57 ` [PATCH 1/7] fuse: check directory aliasing in mkdir Trond Myklebust 2005-11-28 20:09 ` Miklos Szeredi
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®