#define LOV_PATTERN_RAID1 0x002
#define LOV_PATTERN_MDT 0x100
#define LOV_PATTERN_OVERSTRIPING 0x200
+#define LOV_PATTERN_FOREIGN 0x400
#define LOV_PATTERN_F_MASK 0xffff0000
#define LOV_PATTERN_F_HOLE 0x40000000 /* there is hole in LOV EA */
static inline __u32 lov_entry_type(struct lov_stripe_md_entry *lsme)
{
if ((lov_pattern(lsme->lsme_pattern) & LOV_PATTERN_RAID0) ||
- (lov_pattern(lsme->lsme_pattern) == LOV_PATTERN_MDT))
+ (lov_pattern(lsme->lsme_pattern) == LOV_PATTERN_MDT) ||
+ (lov_pattern(lsme->lsme_pattern) == LOV_PATTERN_FOREIGN))
return lov_pattern(lsme->lsme_pattern &
~LOV_PATTERN_OVERSTRIPING);
return 0;
unsigned short lre_mirror_id;
unsigned short lre_preferred:1,
lre_stale:1, /* set if any components is stale */
- lre_valid:1; /* set if at least one of components
+ lre_valid:1, /* set if at least one of components
* in this mirror is valid */
+ lre_foreign:1; /* set if it is a foreign component */
+
unsigned short lre_start; /* index to lo_entries, start index of
* this mirror */
unsigned short lre_end; /* end index of this mirror */
static void lsme_free(struct lov_stripe_md_entry *lsme)
{
- unsigned int stripe_count = lsme->lsme_stripe_count;
+ unsigned int stripe_count;
unsigned int i;
size_t lsme_size;
+ if (lsme->lsme_magic == LOV_MAGIC_FOREIGN) {
+ /*
+ * TODO: In addition to HSM foreign layout, It needs to add
+ * support for other kinds of foreign layout types such as
+ * DAOS, S3. When add these supports, it will use non-inline
+ * @lov_hsm_base to store layout information, and need to
+ * free extra allocated buffer.
+ */
+ OBD_FREE_LARGE(lsme, sizeof(*lsme));
+ return;
+ }
+
+ stripe_count = lsme->lsme_stripe_count;
if (!lsme_inited(lsme) ||
lsme->lsme_pattern & LOV_PATTERN_F_RELEASED)
stripe_count = 0;
else
stripe_count = le16_to_cpu(lmm->lmm_stripe_count);
- if (buf_size < (magic == LOV_MAGIC_V1 ? sizeof(struct lov_mds_md_v1) :
- sizeof(struct lov_mds_md_v3))) {
+ if (buf_size < lov_mds_md_size(stripe_count, magic)) {
CERROR("LOV EA %s too small: %zu, need %u\n",
magic == LOV_MAGIC_V1 ? "V1" : "V3", buf_size,
lov_mds_md_size(stripe_count, magic == LOV_MAGIC_V1 ?
}
static struct lov_stripe_md_entry *
+lsme_unpack_foreign(struct lov_obd *lov, void *buf, size_t buf_size,
+ bool inited, loff_t *maxbytes)
+{
+ struct lov_stripe_md_entry *lsme;
+ struct lov_foreign_md *lfm = buf;
+ __u32 magic;
+
+ ENTRY;
+
+ magic = le32_to_cpu(lfm->lfm_magic);
+ if (magic != LOV_MAGIC_FOREIGN)
+ RETURN(ERR_PTR(-EINVAL));
+
+ OBD_ALLOC_LARGE(lsme, sizeof(*lsme));
+ if (!lsme)
+ RETURN(ERR_PTR(-ENOMEM));
+
+ lsme->lsme_magic = magic;
+ lsme->lsme_pattern = LOV_PATTERN_FOREIGN;
+ lsme->lsme_flags = 0;
+
+ if (maxbytes)
+ *maxbytes = MAX_LFS_FILESIZE;
+
+ RETURN(lsme);
+}
+
+static struct lov_stripe_md_entry *
lsme_unpack_comp(struct lov_obd *lov, struct lov_mds_md *lmm,
size_t lmm_buf_size, bool inited, loff_t *maxbytes)
{
unsigned int magic;
- unsigned int stripe_count;
-
- stripe_count = le16_to_cpu(lmm->lmm_stripe_count);
- if (stripe_count == 0 &&
- lov_pattern(le32_to_cpu(lmm->lmm_pattern)) != LOV_PATTERN_MDT)
- RETURN(ERR_PTR(-EINVAL));
- /* un-instantiated lmm contains no ost id info, i.e. lov_ost_data_v1 */
- if (!inited)
- stripe_count = 0;
magic = le32_to_cpu(lmm->lmm_magic);
- if (magic != LOV_MAGIC_V1 && magic != LOV_MAGIC_V3)
+ if (magic != LOV_MAGIC_V1 && magic != LOV_MAGIC_V3 &&
+ magic != LOV_MAGIC_FOREIGN)
RETURN(ERR_PTR(-EINVAL));
- if (lmm_buf_size < lov_mds_md_size(stripe_count, magic))
+ if (magic != LOV_MAGIC_FOREIGN &&
+ le16_to_cpu(lmm->lmm_stripe_count) == 0 &&
+ lov_pattern(le32_to_cpu(lmm->lmm_pattern)) != LOV_PATTERN_MDT)
RETURN(ERR_PTR(-EINVAL));
if (magic == LOV_MAGIC_V1) {
return lsme_unpack(lov, lmm, lmm_buf_size, NULL,
inited, lmm->lmm_objects, maxbytes);
- } else {
+ } else if (magic == LOV_MAGIC_V3) {
struct lov_mds_md_v3 *lmm3 = (struct lov_mds_md_v3 *)lmm;
return lsme_unpack(lov, lmm, lmm_buf_size, lmm3->lmm_pool_name,
inited, lmm3->lmm_objects, maxbytes);
+ } else { /* LOV_MAGIC_FOREIGN */
+ return lsme_unpack_foreign(lov, lmm, lmm_buf_size,
+ inited, maxbytes);
}
}
#define lsm_foreign(lsm) (lsm->lsm_entries[0])
+static inline bool lsme_is_foreign(const struct lov_stripe_md_entry *lsme)
+{
+ return lsme->lsme_magic == LOV_MAGIC_FOREIGN;
+}
+
+static inline bool lsm_entry_is_foreign(const struct lov_stripe_md *lsm,
+ int index)
+{
+ return lsme_is_foreign(lsm->lsm_entries[index]);
+}
+
static inline bool lsme_inited(const struct lov_stripe_md_entry *lsme)
{
return lsme->lsme_flags & LCME_FL_INIT;
LASSERT(lsm->lsm_magic == LOV_MAGIC_COMP_V1);
- size = sizeof(struct lov_comp_md_v1);
+ size = sizeof(struct lov_comp_md_v1) +
+ sizeof(struct lov_comp_md_entry_v1) * lsm->lsm_entry_count;
for (entry = 0; entry < lsm->lsm_entry_count; entry++) {
u16 stripe_count;
else
stripe_count = 0;
- size += sizeof(*lsme);
size += lov_mds_md_size(stripe_count,
lsme->lsme_magic);
}
if (!lre->lre_valid)
continue;
+ if (lre->lre_foreign)
+ continue;
+
lov_foreach_mirror_layout_entry(obj, lle, lre) {
if (!lle->lle_valid)
continue;
continue;
}
+ if (lsm_entry_is_foreign(lsm, index))
+ continue;
+
if (!le->lle_valid && !ios->cis_io->ci_designated_mirror) {
CERROR("I/O to invalid component: %d, mirror: %d\n",
index, lio->lis_mirror_index);
lse = lov_lse(lio->lis_object, index);
+ if (lsme_is_foreign(lse))
+ RETURN(-EINVAL);
+
next = MAX_LFS_FILESIZE;
if (lse->lsme_stripe_count > 1) {
unsigned long ssize = lse->lsme_stripe_size;
offset = cl_offset(obj, start);
index = lov_io_layout_at(lio, offset);
- if (index < 0 || !lsm_entry_inited(loo->lo_lsm, index))
+ if (index < 0 || !lsm_entry_inited(loo->lo_lsm, index) ||
+ lsm_entry_is_foreign(loo->lo_lsm, index))
RETURN(-ENODATA);
/* avoid readahead to expand to stale components */
for (i = start_index; i <= end_index; i++) {
struct lov_layout_entry *lle = lov_entry(lov, i);
+ LASSERT(!lsme_is_foreign(lle->lle_lsme));
+
if ((offset >= lle->lle_extent->e_start &&
offset < lle->lle_extent->e_end) ||
(offset == OBD_OBJECT_EOF &&
}
lle->lle_comp_ops = &dom_ops;
break;
+ case LOV_PATTERN_FOREIGN:
+ lle->lle_comp_ops = NULL;
+ break;
default:
CERROR("%s: unknown composite layout entry type %i\n",
lov2obd(dev->ld_lov)->obd_name,
if (mirror_id == lre->lre_mirror_id) {
lre->lre_valid |= lle->lle_valid;
lre->lre_stale |= !lle->lle_valid;
+ lre->lre_foreign |=
+ lsme_is_foreign(lle->lle_lsme);
lre->lre_end = i;
continue;
}
LCME_FL_PREF_RD);
lre->lre_valid = lle->lle_valid;
lre->lre_stale = !lle->lle_valid;
+ lre->lre_foreign = lsme_is_foreign(lle->lle_lsme);
}
/* sanity check for FLR */
if (!lsme_inited(lle->lle_lsme))
continue;
+ if (lsme_is_foreign(lle->lle_lsme))
+ continue;
+
result = lle->lle_comp_ops->lco_init(env, dev, lov, index,
conf, lle);
if (result < 0)
if (lre->lre_stale)
continue;
+ if (lre->lre_foreign)
+ continue;
+
mirror_count++; /* valid mirror */
if (lre->lre_preferred || comp->lo_preferred_mirror < 0)
lov_layout_wait(env, lov);
if (comp->lo_entries)
- lov_foreach_layout_entry(lov, entry)
+ lov_foreach_layout_entry(lov, entry) {
+ if (lsme_is_foreign(entry->lle_lsme))
+ continue;
+
lov_delete_raid0(env, lov, entry);
+ }
RETURN(0);
}
lse->lsme_id, lse->lsme_pattern, lse->lsme_layout_gen,
lse->lsme_flags, lse->lsme_stripe_count,
lse->lsme_stripe_size);
- lov_print_raid0(env, cookie, p, lle);
+
+ if (!lsme_is_foreign(lse))
+ lov_print_raid0(env, cookie, p, lle);
}
return 0;