summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/genext2fs/genext2fs-1.4.1/0012-Add-rev-1-support-large-file-support-and-rework-hole.patch
blob: 2de6608c0c348e352a40b1a0dbd272a413321341 (plain)
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
Upstream-Status: inappropriate

From fbcbbba3b65402bd43a9e36593d544ff3451620e Mon Sep 17 00:00:00 2001
From: Corey Minyard <cminyard@mvista.com>
Date: Fri, 3 Jun 2011 21:09:25 -0500
Subject: [PATCH 12/19] Add rev 1 support, large file support, and rework holes

Add support for individual files larger than 2GB, which requires some
rev 1 filesystem support.

Also, since we have a non-overly filesystem structure, rework the
OP_HOLES hack and just put that flag in the filesystem structure.
This avoid having to mess around with the reserved bytes (which
changed with rev 1 support).
---
 genext2fs.c |   69 +++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 56 insertions(+), 13 deletions(-)

diff --git a/genext2fs.c b/genext2fs.c
index 8a7f589..e420bba 100644
--- a/genext2fs.c
+++ b/genext2fs.c
@@ -233,10 +233,6 @@ struct stats {
 #define FM_IWOTH   0000002	// write
 #define FM_IXOTH   0000001	// execute
 
-// options
-
-#define OP_HOLES     0x01       // make files with holes
-
 /* Defines for accessing group details */
 
 // Number of groups in the filesystem
@@ -485,7 +481,22 @@ is_blk_empty(uint8 *b)
 	udecl32(s_creator_os)          /* Indicator of which OS created the filesystem */ \
 	udecl32(s_rev_level)           /* The revision level of the filesystem */ \
 	udecl16(s_def_resuid)          /* The default uid for reserved blocks */ \
-	udecl16(s_def_resgid)          /* The default gid for reserved blocks */
+	udecl16(s_def_resgid)          /* The default gid for reserved blocks */ \
+	/* rev 1 version fields start here */ \
+	udecl32(s_first_ino) 		/* First non-reserved inode */	\
+	udecl16(s_inode_size) 		/* size of inode structure */	\
+	udecl16(s_block_group_nr) 	/* block group # of this superblock */ \
+	udecl32(s_feature_compat) 	/* compatible feature set */	\
+	udecl32(s_feature_incompat) 	/* incompatible feature set */	\
+	udecl32(s_feature_ro_compat) 	/* readonly-compatible feature set */ \
+	utdecl8(s_uuid,16)		/* 128-bit uuid for volume */	\
+	utdecl8(s_volume_name,16) 	/* volume name */		\
+	utdecl8(s_last_mounted,64) 	/* directory where last mounted */ \
+	udecl32(s_algorithm_usage_bitmap) /* For compression */
+
+#define EXT2_GOOD_OLD_FIRST_INO	11
+#define EXT2_GOOD_OLD_INODE_SIZE 128
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE	0x0002
 
 #define groupdescriptor_decl \
 	udecl32(bg_block_bitmap)       /* Block number of the block bitmap */ \
@@ -525,6 +536,7 @@ is_blk_empty(uint8 *b)
 
 #define decl8(x) int8 x;
 #define udecl8(x) uint8 x;
+#define utdecl8(x,n) uint8 x[n];
 #define decl16(x) int16 x;
 #define udecl16(x) uint16 x;
 #define decl32(x) int32 x;
@@ -534,7 +546,7 @@ is_blk_empty(uint8 *b)
 typedef struct
 {
 	superblock_decl
-	uint32 s_reserved[235];       // Reserved
+	uint32 s_reserved[205];       // Reserved
 } superblock;
 
 typedef struct
@@ -616,6 +628,8 @@ typedef struct
 	int32 hdlink_cnt;
 	struct hdlinks_s hdlinks;
 
+	int holes;
+
 	listcache blks;
 	listcache inodes;
 	listcache blkmaps;
@@ -628,6 +642,7 @@ typedef struct
 
 #undef decl8
 #undef udecl8
+#undef utdecl8
 #undef decl16
 #undef udecl16
 #undef decl32
@@ -636,6 +651,7 @@ typedef struct
 
 #define decl8(x)
 #define udecl8(x)
+#define utdecl8(x,n)
 #define decl16(x) this->x = swab16(this->x);
 #define udecl16(x) this->x = swab16(this->x);
 #define decl32(x) this->x = swab32(this->x);
@@ -700,6 +716,7 @@ swap_block(block b)
 
 #undef decl8
 #undef udecl8
+#undef utdecl8
 #undef decl16
 #undef udecl16
 #undef decl32
@@ -1695,7 +1712,7 @@ extend_inode_blk(filesystem *fs, inode_pos *ipos, block b, int amount)
 
 	for (pos = 0; amount; pos += BLOCKSIZE)
 	{
-		int hole = ((fs->sb->s_reserved[200] & OP_HOLES) && is_blk_empty(b + pos));
+		int hole = (fs->holes && is_blk_empty(b + pos));
 
 		bk = walk_bw(fs, ipos->nod, &ipos->bw, &amount, hole);
 		if (bk == WALK_END)
@@ -1912,6 +1929,14 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint
 	return nod;
 }
 
+static void
+fs_upgrade_rev1_largefile(filesystem *fs)
+{
+	fs->sb->s_rev_level = 1;
+	fs->sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
+	fs->sb->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
+}
+
 #define COPY_BLOCKS 16
 #define CB_SIZE (COPY_BLOCKS * BLOCKSIZE)
 
@@ -1926,11 +1951,16 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, off_
 	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);
+	if (size > 0x7fffffff) {
+		if (fs->sb->s_rev_level < 1)
+			fs_upgrade_rev1_largefile(fs);
+		fs->sb->s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
+	}
+	node->i_dir_acl = size >> 32;
 	node->i_size = size;
 	while (size) {
 		readbytes = fread(b, 1, CB_SIZE, f);
@@ -2269,6 +2299,8 @@ swap_gds(filesystem *fs)
 
 // Copy size blocks from src to dst, putting holes in the output
 // file (if possible) if the input block is all zeros.
+// Copy size blocks from src to dst, putting holes in the output
+// file (if possible) if the input block is all zeros.
 static void
 copy_file(filesystem *fs, FILE *dst, FILE *src, size_t size)
 {
@@ -2284,7 +2316,7 @@ copy_file(filesystem *fs, FILE *dst, FILE *src, size_t size)
 	while (size > 0) {
 		if (fread(b, BLOCKSIZE, 1, src) != 1)
 			perror_msg_and_die("copy failed on read");
-		if ((dst != stdout) && is_blk_empty(b)) {
+		if ((dst != stdout) && fs->holes && is_blk_empty(b)) {
 			/* Empty block, just skip it */
 			if (fseek(dst, BLOCKSIZE, SEEK_CUR))
 				perror_msg_and_die("fseek");
@@ -2537,8 +2569,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes,
 	fs->sb->s_max_mnt_count = 20;
 
 	// options for me
-	if(holes)
-		fs->sb->s_reserved[200] |= OP_HOLES;
+	fs->holes = holes;
 	
 	return fs;
 }
@@ -2571,8 +2602,21 @@ load_fs(FILE * fh, int swapit, char *fname)
 		perror_msg_and_die("fread filesystem image superblock");
 	if(swapit)
 		swap_sb(fs->sb);
-	if(fs->sb->s_rev_level || (fs->sb->s_magic != EXT2_MAGIC_NUMBER))
+	if((fs->sb->s_rev_level > 1) || (fs->sb->s_magic != EXT2_MAGIC_NUMBER))
 		error_msg_and_die("not a suitable ext2 filesystem");
+	if (fs->sb->s_rev_level > 0) {
+		if (fs->sb->s_first_ino != EXT2_GOOD_OLD_FIRST_INO)
+			error_msg_and_die("First inode incompatible");
+		if (fs->sb->s_inode_size != EXT2_GOOD_OLD_INODE_SIZE)
+			error_msg_and_die("inode size incompatible");
+		if (fs->sb->s_feature_compat)
+			error_msg_and_die("Unsupported compat features");
+		if (fs->sb->s_feature_incompat)
+			error_msg_and_die("Unsupported incompat features");
+		if (fs->sb->s_feature_ro_compat
+		    & ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
+			error_msg_and_die("Unsupported ro compat features");
+	}
 	fs->nheadblocks = (((GRP_NBGROUPS(fs) * sizeof(groupdescriptor))
 			    + sizeof(superblock) + (BLOCKSIZE - 1))
 			   / BLOCKSIZE);
@@ -2893,7 +2937,6 @@ finish_fs(filesystem *fs)
 		error_msg_and_die("entry mismatch on blockmap cache flush");
 	if (cache_flush(&fs->blks))
 		error_msg_and_die("entry mismatch on block cache flush");
-	fs->sb->s_reserved[200] = 0;
 	if(fs->swapit) {
 		swap_sb(fs->sb);
 		swap_gds(fs);
-- 
1.7.4.1