Hey Vlad, This is the 2.6.25 backport of the NFS-RDMA code. It 100% passes my connectathon tests.
Thanks, Jon
diff --git a/kernel_addons/backport/2.6.25/include/linux/backing-dev.h b/kernel_addons/backport/2.6.25/include/linux/backing-dev.h new file mode 100644 index 0000000..6374cde --- /dev/null +++ b/kernel_addons/backport/2.6.25/include/linux/backing-dev.h @@ -0,0 +1,22 @@ +#ifndef BACKPORT_LINUX_BACK_DEV_H +#define BACKPORT_LINUX_BACK_DEV_H + +#include_next <linux/backing-dev.h> + +static inline int bdi_register(struct backing_dev_info *bdi, struct device *parent, + const char *fmt, ...) +{ + return 0; +} + +static inline int bdi_register_dev(struct backing_dev_info *bdi, dev_t dev) +{ + return bdi_register(bdi, NULL, "%u:%u", MAJOR(dev), MINOR(dev)); +} + +static inline void bdi_unregister(struct backing_dev_info *bdi) +{ + return; +} + +#endif diff --git a/kernel_addons/backport/2.6.25/include/linux/file.h b/kernel_addons/backport/2.6.25/include/linux/file.h new file mode 100644 index 0000000..7c6eacf --- /dev/null +++ b/kernel_addons/backport/2.6.25/include/linux/file.h @@ -0,0 +1,12 @@ +#ifndef BACKPORT_LINUX_FILE_H +#define BACKPORT_LINUX_FILE_H + +#include_next <linux/file.h> +#include <linux/fs.h> + +static inline void drop_file_write_access(struct file *filp) +{ + put_write_access(filp->f_path.dentry->d_inode); +} + +#endif diff --git a/kernel_addons/backport/2.6.25/include/linux/fs.h b/kernel_addons/backport/2.6.25/include/linux/fs.h new file mode 100644 index 0000000..07c1352 --- /dev/null +++ b/kernel_addons/backport/2.6.25/include/linux/fs.h @@ -0,0 +1,34 @@ +#ifndef BACKPORT_LINUX_FS_H +#define BACKPORT_LINUX_FS_H + +#include_next <linux/fs.h> + +#define __locks_copy_lock locks_copy_lock +#define FILE_LOCK_DEFERRED -EINPROGRESS + + +static inline int inode_permission(struct inode *inode, int flags) +{ + return permission(inode, flags, NULL); +} + +static inline int backport_vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) +{ + return vfs_symlink(dir, dentry, oldname, 0); +} + +#ifdef CONFIG_DEBUG_WRITECOUNT +static inline void file_take_write(struct file *f) +{ + WARN_ON(f->f_mnt_write_state != 0); + f->f_mnt_write_state = FILE_MNT_WRITE_TAKEN; +} +#else +static inline void file_take_write(struct file *filp) {} +#endif + + +#define vfs_symlink(_dir, _dentry, _oldname) backport_vfs_symlink(_dir, _dentry, _oldname) + + +#endif diff --git a/kernel_addons/backport/2.6.25/include/linux/kernel.h b/kernel_addons/backport/2.6.25/include/linux/kernel.h new file mode 100644 index 0000000..213ce11 --- /dev/null +++ b/kernel_addons/backport/2.6.25/include/linux/kernel.h @@ -0,0 +1,8 @@ +#ifndef BACKPORT_KERNEL_H_2_6_25 +#define BACKPORT_KERNEL_H_2_6_25 + +#include_next <linux/kernel.h> + +#define USHORT_MAX ((u16)(~0U)) + +#endif diff --git a/kernel_addons/backport/2.6.25/include/linux/mount.h b/kernel_addons/backport/2.6.25/include/linux/mount.h new file mode 100644 index 0000000..978c502 --- /dev/null +++ b/kernel_addons/backport/2.6.25/include/linux/mount.h @@ -0,0 +1,17 @@ +#ifndef BACKPORT_LINUX_MOUNT_H +#define BACKPORT_LINUX_MOUNT_H + +#include_next <linux/mount.h> +#include <linux/fs.h> + +static inline int __mnt_is_readonly(struct vfsmount *mnt) +{ + if (mnt->mnt_sb->s_flags & MS_RDONLY) + return 1; + return 0; +} + +extern int mnt_want_write(struct vfsmount *mnt); +extern void mnt_drop_write(struct vfsmount *mnt); + +#endif diff --git a/kernel_addons/backport/2.6.25/include/linux/proc_fs.h b/kernel_addons/backport/2.6.25/include/linux/proc_fs.h new file mode 100644 index 0000000..79d788a --- /dev/null +++ b/kernel_addons/backport/2.6.25/include/linux/proc_fs.h @@ -0,0 +1,20 @@ +#ifndef BACKPORT_LINUX_PROC_FS_H +#define BACKPORT_LINUX_PROC_FS_H + +#include_next <linux/proc_fs.h> + +static inline struct proc_dir_entry *proc_create_data(const char *name, mode_t mode, + struct proc_dir_entry *parent, + const struct file_operations *proc_fops, + void *data) +{ + struct proc_dir_entry *pde; + + pde = proc_create(name, mode, parent, proc_fops); + if (pde) + pde->data = data; + + return pde; +} + +#endif diff --git a/kernel_addons/backport/2.6.25/include/net/ipv6.h b/kernel_addons/backport/2.6.25/include/net/ipv6.h new file mode 100644 index 0000000..b6123d4 --- /dev/null +++ b/kernel_addons/backport/2.6.25/include/net/ipv6.h @@ -0,0 +1,14 @@ +#ifndef BACKPORT_LINUX_IPV6_H +#define BACKPORT_LINUX_IPV6_H + +#include_next <net/ipv6.h> + +static inline void ipv6_addr_set_v4mapped(const __be32 addr, + struct in6_addr *v4mapped) +{ + ipv6_addr_set(v4mapped, + 0, 0, + htonl(0x0000FFFF), + addr); +} +#endif diff --git a/kernel_addons/backport/2.6.25/include/src/namespace.c b/kernel_addons/backport/2.6.25/include/src/namespace.c new file mode 100644 index 0000000..d86d118 --- /dev/null +++ b/kernel_addons/backport/2.6.25/include/src/namespace.c @@ -0,0 +1,83 @@ +#include <linux/spinlock_types.h> +#include <linux/percpu.h> +#include <linux/mount.h> +#include <linux/module.h> + +struct mnt_writer { + /* + * If holding multiple instances of this lock, they + * must be ordered by cpu number. + */ + spinlock_t lock; + struct lock_class_key lock_class; /* compiles out with !lockdep */ + unsigned long count; + struct vfsmount *mnt; +} ____cacheline_aligned_in_smp; +static DEFINE_PER_CPU(struct mnt_writer, mnt_writers); + +static inline void __clear_mnt_count(struct mnt_writer *cpu_writer) +{ + if (!cpu_writer->mnt) + return; + /* + * This is in case anyone ever leaves an invalid, + * old ->mnt and a count of 0. + */ + if (!cpu_writer->count) + return; + cpu_writer->count = 0; +} + +static inline void use_cpu_writer_for_mount(struct mnt_writer *cpu_writer, + struct vfsmount *mnt) +{ + if (cpu_writer->mnt == mnt) + return; + __clear_mnt_count(cpu_writer); + cpu_writer->mnt = mnt; +} + +int mnt_want_write(struct vfsmount *mnt) +{ + int ret = 0; + struct mnt_writer *cpu_writer; + + cpu_writer = &get_cpu_var(mnt_writers); + spin_lock(&cpu_writer->lock); + if (__mnt_is_readonly(mnt)) { + ret = -EROFS; + goto out; + } + use_cpu_writer_for_mount(cpu_writer, mnt); + cpu_writer->count++; +out: + spin_unlock(&cpu_writer->lock); + put_cpu_var(mnt_writers); + return ret; +} +EXPORT_SYMBOL(mnt_want_write); + +void mnt_drop_write(struct vfsmount *mnt) +{ + struct mnt_writer *cpu_writer; + + cpu_writer = &get_cpu_var(mnt_writers); + spin_lock(&cpu_writer->lock); + + use_cpu_writer_for_mount(cpu_writer, mnt); + if (cpu_writer->count > 0) { + cpu_writer->count--; + } + + spin_unlock(&cpu_writer->lock); + /* + * This could be done right after the spinlock + * is taken because the spinlock keeps us on + * the cpu, and disables preemption. However, + * putting it here bounds the amount that + * __mnt_writers can underflow. Without it, + * we could theoretically wrap __mnt_writers. + */ + put_cpu_var(mnt_writers); +} +EXPORT_SYMBOL(mnt_drop_write); diff --git a/kernel_patches/backport/2.6.25/rnfs_fs.patch b/kernel_patches/backport/2.6.25/rnfs_fs.patch new file mode 100644 index 0000000..342bd8a --- /dev/null +++ b/kernel_patches/backport/2.6.25/rnfs_fs.patch @@ -0,0 +1,175 @@ +diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile +index f646040..9508889 100644 +--- a/drivers/infiniband/core/Makefile ++++ b/drivers/infiniband/core/Makefile +@@ -30,3 +30,5 @@ ib_umad-y := user_mad.o + ib_ucm-y := ucm.o + + ib_uverbs-y := uverbs_main.o uverbs_cmd.o uverbs_marshall.o ++ ++ib_core-y += namespace.o +diff --git a/drivers/infiniband/core/namespace.c b/drivers/infiniband/core/namespace.c +new file mode 100644 +index 0000000..de57f8b +--- /dev/null ++++ b/drivers/infiniband/core/namespace.c +@@ -0,0 +1 @@ ++#include "src/namespace.c" +diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c +index 74f92b7..986d990 100644 +--- a/fs/nfs/dir.c ++++ b/fs/nfs/dir.c +@@ -1907,7 +1907,7 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags) + return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags)); + } + +-int nfs_permission(struct inode *inode, int mask) ++int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) + { + struct rpc_cred *cred; + int res = 0; +@@ -1917,7 +1917,7 @@ int nfs_permission(struct inode *inode, int mask) + if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) + goto out; + /* Is this sys_access() ? */ +- if (mask & MAY_ACCESS) ++ if (nd != NULL && (nd->flags & LOOKUP_ACCESS)) + goto force_lookup; + + switch (inode->i_mode & S_IFMT) { +@@ -1926,7 +1926,8 @@ int nfs_permission(struct inode *inode, int mask) + case S_IFREG: + /* NFSv4 has atomic_open... */ + if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN) +- && (mask & MAY_OPEN)) ++ && nd != NULL ++ && (nd->flags & LOOKUP_OPEN)) + goto out; + break; + case S_IFDIR: +diff --git a/fs/nfs/file.c b/fs/nfs/file.c +index 7846065..9f1bed9 100644 +--- a/fs/nfs/file.c ++++ b/fs/nfs/file.c +@@ -178,8 +178,6 @@ force_reval: + + static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) + { +- loff_t loff; +- + dprintk("NFS: llseek file(%s/%s, %lld, %d)\n", + filp->f_path.dentry->d_parent->d_name.name, + filp->f_path.dentry->d_name.name, +@@ -192,10 +190,7 @@ static loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin) + if (retval < 0) + return (loff_t)retval; + } +- lock_kernel(); /* BKL needed? */ +- loff = generic_file_llseek_unlocked(filp, offset, origin); +- unlock_kernel(); +- return loff; ++ return remote_llseek(filp, offset, origin); + } + + /* +diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c +index 52daefa..d8927e0 100644 +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -1242,7 +1242,7 @@ static inline void nfs4_init_once(struct nfs_inode *nfsi) + #endif + } + +-static void init_once(void *foo) ++static void init_once(struct kmem_cache *cachep, void *foo) + { + struct nfs_inode *nfsi = (struct nfs_inode *) foo; + +diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c +index 66df08d..2f285ef 100644 +--- a/fs/nfs/namespace.c ++++ b/fs/nfs/namespace.c +@@ -129,7 +129,7 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) + goto out_err; + + mntget(mnt); +- err = do_add_mount(mnt, &nd->path, nd->path.mnt->mnt_flags|MNT_SHRINKABLE, ++ err = do_add_mount(mnt, nd, nd->path.mnt->mnt_flags|MNT_SHRINKABLE, + &nfs_automount_list); + if (err < 0) { + mntput(mnt); +diff --git a/fs/nfs/super.c b/fs/nfs/super.c +index e9b2017..19d380c 100644 +--- a/fs/nfs/super.c ++++ b/fs/nfs/super.c +@@ -201,7 +201,7 @@ static match_table_t nfs_secflavor_tokens = { + }; + + +-static void nfs_umount_begin(struct super_block *); ++static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags); + static int nfs_statfs(struct dentry *, struct kstatfs *); + static int nfs_show_options(struct seq_file *, struct vfsmount *); + static int nfs_show_stats(struct seq_file *, struct vfsmount *); +@@ -649,11 +649,13 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt) + * Begin unmount by attempting to remove all automounted mountpoints we added + * in response to xdev traversals and referrals + */ +-static void nfs_umount_begin(struct super_block *sb) ++static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags) + { +- struct nfs_server *server = NFS_SB(sb); ++ struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb); + struct rpc_clnt *rpc; + ++ if (!(flags & MNT_FORCE)) ++ return; + /* -EIO all pending I/O */ + rpc = server->client_acl; + if (!IS_ERR(rpc)) +diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h +index 78a5922..3370498 100644 +--- a/include/linux/nfs_fs.h ++++ b/include/linux/nfs_fs.h +@@ -331,7 +331,7 @@ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *); + extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); + extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr); + extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); +-extern int nfs_permission(struct inode *, int); ++extern int nfs_permission(struct inode *, int, struct nameidata *); + extern int nfs_open(struct inode *, struct file *); + extern int nfs_release(struct inode *, struct file *); + extern int nfs_attribute_timeout(struct inode *inode); +diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c +index 23a2b8f..5a9b0e7 100644 +--- a/net/sunrpc/rpc_pipe.c ++++ b/net/sunrpc/rpc_pipe.c +@@ -897,7 +897,7 @@ static struct file_system_type rpc_pipe_fs_type = { + }; + + static void +-init_once(void *foo) ++init_once(struct kmem_cache * cachep, void *foo) + { + struct rpc_inode *rpci = (struct rpc_inode *) foo; + +diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c +index 5a32cb7..3fba57a 100644 +--- a/net/sunrpc/svc.c ++++ b/net/sunrpc/svc.c +@@ -310,13 +310,12 @@ svc_pool_map_set_cpumask(struct task_struct *task, unsigned int pidx) + switch (m->mode) { + case SVC_POOL_PERCPU: + { +- set_cpus_allowed_ptr(task, &cpumask_of_cpu(node)); ++ set_cpus_allowed(task, cpumask_of_cpu(node)); + break; + } + case SVC_POOL_PERNODE: + { +- node_to_cpumask_ptr(nodecpumask, node); +- set_cpus_allowed_ptr(task, nodecpumask); ++ set_cpus_allowed(task, node_to_cpumask(node)); + break; + } + }
_______________________________________________ ewg mailing list ewg@lists.openfabrics.org http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ewg