[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