]> wimlib.net Git - wimlib/blobdiff - src/unix_apply.c
unix_apply.c: preallocate space for regular files
[wimlib] / src / unix_apply.c
index f1962d9884b63752892217f3eed71b29393a777c..e2ba76f9edddbc4d7fe04fb643dd964e055e5354 100644 (file)
@@ -3,7 +3,7 @@
  */
 
 /*
- * Copyright (C) 2012, 2013, 2014 Eric Biggers
+ * Copyright (C) 2012-2016 Eric Biggers
  *
  * This file is free software; you can redistribute it and/or modify it under
  * the terms of the GNU Lesser General Public License as published by the Free
@@ -156,7 +156,9 @@ unix_build_extraction_path(const struct wim_dentry *dentry,
        d = dentry;
        do {
                p -= d->d_extraction_name_nchars;
-               memcpy(p, d->d_extraction_name, d->d_extraction_name_nchars);
+               if (d->d_extraction_name_nchars)
+                       memcpy(p, d->d_extraction_name,
+                              d->d_extraction_name_nchars);
                *--p = '/';
                d = d->d_parent;
        } while (!dentry_is_root(d) && will_extract_dentry(d));
@@ -434,7 +436,7 @@ unix_extract_if_empty_file(const struct wim_dentry *dentry,
 
                path = unix_build_extraction_path(dentry, ctx);
        retry_create:
-               fd = open(path, O_TRUNC | O_CREAT | O_WRONLY | O_NOFOLLOW, 0644);
+               fd = open(path, O_EXCL | O_CREAT | O_WRONLY | O_NOFOLLOW, 0644);
                if (fd < 0) {
                        if (errno == EEXIST && !unlink(path))
                                goto retry_create;
@@ -575,7 +577,7 @@ unix_begin_extract_blob_instance(const struct blob_descriptor *blob,
        first_dentry = inode_first_extraction_dentry(inode);
        first_path = unix_build_extraction_path(first_dentry, ctx);
 retry_create:
-       fd = open(first_path, O_TRUNC | O_CREAT | O_WRONLY | O_NOFOLLOW, 0644);
+       fd = open(first_path, O_EXCL | O_CREAT | O_WRONLY | O_NOFOLLOW, 0644);
        if (fd < 0) {
                if (errno == EEXIST && !unlink(first_path))
                        goto retry_create;
@@ -583,6 +585,9 @@ retry_create:
                return WIMLIB_ERR_OPEN;
        }
        filedes_init(&ctx->open_fds[ctx->num_open_fds++], fd);
+#ifdef HAVE_POSIX_FALLOCATE
+       posix_fallocate(fd, 0, blob->size);
+#endif
        return unix_create_hardlinks(inode, first_dentry, first_path, ctx);
 }
 
@@ -609,7 +614,8 @@ unix_begin_extract_blob(struct blob_descriptor *blob, void *_ctx)
 
 /* Called when the next chunk of a blob has been read for extraction  */
 static int
-unix_extract_chunk(const void *chunk, size_t size, void *_ctx)
+unix_extract_chunk(const struct blob_descriptor *blob, u64 offset,
+                  const void *chunk, size_t size, void *_ctx)
 {
        struct unix_apply_ctx *ctx = _ctx;
        int ret;
@@ -763,7 +769,7 @@ unix_extract(struct list_head *dentry_list, struct apply_ctx *_ctx)
 
        struct read_blob_callbacks cbs = {
                .begin_blob     = unix_begin_extract_blob,
-               .consume_chunk  = unix_extract_chunk,
+               .continue_blob  = unix_extract_chunk,
                .end_blob       = unix_end_extract_blob,
                .ctx            = ctx,
        };