From: Miklos Szeredi Date: Tue, 11 Jan 2005 14:24:18 +0000 (+0000) Subject: fix X-Git-Tag: fuse_2_2_pre4~7 X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=8139452f9ea124cd9204bc55f51479479b4435dd;p=qemu-gpiodev%2Flibfuse.git fix --- diff --git a/ChangeLog b/ChangeLog index 451e369..34fe25c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2005-01-11 Miklos Szeredi + + * KERNEL: fix possible inode allocation problem, where + sizeof(struct inode) is not aligned (found by Mike Waychison) + + * KERNEL: use new follow_link/put_link methods + + * KERNEL: cosmetic fixes + 2005-01-10 Miklos Szeredi * Released 2.2-pre3 diff --git a/kernel/dir.c b/kernel/dir.c index 7ceb63a..e07ea79 100644 --- a/kernel/dir.c +++ b/kernel/dir.c @@ -16,15 +16,15 @@ #include #endif #include +#ifdef KERNEL_2_6_7_PLUS +#include +#endif static inline unsigned long time_to_jiffies(unsigned long sec, unsigned long nsec) { - /* prevent wrapping of jiffies */ - if (sec + 1 >= LONG_MAX / HZ) - return 0; - - return jiffies + sec * HZ + nsec / (1000000000 / HZ); + struct timespec ts = {sec, nsec}; + return jiffies + timespec_to_jiffies(&ts); } static void fuse_lookup_init(struct fuse_req *req, struct inode *dir, @@ -46,7 +46,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) { if (!entry->d_inode || is_bad_inode(entry->d_inode)) return 0; - else if (entry->d_time && time_after(jiffies, entry->d_time)) { + else if (time_after(jiffies, entry->d_time)) { int err; int version; struct fuse_entry_out outarg; @@ -440,7 +440,7 @@ static int fuse_revalidate(struct dentry *entry) (!(fc->flags & FUSE_ALLOW_ROOT) || current->fsuid != 0)) return -EACCES; - } else if (!fi->i_time || time_before_eq(jiffies, fi->i_time)) + } else if (time_before_eq(jiffies, fi->i_time)) return 0; return fuse_do_getattr(inode); @@ -624,6 +624,18 @@ static void free_link(char *link) free_page((unsigned long) link); } +#ifdef KERNEL_2_6_7_PLUS +static int fuse_follow_link(struct dentry *dentry, struct nameidata *nd) +{ + nd_set_link(nd, read_link(dentry)); + return 0; +} + +static void fuse_put_link(struct dentry *dentry, struct nameidata *nd) +{ + free_link(nd_get_link(nd)); +} +#else static int fuse_readlink(struct dentry *dentry, char __user *buffer, int buflen) { @@ -646,6 +658,7 @@ static int fuse_follow_link(struct dentry *dentry, struct nameidata *nd) free_link(link); return ret; } +#endif static int fuse_dir_open(struct inode *inode, struct file *file) { @@ -1054,8 +1067,13 @@ static struct inode_operations fuse_common_inode_operations = { static struct inode_operations fuse_symlink_inode_operations = { .setattr = fuse_setattr, - .readlink = fuse_readlink, .follow_link = fuse_follow_link, +#ifdef KERNEL_2_6_7_PLUS + .put_link = fuse_put_link, + .readlink = generic_readlink, +#else + .readlink = fuse_readlink, +#endif #ifdef KERNEL_2_6 .getattr = fuse_getattr, #else diff --git a/kernel/fuse_i.h b/kernel/fuse_i.h index 66396da..cda7e9b 100644 --- a/kernel/fuse_i.h +++ b/kernel/fuse_i.h @@ -21,6 +21,9 @@ # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6) # define KERNEL_2_6_6_PLUS # endif +# if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7) +# define KERNEL_2_6_7_PLUS +# endif # if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10) # define KERNEL_2_6_10_PLUS # endif @@ -97,8 +100,11 @@ static inline void set_page_dirty_lock(struct page *page) filesystems */ #define FUSE_ALLOW_ROOT (1 << 4) -/** FUSE specific inode data */ +/** FUSE inode */ struct fuse_inode { + /** Inode data */ + struct inode inode; + /** Unique ID, which identifies the inode between userspace * and kernel */ u64 nodeid; @@ -336,7 +342,7 @@ static inline struct fuse_conn *get_fuse_conn(struct inode *inode) static inline struct fuse_inode *get_fuse_inode(struct inode *inode) { - return (struct fuse_inode *) (&inode[1]); + return container_of(inode, struct fuse_inode, inode); } static inline u64 get_node_id(struct inode *inode) diff --git a/kernel/inode.c b/kernel/inode.c index 2020584..a3a709b 100644 --- a/kernel/inode.c +++ b/kernel/inode.c @@ -82,7 +82,8 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) inode->u.generic_ip = NULL; #endif fi = get_fuse_inode(inode); - memset(fi, 0, sizeof(*fi)); + fi->i_time = jiffies - 1; + fi->nodeid = 0; fi->forget_req = fuse_request_alloc(); if (!fi->forget_req) { kmem_cache_free(fuse_inode_cachep, inode); @@ -619,7 +620,7 @@ static int inc_mount_count(void) return success; } -static int fuse_read_super(struct super_block *sb, void *data, int silent) +static int fuse_fill_super(struct super_block *sb, void *data, int silent) { struct fuse_conn *fc; struct inode *root; @@ -696,7 +697,7 @@ static struct super_block *fuse_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *raw_data) { - return get_sb_nodev(fs_type, flags, raw_data, fuse_read_super); + return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super); } static struct file_system_type fuse_fs_type = { @@ -712,7 +713,7 @@ static struct file_system_type fuse_fs_type = { static struct super_block *fuse_read_super_compat(struct super_block *sb, void *data, int silent) { - int err = fuse_read_super(sb, data, silent); + int err = fuse_fill_super(sb, data, silent); if (err) return NULL; else @@ -722,7 +723,7 @@ static struct super_block *fuse_read_super_compat(struct super_block *sb, static DECLARE_FSTYPE(fuse_fs_type, "fuse", fuse_read_super_compat, 0); #endif -static void fuse_inode_init_once(void * foo, kmem_cache_t * cachep, +static void fuse_inode_init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) { struct inode * inode = foo; @@ -741,7 +742,7 @@ static int __init fuse_fs_init(void) printk("fuse: failed to register filesystem\n"); else { fuse_inode_cachep = kmem_cache_create("fuse_inode", - sizeof(struct inode) + sizeof(struct fuse_inode) , + sizeof(struct fuse_inode), 0, SLAB_HWCACHE_ALIGN, fuse_inode_init_once, NULL); if (!fuse_inode_cachep) { @@ -759,7 +760,7 @@ static void fuse_fs_cleanup(void) kmem_cache_destroy(fuse_inode_cachep); } -int __init fuse_init(void) +static int __init fuse_init(void) { int res; @@ -786,7 +787,7 @@ int __init fuse_init(void) return res; } -void __exit fuse_exit(void) +static void __exit fuse_exit(void) { printk(KERN_DEBUG "fuse exit\n");