[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