Commit 77b339f7 by Carlos Martín Nieto

odb: make the writestream's size a git_off_t

Restricting files to size_t is a silly limitation. The loose backend
writes to a file directly, so there is no issue in using 63 bits for the
size.

We still assume that the header is going to fit in 64 bytes, which does
mean quite a bit smaller files due to the run-length encoding, but it's
still a much larger size than you would want Git to handle.
parent f85a9c27
...@@ -247,7 +247,7 @@ GIT_EXTERN(int) git_odb_write(git_oid *out, git_odb *odb, const void *data, size ...@@ -247,7 +247,7 @@ GIT_EXTERN(int) git_odb_write(git_oid *out, git_odb *odb, const void *data, size
* @param type type of the object that will be written * @param type type of the object that will be written
* @return 0 if the stream was created; error code otherwise * @return 0 if the stream was created; error code otherwise
*/ */
GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **out, git_odb *db, size_t size, git_otype type); GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **out, git_odb *db, git_off_t size, git_otype type);
/** /**
* Write to an odb stream * Write to an odb stream
......
...@@ -86,8 +86,8 @@ struct git_odb_stream { ...@@ -86,8 +86,8 @@ struct git_odb_stream {
unsigned int mode; unsigned int mode;
void *hash_ctx; void *hash_ctx;
size_t declared_size; git_off_t declared_size;
size_t received_bytes; git_off_t received_bytes;
/** /**
* Write at most `len` bytes into `buffer` and advance the stream. * Write at most `len` bytes into `buffer` and advance the stream.
......
...@@ -53,7 +53,7 @@ struct git_odb_backend { ...@@ -53,7 +53,7 @@ struct git_odb_backend {
git_odb_backend *, const git_oid *, const void *, size_t, git_otype); git_odb_backend *, const git_oid *, const void *, size_t, git_otype);
int (* writestream)( int (* writestream)(
git_odb_stream **, git_odb_backend *, size_t, git_otype); git_odb_stream **, git_odb_backend *, git_off_t, git_otype);
int (* readstream)( int (* readstream)(
git_odb_stream **, git_odb_backend *, const git_oid *); git_odb_stream **, git_odb_backend *, const git_oid *);
......
...@@ -76,10 +76,11 @@ static int write_file_stream( ...@@ -76,10 +76,11 @@ static int write_file_stream(
int fd, error; int fd, error;
char buffer[FILEIO_BUFSIZE]; char buffer[FILEIO_BUFSIZE];
git_odb_stream *stream = NULL; git_odb_stream *stream = NULL;
ssize_t read_len = -1, written = 0; ssize_t read_len = -1;
git_off_t written = 0;
if ((error = git_odb_open_wstream( if ((error = git_odb_open_wstream(
&stream, odb, (size_t)file_size, GIT_OBJ_BLOB)) < 0) &stream, odb, file_size, GIT_OBJ_BLOB)) < 0)
return error; return error;
if ((fd = git_futils_open_ro(path)) < 0) { if ((fd = git_futils_open_ro(path)) < 0) {
......
...@@ -47,7 +47,7 @@ static git_cache *odb_cache(git_odb *odb) ...@@ -47,7 +47,7 @@ static git_cache *odb_cache(git_odb *odb)
static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth); static int load_alternates(git_odb *odb, const char *objects_dir, int alternate_depth);
int git_odb__format_object_header(char *hdr, size_t n, size_t obj_len, git_otype obj_type) int git_odb__format_object_header(char *hdr, size_t n, git_off_t obj_len, git_otype obj_type)
{ {
const char *type_str = git_object_type2string(obj_type); const char *type_str = git_object_type2string(obj_type);
int len = p_snprintf(hdr, n, "%s %"PRIuZ, type_str, obj_len); int len = p_snprintf(hdr, n, "%s %"PRIuZ, type_str, obj_len);
...@@ -327,10 +327,15 @@ static void fake_wstream__free(git_odb_stream *_stream) ...@@ -327,10 +327,15 @@ static void fake_wstream__free(git_odb_stream *_stream)
git__free(stream); git__free(stream);
} }
static int init_fake_wstream(git_odb_stream **stream_p, git_odb_backend *backend, size_t size, git_otype type) static int init_fake_wstream(git_odb_stream **stream_p, git_odb_backend *backend, git_off_t size, git_otype type)
{ {
fake_wstream *stream; fake_wstream *stream;
if (!git__is_ssizet(size)) {
giterr_set(GITERR_ODB, "object size too large to keep in memory");
return -1;
}
stream = git__calloc(1, sizeof(fake_wstream)); stream = git__calloc(1, sizeof(fake_wstream));
GITERR_CHECK_ALLOC(stream); GITERR_CHECK_ALLOC(stream);
...@@ -937,7 +942,7 @@ int git_odb_write( ...@@ -937,7 +942,7 @@ int git_odb_write(
return error; return error;
} }
static void hash_header(git_hash_ctx *ctx, size_t size, git_otype type) static void hash_header(git_hash_ctx *ctx, git_off_t size, git_otype type)
{ {
char header[64]; char header[64];
int hdrlen; int hdrlen;
...@@ -947,7 +952,7 @@ static void hash_header(git_hash_ctx *ctx, size_t size, git_otype type) ...@@ -947,7 +952,7 @@ static void hash_header(git_hash_ctx *ctx, size_t size, git_otype type)
} }
int git_odb_open_wstream( int git_odb_open_wstream(
git_odb_stream **stream, git_odb *db, size_t size, git_otype type) git_odb_stream **stream, git_odb *db, git_off_t size, git_otype type)
{ {
size_t i, writes = 0; size_t i, writes = 0;
int error = GIT_ERROR; int error = GIT_ERROR;
......
...@@ -49,7 +49,7 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj); ...@@ -49,7 +49,7 @@ int git_odb__hashobj(git_oid *id, git_rawobj *obj);
/* /*
* Format the object header such as it would appear in the on-disk object * Format the object header such as it would appear in the on-disk object
*/ */
int git_odb__format_object_header(char *hdr, size_t n, size_t obj_len, git_otype obj_type); int git_odb__format_object_header(char *hdr, size_t n, git_off_t obj_len, git_otype obj_type);
/* /*
* Hash an open file descriptor. * Hash an open file descriptor.
* This is a performance call when the contents of a fd need to be hashed, * This is a performance call when the contents of a fd need to be hashed,
......
...@@ -834,7 +834,7 @@ static void loose_backend__stream_free(git_odb_stream *_stream) ...@@ -834,7 +834,7 @@ static void loose_backend__stream_free(git_odb_stream *_stream)
git__free(stream); git__free(stream);
} }
static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_backend, size_t length, git_otype type) static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_backend, git_off_t length, git_otype type)
{ {
loose_backend *backend; loose_backend *backend;
loose_writestream *stream = NULL; loose_writestream *stream = NULL;
...@@ -842,7 +842,7 @@ static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_ ...@@ -842,7 +842,7 @@ static int loose_backend__stream(git_odb_stream **stream_out, git_odb_backend *_
git_buf tmp_path = GIT_BUF_INIT; git_buf tmp_path = GIT_BUF_INIT;
int hdrlen; int hdrlen;
assert(_backend); assert(_backend && length >= 0);
backend = (loose_backend *)_backend; backend = (loose_backend *)_backend;
*stream_out = NULL; *stream_out = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment