diff options
Diffstat (limited to 'fs/9p/vfs_inode_dotl.c')
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index e3dd2a1e2bfc..40895546e103 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -230,20 +230,25 @@ int v9fs_open_to_dotl_flags(int flags) | |||
230 | * @dir: directory inode that is being created | 230 | * @dir: directory inode that is being created |
231 | * @dentry: dentry that is being deleted | 231 | * @dentry: dentry that is being deleted |
232 | * @mode: create permissions | 232 | * @mode: create permissions |
233 | * @nd: path information | ||
234 | * | 233 | * |
235 | */ | 234 | */ |
236 | 235 | ||
237 | static int | 236 | static int |
238 | v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | 237 | v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, |
239 | struct nameidata *nd) | 238 | bool excl) |
239 | { | ||
240 | return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0); | ||
241 | } | ||
242 | |||
243 | static int | ||
244 | v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, | ||
245 | struct file *file, unsigned flags, umode_t omode, | ||
246 | int *opened) | ||
240 | { | 247 | { |
241 | int err = 0; | 248 | int err = 0; |
242 | gid_t gid; | 249 | gid_t gid; |
243 | int flags; | ||
244 | umode_t mode; | 250 | umode_t mode; |
245 | char *name = NULL; | 251 | char *name = NULL; |
246 | struct file *filp; | ||
247 | struct p9_qid qid; | 252 | struct p9_qid qid; |
248 | struct inode *inode; | 253 | struct inode *inode; |
249 | struct p9_fid *fid = NULL; | 254 | struct p9_fid *fid = NULL; |
@@ -251,19 +256,23 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
251 | struct p9_fid *dfid, *ofid, *inode_fid; | 256 | struct p9_fid *dfid, *ofid, *inode_fid; |
252 | struct v9fs_session_info *v9ses; | 257 | struct v9fs_session_info *v9ses; |
253 | struct posix_acl *pacl = NULL, *dacl = NULL; | 258 | struct posix_acl *pacl = NULL, *dacl = NULL; |
259 | struct dentry *res = NULL; | ||
254 | 260 | ||
255 | v9ses = v9fs_inode2v9ses(dir); | 261 | if (d_unhashed(dentry)) { |
256 | if (nd) | 262 | res = v9fs_vfs_lookup(dir, dentry, 0); |
257 | flags = nd->intent.open.flags; | 263 | if (IS_ERR(res)) |
258 | else { | 264 | return PTR_ERR(res); |
259 | /* | 265 | |
260 | * create call without LOOKUP_OPEN is due | 266 | if (res) |
261 | * to mknod of regular files. So use mknod | 267 | dentry = res; |
262 | * operation. | ||
263 | */ | ||
264 | return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0); | ||
265 | } | 268 | } |
266 | 269 | ||
270 | /* Only creates */ | ||
271 | if (!(flags & O_CREAT) || dentry->d_inode) | ||
272 | return finish_no_open(file, res); | ||
273 | |||
274 | v9ses = v9fs_inode2v9ses(dir); | ||
275 | |||
267 | name = (char *) dentry->d_name.name; | 276 | name = (char *) dentry->d_name.name; |
268 | p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx\n", | 277 | p9_debug(P9_DEBUG_VFS, "name:%s flags:0x%x mode:0x%hx\n", |
269 | name, flags, omode); | 278 | name, flags, omode); |
@@ -272,7 +281,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
272 | if (IS_ERR(dfid)) { | 281 | if (IS_ERR(dfid)) { |
273 | err = PTR_ERR(dfid); | 282 | err = PTR_ERR(dfid); |
274 | p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); | 283 | p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); |
275 | return err; | 284 | goto out; |
276 | } | 285 | } |
277 | 286 | ||
278 | /* clone a fid to use for creation */ | 287 | /* clone a fid to use for creation */ |
@@ -280,7 +289,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
280 | if (IS_ERR(ofid)) { | 289 | if (IS_ERR(ofid)) { |
281 | err = PTR_ERR(ofid); | 290 | err = PTR_ERR(ofid); |
282 | p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); | 291 | p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); |
283 | return err; | 292 | goto out; |
284 | } | 293 | } |
285 | 294 | ||
286 | gid = v9fs_get_fsgid_for_create(dir); | 295 | gid = v9fs_get_fsgid_for_create(dir); |
@@ -345,17 +354,18 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
345 | } | 354 | } |
346 | mutex_unlock(&v9inode->v_mutex); | 355 | mutex_unlock(&v9inode->v_mutex); |
347 | /* Since we are opening a file, assign the open fid to the file */ | 356 | /* Since we are opening a file, assign the open fid to the file */ |
348 | filp = lookup_instantiate_filp(nd, dentry, generic_file_open); | 357 | err = finish_open(file, dentry, generic_file_open, opened); |
349 | if (IS_ERR(filp)) { | 358 | if (err) |
350 | err = PTR_ERR(filp); | ||
351 | goto err_clunk_old_fid; | 359 | goto err_clunk_old_fid; |
352 | } | 360 | file->private_data = ofid; |
353 | filp->private_data = ofid; | ||
354 | #ifdef CONFIG_9P_FSCACHE | 361 | #ifdef CONFIG_9P_FSCACHE |
355 | if (v9ses->cache) | 362 | if (v9ses->cache) |
356 | v9fs_cache_inode_set_cookie(inode, filp); | 363 | v9fs_cache_inode_set_cookie(inode, file); |
357 | #endif | 364 | #endif |
358 | return 0; | 365 | *opened |= FILE_CREATED; |
366 | out: | ||
367 | dput(res); | ||
368 | return err; | ||
359 | 369 | ||
360 | error: | 370 | error: |
361 | if (fid) | 371 | if (fid) |
@@ -364,7 +374,7 @@ err_clunk_old_fid: | |||
364 | if (ofid) | 374 | if (ofid) |
365 | p9_client_clunk(ofid); | 375 | p9_client_clunk(ofid); |
366 | v9fs_set_create_acl(NULL, &dacl, &pacl); | 376 | v9fs_set_create_acl(NULL, &dacl, &pacl); |
367 | return err; | 377 | goto out; |
368 | } | 378 | } |
369 | 379 | ||
370 | /** | 380 | /** |
@@ -982,6 +992,7 @@ out: | |||
982 | 992 | ||
983 | const struct inode_operations v9fs_dir_inode_operations_dotl = { | 993 | const struct inode_operations v9fs_dir_inode_operations_dotl = { |
984 | .create = v9fs_vfs_create_dotl, | 994 | .create = v9fs_vfs_create_dotl, |
995 | .atomic_open = v9fs_vfs_atomic_open_dotl, | ||
985 | .lookup = v9fs_vfs_lookup, | 996 | .lookup = v9fs_vfs_lookup, |
986 | .link = v9fs_vfs_link_dotl, | 997 | .link = v9fs_vfs_link_dotl, |
987 | .symlink = v9fs_vfs_symlink_dotl, | 998 | .symlink = v9fs_vfs_symlink_dotl, |