mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-21 16:18:46 +00:00
fileops: stat() before open()ing in git_futils_readbuffer_updated()
This reverts refactoring done in 13224ea4aa
that introduces a performance regression for NFS when reading files that
don't exist. open() forces a cache invalidation on NFS, while stat()ing a
file just uses the cache and is very quick.
To give a specific example, say you have a repo with a thousand packed
refs. Before this change, looking up every single one ould incur a thousand
slow open() calls. With this change, it's a thousand fast stat() calls.
This commit is contained in:
parent
14da618260
commit
9ccdb21155
@ -147,6 +147,7 @@ int git_futils_readbuffer_fd(git_buf *buf, git_file fd, size_t len)
|
||||
int git_futils_readbuffer_updated(
|
||||
git_buf *buf, const char *path, time_t *mtime, size_t *size, int *updated)
|
||||
{
|
||||
int error = 0;
|
||||
git_file fd;
|
||||
struct stat st;
|
||||
bool changed = false;
|
||||
@ -156,11 +157,15 @@ int git_futils_readbuffer_updated(
|
||||
if (updated != NULL)
|
||||
*updated = 0;
|
||||
|
||||
if ((fd = git_futils_open_ro(path)) < 0)
|
||||
return fd;
|
||||
if (p_stat(path, &st) < 0) {
|
||||
error = errno;
|
||||
giterr_set(GITERR_OS, "Failed to stat '%s'", path);
|
||||
if (error == ENOENT || error == ENOTDIR)
|
||||
return GIT_ENOTFOUND;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (p_fstat(fd, &st) < 0 || S_ISDIR(st.st_mode) || !git__is_sizet(st.st_size+1)) {
|
||||
p_close(fd);
|
||||
if (S_ISDIR(st.st_mode) || !git__is_sizet(st.st_size+1)) {
|
||||
giterr_set(GITERR_OS, "Invalid regular file stat for '%s'", path);
|
||||
return -1;
|
||||
}
|
||||
@ -177,7 +182,6 @@ int git_futils_readbuffer_updated(
|
||||
changed = true;
|
||||
|
||||
if (!changed) {
|
||||
p_close(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -186,6 +190,9 @@ int git_futils_readbuffer_updated(
|
||||
if (size != NULL)
|
||||
*size = (size_t)st.st_size;
|
||||
|
||||
if ((fd = git_futils_open_ro(path)) < 0)
|
||||
return fd;
|
||||
|
||||
if (git_futils_readbuffer_fd(buf, fd, (size_t)st.st_size) < 0) {
|
||||
p_close(fd);
|
||||
return -1;
|
||||
|
Loading…
Reference in New Issue
Block a user