Skip to content

Commit 912f655

Browse files
Gang Hetorvalds
Gang He
authored andcommitted
ocfs2: mount shared volume without ha stack
Usually we create and use a ocfs2 shared volume on the top of ha stack. For pcmk based ha stack, which includes DLM, corosync and pacemaker services. The customers complained they could not mount existent ocfs2 volume in the single node without ha stack, e.g. single node backup/restore scenario. Like this case, the customers just want to access the data from the existent ocfs2 volume quickly, but do not want to restart or setup ha stack. Then, I'd like to add a mount option "nocluster", if the users use this option to mount a ocfs2 shared volume, the whole mount will not depend on the ha related services. the command will mount the existent ocfs2 volume directly (like local mount), for avoiding setup the ha stack. Signed-off-by: Gang He <ghe@suse.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Cc: Mark Fasheh <mark@fasheh.com> Cc: Joel Becker <jlbec@evilplan.org> Cc: Junxiao Bi <junxiao.bi@oracle.com> Cc: Joseph Qi <jiangqi903@gmail.com> Cc: Changwei Ge <gechangwei@live.cn> Cc: Jun Piao <piaojun@huawei.com> Link: http://lkml.kernel.org/r/20200423053300.22661-1-ghe@suse.com Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 8f745e6 commit 912f655

File tree

3 files changed

+51
-20
lines changed

3 files changed

+51
-20
lines changed

fs/ocfs2/ocfs2.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ enum ocfs2_mount_options
279279
OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT = 1 << 15, /* Journal Async Commit */
280280
OCFS2_MOUNT_ERRORS_CONT = 1 << 16, /* Return EIO to the calling process on error */
281281
OCFS2_MOUNT_ERRORS_ROFS = 1 << 17, /* Change filesystem to read-only on error */
282+
OCFS2_MOUNT_NOCLUSTER = 1 << 18, /* No cluster aware filesystem mount */
282283
};
283284

284285
#define OCFS2_OSB_SOFT_RO 0x0001
@@ -673,7 +674,8 @@ static inline int ocfs2_cluster_o2cb_global_heartbeat(struct ocfs2_super *osb)
673674

674675
static inline int ocfs2_mount_local(struct ocfs2_super *osb)
675676
{
676-
return (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT);
677+
return ((osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT)
678+
|| (osb->s_mount_opt & OCFS2_MOUNT_NOCLUSTER));
677679
}
678680

679681
static inline int ocfs2_uses_extended_slot_map(struct ocfs2_super *osb)

fs/ocfs2/slot_map.c

+27-19
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,16 @@ static int __ocfs2_find_empty_slot(struct ocfs2_slot_info *si,
254254
int i, ret = -ENOSPC;
255255

256256
if ((preferred >= 0) && (preferred < si->si_num_slots)) {
257-
if (!si->si_slots[preferred].sl_valid) {
257+
if (!si->si_slots[preferred].sl_valid ||
258+
!si->si_slots[preferred].sl_node_num) {
258259
ret = preferred;
259260
goto out;
260261
}
261262
}
262263

263264
for(i = 0; i < si->si_num_slots; i++) {
264-
if (!si->si_slots[i].sl_valid) {
265+
if (!si->si_slots[i].sl_valid ||
266+
!si->si_slots[i].sl_node_num) {
265267
ret = i;
266268
break;
267269
}
@@ -456,24 +458,30 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
456458
spin_lock(&osb->osb_lock);
457459
ocfs2_update_slot_info(si);
458460

459-
/* search for ourselves first and take the slot if it already
460-
* exists. Perhaps we need to mark this in a variable for our
461-
* own journal recovery? Possibly not, though we certainly
462-
* need to warn to the user */
463-
slot = __ocfs2_node_num_to_slot(si, osb->node_num);
464-
if (slot < 0) {
465-
/* if no slot yet, then just take 1st available
466-
* one. */
467-
slot = __ocfs2_find_empty_slot(si, osb->preferred_slot);
461+
if (ocfs2_mount_local(osb))
462+
/* use slot 0 directly in local mode */
463+
slot = 0;
464+
else {
465+
/* search for ourselves first and take the slot if it already
466+
* exists. Perhaps we need to mark this in a variable for our
467+
* own journal recovery? Possibly not, though we certainly
468+
* need to warn to the user */
469+
slot = __ocfs2_node_num_to_slot(si, osb->node_num);
468470
if (slot < 0) {
469-
spin_unlock(&osb->osb_lock);
470-
mlog(ML_ERROR, "no free slots available!\n");
471-
status = -EINVAL;
472-
goto bail;
473-
}
474-
} else
475-
printk(KERN_INFO "ocfs2: Slot %d on device (%s) was already "
476-
"allocated to this node!\n", slot, osb->dev_str);
471+
/* if no slot yet, then just take 1st available
472+
* one. */
473+
slot = __ocfs2_find_empty_slot(si, osb->preferred_slot);
474+
if (slot < 0) {
475+
spin_unlock(&osb->osb_lock);
476+
mlog(ML_ERROR, "no free slots available!\n");
477+
status = -EINVAL;
478+
goto bail;
479+
}
480+
} else
481+
printk(KERN_INFO "ocfs2: Slot %d on device (%s) was "
482+
"already allocated to this node!\n",
483+
slot, osb->dev_str);
484+
}
477485

478486
ocfs2_set_slot(si, slot, osb->node_num);
479487
osb->slot_num = slot;

fs/ocfs2/super.c

+21
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ enum {
175175
Opt_dir_resv_level,
176176
Opt_journal_async_commit,
177177
Opt_err_cont,
178+
Opt_nocluster,
178179
Opt_err,
179180
};
180181

@@ -208,6 +209,7 @@ static const match_table_t tokens = {
208209
{Opt_dir_resv_level, "dir_resv_level=%u"},
209210
{Opt_journal_async_commit, "journal_async_commit"},
210211
{Opt_err_cont, "errors=continue"},
212+
{Opt_nocluster, "nocluster"},
211213
{Opt_err, NULL}
212214
};
213215

@@ -619,6 +621,13 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
619621
goto out;
620622
}
621623

624+
tmp = OCFS2_MOUNT_NOCLUSTER;
625+
if ((osb->s_mount_opt & tmp) != (parsed_options.mount_opt & tmp)) {
626+
ret = -EINVAL;
627+
mlog(ML_ERROR, "Cannot change nocluster option on remount\n");
628+
goto out;
629+
}
630+
622631
tmp = OCFS2_MOUNT_HB_LOCAL | OCFS2_MOUNT_HB_GLOBAL |
623632
OCFS2_MOUNT_HB_NONE;
624633
if ((osb->s_mount_opt & tmp) != (parsed_options.mount_opt & tmp)) {
@@ -859,6 +868,7 @@ static int ocfs2_verify_userspace_stack(struct ocfs2_super *osb,
859868
}
860869

861870
if (ocfs2_userspace_stack(osb) &&
871+
!(osb->s_mount_opt & OCFS2_MOUNT_NOCLUSTER) &&
862872
strncmp(osb->osb_cluster_stack, mopt->cluster_stack,
863873
OCFS2_STACK_LABEL_LEN)) {
864874
mlog(ML_ERROR,
@@ -1139,6 +1149,11 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
11391149
osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" :
11401150
"ordered");
11411151

1152+
if ((osb->s_mount_opt & OCFS2_MOUNT_NOCLUSTER) &&
1153+
!(osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_LOCAL_MOUNT))
1154+
printk(KERN_NOTICE "ocfs2: The shared device (%s) is mounted "
1155+
"without cluster aware mode.\n", osb->dev_str);
1156+
11421157
atomic_set(&osb->vol_state, VOLUME_MOUNTED);
11431158
wake_up(&osb->osb_mount_event);
11441159

@@ -1445,6 +1460,9 @@ static int ocfs2_parse_options(struct super_block *sb,
14451460
case Opt_journal_async_commit:
14461461
mopt->mount_opt |= OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT;
14471462
break;
1463+
case Opt_nocluster:
1464+
mopt->mount_opt |= OCFS2_MOUNT_NOCLUSTER;
1465+
break;
14481466
default:
14491467
mlog(ML_ERROR,
14501468
"Unrecognized mount option \"%s\" "
@@ -1556,6 +1574,9 @@ static int ocfs2_show_options(struct seq_file *s, struct dentry *root)
15561574
if (opts & OCFS2_MOUNT_JOURNAL_ASYNC_COMMIT)
15571575
seq_printf(s, ",journal_async_commit");
15581576

1577+
if (opts & OCFS2_MOUNT_NOCLUSTER)
1578+
seq_printf(s, ",nocluster");
1579+
15591580
return 0;
15601581
}
15611582

0 commit comments

Comments
 (0)