зеркало из https://github.com/microsoft/git.git
Merge branch 'jc/git-open-cloexec'
The codeflow of setting NOATIME and CLOEXEC on file descriptors Git opens has been simplified. We may want to drop the tip one, but we'll see. * jc/git-open-cloexec: sha1_file: stop opening files with O_NOATIME git_open_cloexec(): use fcntl(2) w/ FD_CLOEXEC fallback git_open(): untangle possible NOATIME and CLOEXEC interactions
This commit is contained in:
Коммит
02d0457eb4
3
cache.h
3
cache.h
|
@ -1125,7 +1125,8 @@ extern int write_sha1_file(const void *buf, unsigned long len, const char *type,
|
||||||
extern int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type, unsigned char *sha1, unsigned flags);
|
extern int hash_sha1_file_literally(const void *buf, unsigned long len, const char *type, unsigned char *sha1, unsigned flags);
|
||||||
extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
|
extern int pretend_sha1_file(void *, unsigned long, enum object_type, unsigned char *);
|
||||||
extern int force_object_loose(const unsigned char *sha1, time_t mtime);
|
extern int force_object_loose(const unsigned char *sha1, time_t mtime);
|
||||||
extern int git_open(const char *name);
|
extern int git_open_cloexec(const char *name, int flags);
|
||||||
|
#define git_open(name) git_open_cloexec(name, O_RDONLY)
|
||||||
extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size);
|
extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size);
|
||||||
extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz);
|
extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz);
|
||||||
extern int parse_sha1_header(const char *hdr, unsigned long *sizep);
|
extern int parse_sha1_header(const char *hdr, unsigned long *sizep);
|
||||||
|
|
|
@ -156,14 +156,7 @@ void fill_stat_cache_info(struct cache_entry *ce, struct stat *st)
|
||||||
static int ce_compare_data(const struct cache_entry *ce, struct stat *st)
|
static int ce_compare_data(const struct cache_entry *ce, struct stat *st)
|
||||||
{
|
{
|
||||||
int match = -1;
|
int match = -1;
|
||||||
static int cloexec = O_CLOEXEC;
|
int fd = git_open_cloexec(ce->name, O_RDONLY);
|
||||||
int fd = open(ce->name, O_RDONLY | cloexec);
|
|
||||||
|
|
||||||
if ((cloexec & O_CLOEXEC) && fd < 0 && errno == EINVAL) {
|
|
||||||
/* Try again w/o O_CLOEXEC: the kernel might not support it */
|
|
||||||
cloexec &= ~O_CLOEXEC;
|
|
||||||
fd = open(ce->name, O_RDONLY | cloexec);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
unsigned char sha1[20];
|
unsigned char sha1[20];
|
||||||
|
|
50
sha1_file.c
50
sha1_file.c
|
@ -28,14 +28,6 @@
|
||||||
#include "mergesort.h"
|
#include "mergesort.h"
|
||||||
#include "quote.h"
|
#include "quote.h"
|
||||||
|
|
||||||
#ifndef O_NOATIME
|
|
||||||
#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
|
|
||||||
#define O_NOATIME 01000000
|
|
||||||
#else
|
|
||||||
#define O_NOATIME 0
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SZ_FMT PRIuMAX
|
#define SZ_FMT PRIuMAX
|
||||||
static inline uintmax_t sz_fmt(size_t s) { return s; }
|
static inline uintmax_t sz_fmt(size_t s) { return s; }
|
||||||
|
|
||||||
|
@ -1611,31 +1603,31 @@ int check_sha1_signature(const unsigned char *sha1, void *map,
|
||||||
return hashcmp(sha1, real_sha1) ? -1 : 0;
|
return hashcmp(sha1, real_sha1) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int git_open(const char *name)
|
int git_open_cloexec(const char *name, int flags)
|
||||||
{
|
{
|
||||||
static int sha1_file_open_flag = O_NOATIME | O_CLOEXEC;
|
int fd;
|
||||||
|
static int o_cloexec = O_CLOEXEC;
|
||||||
for (;;) {
|
|
||||||
int fd;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
fd = open(name, O_RDONLY | sha1_file_open_flag);
|
|
||||||
if (fd >= 0)
|
|
||||||
return fd;
|
|
||||||
|
|
||||||
|
fd = open(name, flags | o_cloexec);
|
||||||
|
if ((o_cloexec & O_CLOEXEC) && fd < 0 && errno == EINVAL) {
|
||||||
/* Try again w/o O_CLOEXEC: the kernel might not support it */
|
/* Try again w/o O_CLOEXEC: the kernel might not support it */
|
||||||
if ((sha1_file_open_flag & O_CLOEXEC) && errno == EINVAL) {
|
o_cloexec &= ~O_CLOEXEC;
|
||||||
sha1_file_open_flag &= ~O_CLOEXEC;
|
fd = open(name, flags | o_cloexec);
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Might the failure be due to O_NOATIME? */
|
|
||||||
if (errno != ENOENT && (sha1_file_open_flag & O_NOATIME)) {
|
|
||||||
sha1_file_open_flag &= ~O_NOATIME;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(F_GETFL) && defined(F_SETFL) && defined(FD_CLOEXEC)
|
||||||
|
{
|
||||||
|
static int fd_cloexec = FD_CLOEXEC;
|
||||||
|
|
||||||
|
if (!o_cloexec && 0 <= fd && fd_cloexec) {
|
||||||
|
/* Opened w/o O_CLOEXEC? try with fcntl(2) to add it */
|
||||||
|
int flags = fcntl(fd, F_GETFL);
|
||||||
|
if (fcntl(fd, F_SETFL, flags | fd_cloexec))
|
||||||
|
fd_cloexec = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int stat_sha1_file(const unsigned char *sha1, struct stat *st)
|
static int stat_sha1_file(const unsigned char *sha1, struct stat *st)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче