[Ocfs2-tools-devel] [PATCH 1/2] Create holes in directories

Goldwyn Rodrigues rgoldwyn at gmail.com
Thu Aug 11 08:08:27 PDT 2011


The patch adds the feature to create holes in a directory.
It works on two directories and creates files alternatively in both of them.
Finally, it changes the offset of the [1]th extent record and
increases the filesize.

Signed-off-by: Goldwyn Rodrigues <rgoldwyn at suse.de>

---
diff --git a/fswreck/corrupt.c b/fswreck/corrupt.c
index aa76dcc..161b078 100644
--- a/fswreck/corrupt.c
+++ b/fswreck/corrupt.c
@@ -28,7 +28,7 @@

 extern char *progname;

-static void create_named_directory(ocfs2_filesys *fs, char *dirname,
+void create_named_directory(ocfs2_filesys *fs, char *dirname,
 				   uint64_t *blkno)
 {
 	errcode_t ret;
@@ -151,6 +151,9 @@ void corrupt_file(ocfs2_filesys *fs, enum
fsck_type type, uint16_t slotnum)
 	case DIR_ZERO:
 		func = mess_up_dir_inode;
 		break;
+	case DIR_HOLE:
+		func = mess_up_dir_inode;
+		break;
 	case DIRENT_DOTTY_DUP:
 		func = mess_up_dir_dot;
 		break;
diff --git a/fswreck/dir.c b/fswreck/dir.c
index eb8d0f2..1ee8394 100644
--- a/fswreck/dir.c
+++ b/fswreck/dir.c
@@ -464,10 +464,12 @@ void mess_up_dir_parent_dup(ocfs2_filesys *fs,
enum fsck_type type,
 void mess_up_dir_inode(ocfs2_filesys *fs, enum fsck_type type, uint64_t blkno)
 {
 	errcode_t ret;
-	char *buf = NULL;
-	struct ocfs2_dinode *di;
+	char *buf = NULL, *buf2 = NULL;
+	struct ocfs2_dinode *di, *di2;
 	struct ocfs2_extent_list *el;
-	uint64_t tmp_blkno;
+	uint64_t tmp_blkno, file_ino, dir2;
+	int i;
+	struct ocfs2_extent_rec *er;

 	create_directory(fs, blkno, &tmp_blkno);

@@ -475,6 +477,10 @@ void mess_up_dir_inode(ocfs2_filesys *fs, enum
fsck_type type, uint64_t blkno)
 	if (ret)
 		FSWRK_COM_FATAL(progname, ret);

+	ret = ocfs2_malloc_block(fs->fs_io, &buf2);
+	if (ret)
+		FSWRK_COM_FATAL(progname, ret);
+
 	ret = ocfs2_read_inode(fs, tmp_blkno, buf);
 	if (ret)
 		FSWRK_COM_FATAL(progname, ret);
@@ -484,22 +490,43 @@ void mess_up_dir_inode(ocfs2_filesys *fs, enum
fsck_type type, uint64_t blkno)
 	if (!(di->i_flags & OCFS2_VALID_FL))
 		FSWRK_FATAL("not a valid file");

-	if (di->i_dyn_features & OCFS2_INLINE_DATA_FL) {
-
-		FSWRK_FATAL("Inlined directory");
-
-	} else {
-
-		el = &(di->id2.i_list);
-		if (el->l_next_free_rec == 0)
-			FSWRK_FATAL("directory empty");
-
-		el->l_next_free_rec = 0;
+	switch(type) {
+		case DIR_HOLE:
+			create_named_directory(fs, "tmp1", &dir2);
+			for (i = 0; i < fs->fs_blocksize; i++) {
+				if (i%2)
+					create_file(fs, blkno, &file_ino);
+				else
+					create_file(fs, dir2, &file_ino);
+			}
+			ret = ocfs2_read_inode(fs, dir2, buf2);
+			di2 = (struct ocfs2_dinode *)buf2;
+			el = &(di2->id2.i_list);
+			er = &(el->l_recs[1]);
+			er->e_cpos += 3;
+			di2->i_size += 23 * fs->fs_blocksize;
+			ret = ocfs2_write_inode(fs, dir2, buf2);
+			fprintf(stdout, "DIR_HOLE: Messed up extent record"
+				" of %"PRIu64" to show a hole.\n",
+				di->i_blkno);
+			break;
+		case DIR_ZERO:
+			if (di->i_dyn_features & OCFS2_INLINE_DATA_FL) {
+				FSWRK_FATAL("Inlined directory");
+			} else {
+				el = &(di->id2.i_list);
+				if (el->l_next_free_rec == 0)
+					FSWRK_FATAL("directory empty");
+				el->l_next_free_rec = 0;
+			}
+			fprintf(stdout, "DIR_ZERO: "
+				"Corrupt directory#%"PRIu64", empty its"
+				" content.\n", tmp_blkno);
+			break;
+		default:
+			fprintf(stdout, "Invalid code passed for dir\n");
 	}

-	fprintf(stdout, "DIR_ZERO: "
-		"Corrupt directory#%"PRIu64", empty its content.\n",
-		tmp_blkno);

 	ret = ocfs2_write_inode(fs, tmp_blkno, buf);
 	if (ret)
@@ -507,6 +534,8 @@ void mess_up_dir_inode(ocfs2_filesys *fs, enum
fsck_type type, uint64_t blkno)

 	if (buf)
 		ocfs2_free(&buf);
+	if (buf2)
+		ocfs2_free(&buf2);
 	return;
 }

diff --git a/fswreck/include/corrupt.h b/fswreck/include/corrupt.h
index 0fb7193..7037b16 100644
--- a/fswreck/include/corrupt.h
+++ b/fswreck/include/corrupt.h
@@ -37,5 +37,6 @@ void corrupt_truncate_log(ocfs2_filesys *fs, enum
fsck_type type,
 void corrupt_refcount(ocfs2_filesys *fs, enum fsck_type type,
uint16_t slotnum);
 void corrupt_discontig_bg(ocfs2_filesys *fs, enum fsck_type type,
 			  uint16_t slotnum);
+void create_named_directory(ocfs2_filesys *fs, char *name, uint64_t *blkno);

 #endif		/* __CORRUPT_H */
diff --git a/fswreck/include/fsck_type.h b/fswreck/include/fsck_type.h
index e58d343..c18a134 100644
--- a/fswreck/include/fsck_type.h
+++ b/fswreck/include/fsck_type.h
@@ -101,6 +101,7 @@ enum fsck_type
 	LINK_SIZE,
 	LINK_BLOCKS,
 	DIR_ZERO,
+	DIR_HOLE,
 	INODE_SIZE,
 	INODE_SPARSE_SIZE,
 	INODE_CLUSTERS,
diff --git a/fswreck/main.c b/fswreck/main.c
index b1b2fcb..14b0301 100644
--- a/fswreck/main.c
+++ b/fswreck/main.c
@@ -117,6 +117,8 @@ static struct prompt_code prompt_codes[NUM_FSCK_TYPE] = {
 			   "Corrupt dir's dotdot entry's ino it points to"),
 	define_prompt_code(DIR_ZERO, corrupt_file,
 			   "Corrupt directory, empty its content"),
+	define_prompt_code(DIR_HOLE, corrupt_file,
+			   "Create a hole in the directory"),
 	define_prompt_code(DIRENT_DOTTY_DUP, corrupt_file,
 			   "Duplicate '.' dirent to a directory"),
 	define_prompt_code(DIRENT_NOT_DOTTY, corrupt_file,



More information about the Ocfs2-tools-devel mailing list