@@ -82,4 +82,6 @@ static inline void v9fs_invalidate_inode_attr(struct inode *inode)
v9inode->cache_validity |= V9FS_INO_INVALID_ATTR;
return;
}
+
+int v9fs_open_to_dotl_flags(int flags);
#endif
@@ -65,7 +65,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
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));
@@ -553,6 +553,19 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid,
}
/**
+ * v9fs_at_to_dotl_flags- convert Linux specific AT flags to
+ * plan 9 AT flag.
+ * @flags: flags to convert
+ */
+static int v9fs_at_to_dotl_flags(int flags)
+{
+ int rflags = 0;
+ if (flags & AT_REMOVEDIR)
+ rflags |= P9_DOTL_AT_REMOVEDIR;
+ return rflags;
+}
+
+/**
* v9fs_remove - helper function to remove files and directories
* @dir: directory inode that is being deleted
* @dentry: dentry that is being deleted
@@ -579,7 +592,8 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags)
return retval;
}
if (v9fs_proto_dotl(v9ses))
- retval = p9_client_unlinkat(dfid, dentry->d_name.name, flags);
+ retval = p9_client_unlinkat(dfid, dentry->d_name.name,
+ v9fs_at_to_dotl_flags(flags));
if (retval == -EOPNOTSUPP) {
/* Try the one based on path */
v9fid = v9fs_fid_clone(dentry);
@@ -192,6 +192,52 @@ v9fs_inode_from_fid_dotl(struct v9fs_session_info *v9ses, struct p9_fid *fid,
}
/**
+ * 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;
+
+ if (flags & O_WRONLY)
+ rflags |= P9_DOTL_WRONLY;
+ if (flags & O_RDWR)
+ rflags |= P9_DOTL_RDWR;
+ if (flags & O_CREAT)
+ rflags |= P9_DOTL_CREAT;
+ if (flags & O_EXCL)
+ rflags |= P9_DOTL_EXCL;
+ if (flags & O_NOCTTY)
+ rflags |= P9_DOTL_NOCTTY;
+ if (flags & O_TRUNC)
+ rflags |= P9_DOTL_TRUNC;
+ if (flags & O_APPEND)
+ rflags |= P9_DOTL_APPEND;
+ if (flags & O_NONBLOCK)
+ rflags |= P9_DOTL_NONBLOCK;
+ if (flags & O_DSYNC)
+ rflags |= P9_DOTL_DSYNC;
+ if (flags & FASYNC)
+ rflags |= P9_DOTL_FASYNC;
+ if (flags & O_DIRECT)
+ rflags |= P9_DOTL_DIRECT;
+ if (flags & O_LARGEFILE)
+ rflags |= P9_DOTL_LARGEFILE;
+ if (flags & O_DIRECTORY)
+ rflags |= P9_DOTL_DIRECTORY;
+ if (flags & O_NOFOLLOW)
+ rflags |= P9_DOTL_NOFOLLOW;
+ if (flags & O_NOATIME)
+ rflags |= P9_DOTL_NOATIME;
+ if (flags & O_CLOEXEC)
+ rflags |= P9_DOTL_CLOEXEC;
+ if (flags & O_SYNC)
+ rflags |= P9_DOTL_SYNC;
+ return rflags;
+}
+
+/**
* v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol.
* @dir: directory inode that is being created
* @dentry: dentry that is being deleted
@@ -259,7 +305,8 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode,
"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",
@@ -288,6 +288,29 @@ 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_CREAT 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