--- /dev/null
+From f88657ce3f9713a0c62101dffb0e972a979e77b9 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Date: Wed, 3 Aug 2011 19:55:32 +0530
+Subject: fs/9p: Add OS dependent open flags in 9p protocol
+
+From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+
+commit f88657ce3f9713a0c62101dffb0e972a979e77b9 upstream.
+
+Some of the flags are OS/arch dependent we add a 9p
+protocol value which maps to asm-generic/fcntl.h values in Linux
+Based on the original patch from Venkateswararao Jujjuri <jvrao@linux.vnet.ibm.com>
+
+[extra comments from author as to why this needs to go to stable:
+
+Earlier for different operation such as open we used the values of open
+flag as defined by the OS. But some of these flags such as O_DIRECT are
+arch dependent. So if we have the 9p client and server running on
+different architectures, we end up with client sending client
+architecture value of these open flag and server will try to map these
+values to what its architecture states. For ex: O_DIRECT on a x86 client
+maps to
+
+#define O_DIRECT 00040000
+
+Where as on sparc server it will maps to
+
+#define O_DIRECT 0x100000
+
+Hence we need to map these open flags to OS/arch independent flag
+values. Getting these changes to an early version of kernel ensures us
+that we work with different combination of client and server. We should
+ideally backport this patch to all possible kernel version.]
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Signed-off-by: Harsh Prateek Bora <harsh@linux.vnet.ibm.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/9p/v9fs_vfs.h | 2 +
+ fs/9p/vfs_file.c | 2 -
+ fs/9p/vfs_inode_dotl.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++-
+ include/net/9p/9p.h | 24 +++++++++++++++++++++
+ 4 files changed, 81 insertions(+), 2 deletions(-)
+
+--- a/fs/9p/v9fs_vfs.h
++++ b/fs/9p/v9fs_vfs.h
+@@ -82,4 +82,6 @@ static inline void v9fs_invalidate_inode
+ v9inode->cache_validity |= V9FS_INO_INVALID_ATTR;
+ return;
+ }
++
++int v9fs_open_to_dotl_flags(int flags);
+ #endif
+--- a/fs/9p/vfs_file.c
++++ b/fs/9p/vfs_file.c
+@@ -65,7 +65,7 @@ int v9fs_file_open(struct inode *inode,
+ v9inode = V9FS_I(inode);
+ v9ses = v9fs_inode2v9ses(inode);
+ if (v9fs_proto_dotl(v9ses))
+- omode = file->f_flags;
++ omode = v9fs_open_to_dotl_flags(file->f_flags);
+ else
+ omode = v9fs_uflags2omode(file->f_flags,
+ v9fs_proto_dotu(v9ses));
+--- a/fs/9p/vfs_inode_dotl.c
++++ b/fs/9p/vfs_inode_dotl.c
+@@ -191,6 +191,58 @@ v9fs_inode_from_fid_dotl(struct v9fs_ses
+ return inode;
+ }
+
++struct dotl_openflag_map {
++ int open_flag;
++ int dotl_flag;
++};
++
++static int v9fs_mapped_dotl_flags(int flags)
++{
++ int i;
++ int rflags = 0;
++ struct dotl_openflag_map dotl_oflag_map[] = {
++ { O_CREAT, P9_DOTL_CREATE },
++ { O_EXCL, P9_DOTL_EXCL },
++ { O_NOCTTY, P9_DOTL_NOCTTY },
++ { O_TRUNC, P9_DOTL_TRUNC },
++ { O_APPEND, P9_DOTL_APPEND },
++ { O_NONBLOCK, P9_DOTL_NONBLOCK },
++ { O_DSYNC, P9_DOTL_DSYNC },
++ { FASYNC, P9_DOTL_FASYNC },
++ { O_DIRECT, P9_DOTL_DIRECT },
++ { O_LARGEFILE, P9_DOTL_LARGEFILE },
++ { O_DIRECTORY, P9_DOTL_DIRECTORY },
++ { O_NOFOLLOW, P9_DOTL_NOFOLLOW },
++ { O_NOATIME, P9_DOTL_NOATIME },
++ { O_CLOEXEC, P9_DOTL_CLOEXEC },
++ { O_SYNC, P9_DOTL_SYNC},
++ };
++ for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) {
++ if (flags & dotl_oflag_map[i].open_flag)
++ rflags |= dotl_oflag_map[i].dotl_flag;
++ }
++ return rflags;
++}
++
++/**
++ * v9fs_open_to_dotl_flags- convert Linux specific open flags to
++ * plan 9 open flag.
++ * @flags: flags to convert
++ */
++int v9fs_open_to_dotl_flags(int flags)
++{
++ int rflags = 0;
++
++ /*
++ * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY
++ * and P9_DOTL_NOACCESS
++ */
++ rflags |= flags & O_ACCMODE;
++ rflags |= v9fs_mapped_dotl_flags(flags);
++
++ return rflags;
++}
++
+ /**
+ * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
+ * @dir: directory inode that is being created
+@@ -259,7 +311,8 @@ v9fs_vfs_create_dotl(struct inode *dir,
+ "Failed to get acl values in creat %d\n", err);
+ goto error;
+ }
+- err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid);
++ err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags),
++ mode, gid, &qid);
+ if (err < 0) {
+ P9_DPRINTK(P9_DEBUG_VFS,
+ "p9_client_open_dotl failed in creat %d\n",
+--- a/include/net/9p/9p.h
++++ b/include/net/9p/9p.h
+@@ -278,6 +278,30 @@ enum p9_perm_t {
+ P9_DMSETVTX = 0x00010000,
+ };
+
++/* 9p2000.L open flags */
++#define P9_DOTL_RDONLY 00000000
++#define P9_DOTL_WRONLY 00000001
++#define P9_DOTL_RDWR 00000002
++#define P9_DOTL_NOACCESS 00000003
++#define P9_DOTL_CREATE 00000100
++#define P9_DOTL_EXCL 00000200
++#define P9_DOTL_NOCTTY 00000400
++#define P9_DOTL_TRUNC 00001000
++#define P9_DOTL_APPEND 00002000
++#define P9_DOTL_NONBLOCK 00004000
++#define P9_DOTL_DSYNC 00010000
++#define P9_DOTL_FASYNC 00020000
++#define P9_DOTL_DIRECT 00040000
++#define P9_DOTL_LARGEFILE 00100000
++#define P9_DOTL_DIRECTORY 00200000
++#define P9_DOTL_NOFOLLOW 00400000
++#define P9_DOTL_NOATIME 01000000
++#define P9_DOTL_CLOEXEC 02000000
++#define P9_DOTL_SYNC 04000000
++
++/* 9p2000.L at flags */
++#define P9_DOTL_AT_REMOVEDIR 0x200
++
+ /**
+ * enum p9_qid_t - QID types
+ * @P9_QTDIR: directory