diff options
| -rw-r--r-- | fs/9p/v9fs_vfs.h | 2 | ||||
| -rw-r--r-- | fs/9p/vfs_file.c | 2 | ||||
| -rw-r--r-- | fs/9p/vfs_inode.c | 16 | ||||
| -rw-r--r-- | fs/9p/vfs_inode_dotl.c | 55 | ||||
| -rw-r--r-- | include/net/9p/9p.h | 24 |
5 files changed, 96 insertions, 3 deletions
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 7ac1faec2bde..410ffd6ceb5f 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h | |||
| @@ -83,4 +83,6 @@ static inline void v9fs_invalidate_inode_attr(struct inode *inode) | |||
| 83 | v9inode->cache_validity |= V9FS_INO_INVALID_ATTR; | 83 | v9inode->cache_validity |= V9FS_INO_INVALID_ATTR; |
| 84 | return; | 84 | return; |
| 85 | } | 85 | } |
| 86 | |||
| 87 | int v9fs_open_to_dotl_flags(int flags); | ||
| 86 | #endif | 88 | #endif |
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 3c173fcc2c5a..c2f107583125 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
| @@ -65,7 +65,7 @@ int v9fs_file_open(struct inode *inode, struct file *file) | |||
| 65 | v9inode = V9FS_I(inode); | 65 | v9inode = V9FS_I(inode); |
| 66 | v9ses = v9fs_inode2v9ses(inode); | 66 | v9ses = v9fs_inode2v9ses(inode); |
| 67 | if (v9fs_proto_dotl(v9ses)) | 67 | if (v9fs_proto_dotl(v9ses)) |
| 68 | omode = file->f_flags; | 68 | omode = v9fs_open_to_dotl_flags(file->f_flags); |
| 69 | else | 69 | else |
| 70 | omode = v9fs_uflags2omode(file->f_flags, | 70 | omode = v9fs_uflags2omode(file->f_flags, |
| 71 | v9fs_proto_dotu(v9ses)); | 71 | v9fs_proto_dotu(v9ses)); |
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 3563cace0a2e..9e3ea6ce6951 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
| @@ -553,6 +553,19 @@ v9fs_inode_from_fid(struct v9fs_session_info *v9ses, struct p9_fid *fid, | |||
| 553 | } | 553 | } |
| 554 | 554 | ||
| 555 | /** | 555 | /** |
| 556 | * v9fs_at_to_dotl_flags- convert Linux specific AT flags to | ||
| 557 | * plan 9 AT flag. | ||
| 558 | * @flags: flags to convert | ||
| 559 | */ | ||
| 560 | static int v9fs_at_to_dotl_flags(int flags) | ||
| 561 | { | ||
| 562 | int rflags = 0; | ||
| 563 | if (flags & AT_REMOVEDIR) | ||
| 564 | rflags |= P9_DOTL_AT_REMOVEDIR; | ||
| 565 | return rflags; | ||
| 566 | } | ||
| 567 | |||
| 568 | /** | ||
| 556 | * v9fs_remove - helper function to remove files and directories | 569 | * v9fs_remove - helper function to remove files and directories |
| 557 | * @dir: directory inode that is being deleted | 570 | * @dir: directory inode that is being deleted |
| 558 | * @dentry: dentry that is being deleted | 571 | * @dentry: dentry that is being deleted |
| @@ -579,7 +592,8 @@ static int v9fs_remove(struct inode *dir, struct dentry *dentry, int flags) | |||
| 579 | return retval; | 592 | return retval; |
| 580 | } | 593 | } |
| 581 | if (v9fs_proto_dotl(v9ses)) | 594 | if (v9fs_proto_dotl(v9ses)) |
| 582 | retval = p9_client_unlinkat(dfid, dentry->d_name.name, flags); | 595 | retval = p9_client_unlinkat(dfid, dentry->d_name.name, |
| 596 | v9fs_at_to_dotl_flags(flags)); | ||
| 583 | if (retval == -EOPNOTSUPP) { | 597 | if (retval == -EOPNOTSUPP) { |
| 584 | /* Try the one based on path */ | 598 | /* Try the one based on path */ |
| 585 | v9fid = v9fs_fid_clone(dentry); | 599 | v9fid = v9fs_fid_clone(dentry); |
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index a3f2540cc4b2..aded79fcd5cf 100644 --- 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_session_info *v9ses, struct p9_fid *fid, | |||
| 191 | return inode; | 191 | return inode; |
| 192 | } | 192 | } |
| 193 | 193 | ||
| 194 | struct dotl_openflag_map { | ||
| 195 | int open_flag; | ||
| 196 | int dotl_flag; | ||
| 197 | }; | ||
| 198 | |||
| 199 | static int v9fs_mapped_dotl_flags(int flags) | ||
| 200 | { | ||
| 201 | int i; | ||
| 202 | int rflags = 0; | ||
| 203 | struct dotl_openflag_map dotl_oflag_map[] = { | ||
| 204 | { O_CREAT, P9_DOTL_CREATE }, | ||
| 205 | { O_EXCL, P9_DOTL_EXCL }, | ||
| 206 | { O_NOCTTY, P9_DOTL_NOCTTY }, | ||
| 207 | { O_TRUNC, P9_DOTL_TRUNC }, | ||
| 208 | { O_APPEND, P9_DOTL_APPEND }, | ||
| 209 | { O_NONBLOCK, P9_DOTL_NONBLOCK }, | ||
| 210 | { O_DSYNC, P9_DOTL_DSYNC }, | ||
| 211 | { FASYNC, P9_DOTL_FASYNC }, | ||
| 212 | { O_DIRECT, P9_DOTL_DIRECT }, | ||
| 213 | { O_LARGEFILE, P9_DOTL_LARGEFILE }, | ||
| 214 | { O_DIRECTORY, P9_DOTL_DIRECTORY }, | ||
| 215 | { O_NOFOLLOW, P9_DOTL_NOFOLLOW }, | ||
| 216 | { O_NOATIME, P9_DOTL_NOATIME }, | ||
| 217 | { O_CLOEXEC, P9_DOTL_CLOEXEC }, | ||
| 218 | { O_SYNC, P9_DOTL_SYNC}, | ||
| 219 | }; | ||
| 220 | for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) { | ||
| 221 | if (flags & dotl_oflag_map[i].open_flag) | ||
| 222 | rflags |= dotl_oflag_map[i].dotl_flag; | ||
| 223 | } | ||
| 224 | return rflags; | ||
| 225 | } | ||
| 226 | |||
| 227 | /** | ||
| 228 | * v9fs_open_to_dotl_flags- convert Linux specific open flags to | ||
| 229 | * plan 9 open flag. | ||
| 230 | * @flags: flags to convert | ||
| 231 | */ | ||
| 232 | int v9fs_open_to_dotl_flags(int flags) | ||
| 233 | { | ||
| 234 | int rflags = 0; | ||
| 235 | |||
| 236 | /* | ||
| 237 | * We have same bits for P9_DOTL_READONLY, P9_DOTL_WRONLY | ||
| 238 | * and P9_DOTL_NOACCESS | ||
| 239 | */ | ||
| 240 | rflags |= flags & O_ACCMODE; | ||
| 241 | rflags |= v9fs_mapped_dotl_flags(flags); | ||
| 242 | |||
| 243 | return rflags; | ||
| 244 | } | ||
| 245 | |||
| 194 | /** | 246 | /** |
| 195 | * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol. | 247 | * v9fs_vfs_create_dotl - VFS hook to create files for 9P2000.L protocol. |
| 196 | * @dir: directory inode that is being created | 248 | * @dir: directory inode that is being created |
| @@ -259,7 +311,8 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, int omode, | |||
| 259 | "Failed to get acl values in creat %d\n", err); | 311 | "Failed to get acl values in creat %d\n", err); |
| 260 | goto error; | 312 | goto error; |
| 261 | } | 313 | } |
| 262 | err = p9_client_create_dotl(ofid, name, flags, mode, gid, &qid); | 314 | err = p9_client_create_dotl(ofid, name, v9fs_open_to_dotl_flags(flags), |
| 315 | mode, gid, &qid); | ||
| 263 | if (err < 0) { | 316 | if (err < 0) { |
| 264 | P9_DPRINTK(P9_DEBUG_VFS, | 317 | P9_DPRINTK(P9_DEBUG_VFS, |
| 265 | "p9_client_open_dotl failed in creat %d\n", | 318 | "p9_client_open_dotl failed in creat %d\n", |
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h index 342dcf13d039..957ab99897a1 100644 --- a/include/net/9p/9p.h +++ b/include/net/9p/9p.h | |||
| @@ -288,6 +288,30 @@ enum p9_perm_t { | |||
| 288 | P9_DMSETVTX = 0x00010000, | 288 | P9_DMSETVTX = 0x00010000, |
| 289 | }; | 289 | }; |
| 290 | 290 | ||
| 291 | /* 9p2000.L open flags */ | ||
| 292 | #define P9_DOTL_RDONLY 00000000 | ||
| 293 | #define P9_DOTL_WRONLY 00000001 | ||
| 294 | #define P9_DOTL_RDWR 00000002 | ||
| 295 | #define P9_DOTL_NOACCESS 00000003 | ||
| 296 | #define P9_DOTL_CREATE 00000100 | ||
| 297 | #define P9_DOTL_EXCL 00000200 | ||
| 298 | #define P9_DOTL_NOCTTY 00000400 | ||
| 299 | #define P9_DOTL_TRUNC 00001000 | ||
| 300 | #define P9_DOTL_APPEND 00002000 | ||
| 301 | #define P9_DOTL_NONBLOCK 00004000 | ||
| 302 | #define P9_DOTL_DSYNC 00010000 | ||
| 303 | #define P9_DOTL_FASYNC 00020000 | ||
| 304 | #define P9_DOTL_DIRECT 00040000 | ||
| 305 | #define P9_DOTL_LARGEFILE 00100000 | ||
| 306 | #define P9_DOTL_DIRECTORY 00200000 | ||
| 307 | #define P9_DOTL_NOFOLLOW 00400000 | ||
| 308 | #define P9_DOTL_NOATIME 01000000 | ||
| 309 | #define P9_DOTL_CLOEXEC 02000000 | ||
| 310 | #define P9_DOTL_SYNC 04000000 | ||
| 311 | |||
| 312 | /* 9p2000.L at flags */ | ||
| 313 | #define P9_DOTL_AT_REMOVEDIR 0x200 | ||
| 314 | |||
| 291 | /** | 315 | /** |
| 292 | * enum p9_qid_t - QID types | 316 | * enum p9_qid_t - QID types |
| 293 | * @P9_QTDIR: directory | 317 | * @P9_QTDIR: directory |
