aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--kernel/dir.c34
-rw-r--r--kernel/fuse_i.h10
-rw-r--r--kernel/inode.c17
4 files changed, 52 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index 451e369..34fe25c 100644
--- 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
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 <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
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");