1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
Upstream-Status: inappropriate
From 0a7d5b11e62e54f88ce3a49d0c2327d537b3f531 Mon Sep 17 00:00:00 2001
From: Corey Minyard <cminyard@mvista.com>
Date: Sun, 5 Jun 2011 15:42:24 -0500
Subject: [PATCH 11/19] Copy files into the filesystem a piece at a time
Instead of malloc-ing and entire files-worth of memory, reading it in,
and writing it to the filesystem, do it a piece at a time. This allows
very large files to be supported.
Also, use off_t and make it 64-bits so it supports filesystems and files
larger than 2GB. Full support for >2GB files is not quite here, that
requires rev 1 filesystem support, which is coming later.
---
genext2fs.c | 35 +++++++++++++++++++++++------------
1 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/genext2fs.c b/genext2fs.c
index f79438d..8a7f589 100644
--- a/genext2fs.c
+++ b/genext2fs.c
@@ -53,6 +53,12 @@
// along with -q, -P, -U
+/*
+ * Allow fseeko/off_t to be 64-bit offsets to allow filesystems and
+ * individual files >2GB.
+ */
+#define _FILE_OFFSET_BITS 64
+
#include <config.h>
#include <stdio.h>
@@ -603,7 +609,6 @@ struct hdlinks_s
typedef struct
{
FILE *f;
- uint8 *data;
superblock *sb;
groupdescriptor *gd;
uint32 nheadblocks;
@@ -1907,30 +1912,38 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint
return nod;
}
+#define COPY_BLOCKS 16
+#define CB_SIZE (COPY_BLOCKS * BLOCKSIZE)
+
// make a file from a FILE*
static uint32
-mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, size_t size, FILE *f, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime)
+mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, off_t size, FILE *f, uid_t uid, gid_t gid, uint32 ctime, uint32 mtime)
{
uint8 * b;
uint32 nod = mknod_fs(fs, parent_nod, name, mode|FM_IFREG, uid, gid, 0, 0, ctime, mtime);
nod_info *ni;
inode *node = get_nod(fs, nod, &ni);
+ size_t readbytes;
inode_pos ipos;
+
+ b = malloc(CB_SIZE);
+ if (!b)
+ error_msg_and_die("mkfile_fs: out of memory");
inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL);
node->i_size = size;
- if (size) {
- if(!(b = (uint8*)calloc(rndup(size, BLOCKSIZE), 1)))
- error_msg_and_die("not enough mem to read file '%s'", name);
- if(f)
- if (fread(b, size, 1, f) != 1) // FIXME: ugly. use mmap() ...
- error_msg_and_die("fread failed");
+ while (size) {
+ readbytes = fread(b, 1, CB_SIZE, f);
+ if ((size < CB_SIZE && readbytes != size)
+ || (size >= CB_SIZE && readbytes != CB_SIZE))
+ error_msg_and_die("fread failed");
extend_inode_blk(fs, &ipos, b,
- rndup(size, BLOCKSIZE) / BLOCKSIZE);
- free(b);
+ rndup(readbytes, BLOCKSIZE) / BLOCKSIZE);
+ size -= readbytes;
}
inode_pos_finish(fs, &ipos);
put_nod(ni);
+ free(b);
return nod;
}
@@ -2306,8 +2319,6 @@ alloc_fs(int swapit, char *fname, uint32 nbblocks, FILE *srcfile)
if (!fs->hdlinks.hdl)
error_msg_and_die("Not enough memory");
fs->hdlinks.count = 0 ;
- fs->sb = (superblock *) (fs->data + BLOCKSIZE);
- fs->gd = (groupdescriptor *) (fs->sb + 1);
if (strcmp(fname, "-") == 0)
fs->f = tmpfile();
--
1.7.4.1
|