From: Alan T. DeKok Date: Mon, 26 Feb 2018 19:41:41 +0000 (-0500) Subject: don't lock the file if it has been renamed X-Git-Tag: release_3_0_17~55 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=abbbf09df831;p=thirdparty%2Ffreeradius-server.git don't lock the file if it has been renamed --- diff --git a/src/main/exfile.c b/src/main/exfile.c index 5a3953753ee..4802d94cbad 100644 --- a/src/main/exfile.c +++ b/src/main/exfile.c @@ -33,6 +33,8 @@ typedef struct exfile_entry_t { int fd; //!< File descriptor associated with an entry. uint32_t hash; //!< Hash for cheap comparison. time_t last_used; //!< Last time the entry was used. + dev_t st_dev; //!< device inode + ino_t st_ino; //!< inode number char *filename; //!< Filename. } exfile_entry_t; @@ -325,6 +327,16 @@ int exfile_open(exfile_t *ef, char const *filename, mode_t permissions) PTHREAD_MUTEX_UNLOCK(&(ef->mutex)); return -1; } + + if (fstat(ef->entries[i].fd, &st) < 0) goto error; + + /* + * Remember which device and inode this file is + * for. + */ + ef->entries[i].st_dev = st.st_dev; + ef->entries[i].st_ino = st.st_ino; + } else { i = found; } @@ -378,8 +390,7 @@ int exfile_open(exfile_t *ef, char const *filename, mode_t permissions) } /* - * Maybe someone deleted the file while we were waiting - * for the lock. If so, re-open it. + * See which file it really is. */ if (fstat(ef->entries[i].fd, &st) < 0) { fr_strerror_printf("Failed to stat file %s: %s", filename, strerror(errno)); @@ -387,16 +398,19 @@ int exfile_open(exfile_t *ef, char const *filename, mode_t permissions) } /* - * It's unlinked from the file system, close the FD and - * try to re-open it. + * Maybe the file was unlinked from the file system, OR + * the file we opened is NOT the one we had cached. If + * so, close the file and re-open it from scratch. */ - if (st.st_nlink == 0) { + if ((st.st_nlink == 0) || + (st.st_dev != ef->entries[i].st_dev) || + (st.st_ino != ef->entries[i].st_ino)) { close(ef->entries[i].fd); goto reopen; } /* - * If we're appending, eek to the end of the file before + * If we're appending, seek to the end of the file before * returning the FD to the caller. */ (void) lseek(ef->entries[i].fd, 0, SEEK_END);