[Debian-ha-commits] [ocfs2-tools] 32/58: Add check to compare journal size and cluster size

Valentin Vidic vvidic-guest at moszumanska.debian.org
Tue Jun 20 13:40:42 UTC 2017


This is an automated email from the git hooks/post-receive script.

vvidic-guest pushed a commit to branch upstream
in repository ocfs2-tools.

commit 1eddb106cb6b62b9ac86c1096c992f4850c288e1
Author: Ashish Samant <ashish.samant at oracle.com>
Date:   Wed Apr 29 15:09:19 2015 -0700

    Add check to compare journal size and cluster size
    
    If user doesn't provide right Journal size, mkfs should fail. Currently it
    succeeds but ends up as unusable fs.
    
    1. mkfs.ocfs2 -J size=4M -C 1M -N 2 -L xvdh --cluster-name=ocfs2big
      --cluster-stack=o2cb --force --global-heartbeat /dev/xvdh
    2. mount -t ocfs2 /dev/xvdh /mnt
    
    3. mkdir aa
        mkdir: cannot create directory `aa': No space left on device
    
    This happens because of the following:
    
    The kernel allows the maximum transaction buffer to be 1\4 th of the journal
    size and this is further divided by 2 for transaction reservation support.
    Some operations such as mkdir can require more than a cluster worth of journal
    credits. Such operations will fail if the journal size is not greater than
    cluster size * 8.
    
    This patch adds this check for user provided values and modifies the default
    calculation to account for the same. It will fail mkfs if the conditions are
    not met instead of creating a non-functional filesystem.
    
    Signed-off-by: Ashish Samant <ashish.samant at oracle.com>
    Reviewed-by: Srinivas Eeda <srinivas.eeda at oracle.com>
    Signed-off-by: Junxiao Bi <junxiao.bi at oracle.com>
---
 include/ocfs2-kernel/ocfs2_fs.h |  2 ++
 mkfs.ocfs2/mkfs.c               | 51 +++++++++++++++++++++++++++++++++++++----
 2 files changed, 49 insertions(+), 4 deletions(-)

diff --git a/include/ocfs2-kernel/ocfs2_fs.h b/include/ocfs2-kernel/ocfs2_fs.h
index 620c6de..a85d218 100644
--- a/include/ocfs2-kernel/ocfs2_fs.h
+++ b/include/ocfs2-kernel/ocfs2_fs.h
@@ -317,6 +317,8 @@
 
 /* Journal limits (in bytes) */
 #define OCFS2_MIN_JOURNAL_SIZE		(4 * 1024 * 1024)
+/* Minimum Journal size shift with respect to cluster size */
+#define OCFS2_MIN_CLUSTER_TO_JOURNAL_SIZE_SHIFT		3
 
 /*
  * Default local alloc size (in megabytes)
diff --git a/mkfs.ocfs2/mkfs.c b/mkfs.ocfs2/mkfs.c
index 18dff97..f36d637 100644
--- a/mkfs.ocfs2/mkfs.c
+++ b/mkfs.ocfs2/mkfs.c
@@ -1450,10 +1450,30 @@ static unsigned int journal_size_vmstore(State *s)
 	return 32768;
 }
 
+static int journal_size_valid(unsigned int j_blocks, State *s)
+{
+	return (j_blocks * s->initial_slots + 1024) <=
+		s->volume_size_in_blocks;
+}
+
+/* For operations such as mkdir that can require more than a cluster worth
+ * of journal credits, journal size should be greater than cluster size * 8.
+ * The kernel allows the maximum transaction buffer to be 1\4 th of the
+ * journal size and this is further divided by 2 for transaction
+ * reservation support. We calculate minimum journal size here
+ * accordingly and and ceil w.r.t to the cluster size.*/
+static unsigned int journal_min_size(uint32_t cluster_size)
+{
+	return (cluster_size << OCFS2_MIN_CLUSTER_TO_JOURNAL_SIZE_SHIFT)
+		+ cluster_size;
+}
+
 /* stolen from e2fsprogs, modified to fit ocfs2 patterns */
 static uint64_t figure_journal_size(uint64_t size, State *s)
 {
 	unsigned int j_blocks;
+	uint64_t ret;
+	unsigned int min_journal_size;
 
 	if (s->hb_dev)
 		return 0;
@@ -1463,19 +1483,27 @@ static uint64_t figure_journal_size(uint64_t size, State *s)
 		exit(1);
 	}
 
+	min_journal_size = journal_min_size(s->cluster_size);
 	if (size > 0) {
 		j_blocks = size >> s->blocksize_bits;
 		/* mke2fs knows about free blocks at this point, but
 		 * we don't so lets just take a wild guess as to what
 		 * the fs overhead we're looking at will be. */
-		if ((j_blocks * s->initial_slots + 1024) > 
-		    s->volume_size_in_blocks) {
+		if (!journal_size_valid(j_blocks, s)) {
 			fprintf(stderr, 
 				"Journal size too big for filesystem.\n");
 			exit(1);
 		}
 
-		return align_bytes_to_clusters_ceil(s, size);
+		ret = align_bytes_to_clusters_ceil(s, size);
+		/* It is better to fail mkfs than to create a non-functional
+		 * filesystem.*/
+		if (ret < min_journal_size) {
+			fprintf(stderr,
+				"Journal size too small for filesystem.\n");
+			exit(1);
+		}
+		return ret;
 	}
 
 	switch (s->fs_type) {
@@ -1493,7 +1521,22 @@ static uint64_t figure_journal_size(uint64_t size, State *s)
 		break;
 	}
 
-	return align_bytes_to_clusters_ceil(s, j_blocks << s->blocksize_bits);
+	ret = align_bytes_to_clusters_ceil(s, j_blocks << s->blocksize_bits);
+	/* If the default journal size is less than the minimum required
+	 * size, set the default to the minimum size. Then fail if
+	 * the journal size is not valid*/
+	if (ret < min_journal_size) {
+		ret = min_journal_size;
+		j_blocks = ret >> s->blocksize_bits;
+		if (!journal_size_valid(j_blocks, s)) {
+			fprintf(stderr,
+				"Volume size too small for required "
+				"configuration.\nIncrease volume size or "
+				"reduce cluster size\n");
+			exit(1);
+		}
+	}
+	return ret;
 }
 
 static uint32_t cluster_size_default(State *s)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-ha/ocfs2-tools.git



More information about the Debian-HA-Commits mailing list