]> code.ossystems Code Review - openembedded-core.git/blob
2de6608c0c348e352a40b1a0dbd272a413321341
[openembedded-core.git] /
1 Upstream-Status: inappropriate
2
3 From fbcbbba3b65402bd43a9e36593d544ff3451620e Mon Sep 17 00:00:00 2001
4 From: Corey Minyard <cminyard@mvista.com>
5 Date: Fri, 3 Jun 2011 21:09:25 -0500
6 Subject: [PATCH 12/19] Add rev 1 support, large file support, and rework holes
7
8 Add support for individual files larger than 2GB, which requires some
9 rev 1 filesystem support.
10
11 Also, since we have a non-overly filesystem structure, rework the
12 OP_HOLES hack and just put that flag in the filesystem structure.
13 This avoid having to mess around with the reserved bytes (which
14 changed with rev 1 support).
15 ---
16  genext2fs.c |   69 +++++++++++++++++++++++++++++++++++++++++++++++-----------
17  1 files changed, 56 insertions(+), 13 deletions(-)
18
19 diff --git a/genext2fs.c b/genext2fs.c
20 index 8a7f589..e420bba 100644
21 --- a/genext2fs.c
22 +++ b/genext2fs.c
23 @@ -233,10 +233,6 @@ struct stats {
24  #define FM_IWOTH   0000002     // write
25  #define FM_IXOTH   0000001     // execute
26  
27 -// options
28 -
29 -#define OP_HOLES     0x01       // make files with holes
30 -
31  /* Defines for accessing group details */
32  
33  // Number of groups in the filesystem
34 @@ -485,7 +481,22 @@ is_blk_empty(uint8 *b)
35         udecl32(s_creator_os)          /* Indicator of which OS created the filesystem */ \
36         udecl32(s_rev_level)           /* The revision level of the filesystem */ \
37         udecl16(s_def_resuid)          /* The default uid for reserved blocks */ \
38 -       udecl16(s_def_resgid)          /* The default gid for reserved blocks */
39 +       udecl16(s_def_resgid)          /* The default gid for reserved blocks */ \
40 +       /* rev 1 version fields start here */ \
41 +       udecl32(s_first_ino)            /* First non-reserved inode */  \
42 +       udecl16(s_inode_size)           /* size of inode structure */   \
43 +       udecl16(s_block_group_nr)       /* block group # of this superblock */ \
44 +       udecl32(s_feature_compat)       /* compatible feature set */    \
45 +       udecl32(s_feature_incompat)     /* incompatible feature set */  \
46 +       udecl32(s_feature_ro_compat)    /* readonly-compatible feature set */ \
47 +       utdecl8(s_uuid,16)              /* 128-bit uuid for volume */   \
48 +       utdecl8(s_volume_name,16)       /* volume name */               \
49 +       utdecl8(s_last_mounted,64)      /* directory where last mounted */ \
50 +       udecl32(s_algorithm_usage_bitmap) /* For compression */
51 +
52 +#define EXT2_GOOD_OLD_FIRST_INO        11
53 +#define EXT2_GOOD_OLD_INODE_SIZE 128
54 +#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
55  
56  #define groupdescriptor_decl \
57         udecl32(bg_block_bitmap)       /* Block number of the block bitmap */ \
58 @@ -525,6 +536,7 @@ is_blk_empty(uint8 *b)
59  
60  #define decl8(x) int8 x;
61  #define udecl8(x) uint8 x;
62 +#define utdecl8(x,n) uint8 x[n];
63  #define decl16(x) int16 x;
64  #define udecl16(x) uint16 x;
65  #define decl32(x) int32 x;
66 @@ -534,7 +546,7 @@ is_blk_empty(uint8 *b)
67  typedef struct
68  {
69         superblock_decl
70 -       uint32 s_reserved[235];       // Reserved
71 +       uint32 s_reserved[205];       // Reserved
72  } superblock;
73  
74  typedef struct
75 @@ -616,6 +628,8 @@ typedef struct
76         int32 hdlink_cnt;
77         struct hdlinks_s hdlinks;
78  
79 +       int holes;
80 +
81         listcache blks;
82         listcache inodes;
83         listcache blkmaps;
84 @@ -628,6 +642,7 @@ typedef struct
85  
86  #undef decl8
87  #undef udecl8
88 +#undef utdecl8
89  #undef decl16
90  #undef udecl16
91  #undef decl32
92 @@ -636,6 +651,7 @@ typedef struct
93  
94  #define decl8(x)
95  #define udecl8(x)
96 +#define utdecl8(x,n)
97  #define decl16(x) this->x = swab16(this->x);
98  #define udecl16(x) this->x = swab16(this->x);
99  #define decl32(x) this->x = swab32(this->x);
100 @@ -700,6 +716,7 @@ swap_block(block b)
101  
102  #undef decl8
103  #undef udecl8
104 +#undef utdecl8
105  #undef decl16
106  #undef udecl16
107  #undef decl32
108 @@ -1695,7 +1712,7 @@ extend_inode_blk(filesystem *fs, inode_pos *ipos, block b, int amount)
109  
110         for (pos = 0; amount; pos += BLOCKSIZE)
111         {
112 -               int hole = ((fs->sb->s_reserved[200] & OP_HOLES) && is_blk_empty(b + pos));
113 +               int hole = (fs->holes && is_blk_empty(b + pos));
114  
115                 bk = walk_bw(fs, ipos->nod, &ipos->bw, &amount, hole);
116                 if (bk == WALK_END)
117 @@ -1912,6 +1929,14 @@ mklink_fs(filesystem *fs, uint32 parent_nod, const char *name, size_t size, uint
118         return nod;
119  }
120  
121 +static void
122 +fs_upgrade_rev1_largefile(filesystem *fs)
123 +{
124 +       fs->sb->s_rev_level = 1;
125 +       fs->sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
126 +       fs->sb->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
127 +}
128 +
129  #define COPY_BLOCKS 16
130  #define CB_SIZE (COPY_BLOCKS * BLOCKSIZE)
131  
132 @@ -1926,11 +1951,16 @@ mkfile_fs(filesystem *fs, uint32 parent_nod, const char *name, uint32 mode, off_
133         size_t readbytes;
134         inode_pos ipos;
135  
136 -
137         b = malloc(CB_SIZE);
138         if (!b)
139                 error_msg_and_die("mkfile_fs: out of memory");
140         inode_pos_init(fs, &ipos, nod, INODE_POS_TRUNCATE, NULL);
141 +       if (size > 0x7fffffff) {
142 +               if (fs->sb->s_rev_level < 1)
143 +                       fs_upgrade_rev1_largefile(fs);
144 +               fs->sb->s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
145 +       }
146 +       node->i_dir_acl = size >> 32;
147         node->i_size = size;
148         while (size) {
149                 readbytes = fread(b, 1, CB_SIZE, f);
150 @@ -2269,6 +2299,8 @@ swap_gds(filesystem *fs)
151  
152  // Copy size blocks from src to dst, putting holes in the output
153  // file (if possible) if the input block is all zeros.
154 +// Copy size blocks from src to dst, putting holes in the output
155 +// file (if possible) if the input block is all zeros.
156  static void
157  copy_file(filesystem *fs, FILE *dst, FILE *src, size_t size)
158  {
159 @@ -2284,7 +2316,7 @@ copy_file(filesystem *fs, FILE *dst, FILE *src, size_t size)
160         while (size > 0) {
161                 if (fread(b, BLOCKSIZE, 1, src) != 1)
162                         perror_msg_and_die("copy failed on read");
163 -               if ((dst != stdout) && is_blk_empty(b)) {
164 +               if ((dst != stdout) && fs->holes && is_blk_empty(b)) {
165                         /* Empty block, just skip it */
166                         if (fseek(dst, BLOCKSIZE, SEEK_CUR))
167                                 perror_msg_and_die("fseek");
168 @@ -2537,8 +2569,7 @@ init_fs(int nbblocks, int nbinodes, int nbresrvd, int holes,
169         fs->sb->s_max_mnt_count = 20;
170  
171         // options for me
172 -       if(holes)
173 -               fs->sb->s_reserved[200] |= OP_HOLES;
174 +       fs->holes = holes;
175         
176         return fs;
177  }
178 @@ -2571,8 +2602,21 @@ load_fs(FILE * fh, int swapit, char *fname)
179                 perror_msg_and_die("fread filesystem image superblock");
180         if(swapit)
181                 swap_sb(fs->sb);
182 -       if(fs->sb->s_rev_level || (fs->sb->s_magic != EXT2_MAGIC_NUMBER))
183 +       if((fs->sb->s_rev_level > 1) || (fs->sb->s_magic != EXT2_MAGIC_NUMBER))
184                 error_msg_and_die("not a suitable ext2 filesystem");
185 +       if (fs->sb->s_rev_level > 0) {
186 +               if (fs->sb->s_first_ino != EXT2_GOOD_OLD_FIRST_INO)
187 +                       error_msg_and_die("First inode incompatible");
188 +               if (fs->sb->s_inode_size != EXT2_GOOD_OLD_INODE_SIZE)
189 +                       error_msg_and_die("inode size incompatible");
190 +               if (fs->sb->s_feature_compat)
191 +                       error_msg_and_die("Unsupported compat features");
192 +               if (fs->sb->s_feature_incompat)
193 +                       error_msg_and_die("Unsupported incompat features");
194 +               if (fs->sb->s_feature_ro_compat
195 +                   & ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
196 +                       error_msg_and_die("Unsupported ro compat features");
197 +       }
198         fs->nheadblocks = (((GRP_NBGROUPS(fs) * sizeof(groupdescriptor))
199                             + sizeof(superblock) + (BLOCKSIZE - 1))
200                            / BLOCKSIZE);
201 @@ -2893,7 +2937,6 @@ finish_fs(filesystem *fs)
202                 error_msg_and_die("entry mismatch on blockmap cache flush");
203         if (cache_flush(&fs->blks))
204                 error_msg_and_die("entry mismatch on block cache flush");
205 -       fs->sb->s_reserved[200] = 0;
206         if(fs->swapit) {
207                 swap_sb(fs->sb);
208                 swap_gds(fs);
209 -- 
210 1.7.4.1
211