fix
authorMiklos Szeredi <miklos@szeredi.hu>
Tue, 11 Jan 2005 14:24:18 +0000 (14:24 +0000)
committerMiklos Szeredi <miklos@szeredi.hu>
Tue, 11 Jan 2005 14:24:18 +0000 (14:24 +0000)
ChangeLog
kernel/dir.c
kernel/fuse_i.h
kernel/inode.c

index 451e369ea571ebb4bbfecfbfd0ff84b344fac2c6..34fe25c9fe935163ea275af701cbe1cc95cd07d7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2005-01-11  Miklos Szeredi <miklos@szeredi.hu>
+
+       * 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 <miklos@szeredi.hu>
 
        * Released 2.2-pre3
index 7ceb63accf6c7ed20bdaecd98b9b4355b81a59ee..e07ea79db06b1b3b24c1884255ce7055dec3106e 100644 (file)
 #include <linux/mm.h>
 #endif
 #include <linux/sched.h>
+#ifdef KERNEL_2_6_7_PLUS
+#include <linux/namei.h>
+#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
index 66396da80653a6468bcabd47d5eb555a9712d97e..cda7e9be66f027c42876dfa3f44835e4675a426a 100644 (file)
@@ -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)
index 2020584bd83996a433fb20c9a34123058405e353..a3a709b078e5f9ccec659c0aa71e0a229cf3d6b4 100644 (file)
@@ -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");