[Ocfs2-tools-devel] [PATCH 5/5] mount.ocfs2: Fix bugs related to hard-ro mounts

Sunil Mushran sunil.mushran at oracle.com
Mon Jun 6 12:01:34 PDT 2011


Patch teaches the libocfs2 call, ocfs2_open(), to detect hard-ro devices.

It also fixes a bug in mount.ocfs2, introduced by commit
52bae5e7a358e927a1e841ead2c6a95cf68c5db1, due to which it stopped appending
the mount option heartbeat=none for hard-ro mounts.

Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
---
 include/ocfs2/ocfs2.h     |    3 +++
 libocfs2/openfs.c         |   10 ++++++++++
 libocfs2/unix_io.c        |   13 +++++++++++++
 mount.ocfs2/mount.ocfs2.c |   40 +++++++++++-----------------------------
 4 files changed, 37 insertions(+), 29 deletions(-)

diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index fa91a54..f2a8490 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -92,6 +92,7 @@
 #define OCFS2_FLAG_NO_ECC_CHECKS      0x0200	/* Do not validate metaecc
 						 * information on block
 						 * reads. */
+#define OCFS2_FLAG_HARD_RO            0x0400
 
 
 /* Return flags for the directory iterator functions */
@@ -291,6 +292,7 @@ errcode_t ocfs2_malloc_blocks(io_channel *channel, int num_blocks,
 			      void *ptr);
 errcode_t ocfs2_malloc_block(io_channel *channel, void *ptr);
 
+int io_is_device_readonly(io_channel *channel);
 errcode_t io_open(const char *name, int flags, io_channel **channel);
 errcode_t io_close(io_channel *channel);
 int io_get_error(io_channel *channel);
@@ -342,6 +344,7 @@ errcode_t ocfs2_read_blocks(ocfs2_filesys *fs, int64_t blkno, int count,
 			    char *data);
 errcode_t ocfs2_read_blocks_nocache(ocfs2_filesys *fs, int64_t blkno, int count,
 				    char *data);
+int ocfs2_is_hard_readonly(ocfs2_filesys *fs);
 int ocfs2_mount_local(ocfs2_filesys *fs);
 errcode_t ocfs2_open(const char *name, int flags,
 		     unsigned int superblock, unsigned int blksize,
diff --git a/libocfs2/openfs.c b/libocfs2/openfs.c
index 9d477a5..4fc38bd 100644
--- a/libocfs2/openfs.c
+++ b/libocfs2/openfs.c
@@ -264,6 +264,11 @@ int ocfs2_mount_local(ocfs2_filesys *fs)
 	       OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT;
 }
 
+int ocfs2_is_hard_readonly(ocfs2_filesys *fs)
+{
+	return fs->fs_flags & OCFS2_FLAG_HARD_RO;
+}
+
 errcode_t ocfs2_open(const char *name, int flags,
 		     unsigned int superblock, unsigned int block_size,
 		     ocfs2_filesys **ret_fs)
@@ -306,6 +311,11 @@ errcode_t ocfs2_open(const char *name, int flags,
 			block_size = fs->ost->ost_fsblksz;
 	}
 
+	/* image file is not a device */
+	if (!(flags & OCFS2_FLAG_IMAGE_FILE)) {
+		if (io_is_device_readonly(fs->fs_io))
+			fs->fs_flags |= OCFS2_FLAG_HARD_RO;
+	}
 
 	/*
 	 * If OCFS2_FLAG_NO_REV_CHECK is specified, fsck (or someone
diff --git a/libocfs2/unix_io.c b/libocfs2/unix_io.c
index 4d16b0c..7437fca 100644
--- a/libocfs2/unix_io.c
+++ b/libocfs2/unix_io.c
@@ -33,6 +33,7 @@
 #include <assert.h>
 #include <string.h>
 #include <sys/types.h>
+#include <sys/ioctl.h>
 #include <unistd.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -40,6 +41,7 @@
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/utsname.h>
+#include <linux/fs.h>
 #endif
 #include <sys/mman.h>
 #include <inttypes.h>
@@ -618,6 +620,17 @@ static errcode_t io_validate_o_direct(io_channel *channel)
 	return ret;
 }
 
+int io_is_device_readonly(io_channel *channel)
+{
+	errcode_t ret;
+	int dev_ro;
+
+	ret = ioctl(channel->io_fd, BLKROGET, &dev_ro);
+	if (ret >= 0 && dev_ro)
+		return 1;
+	return 0;
+}
+
 errcode_t io_open(const char *name, int flags, io_channel **channel)
 {
 	errcode_t ret;
diff --git a/mount.ocfs2/mount.ocfs2.c b/mount.ocfs2/mount.ocfs2.c
index a5e117d..20824cf 100644
--- a/mount.ocfs2/mount.ocfs2.c
+++ b/mount.ocfs2/mount.ocfs2.c
@@ -112,7 +112,7 @@ static errcode_t add_mount_options(ocfs2_filesys *fs,
 	char stackstr[strlen(OCFS2_CLUSTER_STACK_ARG) + OCFS2_STACK_LABEL_LEN + 1];
 	struct ocfs2_super_block *sb = OCFS2_RAW_SB(fs->fs_super);
 
-	if (ocfs2_mount_local(fs)) {
+	if (ocfs2_mount_local(fs) || ocfs2_is_hard_readonly(fs)) {
 		add = OCFS2_HB_NONE;
 		goto addit;
 	}
@@ -245,24 +245,6 @@ static int process_options(struct mount_options *mo)
 	return 0;
 }
 
-static int check_dev_readonly(const char *dev, int *dev_ro)
-{
-	int fd;
-	int ret;
-
-	fd = open64(dev, O_RDONLY);
-	if (fd < 0)
-		return errno;
-
-	ret = ioctl(fd, BLKROGET, dev_ro);
-	if (ret < 0)
-		return errno;
-
-	close(fd);
-
-	return 0;
-}
-
 static int run_hb_ctl(const char *hb_ctl_path,
 		      const char *device, const char *arg)
 {
@@ -326,7 +308,6 @@ int main(int argc, char **argv)
 {
 	errcode_t ret = 0;
 	struct mount_options mo;
-	int dev_ro = 0;
 	ocfs2_filesys *fs = NULL;
 	struct o2cb_cluster_desc cluster;
 	struct o2cb_region_desc desc;
@@ -366,6 +347,15 @@ int main(int argc, char **argv)
 
 	clustered = (0 == ocfs2_mount_local(fs));
 
+	if (ocfs2_is_hard_readonly(fs) && (clustered ||
+					   !(mo.flags & MS_RDONLY))) {
+		ret = OCFS2_ET_IO;
+		com_err(progname, ret,
+			"while mounting read-only device in %s mode",
+			(clustered ? "clustered" : "read-write"));
+		goto bail;
+	}
+
 	if (verbose)
 		printf("device=%s\n", mo.dev);
 
@@ -393,14 +383,6 @@ int main(int argc, char **argv)
 		desc.r_service = OCFS2_FS_NAME;
 	}
 
-	if (mo.flags & MS_RDONLY) {
-		ret = check_dev_readonly(mo.dev, &dev_ro);
-		if (ret) {
-			com_err(progname, ret, "device not accessible");
-			goto bail;
-		}
-	}
-
 	ret = add_mount_options(fs, &cluster, &mo.xtra_opts);
 	if (ret) {
 		com_err(progname, ret, "while adding mount options");
@@ -424,7 +406,7 @@ int main(int argc, char **argv)
 
 	block_signals (SIG_BLOCK);
 
-	if (!(mo.flags & MS_REMOUNT) && !dev_ro && clustered) {
+	if (clustered && !(mo.flags & MS_REMOUNT)) {
 		ret = o2cb_begin_group_join(&cluster, &desc);
 		if (ret) {
 			block_signals (SIG_UNBLOCK);
-- 
1.7.4.1




More information about the Ocfs2-tools-devel mailing list