ocfs2: Add an incompat feature flag OCFS2_FEATURE_INCOMPAT_CLUSTERINFO
OCFS2_FEATURE_INCOMPAT_CLUSTERINFO allows us to use sb->s_cluster_info for both userspace and o2cb cluster stacks. It also allows us to extend cluster info to include stack flags. This patch also adds stackflags to sb->s_clusterinfo. It also introduces a clusterinfo flag OCFS2_CLUSTER_O2CB_GLOBAL_HEARTBEAT to denote the enabled global heartbeat mode. This incompat flag can be set/cleared using tunefs.ocfs2 --fs-features. The clusterinfo flag is set/cleared using tunefs.ocfs2 --update-cluster-stack. Signed-off-by: Sunil Mushran <sunil.mushran@oracle.com>
This commit is contained in:
@@ -368,6 +368,8 @@ struct ocfs2_super
|
|||||||
struct ocfs2_alloc_stats alloc_stats;
|
struct ocfs2_alloc_stats alloc_stats;
|
||||||
char dev_str[20]; /* "major,minor" of the device */
|
char dev_str[20]; /* "major,minor" of the device */
|
||||||
|
|
||||||
|
u8 osb_stackflags;
|
||||||
|
|
||||||
char osb_cluster_stack[OCFS2_STACK_LABEL_LEN + 1];
|
char osb_cluster_stack[OCFS2_STACK_LABEL_LEN + 1];
|
||||||
struct ocfs2_cluster_connection *cconn;
|
struct ocfs2_cluster_connection *cconn;
|
||||||
struct ocfs2_lock_res osb_super_lockres;
|
struct ocfs2_lock_res osb_super_lockres;
|
||||||
@@ -601,10 +603,35 @@ static inline int ocfs2_is_soft_readonly(struct ocfs2_super *osb)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ocfs2_userspace_stack(struct ocfs2_super *osb)
|
static inline int ocfs2_clusterinfo_valid(struct ocfs2_super *osb)
|
||||||
{
|
{
|
||||||
return (osb->s_feature_incompat &
|
return (osb->s_feature_incompat &
|
||||||
OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK);
|
(OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK |
|
||||||
|
OCFS2_FEATURE_INCOMPAT_CLUSTERINFO));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ocfs2_userspace_stack(struct ocfs2_super *osb)
|
||||||
|
{
|
||||||
|
if (ocfs2_clusterinfo_valid(osb) &&
|
||||||
|
memcmp(osb->osb_cluster_stack, OCFS2_CLASSIC_CLUSTER_STACK,
|
||||||
|
OCFS2_STACK_LABEL_LEN))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ocfs2_o2cb_stack(struct ocfs2_super *osb)
|
||||||
|
{
|
||||||
|
if (ocfs2_clusterinfo_valid(osb) &&
|
||||||
|
!memcmp(osb->osb_cluster_stack, OCFS2_CLASSIC_CLUSTER_STACK,
|
||||||
|
OCFS2_STACK_LABEL_LEN))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int ocfs2_cluster_o2cb_global_heartbeat(struct ocfs2_super *osb)
|
||||||
|
{
|
||||||
|
return ocfs2_o2cb_stack(osb) &&
|
||||||
|
(osb->osb_stackflags & OCFS2_CLUSTER_O2CB_GLOBAL_HEARTBEAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int ocfs2_mount_local(struct ocfs2_super *osb)
|
static inline int ocfs2_mount_local(struct ocfs2_super *osb)
|
||||||
|
@@ -101,7 +101,8 @@
|
|||||||
| OCFS2_FEATURE_INCOMPAT_META_ECC \
|
| OCFS2_FEATURE_INCOMPAT_META_ECC \
|
||||||
| OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS \
|
| OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS \
|
||||||
| OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE \
|
| OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE \
|
||||||
| OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG)
|
| OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG \
|
||||||
|
| OCFS2_FEATURE_INCOMPAT_CLUSTERINFO)
|
||||||
#define OCFS2_FEATURE_RO_COMPAT_SUPP (OCFS2_FEATURE_RO_COMPAT_UNWRITTEN \
|
#define OCFS2_FEATURE_RO_COMPAT_SUPP (OCFS2_FEATURE_RO_COMPAT_UNWRITTEN \
|
||||||
| OCFS2_FEATURE_RO_COMPAT_USRQUOTA \
|
| OCFS2_FEATURE_RO_COMPAT_USRQUOTA \
|
||||||
| OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)
|
| OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)
|
||||||
@@ -169,6 +170,13 @@
|
|||||||
/* Discontigous block groups */
|
/* Discontigous block groups */
|
||||||
#define OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG 0x2000
|
#define OCFS2_FEATURE_INCOMPAT_DISCONTIG_BG 0x2000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Incompat bit to indicate useable clusterinfo with stackflags for all
|
||||||
|
* cluster stacks (userspace adnd o2cb). If this bit is set,
|
||||||
|
* INCOMPAT_USERSPACE_STACK becomes superfluous and thus should not be set.
|
||||||
|
*/
|
||||||
|
#define OCFS2_FEATURE_INCOMPAT_CLUSTERINFO 0x4000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* backup superblock flag is used to indicate that this volume
|
* backup superblock flag is used to indicate that this volume
|
||||||
* has backup superblocks.
|
* has backup superblocks.
|
||||||
@@ -292,10 +300,13 @@
|
|||||||
#define OCFS2_VOL_UUID_LEN 16
|
#define OCFS2_VOL_UUID_LEN 16
|
||||||
#define OCFS2_MAX_VOL_LABEL_LEN 64
|
#define OCFS2_MAX_VOL_LABEL_LEN 64
|
||||||
|
|
||||||
/* The alternate, userspace stack fields */
|
/* The cluster stack fields */
|
||||||
#define OCFS2_STACK_LABEL_LEN 4
|
#define OCFS2_STACK_LABEL_LEN 4
|
||||||
#define OCFS2_CLUSTER_NAME_LEN 16
|
#define OCFS2_CLUSTER_NAME_LEN 16
|
||||||
|
|
||||||
|
/* Classic (historically speaking) cluster stack */
|
||||||
|
#define OCFS2_CLASSIC_CLUSTER_STACK "o2cb"
|
||||||
|
|
||||||
/* Journal limits (in bytes) */
|
/* Journal limits (in bytes) */
|
||||||
#define OCFS2_MIN_JOURNAL_SIZE (4 * 1024 * 1024)
|
#define OCFS2_MIN_JOURNAL_SIZE (4 * 1024 * 1024)
|
||||||
|
|
||||||
@@ -305,6 +316,11 @@
|
|||||||
*/
|
*/
|
||||||
#define OCFS2_MIN_XATTR_INLINE_SIZE 256
|
#define OCFS2_MIN_XATTR_INLINE_SIZE 256
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Cluster info flags (ocfs2_cluster_info.ci_stackflags)
|
||||||
|
*/
|
||||||
|
#define OCFS2_CLUSTER_O2CB_GLOBAL_HEARTBEAT (0x01)
|
||||||
|
|
||||||
struct ocfs2_system_inode_info {
|
struct ocfs2_system_inode_info {
|
||||||
char *si_name;
|
char *si_name;
|
||||||
int si_iflags;
|
int si_iflags;
|
||||||
@@ -566,9 +582,21 @@ struct ocfs2_slot_map_extended {
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ci_stackflags is only valid if the incompat bit
|
||||||
|
* OCFS2_FEATURE_INCOMPAT_CLUSTERINFO is set.
|
||||||
|
*/
|
||||||
struct ocfs2_cluster_info {
|
struct ocfs2_cluster_info {
|
||||||
/*00*/ __u8 ci_stack[OCFS2_STACK_LABEL_LEN];
|
/*00*/ __u8 ci_stack[OCFS2_STACK_LABEL_LEN];
|
||||||
__le32 ci_reserved;
|
union {
|
||||||
|
__le32 ci_reserved;
|
||||||
|
struct {
|
||||||
|
__u8 ci_stackflags;
|
||||||
|
__u8 ci_reserved1;
|
||||||
|
__u8 ci_reserved2;
|
||||||
|
__u8 ci_reserved3;
|
||||||
|
};
|
||||||
|
};
|
||||||
/*08*/ __u8 ci_cluster[OCFS2_CLUSTER_NAME_LEN];
|
/*08*/ __u8 ci_cluster[OCFS2_CLUSTER_NAME_LEN];
|
||||||
/*18*/
|
/*18*/
|
||||||
};
|
};
|
||||||
@@ -605,9 +633,9 @@ struct ocfs2_super_block {
|
|||||||
* group header */
|
* group header */
|
||||||
/*50*/ __u8 s_label[OCFS2_MAX_VOL_LABEL_LEN]; /* Label for mounting, etc. */
|
/*50*/ __u8 s_label[OCFS2_MAX_VOL_LABEL_LEN]; /* Label for mounting, etc. */
|
||||||
/*90*/ __u8 s_uuid[OCFS2_VOL_UUID_LEN]; /* 128-bit uuid */
|
/*90*/ __u8 s_uuid[OCFS2_VOL_UUID_LEN]; /* 128-bit uuid */
|
||||||
/*A0*/ struct ocfs2_cluster_info s_cluster_info; /* Selected userspace
|
/*A0*/ struct ocfs2_cluster_info s_cluster_info; /* Only valid if either
|
||||||
stack. Only valid
|
userspace or clusterinfo
|
||||||
with INCOMPAT flag. */
|
INCOMPAT flag set. */
|
||||||
/*B8*/ __le16 s_xattr_inline_size; /* extended attribute inline size
|
/*B8*/ __le16 s_xattr_inline_size; /* extended attribute inline size
|
||||||
for this fs*/
|
for this fs*/
|
||||||
__le16 s_reserved0;
|
__le16 s_reserved0;
|
||||||
|
@@ -2149,7 +2149,9 @@ static int ocfs2_initialize_super(struct super_block *sb,
|
|||||||
goto bail;
|
goto bail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ocfs2_userspace_stack(osb)) {
|
if (ocfs2_clusterinfo_valid(osb)) {
|
||||||
|
osb->osb_stackflags =
|
||||||
|
OCFS2_RAW_SB(di)->s_cluster_info.ci_stackflags;
|
||||||
memcpy(osb->osb_cluster_stack,
|
memcpy(osb->osb_cluster_stack,
|
||||||
OCFS2_RAW_SB(di)->s_cluster_info.ci_stack,
|
OCFS2_RAW_SB(di)->s_cluster_info.ci_stack,
|
||||||
OCFS2_STACK_LABEL_LEN);
|
OCFS2_STACK_LABEL_LEN);
|
||||||
|
Reference in New Issue
Block a user