[Ocfs2-tools-devel] [PATCH 06/12] mkfs.ocfs2: Write directory trailers when necessary.
Joel Becker
joel.becker at oracle.com
Mon Dec 29 19:23:42 PST 2008
Add the code to put trailers on dirblocks when they are created in mkfs.
This includes a little convenience routine, fill_fake_fs(), that allows
us to use simple functions on a fake ocfs2_filesys created from State.
Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
mkfs.ocfs2/mkfs.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 85 insertions(+), 6 deletions(-)
diff --git a/mkfs.ocfs2/mkfs.c b/mkfs.ocfs2/mkfs.c
index 6b91e4d..d2690cb 100644
--- a/mkfs.ocfs2/mkfs.c
+++ b/mkfs.ocfs2/mkfs.c
@@ -184,6 +184,46 @@ static int hb_dev_skip(State *s, int system_inode)
return ret;
}
+static void fill_fake_fs(State *s, ocfs2_filesys *fake_fs, void *buf)
+{
+ memset(buf, 0, s->blocksize);
+ memset(fake_fs, 0, sizeof(ocfs2_filesys));
+
+ fake_fs->fs_super = buf;
+ fake_fs->fs_blocksize = s->blocksize;
+ fake_fs->fs_clustersize = s->cluster_size;
+
+ OCFS2_RAW_SB(fake_fs->fs_super)->s_feature_incompat =
+ s->feature_flags.opt_incompat;
+ OCFS2_RAW_SB(fake_fs->fs_super)->s_feature_ro_compat =
+ s->feature_flags.opt_ro_compat;
+ OCFS2_RAW_SB(fake_fs->fs_super)->s_feature_compat =
+ s->feature_flags.opt_compat;
+}
+
+static void mkfs_init_dir_trailer(State *s, DirData *dir, void *buf)
+{
+ char super_buf[OCFS2_MAX_BLOCKSIZE];
+ ocfs2_filesys fake_fs;
+ struct ocfs2_dir_entry *de;
+ struct ocfs2_dinode fake_di = {
+ .i_blkno = dir->record->fe_off >> s->blocksize_bits,
+ };
+ uint64_t blkno = dir->record->extent_off;
+
+ /* Find out how far we are in our directory */
+ blkno += ((char *)buf) - ((char *)dir->buf);
+ blkno >>= s->blocksize_bits;
+
+ fill_fake_fs(s, &fake_fs, super_buf);
+
+ if (ocfs2_supports_dir_trailer(&fake_fs)) {
+ de = buf;
+ de->rec_len = ocfs2_dir_trailer_blk_off(&fake_fs);
+ ocfs2_init_dir_trailer(&fake_fs, &fake_di, blkno, buf);
+ }
+}
+
static inline uint32_t system_dir_bytes_needed(State *s)
{
int each = OCFS2_DIR_REC_LEN(SYSTEM_FILE_NAME_MAX);
@@ -1784,6 +1824,8 @@ add_entry_to_directory(State *s, DirData *dir, char *name, uint64_t byte_off,
de = (struct ocfs2_dir_entry *)p;
de->inode = 0;
de->rec_len = s->blocksize;
+ if (!s->inline_data || !dir->record->dir_data)
+ mkfs_init_dir_trailer(s, dir, p);
got_it:
de->name_len = strlen(name);
@@ -2159,7 +2201,7 @@ write_bitmap_data(State *s, AllocBitmap *bitmap)
{
int i;
uint64_t parent_blkno;
- struct ocfs2_group_desc *gd;
+ struct ocfs2_group_desc *gd, *gd_buf;
char *buf = NULL;
buf = do_malloc(s, s->cluster_size);
@@ -2176,7 +2218,8 @@ write_bitmap_data(State *s, AllocBitmap *bitmap)
* blkno until now. */
gd->bg_parent_dinode = parent_blkno;
memcpy(buf, gd, s->blocksize);
- ocfs2_swap_group_desc((struct ocfs2_group_desc *)buf);
+ gd_buf = (struct ocfs2_group_desc *)buf;
+ ocfs2_swap_group_desc(gd_buf);
do_pwrite(s, buf, s->cluster_size,
gd->bg_blkno << s->blocksize_bits);
}
@@ -2192,6 +2235,44 @@ write_group_data(State *s, AllocGroup *group)
ocfs2_swap_group_desc(group->gd);
}
+static void mkfs_swap_dir(State *s, DirData *dir,
+ errcode_t (*swap_entry_func)(void *buf,
+ uint64_t bytes))
+{
+ char *p = dir->buf;
+ unsigned int offset = 0;
+ unsigned int end = s->blocksize;
+ char super_buf[OCFS2_MAX_BLOCKSIZE];
+ ocfs2_filesys fake_fs;
+ struct ocfs2_dir_block_trailer *trailer;
+
+ if (!dir->record->extent_len)
+ return;
+
+ fill_fake_fs(s, &fake_fs, super_buf);
+ if (!s->inline_data || !dir->record->dir_data)
+ end = ocfs2_dir_trailer_blk_off(&fake_fs);
+
+ while (offset < dir->record->file_size) {
+ trailer = ocfs2_dir_trailer_from_block(&fake_fs, p);
+ swap_entry_func(p, end);
+ if (end != s->blocksize)
+ ocfs2_swap_dir_trailer(trailer);
+ offset += s->blocksize;
+ p += offset;
+ }
+}
+
+static void mkfs_swap_dir_from_cpu(State *s, DirData *dir)
+{
+ mkfs_swap_dir(s, dir, ocfs2_swap_dir_entries_from_cpu);
+}
+
+static void mkfs_swap_dir_to_cpu(State *s, DirData *dir)
+{
+ mkfs_swap_dir(s, dir, ocfs2_swap_dir_entries_to_cpu);
+}
+
static void
write_directory_data(State *s, DirData *dir)
{
@@ -2199,12 +2280,10 @@ write_directory_data(State *s, DirData *dir)
return;
if (dir->buf)
- ocfs2_swap_dir_entries_from_cpu(dir->buf,
- dir->record->file_size);
+ mkfs_swap_dir_from_cpu(s, dir);
write_metadata(s, dir->record, dir->buf);
if (dir->buf)
- ocfs2_swap_dir_entries_to_cpu(dir->buf,
- dir->record->file_size);
+ mkfs_swap_dir_to_cpu(s, dir);
}
static void
--
1.5.6.5
More information about the Ocfs2-tools-devel
mailing list