# HG changeset patch # User mszeredi # Date 1197485983 0 # Node ID 5b8914cfe0fb7ccfb6e7f61512374d8541f2a193 # Parent 81a85541800582144b7381e0b022c10245facc61 Fix kernel module compile for 2.6.24 --- a/kernel/dir.c Wed Dec 12 14:33:17 2007 +0000 +++ b/kernel/dir.c Wed Dec 12 18:59:43 2007 +0000 @@ -191,7 +191,7 @@ static int invalid_nodeid(u64 nodeid) return !nodeid || nodeid == FUSE_ROOT_ID; } -static struct dentry_operations fuse_dentry_operations = { +struct dentry_operations fuse_dentry_operations = { .d_revalidate = fuse_dentry_revalidate, }; @@ -378,6 +378,7 @@ static int fuse_create_open(struct inode } fuse_put_request(fc, forget_req); d_instantiate(entry, inode); + fuse_invalidate_attr(dir); fuse_change_timeout(entry, &outentry); file = lookup_instantiate_filp(nd, entry, generic_file_open); if (IS_ERR(file)) { @@ -619,6 +620,9 @@ static int fuse_rename(struct inode *old err = req->out.h.error; fuse_put_request(fc, req); if (!err) { + /* ctime changes */ + fuse_invalidate_attr(oldent->d_inode); + fuse_invalidate_attr(olddir); if (olddir != newdir) fuse_invalidate_attr(newdir); --- a/kernel/fuse_i.h Wed Dec 12 14:33:17 2007 +0000 +++ b/kernel/fuse_i.h Wed Dec 12 18:59:43 2007 +0000 @@ -47,6 +47,9 @@ #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23) # define KERNEL_2_6_23_PLUS +#endif +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +# define KERNEL_2_6_24_PLUS #endif #if defined(__arm__) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) @@ -647,3 +650,5 @@ int fuse_valid_type(int m); * Is task allowed to perform filesystem operation? */ int fuse_allow_task(struct fuse_conn *fc, struct task_struct *task); + +extern struct dentry_operations fuse_dentry_operations; --- a/kernel/inode.c Wed Dec 12 14:33:17 2007 +0000 +++ b/kernel/inode.c Wed Dec 12 18:59:43 2007 +0000 @@ -520,21 +520,26 @@ static struct inode *get_root_inode(stru #ifdef HAVE_EXPORTFS_H #include #endif -static struct dentry *fuse_get_dentry(struct super_block *sb, void *vobjp) + +struct fuse_inode_handle { - __u32 *objp = vobjp; - unsigned long nodeid = objp[0]; - __u32 generation = objp[1]; + u64 nodeid; + u32 generation; +}; + +static struct dentry *fuse_get_dentry(struct super_block *sb, + struct fuse_inode_handle *handle) +{ struct inode *inode; struct dentry *entry; - if (nodeid == 0) + if (handle->nodeid == 0) return ERR_PTR(-ESTALE); - inode = ilookup5(sb, nodeid, fuse_inode_eq, &nodeid); + inode = ilookup5(sb, handle->nodeid, fuse_inode_eq, &handle->nodeid); if (!inode) return ERR_PTR(-ESTALE); - if (inode->i_generation != generation) { + if (inode->i_generation != handle->generation) { iput(inode); return ERR_PTR(-ESTALE); } @@ -544,42 +549,130 @@ static struct dentry *fuse_get_dentry(st iput(inode); return ERR_PTR(-ENOMEM); } + entry->d_op = &fuse_dentry_operations; return entry; } -static int fuse_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, - int connectable) +static int fuse_encode_fh(struct dentry *dentry, u32 *fh, int *max_len, + int connectable) { struct inode *inode = dentry->d_inode; int len = *max_len; int type = 1; + u64 nodeid; + u32 generation; - if (len < 2 || (connectable && len < 4)) - return 255; + if (len < 3 || (connectable && len < 6)) + return 255; - len = 2; - fh[0] = get_fuse_inode(inode)->nodeid; - fh[1] = inode->i_generation; + nodeid = get_fuse_inode(inode)->nodeid; + generation = inode->i_generation; + + len = 3; + fh[0] = (u32)(nodeid >> 32); + fh[1] = (u32)(nodeid & 0xffffffff); + fh[2] = generation; + if (connectable && !S_ISDIR(inode->i_mode)) { struct inode *parent; spin_lock(&dentry->d_lock); parent = dentry->d_parent->d_inode; - fh[2] = get_fuse_inode(parent)->nodeid; - fh[3] = parent->i_generation; + nodeid = get_fuse_inode(parent)->nodeid; + generation = parent->i_generation; + + fh[3] = (u32)(nodeid >> 32); + fh[4] = (u32)(nodeid & 0xffffffff); + fh[5] = generation; spin_unlock(&dentry->d_lock); - len = 4; + + len = 6; type = 2; } + *max_len = len; return type; } +#ifdef KERNEL_2_6_24_PLUS +static struct dentry *fuse_fh_to_dentry(struct super_block *sb, + struct fid *fid, int fh_len, int fh_type) +{ + struct fuse_inode_handle handle; + + if (fh_len < 3 || fh_type > 2) + return NULL; + + handle.nodeid = (u64) fid->raw[0] << 32; + handle.nodeid |= (u64) fid->raw[1]; + handle.generation = fid->raw[2]; + return fuse_get_dentry(sb, &handle); +} + +static struct dentry *fuse_fh_to_parent(struct super_block *sb, + struct fid *fid, int fh_len, int fh_type) +{ + struct fuse_inode_handle parent; + + if (fh_type != 2 || fh_len < 6) + return NULL; + + parent.nodeid = (u64) fid->raw[3] << 32; + parent.nodeid |= (u64) fid->raw[4]; + parent.generation = fid->raw[5]; + return fuse_get_dentry(sb, &parent); +} + + +static const struct export_operations fuse_export_operations = { + .fh_to_dentry = fuse_fh_to_dentry, + .fh_to_parent = fuse_fh_to_parent, + .encode_fh = fuse_encode_fh, +}; +#else +static struct dentry *fuse_get_dentry_old(struct super_block *sb, void *objp) +{ + return fuse_get_dentry(sb, objp); +} + +static struct dentry *fuse_decode_fh(struct super_block *sb, u32 *fh, + int fh_len, int fileid_type, + int (*acceptable)(void *context, struct dentry *de), + void *context) +{ + struct fuse_inode_handle handle; + struct fuse_inode_handle parent; + + if (fh_len < 3 || fileid_type > 2) + return NULL; + + if (fileid_type == 2) { + if (fh_len < 6) + return NULL; + + parent.nodeid = (u64) fh[3] << 32; + parent.nodeid |= (u64) fh[4]; + parent.generation = fh[5]; + } else { + parent.nodeid = 0; + parent.generation = 0; + } + + handle.nodeid = (u64) fh[0] << 32; + handle.nodeid |= (u64) fh[1]; + handle.generation = fh[2]; + + return ret = fuse_export_operations. + find_exported_dentry(sb, &handle, &parent, acceptable, context); +} + static struct export_operations fuse_export_operations = { - .get_dentry = fuse_get_dentry, + .get_dentry = fuse_get_dentry_old, .encode_fh = fuse_encode_fh, + .decode_fh = fuse_decode_fh, }; +#endif #endif static struct super_operations fuse_super_operations = { @@ -845,8 +938,12 @@ static decl_subsys(fuse, NULL, NULL); static decl_subsys(fuse, NULL, NULL); static decl_subsys(connections, NULL, NULL); +#ifdef KERNEL_2_6_24_PLUS +static void fuse_inode_init_once(struct kmem_cache *cachep, void *foo) +#else static void fuse_inode_init_once(void *foo, struct kmem_cache *cachep, unsigned long flags) +#endif { struct inode * inode = foo;