[Ocfs2-tools-devel] [PATCH] Compress dirs option in fsck
Goldwyn Rodrigues
rgoldwyn at gmail.com
Wed Aug 19 15:14:59 PDT 2009
This patch adds the option to compress directories (-D) in fsck.
The option compresses the directory entries and consolidates a hole at
the end of the directory block. This consolidated hole increases the
chance of ocfs2_prepare_dir_for_insert (kmp) to find a hole using
ocfs2_find_dir_space_* functions while inserting a new directory entry
in the directory.
Perhaps #define OCFS2_DIR_REC_LEN needs a better place.
Signed-off-by: Goldwyn Rodrigues <rgoldwyn at suse.de>
---
diff --git a/fsck.ocfs2/fsck.c b/fsck.ocfs2/fsck.c
index 74c18ac..2f31257 100644
--- a/fsck.ocfs2/fsck.c
+++ b/fsck.ocfs2/fsck.c
@@ -650,7 +650,7 @@ int main(int argc, char **argv)
setlinebuf(stderr);
setlinebuf(stdout);
- while((c = getopt(argc, argv, "b:B:fFGnuvVyr:")) != EOF) {
+ while((c = getopt(argc, argv, "b:B:DfFGnuvVyr:")) != EOF) {
switch (c) {
case 'b':
blkno = read_number(optarg);
@@ -675,6 +675,9 @@ int main(int argc, char **argv)
goto out;
}
break;
+ case 'D':
+ ost->ost_rehash_dirs = 1;
+ break;
case 'F':
ost->ost_skip_o2cb = 1;
diff --git a/fsck.ocfs2/include/fsck.h b/fsck.ocfs2/include/fsck.h
index 240286c..93c4b21 100644
--- a/fsck.ocfs2/include/fsck.h
+++ b/fsck.ocfs2/include/fsck.h
@@ -73,7 +73,8 @@ typedef struct _o2fsck_state {
ost_stale_mounts:1, /* set when reading publish blocks
* that still indicated mounted */
ost_fix_fs_gen:1,
- ost_has_journal_dirty:1;
+ ost_has_journal_dirty:1,
+ ost_rehash_dirs:1;
errcode_t ost_err;
} o2fsck_state;
diff --git a/fsck.ocfs2/pass2.c b/fsck.ocfs2/pass2.c
index 810bf10..2d9d074 100644
--- a/fsck.ocfs2/pass2.c
+++ b/fsck.ocfs2/pass2.c
@@ -668,6 +668,7 @@ static unsigned
pass2_dir_block_iterate(o2fsck_dirblock_entry *dbe,
struct dirblock_data *dd = priv_data;
struct ocfs2_dir_entry *dirent, *prev = NULL;
unsigned int offset = 0, ret_flags = 0, end = dd->fs->fs_blocksize;
+ unsigned int write_off, saved_reclen;
struct ocfs2_dinode *di = (struct ocfs2_dinode *)dd->inoblock_buf;
errcode_t ret = 0;
@@ -723,6 +724,8 @@ static unsigned
pass2_dir_block_iterate(o2fsck_dirblock_entry *dbe,
end = ocfs2_dir_trailer_blk_off(dd->fs);
}
+ write_off = offset;
+
while (offset < end) {
dirent = (struct ocfs2_dir_entry *)(dd->dirblock_buf + offset);
@@ -804,8 +807,31 @@ static unsigned
pass2_dir_block_iterate(o2fsck_dirblock_entry *dbe,
dirent->name, (uint64_t)dirent->inode);
o2fsck_icount_delta(dd->ost->ost_icount_refs, dirent->inode, 1);
next:
- offset += dirent->rec_len;
+ saved_reclen=dirent->rec_len;
+ if ((dd->ost->ost_rehash_dirs) && dirent->inode) {
+ dirent->rec_len = OCFS2_DIR_REC_LEN(dirent->name_len);
+ if (write_off < offset) {
+ /* memcpy works good even though
+ it is the same buffer*/
+ verbosef("ino: %llu woff: %u off: %u\n",
+ dirent->inode, write_off, offset);
+ memcpy(dd->dirblock_buf + write_off,
+ dd->dirblock_buf + offset,
+ dirent->rec_len);
+ dirent = dd->dirblock_buf + write_off;
+ }
+ write_off += dirent->rec_len;
+ ret_flags |= OCFS2_DIRENT_CHANGED;
+ }
prev = dirent;
+ offset += saved_reclen;
+ }
+
+ /* Zero the rest of the block */
+ if (dd->ost->ost_rehash_dirs) {
+ memset(dd->dirblock_buf + write_off, '\0', end - write_off);
+ ret_flags |= OCFS2_DIRENT_CHANGED;
+ dirent->rec_len = dirent->rec_len + end - write_off;
}
if (ocfs2_dir_has_trailer(dd->fs, di))
diff --git a/libocfs2/dir_iterate.h b/libocfs2/dir_iterate.h
index f281af2..2d9587b 100644
--- a/libocfs2/dir_iterate.h
+++ b/libocfs2/dir_iterate.h
@@ -49,4 +49,11 @@ extern int ocfs2_process_dir_block(ocfs2_filesys *fs,
uint16_t ext_flags,
void *priv_data);
+#define OCFS2_DIR_PAD 4
+#define OCFS2_DIR_ROUND (OCFS2_DIR_PAD - 1)
+#define OCFS2_DIR_MEMBER_LEN offsetof(struct ocfs2_dir_entry, name)
+#define OCFS2_DIR_REC_LEN(name_len) (((name_len) + OCFS2_DIR_MEMBER_LEN + \
+ OCFS2_DIR_ROUND) & \
+ ~OCFS2_DIR_ROUND)
+
#endif /* _DIR_ITERATE_H */
More information about the Ocfs2-tools-devel
mailing list