@@ -1670,6 +1670,8 @@ static struct dentry *lookup_dcache(const struct qstr *name,
16701670 * dentries - as the matter of fact, this only gets called
16711671 * when directory is guaranteed to have no in-lookup children
16721672 * at all.
1673+ * Will return -ENOENT if name isn't found and LOOKUP_CREATE wasn't passed.
1674+ * Will return -EEXIST if name is found and LOOKUP_EXCL was passed.
16731675 */
16741676struct dentry * lookup_one_qstr_excl (const struct qstr * name ,
16751677 struct dentry * base ,
@@ -1680,7 +1682,7 @@ struct dentry *lookup_one_qstr_excl(const struct qstr *name,
16801682 struct inode * dir = base -> d_inode ;
16811683
16821684 if (dentry )
1683- return dentry ;
1685+ goto found ;
16841686
16851687 /* Don't create child dentry for a dead directory. */
16861688 if (unlikely (IS_DEADDIR (dir )))
@@ -1695,6 +1697,17 @@ struct dentry *lookup_one_qstr_excl(const struct qstr *name,
16951697 dput (dentry );
16961698 dentry = old ;
16971699 }
1700+ found :
1701+ if (IS_ERR (dentry ))
1702+ return dentry ;
1703+ if (d_is_negative (dentry ) && !(flags & LOOKUP_CREATE )) {
1704+ dput (dentry );
1705+ return ERR_PTR (- ENOENT );
1706+ }
1707+ if (d_is_positive (dentry ) && (flags & LOOKUP_EXCL )) {
1708+ dput (dentry );
1709+ return ERR_PTR (- EEXIST );
1710+ }
16981711 return dentry ;
16991712}
17001713EXPORT_SYMBOL (lookup_one_qstr_excl );
@@ -4078,27 +4091,13 @@ static struct dentry *filename_create(int dfd, struct filename *name,
40784091 * '/', and a directory wasn't requested.
40794092 */
40804093 if (last .name [last .len ] && !want_dir )
4081- create_flags = 0 ;
4094+ create_flags &= ~ LOOKUP_CREATE ;
40824095 inode_lock_nested (path -> dentry -> d_inode , I_MUTEX_PARENT );
40834096 dentry = lookup_one_qstr_excl (& last , path -> dentry ,
40844097 reval_flag | create_flags );
40854098 if (IS_ERR (dentry ))
40864099 goto unlock ;
40874100
4088- error = - EEXIST ;
4089- if (d_is_positive (dentry ))
4090- goto fail ;
4091-
4092- /*
4093- * Special case - lookup gave negative, but... we had foo/bar/
4094- * From the vfs_mknod() POV we just have a negative dentry -
4095- * all is fine. Let's be bastards - you had / on the end, you've
4096- * been asking for (non-existent) directory. -ENOENT for you.
4097- */
4098- if (unlikely (!create_flags )) {
4099- error = - ENOENT ;
4100- goto fail ;
4101- }
41024101 if (unlikely (err2 )) {
41034102 error = err2 ;
41044103 goto fail ;
@@ -4445,10 +4444,6 @@ int do_rmdir(int dfd, struct filename *name)
44454444 error = PTR_ERR (dentry );
44464445 if (IS_ERR (dentry ))
44474446 goto exit3 ;
4448- if (!dentry -> d_inode ) {
4449- error = - ENOENT ;
4450- goto exit4 ;
4451- }
44524447 error = security_path_rmdir (& path , dentry );
44534448 if (error )
44544449 goto exit4 ;
@@ -4579,7 +4574,7 @@ int do_unlinkat(int dfd, struct filename *name)
45794574 if (!IS_ERR (dentry )) {
45804575
45814576 /* Why not before? Because we want correct error value */
4582- if (last .name [last .len ] || d_is_negative ( dentry ) )
4577+ if (last .name [last .len ])
45834578 goto slashes ;
45844579 inode = dentry -> d_inode ;
45854580 ihold (inode );
@@ -4613,9 +4608,7 @@ int do_unlinkat(int dfd, struct filename *name)
46134608 return error ;
46144609
46154610slashes :
4616- if (d_is_negative (dentry ))
4617- error = - ENOENT ;
4618- else if (d_is_dir (dentry ))
4611+ if (d_is_dir (dentry ))
46194612 error = - EISDIR ;
46204613 else
46214614 error = - ENOTDIR ;
@@ -5115,7 +5108,8 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd,
51155108 struct qstr old_last , new_last ;
51165109 int old_type , new_type ;
51175110 struct inode * delegated_inode = NULL ;
5118- unsigned int lookup_flags = 0 , target_flags = LOOKUP_RENAME_TARGET ;
5111+ unsigned int lookup_flags = 0 , target_flags =
5112+ LOOKUP_RENAME_TARGET | LOOKUP_CREATE ;
51195113 bool should_retry = false;
51205114 int error = - EINVAL ;
51215115
@@ -5128,6 +5122,8 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd,
51285122
51295123 if (flags & RENAME_EXCHANGE )
51305124 target_flags = 0 ;
5125+ if (flags & RENAME_NOREPLACE )
5126+ target_flags |= LOOKUP_EXCL ;
51315127
51325128retry :
51335129 error = filename_parentat (olddfd , from , lookup_flags , & old_path ,
@@ -5169,23 +5165,12 @@ int do_renameat2(int olddfd, struct filename *from, int newdfd,
51695165 error = PTR_ERR (old_dentry );
51705166 if (IS_ERR (old_dentry ))
51715167 goto exit3 ;
5172- /* source must exist */
5173- error = - ENOENT ;
5174- if (d_is_negative (old_dentry ))
5175- goto exit4 ;
51765168 new_dentry = lookup_one_qstr_excl (& new_last , new_path .dentry ,
51775169 lookup_flags | target_flags );
51785170 error = PTR_ERR (new_dentry );
51795171 if (IS_ERR (new_dentry ))
51805172 goto exit4 ;
5181- error = - EEXIST ;
5182- if ((flags & RENAME_NOREPLACE ) && d_is_positive (new_dentry ))
5183- goto exit5 ;
51845173 if (flags & RENAME_EXCHANGE ) {
5185- error = - ENOENT ;
5186- if (d_is_negative (new_dentry ))
5187- goto exit5 ;
5188-
51895174 if (!d_is_dir (new_dentry )) {
51905175 error = - ENOTDIR ;
51915176 if (new_last .name [new_last .len ])
0 commit comments