diff -uNpar kernel-source-subfs-0.9/subfs.c kernel-source-subfs-0.9.new/subfs.c --- kernel-source-subfs-0.9/subfs.c 2006-12-10 14:40:25 +0300 +++ kernel-source-subfs-0.9.new/subfs.c 2006-12-10 14:41:31 +0300 @@ -25,6 +25,8 @@ #include <asm/signal.h> #include <linux/signal.h> #include <linux/sched.h> +#include <linux/version.h> +#include <linux/rcupdate.h> #include "subfs.h" @@ -94,11 +96,11 @@ static void subfs_send_signal(void) struct task_struct *task = current; int signal = SIGCONT; - read_lock(&tasklist_lock); + rcu_read_lock(); spin_lock_irq(&task->sighand->siglock); sigaddset(&task->pending.signal, signal); spin_unlock_irq(&task->sighand->siglock); - read_unlock(&tasklist_lock); + rcu_read_unlock(); set_tsk_thread_flag(task, TIF_SIGPENDING); return; } @@ -262,9 +264,15 @@ static int subfs_open(struct inode *inod /* Implements the statfs method so df and such will work on the mountpoint. */ +#ifdef NEW_VFS_ROOT_DENTRY_API +static int subfs_statfs(struct dentry *dentry, struct kstatfs *buf) +{ + struct subfs_mount *sfs_mnt = dentry->d_sb->s_fs_info; +#else static int subfs_statfs(struct super_block *sb, struct kstatfs *buf) { struct subfs_mount *sfs_mnt = sb->s_fs_info; +#endif struct vfsmount *child; if (down_interruptible(&sfs_mnt->sem)) return -ERESTARTSYS; @@ -382,33 +390,61 @@ static int proc_opts(struct subfs_mount * subfs_mount structure is pointed to by the s_fs_info field of the * superblock structure. */ +#ifdef NEW_VFS_ROOT_DENTRY_API +static int subfs_get_super(struct file_system_type *fst, + int flags, const char *devname, void *data, + struct vfsmount *mnt) +#else static struct super_block *subfs_get_super(struct file_system_type *fst, int flags, const char *devname, void *data) +#endif { char *device; struct subfs_mount *newmount; int ret; - if (!(newmount = kmalloc(sizeof(struct subfs_mount), GFP_KERNEL))) - return ERR_PTR(-ENOMEM); + if (!(newmount = kmalloc(sizeof(struct subfs_mount), GFP_KERNEL))) { + ret = -ENOMEM; + goto err; + } newmount->req_fs = NULL; newmount->sb = NULL; newmount->mount = NULL; newmount->procuid = 0; sema_init(&newmount->sem, 1); - if (!(device = kmalloc((strlen(devname) + 1), GFP_KERNEL))) - return ERR_PTR(-ENOMEM); + if (!(device = kmalloc((strlen(devname) + 1), GFP_KERNEL))) { + ret = -ENOMEM; + goto err; + } strcpy(device, devname); newmount->device = device; if (!(newmount->helper_prog = - kmalloc(sizeof(SUBMOUNTD_PATH), GFP_KERNEL))) - return ERR_PTR(-ENOMEM); + kmalloc(sizeof(SUBMOUNTD_PATH), GFP_KERNEL))) { + ret = -ENOMEM; + goto err; + } strcpy(newmount->helper_prog, SUBMOUNTD_PATH); if ((ret = proc_opts(newmount, data))) - return ERR_PTR(ret); + goto err; +#ifdef NEW_VFS_ROOT_DENTRY_API + ret = get_sb_nodev(fst, flags, data, subfs_fill_super, mnt); + if (ret) + goto err; + newmount->sb = mnt->mnt_sb; + newmount->sb->s_fs_info = newmount; + return ret; +#else newmount->sb = get_sb_nodev(fst, flags, data, subfs_fill_super); newmount->sb->s_fs_info = newmount; return newmount->sb; +#endif + +err: +#ifdef NEW_VFS_ROOT_DENTRY_API + return ret; +#else + return ERR_PTR(ret); +#endif } diff -uNpar kernel-source-subfs-0.9/subfs.h kernel-source-subfs-0.9.new/subfs.h --- kernel-source-subfs-0.9/subfs.h 2004-02-27 01:54:58 +0300 +++ kernel-source-subfs-0.9.new/subfs.h 2006-12-10 14:40:57 +0300 @@ -19,6 +19,10 @@ #define ROOT_MODE 0777 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17) +#define NEW_VFS_ROOT_DENTRY_API +#endif + struct subfs_mount { char *device; char *options; @@ -33,8 +37,17 @@ struct subfs_mount { static void subfs_kill_super(struct super_block *sb); + +#ifdef NEW_VFS_ROOT_DENTRY_API +static int subfs_get_super(struct file_system_type *fst, + int flags, const char *devname, void *data, struct vfsmount *mnt); +static int subfs_statfs(struct dentry *dentry, struct kstatfs *buf); +#else static struct super_block *subfs_get_super(struct file_system_type *fst, int flags, const char *devname, void *data); +static int subfs_statfs(struct super_block *sb, struct kstatfs *buf); +#endif + static struct vfsmount *get_subfs_vfsmount(struct super_block *sb); static int subfs_fill_super(struct super_block *sb, void *data, int silent); @@ -47,7 +60,6 @@ static int mount_real_fs(struct subfs_mo static void subfs_send_signal(void); static void subfs_set_fs_pwd(struct fs_struct *fs, struct vfsmount *mnt, struct dentry *dentry); -static int subfs_statfs(struct super_block *sb, struct kstatfs *buf); static struct file_system_type subfs_type = {