From: Gabriel Ivăncescu gabrielopcode@gmail.com
This avoids the fstat call check, reducing syscalls in the most common case.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- server/fd.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/server/fd.c b/server/fd.c index 5ccca271b8a..3ccd1acff30 100644 --- a/server/fd.c +++ b/server/fd.c @@ -2733,14 +2733,10 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da }
/* link() expects that the target doesn't exist */ - /* rename() cannot replace files with directories */ - if (create_link || (!fstat( fd->unix_fd, &st ) && S_ISDIR( st.st_mode ))) + if (create_link && unlink( name )) { - if (unlink( name )) - { - file_set_error(); - goto failed; - } + file_set_error(); + goto failed; } }
@@ -2754,8 +2750,18 @@ static void set_fd_name( struct fd *fd, struct fd *root, const char *nameptr, da
if (rename( fd->unix_name, name )) { - file_set_error(); - goto failed; + if (errno != ENOTDIR) + { + file_set_error(); + goto failed; + } + + /* rename() cannot replace files with directories */ + if (unlink( name ) || rename( fd->unix_name, name )) + { + file_set_error(); + goto failed; + } }
if (is_file_executable( fd->unix_name ) != is_file_executable( name ) && !fstat( fd->unix_fd, &st ))