@@ -219,6 +219,7 @@ static int __cifs_do_create(struct inode *dir, struct dentry *direntry,
219219 int rdwr_for_fscache = 0 ;
220220 __le32 lease_flags = 0 ;
221221
222+ * inode = NULL ;
222223 * oplock = 0 ;
223224 if (tcon -> ses -> server -> oplocks )
224225 * oplock = REQ_OPLOCK ;
@@ -462,7 +463,6 @@ static int __cifs_do_create(struct inode *dir, struct dentry *direntry,
462463 goto out_err ;
463464 }
464465
465- d_drop (direntry );
466466 * inode = newinode ;
467467 return rc ;
468468
@@ -478,11 +478,11 @@ static int cifs_do_create(struct inode *dir, struct dentry *direntry,
478478 unsigned int xid , struct tcon_link * tlink ,
479479 unsigned int oflags , umode_t mode ,
480480 __u32 * oplock , struct cifs_fid * fid ,
481- struct cifs_open_info_data * buf )
481+ struct cifs_open_info_data * buf ,
482+ struct inode * * inode )
482483{
483484 void * page = alloc_dentry_path ();
484485 const char * full_path ;
485- struct inode * inode ;
486486 int rc ;
487487
488488 full_path = build_path_from_dentry (direntry , page );
@@ -491,9 +491,7 @@ static int cifs_do_create(struct inode *dir, struct dentry *direntry,
491491 } else {
492492 rc = __cifs_do_create (dir , direntry , full_path , xid ,
493493 tlink , oflags , mode , oplock ,
494- fid , buf , & inode );
495- if (!rc )
496- d_add (direntry , inode );
494+ fid , buf , inode );
497495 }
498496 free_dentry_path (page );
499497 return rc ;
@@ -504,13 +502,13 @@ static int cifs_do_create(struct inode *dir, struct dentry *direntry,
504502 * Look up, create and open a CIFS file.
505503 *
506504 * The initial dentry state is in-lookup or hashed-negative. On success, dentry
507- * will become hashed-positive by calling d_drop() & d_add(), respectively.
505+ * will become hashed-positive by calling d_splice_alias() if in-lookup,
506+ * otherwise d_instantiate().
508507 */
509- int
510- cifs_atomic_open (struct inode * inode , struct dentry * direntry ,
511- struct file * file , unsigned int oflags , umode_t mode )
508+ int cifs_atomic_open (struct inode * dir , struct dentry * direntry ,
509+ struct file * file , unsigned int oflags , umode_t mode )
512510{
513- struct cifs_sb_info * cifs_sb = CIFS_SB (inode );
511+ struct cifs_sb_info * cifs_sb = CIFS_SB (dir );
514512 struct cifs_open_info_data buf = {};
515513 struct TCP_Server_Info * server ;
516514 struct cifsFileInfo * file_info ;
@@ -519,6 +517,8 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
519517 struct tcon_link * tlink ;
520518 struct cifs_tcon * tcon ;
521519 unsigned int sbflags ;
520+ struct dentry * alias ;
521+ struct inode * inode ;
522522 unsigned int xid ;
523523 __u32 oplock ;
524524 int rc ;
@@ -545,13 +545,13 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
545545 if (!d_in_lookup (direntry ))
546546 return - ENOENT ;
547547
548- return finish_no_open (file , cifs_lookup (inode , direntry , 0 ));
548+ return finish_no_open (file , cifs_lookup (dir , direntry , 0 ));
549549 }
550550
551551 xid = get_xid ();
552552
553553 cifs_dbg (FYI , "parent inode = 0x%p name is: %pd and dentry = 0x%p\n" ,
554- inode , direntry , direntry );
554+ dir , direntry , direntry );
555555
556556 tlink = cifs_sb_tlink (cifs_sb );
557557 if (IS_ERR (tlink )) {
@@ -572,13 +572,21 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
572572
573573 cifs_add_pending_open (& fid , tlink , & open );
574574
575- rc = cifs_do_create (inode , direntry , xid , tlink , oflags , mode ,
576- & oplock , & fid , & buf );
575+ rc = cifs_do_create (dir , direntry , xid , tlink , oflags , mode ,
576+ & oplock , & fid , & buf , & inode );
577577 if (rc ) {
578578 cifs_del_pending_open (& open );
579579 goto out ;
580580 }
581581
582+ if (d_in_lookup (direntry )) {
583+ alias = d_splice_alias (inode , direntry );
584+ if (!IS_ERR_OR_NULL (alias ))
585+ direntry = alias ;
586+ } else {
587+ d_instantiate (direntry , inode );
588+ }
589+
582590 if ((oflags & (O_CREAT | O_EXCL )) == (O_CREAT | O_EXCL ))
583591 file -> f_mode |= FMODE_CREATED ;
584592
@@ -622,11 +630,12 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
622630 * Create a CIFS file.
623631 *
624632 * The initial dentry state is hashed-negative. On success, dentry will become
625- * hashed-positive by calling d_drop() & d_add(), respectively .
633+ * hashed-positive by calling d_instantiate() .
626634 */
627- int cifs_create (struct mnt_idmap * idmap , struct inode * inode ,
635+ int cifs_create (struct mnt_idmap * idmap , struct inode * dir ,
628636 struct dentry * direntry , umode_t mode , bool excl )
629637{
638+ struct cifs_sb_info * cifs_sb = CIFS_SB (dir );
630639 int rc ;
631640 unsigned int xid = get_xid ();
632641 /*
@@ -640,19 +649,20 @@ int cifs_create(struct mnt_idmap *idmap, struct inode *inode,
640649 struct tcon_link * tlink ;
641650 struct cifs_tcon * tcon ;
642651 struct TCP_Server_Info * server ;
652+ struct inode * inode ;
643653 struct cifs_fid fid ;
644654 __u32 oplock ;
645655 struct cifs_open_info_data buf = {};
646656
647657 cifs_dbg (FYI , "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n" ,
648- inode , direntry , direntry );
658+ dir , direntry , direntry );
649659
650- if (unlikely (cifs_forced_shutdown (CIFS_SB ( inode -> i_sb ) ))) {
660+ if (unlikely (cifs_forced_shutdown (cifs_sb ))) {
651661 rc = smb_EIO (smb_eio_trace_forced_shutdown );
652662 goto out_free_xid ;
653663 }
654664
655- tlink = cifs_sb_tlink (CIFS_SB ( inode -> i_sb ) );
665+ tlink = cifs_sb_tlink (cifs_sb );
656666 rc = PTR_ERR (tlink );
657667 if (IS_ERR (tlink ))
658668 goto out_free_xid ;
@@ -663,9 +673,13 @@ int cifs_create(struct mnt_idmap *idmap, struct inode *inode,
663673 if (server -> ops -> new_lease_key )
664674 server -> ops -> new_lease_key (& fid );
665675
666- rc = cifs_do_create (inode , direntry , xid , tlink , oflags , mode , & oplock , & fid , & buf );
667- if (!rc && server -> ops -> close )
668- server -> ops -> close (xid , tcon , & fid );
676+ rc = cifs_do_create (dir , direntry , xid , tlink , oflags ,
677+ mode , & oplock , & fid , & buf , & inode );
678+ if (!rc ) {
679+ d_instantiate (direntry , inode );
680+ if (server -> ops -> close )
681+ server -> ops -> close (xid , tcon , & fid );
682+ }
669683
670684 cifs_free_open_info (& buf );
671685 cifs_put_tlink (tlink );
@@ -1035,7 +1049,7 @@ static int set_tmpfile_attr(const unsigned int xid, unsigned int oflags,
10351049 * Create a hidden temporary CIFS file with delete-on-close bit set.
10361050 *
10371051 * The initial dentry state is unhashed-negative. On success, dentry will
1038- * become unhashed-positive by calling d_drop() & d_instantiate(), respectively .
1052+ * become unhashed-positive by calling d_instantiate().
10391053 */
10401054int cifs_tmpfile (struct mnt_idmap * idmap , struct inode * dir ,
10411055 struct file * file , umode_t mode )
0 commit comments