aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/vfs_inode_dotl.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/9p/vfs_inode_dotl.c')
-rw-r--r--fs/9p/vfs_inode_dotl.c59
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
237static int 236static int
238v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, 237v9fs_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
243static int
244v9fs_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;
366out:
367 dput(res);
368 return err;
359 369
360error: 370error:
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
983const struct inode_operations v9fs_dir_inode_operations_dotl = { 993const 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,