#define XATTR_NAME_LOV "trusted.lov"
#define XATTR_NAME_LMA "trusted.lma"
#define XATTR_NAME_LMV "trusted.lmv"
-#define XATTR_NAME_DEFALT_LMV "trusted.dmv"
+#define XATTR_NAME_DEFAULT_LMV "trusted.dmv"
#define XATTR_NAME_LINK "trusted.link"
#define XATTR_NAME_FID "trusted.fid"
#define XATTR_NAME_VERSION "trusted.version"
#define OBD_MD_FLDATAVERSION (0x0010000000000000ULL) /* iversion sum */
#define OBD_MD_FLRELEASED (0x0020000000000000ULL) /* file released */
+#define OBD_MD_DEFAULT_MEA (0x0040000000000000ULL) /* default MEA */
+
#define OBD_MD_FLGETATTR (OBD_MD_FLID | OBD_MD_FLATIME | OBD_MD_FLMTIME | \
OBD_MD_FLCTIME | OBD_MD_FLSIZE | OBD_MD_FLBLKSZ | \
OBD_MD_FLMODE | OBD_MD_FLTYPE | OBD_MD_FLUID | \
struct lmv_user_md lmv_user_md;
};
+extern void lustre_swab_lmv_mds_md(union lmv_mds_md *lmm);
+
static inline int lmv_mds_md_size(int stripe_count, unsigned int lmm_magic)
{
switch (lmm_magic) {
#define LL_IOC_SET_LEASE _IOWR('f', 243, long)
#define LL_IOC_GET_LEASE _IO('f', 244)
#define LL_IOC_HSM_IMPORT _IOWR('f', 245, struct hsm_user_import)
+#define LL_IOC_LMV_SET_DEFAULT_STRIPE _IOWR('f', 246, struct lmv_user_md)
#define LL_STATFS_LMV 1
#define LL_STATFS_LOV 2
check_stripecount:1, /* LOV stripe count */
exclude_stripecount:1,
check_layout:1,
- exclude_layout:1;
+ exclude_layout:1,
+ get_default_lmv:1; /* Get default LMV */
int verbose;
int quiet;
extern int llapi_find(char *path, struct find_param *param);
extern int llapi_file_fget_mdtidx(int fd, int *mdtidx);
+extern int llapi_dir_set_default_lmv_stripe(const char *name, int stripe_offset,
+ int stripe_count, int stripe_pattern,
+ const char *pool_name);
extern int llapi_dir_create_pool(const char *name, int flags, int stripe_offset,
int stripe_count, int stripe_pattern,
const char *poolname);
/** metadata attributes */
enum ma_valid {
- MA_INODE = (1 << 0),
- MA_LOV = (1 << 1),
- MA_COOKIE = (1 << 2),
- MA_FLAGS = (1 << 3),
- MA_LMV = (1 << 4),
- MA_ACL_DEF = (1 << 5),
- MA_LOV_DEF = (1 << 6),
- MA_LAY_GEN = (1 << 7),
- MA_HSM = (1 << 8),
- MA_SOM = (1 << 9),
- MA_PFID = (1 << 10)
+ MA_INODE = (1 << 0),
+ MA_LOV = (1 << 1),
+ MA_COOKIE = (1 << 2),
+ MA_FLAGS = (1 << 3),
+ MA_LMV = (1 << 4),
+ MA_ACL_DEF = (1 << 5),
+ MA_LOV_DEF = (1 << 6),
+ MA_LAY_GEN = (1 << 7),
+ MA_HSM = (1 << 8),
+ MA_SOM = (1 << 9),
+ MA_PFID = (1 << 10),
+ MA_LMV_DEF = (1 << 11)
};
typedef enum {
lum_size = sizeof(struct lov_user_md_v3);
break;
}
+ case LMV_USER_MAGIC: {
+ if (lump->lmm_magic != cpu_to_le32(LMV_USER_MAGIC))
+ lustre_swab_lmv_user_md(
+ (struct lmv_user_md *)lump);
+ lum_size = sizeof(struct lmv_user_md);
+ break;
+ }
default: {
CDEBUG(D_IOCTL, "bad userland LOV MAGIC:"
" %#08x != %#08x nor %#08x\n",
RETURN(rc);
}
-int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
- int *lmm_size, struct ptlrpc_request **request)
+/**
+ * This function will be used to get default LOV/LMV/Default LMV
+ * @valid will be used to indicate which stripe it will retrieve
+ * OBD_MD_MEA LMV stripe EA
+ * OBD_MD_DEFAULT_MEA Default LMV stripe EA
+ * otherwise Default LOV EA.
+ * Each time, it can only retrieve 1 stripe EA
+ **/
+int ll_dir_getstripe(struct inode *inode, void **plmm, int *plmm_size,
+ struct ptlrpc_request **request, obd_valid valid)
{
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct mdt_body *body;
- struct lov_mds_md *lmm = NULL;
- struct ptlrpc_request *req = NULL;
- int rc, lmmsize;
- struct md_op_data *op_data;
+ struct ll_sb_info *sbi = ll_i2sbi(inode);
+ struct mdt_body *body;
+ struct lov_mds_md *lmm = NULL;
+ struct ptlrpc_request *req = NULL;
+ int rc, lmm_size;
+ struct md_op_data *op_data;
+ ENTRY;
- rc = ll_get_max_mdsize(sbi, &lmmsize);
- if (rc)
- RETURN(rc);
+ rc = ll_get_max_mdsize(sbi, &lmm_size);
+ if (rc)
+ RETURN(rc);
- op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL,
- 0, lmmsize, LUSTRE_OPC_ANY,
- NULL);
- if (IS_ERR(op_data))
- RETURN(PTR_ERR(op_data));
+ op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL,
+ 0, lmm_size, LUSTRE_OPC_ANY,
+ NULL);
+ if (IS_ERR(op_data))
+ RETURN(PTR_ERR(op_data));
- op_data->op_valid = OBD_MD_FLEASIZE | OBD_MD_FLDIREA;
- rc = md_getattr(sbi->ll_md_exp, op_data, &req);
- ll_finish_md_op_data(op_data);
- if (rc < 0) {
+ op_data->op_valid = valid | OBD_MD_FLEASIZE | OBD_MD_FLDIREA;
+ rc = md_getattr(sbi->ll_md_exp, op_data, &req);
+ ll_finish_md_op_data(op_data);
+ if (rc < 0) {
CDEBUG(D_INFO, "md_getattr failed on inode "
DFID": rc %d\n", PFID(ll_inode2fid(inode)), rc);
- GOTO(out, rc);
- }
+ GOTO(out, rc);
+ }
- body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
- LASSERT(body != NULL);
+ body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
+ LASSERT(body != NULL);
- lmmsize = body->eadatasize;
+ lmm_size = body->eadatasize;
- if (!(body->valid & (OBD_MD_FLEASIZE | OBD_MD_FLDIREA)) ||
- lmmsize == 0) {
- GOTO(out, rc = -ENODATA);
- }
+ if (!(body->valid & (OBD_MD_FLEASIZE | OBD_MD_FLDIREA)) ||
+ lmm_size == 0) {
+ GOTO(out, rc = -ENODATA);
+ }
- lmm = req_capsule_server_sized_get(&req->rq_pill,
- &RMF_MDT_MD, lmmsize);
- LASSERT(lmm != NULL);
-
- /*
- * This is coming from the MDS, so is probably in
- * little endian. We convert it to host endian before
- * passing it to userspace.
- */
- /* We don't swab objects for directories */
- switch (le32_to_cpu(lmm->lmm_magic)) {
- case LOV_MAGIC_V1:
- if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
- lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
- break;
- case LOV_MAGIC_V3:
- if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
- lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
- break;
- default:
- CERROR("unknown magic: %lX\n", (unsigned long)lmm->lmm_magic);
- rc = -EPROTO;
- }
+ lmm = req_capsule_server_sized_get(&req->rq_pill,
+ &RMF_MDT_MD, lmm_size);
+ LASSERT(lmm != NULL);
+
+ /*
+ * This is coming from the MDS, so is probably in
+ * little endian. We convert it to host endian before
+ * passing it to userspace.
+ */
+ /* We don't swab objects for directories */
+ switch (le32_to_cpu(lmm->lmm_magic)) {
+ case LOV_MAGIC_V1:
+ if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+ lustre_swab_lov_user_md_v1((struct lov_user_md_v1 *)lmm);
+ break;
+ case LOV_MAGIC_V3:
+ if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+ lustre_swab_lov_user_md_v3((struct lov_user_md_v3 *)lmm);
+ break;
+ case LMV_MAGIC:
+ if (LOV_MAGIC != cpu_to_le32(LOV_MAGIC))
+ lustre_swab_lmv_mds_md((union lmv_mds_md *)lmm);
+ break;
+ case LMV_USER_MAGIC:
+ if (LMV_USER_MAGIC != cpu_to_le32(LMV_USER_MAGIC))
+ lustre_swab_lmv_user_md((struct lmv_user_md *)lmm);
+ break;
+ default:
+ CERROR("unknown magic: %lX\n", (unsigned long)lmm->lmm_magic);
+ rc = -EPROTO;
+ }
out:
- *lmmp = lmm;
- *lmm_size = lmmsize;
- *request = req;
- return rc;
+ *plmm = lmm;
+ *plmm_size = lmm_size;
+ *request = req;
+ return rc;
+}
+
+static int ll_get_mdt_idx_by_fid(struct ll_sb_info *sbi,
+ const struct lu_fid *fid)
+{
+ struct md_op_data *op_data;
+ int rc;
+ int mdt_index;
+ ENTRY;
+
+ OBD_ALLOC_PTR(op_data);
+ if (op_data == NULL)
+ RETURN(-ENOMEM);
+
+ op_data->op_flags |= MF_GET_MDT_IDX;
+ op_data->op_fid1 = *fid;
+ rc = md_getattr(sbi->ll_md_exp, op_data, NULL);
+ mdt_index = op_data->op_mds;
+ OBD_FREE_PTR(op_data);
+ if (rc < 0)
+ RETURN(rc);
+
+ RETURN(mdt_index);
}
/*
*/
int ll_get_mdt_idx(struct inode *inode)
{
- struct ll_sb_info *sbi = ll_i2sbi(inode);
- struct md_op_data *op_data;
- int rc, mdtidx;
- ENTRY;
-
- op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0,
- 0, LUSTRE_OPC_ANY, NULL);
- if (IS_ERR(op_data))
- RETURN(PTR_ERR(op_data));
-
- op_data->op_flags |= MF_GET_MDT_IDX;
- rc = md_getattr(sbi->ll_md_exp, op_data, NULL);
- mdtidx = op_data->op_mds;
- ll_finish_md_op_data(op_data);
- if (rc < 0) {
- CDEBUG(D_INFO, "md_getattr_name: %d\n", rc);
- RETURN(rc);
- }
- return mdtidx;
+ return ll_get_mdt_idx_by_fid(ll_i2sbi(inode), ll_inode2fid(inode));
}
/**
RETURN(rc);
}
+ case LL_IOC_LMV_SET_DEFAULT_STRIPE: {
+ struct lmv_user_md lum;
+ struct lmv_user_md __user *ulump =
+ (struct lmv_user_md __user *)arg;
+ int rc;
+
+ if (copy_from_user(&lum, ulump, sizeof(lum)))
+ RETURN(-EFAULT);
+
+ if (lum.lum_magic != LMV_USER_MAGIC)
+ RETURN(-EINVAL);
+
+ rc = ll_dir_setstripe(inode, (struct lov_user_md *)&lum, 0);
+
+ RETURN(rc);
+ }
case LL_IOC_LOV_SETSTRIPE: {
struct lov_user_md_v3 lumv3;
struct lov_user_md_v1 *lumv1 = (struct lov_user_md_v1 *)&lumv3;
RETURN(rc);
}
case LL_IOC_LMV_GETSTRIPE: {
- struct lmv_user_md *lump = (struct lmv_user_md *)arg;
- struct lmv_user_md lum;
- struct lmv_user_md *tmp;
- int lum_size;
- int rc = 0;
- int mdtindex;
-
- if (copy_from_user(&lum, lump, sizeof(struct lmv_user_md)))
+ struct lmv_user_md __user *ulmv =
+ (struct lmv_user_md __user *)arg;
+ struct lmv_user_md lum;
+ struct ptlrpc_request *request = NULL;
+ union lmv_mds_md *lmm = NULL;
+ int lmmsize;
+ obd_valid valid = 0;
+ struct lmv_user_md *tmp = NULL;
+ int mdt_index;
+ int lum_size;
+ int stripe_count;
+ int i;
+ int rc;
+
+ if (copy_from_user(&lum, ulmv, sizeof(*ulmv)))
RETURN(-EFAULT);
- if (lum.lum_magic != LMV_MAGIC_V1)
+ /* lum_magic will indicate which stripe the ioctl will like
+ * to get, LMV_MAGIC_V1 is for normal LMV stripe, LMV_USER_MAGIC
+ * is for default LMV stripe */
+ if (lum.lum_magic == LMV_MAGIC_V1)
+ valid |= OBD_MD_MEA;
+ else if (lum.lum_magic == LMV_USER_MAGIC)
+ valid |= OBD_MD_DEFAULT_MEA;
+ else
RETURN(-EINVAL);
- lum_size = lmv_user_md_size(1, LMV_MAGIC_V1);
+ rc = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize, &request,
+ valid);
+ if (rc != 0 && rc != -ENODATA)
+ GOTO(finish_req, rc);
+
+ /* Get default LMV EA */
+ if (lum.lum_magic == LMV_USER_MAGIC) {
+ if (rc != 0)
+ GOTO(finish_req, rc);
+
+ if (lmmsize > sizeof(*ulmv))
+ GOTO(finish_req, rc = -EINVAL);
+
+ if (copy_to_user(ulmv, lmm, lmmsize))
+ GOTO(finish_req, rc = -EFAULT);
+
+ GOTO(finish_req, rc);
+ }
+
+ /* Get normal LMV EA */
+ if (rc == -ENODATA) {
+ stripe_count = 1;
+ } else {
+ LASSERT(lmm != NULL);
+ stripe_count = lmv_mds_md_stripe_count_get(lmm);
+ }
+
+ lum_size = lmv_user_md_size(stripe_count, LMV_MAGIC_V1);
OBD_ALLOC(tmp, lum_size);
if (tmp == NULL)
- GOTO(free_lmv, rc = -ENOMEM);
+ GOTO(finish_req, rc = -ENOMEM);
- memcpy(tmp, &lum, sizeof(lum));
+ tmp->lum_magic = LMV_MAGIC_V1;
tmp->lum_stripe_count = 1;
- mdtindex = ll_get_mdt_idx(inode);
- if (mdtindex < 0)
- GOTO(free_lmv, rc = -ENOMEM);
-
- tmp->lum_stripe_offset = mdtindex;
- tmp->lum_objects[0].lum_mds = mdtindex;
- memcpy(&tmp->lum_objects[0].lum_fid, ll_inode2fid(inode),
- sizeof(struct lu_fid));
- if (copy_to_user((void *)arg, tmp, lum_size))
- GOTO(free_lmv, rc = -EFAULT);
-free_lmv:
- if (tmp)
- OBD_FREE(tmp, lum_size);
- RETURN(rc);
+ mdt_index = ll_get_mdt_idx(inode);
+ if (mdt_index < 0)
+ GOTO(out_tmp, rc = -ENOMEM);
+ tmp->lum_stripe_offset = mdt_index;
+ tmp->lum_objects[0].lum_mds = mdt_index;
+ tmp->lum_objects[0].lum_fid = *ll_inode2fid(inode);
+ for (i = 1; i < stripe_count; i++) {
+ struct lmv_mds_md_v1 *lmm1;
+
+ lmm1 = &lmm->lmv_md_v1;
+ mdt_index = ll_get_mdt_idx_by_fid(sbi,
+ &lmm1->lmv_stripe_fids[i]);
+ if (mdt_index < 0)
+ GOTO(out_tmp, rc = mdt_index);
+
+ tmp->lum_objects[i].lum_mds = mdt_index;
+ tmp->lum_objects[i].lum_fid = lmm1->lmv_stripe_fids[i];
+ tmp->lum_stripe_count++;
+ }
+
+ if (copy_to_user(ulmv, tmp, lum_size))
+ GOTO(out_tmp, rc = -EFAULT);
+out_tmp:
+ OBD_FREE(tmp, lum_size);
+finish_req:
+ ptlrpc_req_finished(request);
+ return rc;
}
+
case LL_IOC_REMOVE_ENTRY: {
char *filename = NULL;
int namelen = 0;
rc = ll_lov_getstripe_ea_info(inode, filename, &lmm,
&lmmsize, &request);
- } else {
- rc = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
- }
+ } else {
+ rc = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize,
+ &request, 0);
+ }
if (request) {
body = req_capsule_server_get(&request->rq_pill,
struct ptlrpc_request **request);
int ll_dir_setstripe(struct inode *inode, struct lov_user_md *lump,
int set_default);
-int ll_dir_getstripe(struct inode *inode, struct lov_mds_md **lmmp,
- int *lmm_size, struct ptlrpc_request **request);
+int ll_dir_getstripe(struct inode *inode, void **lmmp,
+ int *lmm_size, struct ptlrpc_request **request,
+ obd_valid valid);
#ifdef HAVE_FILE_FSYNC_4ARGS
int ll_fsync(struct file *file, loff_t start, loff_t end, int data);
#elif defined(HAVE_FILE_FSYNC_2ARGS)
lsm = ccc_inode_lsm_get(inode);
if (lsm == NULL) {
- if (S_ISDIR(inode->i_mode)) {
- rc = ll_dir_getstripe(inode, &lmm,
- &lmmsize, &request);
- } else {
- rc = -ENODATA;
- }
- } else {
- /* LSM is present already after lookup/getattr call.
- * we need to grab layout lock once it is implemented */
+ if (S_ISDIR(inode->i_mode)) {
+ rc = ll_dir_getstripe(inode, (void **)&lmm,
+ &lmmsize, &request, 0);
+ } else {
+ rc = -ENODATA;
+ }
+ } else {
+ /* LSM is present already after lookup/getattr call.
+ * we need to grab layout lock once it is implemented */
rc = obd_packmd(ll_i2dtexp(inode), &lmm, lsm);
lmmsize = rc;
}
}
if (S_ISREG(inode->i_mode)) {
if (!ll_i2info(inode)->lli_has_smd)
- rc2 = -1;
- } else if (S_ISDIR(inode->i_mode)) {
- rc2 = ll_dir_getstripe(inode, &lmm, &lmmsize, &request);
- }
+ rc2 = -1;
+ } else if (S_ISDIR(inode->i_mode)) {
+ rc2 = ll_dir_getstripe(inode, (void **)&lmm, &lmmsize, &request,
+ 0);
+ }
if (rc2 < 0) {
GOTO(out, rc2 = 0);
static inline int
lod_get_default_lmv_ea(const struct lu_env *env, struct lod_object *lo)
{
- return lod_get_ea(env, lo, XATTR_NAME_DEFALT_LMV);
+ return lod_get_ea(env, lo, XATTR_NAME_DEFAULT_LMV);
}
void lod_fix_desc(struct lov_desc *desc);
attr->la_mode = S_IFREG;
}
rc = lod_declare_striped_object(env, dt, attr, buf, th);
- if (rc)
+ } else if (S_ISDIR(mode)) {
+ struct lod_device *d = lu2lod_dev(dt->do_lu.lo_dev);
+ struct lod_object *lo = lod_dt_obj(dt);
+ int i;
+
+ if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) {
+ struct lmv_user_md_v1 *lum;
+
+ LASSERT(buf != NULL && buf->lb_buf != NULL);
+ lum = buf->lb_buf;
+ rc = lod_verify_md_striping(d, lum);
+ if (rc != 0)
+ RETURN(rc);
+ }
+
+ rc = dt_declare_xattr_set(env, next, buf, name, fl, th);
+ if (rc != 0)
+ RETURN(rc);
+
+ /* set xattr to each stripes, if needed */
+ rc = lod_load_striping(env, lo);
+ if (rc != 0)
RETURN(rc);
+
+ if (lo->ldo_stripenr == 0)
+ RETURN(rc);
+
+ for (i = 0; i < lo->ldo_stripenr; i++) {
+ LASSERT(lo->ldo_stripe[i]);
+ rc = dt_declare_xattr_set(env, lo->ldo_stripe[i], buf,
+ name, fl, th);
+ if (rc != 0)
+ break;
+ }
} else {
rc = dt_declare_xattr_set(env, next, buf, name, fl, th);
}
RETURN(rc);
}
+static int lod_xattr_set_default_lmv_on_dir(const struct lu_env *env,
+ struct dt_object *dt,
+ const struct lu_buf *buf,
+ const char *name, int fl,
+ struct thandle *th,
+ struct lustre_capa *capa)
+{
+ struct dt_object *next = dt_object_child(dt);
+ struct lod_object *l = lod_dt_obj(dt);
+ struct lmv_user_md_v1 *lum;
+ int rc;
+ ENTRY;
+
+ LASSERT(buf != NULL && buf->lb_buf != NULL);
+ lum = buf->lb_buf;
+
+ CDEBUG(D_OTHER, "set default stripe_count # %u stripe_offset %d\n",
+ le32_to_cpu(lum->lum_stripe_count),
+ (int)le32_to_cpu(lum->lum_stripe_offset));
+
+ if (LMVEA_DELETE_VALUES((le32_to_cpu(lum->lum_stripe_count)),
+ le32_to_cpu(lum->lum_stripe_offset)) &&
+ le32_to_cpu(lum->lum_magic) == LMV_USER_MAGIC) {
+ rc = dt_xattr_del(env, next, name, th, capa);
+ if (rc == -ENODATA)
+ rc = 0;
+ } else {
+ rc = dt_xattr_set(env, next, buf, name, fl, th, capa);
+ if (rc != 0)
+ RETURN(rc);
+
+ /* Update default stripe cache */
+ if (l->ldo_dir_stripe == NULL) {
+ OBD_ALLOC_PTR(l->ldo_dir_stripe);
+ if (l->ldo_dir_stripe == NULL)
+ RETURN(-ENOMEM);
+ }
+
+ l->ldo_dir_striping_cached = 0;
+ l->ldo_dir_def_striping_set = 1;
+ l->ldo_dir_def_stripenr =
+ le32_to_cpu(lum->lum_stripe_count) - 1;
+ }
+
+ RETURN(rc);
+}
+
static int lod_xattr_set_lmv(const struct lu_env *env, struct dt_object *dt,
const struct lu_buf *buf, const char *name,
int fl, struct thandle *th,
const char *name, int fl, struct thandle *th,
struct lustre_capa *capa)
{
+ struct lod_object *lo = lod_dt_obj(dt);
struct dt_object *next = dt_object_child(dt);
__u32 attr;
int rc;
+ int i;
ENTRY;
attr = dt->do_lu.lo_header->loh_attr & S_IFMT;
} else {
rc = lod_striping_create(env, dt, NULL, NULL, th);
}
- RETURN(rc);
+ } else if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) {
+ if (!S_ISDIR(attr))
+ RETURN(-ENOTDIR);
+ rc = lod_xattr_set_default_lmv_on_dir(env, dt, buf, name, fl,
+ th, capa);
} else {
/*
* behave transparantly for all other EAs
rc = dt_xattr_set(env, next, buf, name, fl, th, capa);
}
+ if (rc != 0 || !S_ISDIR(attr))
+ RETURN(rc);
+
+ if (lo->ldo_stripenr == 0)
+ RETURN(rc);
+
+ for (i = 0; i < lo->ldo_stripenr; i++) {
+ LASSERT(lo->ldo_stripe[i]);
+ rc = dt_xattr_set(env, lo->ldo_stripe[i], buf, name, fl, th,
+ capa);
+ if (rc != 0)
+ break;
+ }
+
RETURN(rc);
}
info->lti_buf.lb_len = sizeof(*v1);
if (declare)
rc = dt_declare_xattr_set(env, next, &info->lti_buf,
- XATTR_NAME_DEFALT_LMV, 0,
+ XATTR_NAME_DEFAULT_LMV, 0,
th);
else
rc = dt_xattr_set(env, next, &info->lti_buf,
- XATTR_NAME_DEFALT_LMV, 0, th,
+ XATTR_NAME_DEFAULT_LMV, 0, th,
BYPASS_CAPA);
if (rc != 0)
RETURN(rc);
RETURN(rc);
}
-int mdt_attr_get_lov(struct mdt_thread_info *info,
- struct mdt_object *o, struct md_attr *ma)
+static int mdt_stripe_get(struct mdt_thread_info *info, struct mdt_object *o,
+ struct md_attr *ma, char *name)
{
struct md_object *next = mdt_object_child(o);
struct lu_buf *buf = &info->mti_buf;
int rc;
- buf->lb_buf = ma->ma_lmm;
- buf->lb_len = ma->ma_lmm_size;
- rc = mo_xattr_get(info->mti_env, next, buf, XATTR_NAME_LOV);
+ if (strcmp(name, XATTR_NAME_LOV) == 0) {
+ buf->lb_buf = ma->ma_lmm;
+ buf->lb_len = ma->ma_lmm_size;
+ LASSERT(!(ma->ma_valid & MA_LOV));
+ } else if (strcmp(name, XATTR_NAME_LMV) == 0) {
+ buf->lb_buf = ma->ma_lmv;
+ buf->lb_len = ma->ma_lmv_size;
+ LASSERT(!(ma->ma_valid & MA_LMV));
+ } else if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) {
+ buf->lb_buf = ma->ma_lmv;
+ buf->lb_len = ma->ma_lmv_size;
+ LASSERT(!(ma->ma_valid & MA_LMV_DEF));
+ } else {
+ return -EINVAL;
+ }
+ rc = mo_xattr_get(info->mti_env, next, buf, name);
if (rc > 0) {
- ma->ma_lmm_size = rc;
- ma->ma_valid |= MA_LOV;
+ if (strcmp(name, XATTR_NAME_LOV) == 0) {
+ ma->ma_lmm_size = rc;
+ ma->ma_valid |= MA_LOV;
+ } else if (strcmp(name, XATTR_NAME_LMV) == 0) {
+ ma->ma_lmv_size = rc;
+ ma->ma_valid |= MA_LMV;
+ } else if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0) {
+ ma->ma_lmv_size = rc;
+ ma->ma_valid |= MA_LMV_DEF;
+ }
+
rc = 0;
} else if (rc == -ENODATA) {
/* no LOV EA */
rc = 0;
} else if (rc == -ERANGE) {
- rc = mdt_big_xattr_get(info, o, XATTR_NAME_LOV);
+ /* Default LMV has fixed size, so it must be able to fit
+ * in the original buffer */
+ if (strcmp(name, XATTR_NAME_DEFAULT_LMV) == 0)
+ return rc;
+ rc = mdt_big_xattr_get(info, o, name);
if (rc > 0) {
info->mti_big_lmm_used = 1;
- ma->ma_valid |= MA_LOV;
- ma->ma_lmm = info->mti_big_lmm;
- ma->ma_lmm_size = rc;
+ if (!strcmp(name, XATTR_NAME_LOV)) {
+ ma->ma_valid |= MA_LOV;
+ ma->ma_lmm = info->mti_big_lmm;
+ ma->ma_lmm_size = rc;
+ } else if (!strcmp(name, XATTR_NAME_LMV)) {
+ ma->ma_valid |= MA_LMV;
+ ma->ma_lmv = info->mti_big_lmm;
+ ma->ma_lmv_size = rc;
+ } else {
+ return -EINVAL;
+ }
+
/* update mdt_max_mdsize so all clients
* will be aware about that */
if (info->mti_mdt->mdt_max_mdsize < rc)
}
if (need & MA_LOV && (S_ISREG(mode) || S_ISDIR(mode))) {
- rc = mdt_attr_get_lov(info, o, ma);
+ rc = mdt_stripe_get(info, o, ma, XATTR_NAME_LOV);
if (rc)
GOTO(out, rc);
}
if (need & MA_LMV && S_ISDIR(mode)) {
- buf->lb_buf = ma->ma_lmv;
- buf->lb_len = ma->ma_lmv_size;
- rc2 = mo_xattr_get(env, next, buf, XATTR_NAME_LMV);
- if (rc2 > 0) {
- ma->ma_lmv_size = rc2;
- ma->ma_valid |= MA_LMV;
- } else if (rc2 == -ENODATA) {
- /* no LMV EA */
- ma->ma_lmv_size = 0;
- } else
- GOTO(out, rc = rc2);
+ rc = mdt_stripe_get(info, o, ma, XATTR_NAME_LMV);
+ if (rc != 0)
+ GOTO(out, rc);
+ }
+
+ if (need & MA_LMV_DEF && S_ISDIR(mode)) {
+ rc = mdt_stripe_get(info, o, ma, XATTR_NAME_DEFAULT_LMV);
+ if (rc != 0)
+ GOTO(out, rc);
}
if (need & MA_SOM && S_ISREG(mode)) {
/* If it is dir object and client require MEA, then we got MEA */
if (S_ISDIR(lu_object_attr(&next->mo_lu)) &&
- reqbody->valid & OBD_MD_MEA) {
+ (reqbody->valid & (OBD_MD_MEA | OBD_MD_DEFAULT_MEA))) {
/* Assumption: MDT_MD size is enough for lmv size. */
ma->ma_lmv = buffer->lb_buf;
ma->ma_lmv_size = buffer->lb_len;
ma->ma_need = MA_INODE;
- if (ma->ma_lmv_size > 0)
- ma->ma_need |= MA_LMV;
+ if (ma->ma_lmv_size > 0) {
+ if (reqbody->valid & OBD_MD_MEA)
+ ma->ma_need |= MA_LMV;
+ else if (reqbody->valid & OBD_MD_DEFAULT_MEA)
+ ma->ma_need |= MA_LMV_DEF;
+ }
} else {
ma->ma_lmm = buffer->lb_buf;
ma->ma_lmm_size = buffer->lb_len;
root = mdt_object_find(env, mdt, &rootfid);
if (IS_ERR(root))
RETURN(PTR_ERR(root));
- rc = mdt_attr_get_lov(info, root, ma);
+ rc = mdt_stripe_get(info, root, ma, XATTR_NAME_LOV);
mdt_object_put(info->mti_env, root);
if (unlikely(rc)) {
CERROR("%s: getattr error for "DFID": rc = %d\n",
else
repbody->valid |= OBD_MD_FLEASIZE;
}
- if (ma->ma_valid & MA_LMV) {
- LASSERT(S_ISDIR(la->la_mode));
- repbody->eadatasize = ma->ma_lmv_size;
- repbody->valid |= (OBD_MD_FLDIREA|OBD_MD_MEA);
- }
+ if (ma->ma_valid & MA_LMV) {
+ LASSERT(S_ISDIR(la->la_mode));
+ mdt_dump_lmv(D_INFO, ma->ma_lmv);
+ repbody->eadatasize = ma->ma_lmv_size;
+ repbody->valid |= (OBD_MD_FLDIREA|OBD_MD_MEA);
+ }
+ if (ma->ma_valid & MA_LMV_DEF) {
+ LASSERT(S_ISDIR(la->la_mode));
+ repbody->eadatasize = ma->ma_lmv_size;
+ repbody->valid |= (OBD_MD_FLDIREA|OBD_MD_DEFAULT_MEA);
+ }
} else if (S_ISLNK(la->la_mode) &&
reqbody->valid & OBD_MD_LINKNAME) {
buffer->lb_buf = ma->ma_lmm;
const void *area, ssize_t len);
void mdt_dump_lmm(int level, const struct lov_mds_md *lmm);
+void mdt_dump_lmv(unsigned int level, const union lmv_mds_md *lmv);
int mdt_check_ucred(struct mdt_thread_info *);
int mdt_init_ucred(struct mdt_thread_info *, struct mdt_body *);
}
}
+void mdt_dump_lmv(unsigned int level, const union lmv_mds_md *lmv)
+{
+ const struct lmv_mds_md_v1 *lmm1;
+ int i;
+
+ lmm1 = &lmv->lmv_md_v1;
+ CDEBUG(level, "magic 0x%08X, master %#X stripe_count %#x\n",
+ le32_to_cpu(lmm1->lmv_magic),
+ le32_to_cpu(lmm1->lmv_master_mdt_index),
+ le32_to_cpu(lmm1->lmv_stripe_count));
+ for (i = 0; i < le32_to_cpu(lmm1->lmv_stripe_count); i++) {
+ struct lu_fid fid;
+
+ fid_le_to_cpu(&fid, &lmm1->lmv_stripe_fids[i]);
+ CDEBUG(level, "idx %u subobj "DFID"\n", i, PFID(&fid));
+ }
+}
+
/* Shrink and/or grow reply buffers */
int mdt_fix_reply(struct mdt_thread_info *info)
{
rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA);
rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
RCL_CLIENT);
- ma->ma_lmm_size = rr->rr_eadatalen;
- if (ma->ma_lmm_size > 0) {
- ma->ma_lmm = (void *)rr->rr_eadata;
- ma->ma_valid |= MA_LOV;
- }
- }
+ if (rr->rr_eadatalen > 0) {
+ const struct lmv_user_md *lum;
+
+ lum = rr->rr_eadata;
+ /* Sigh ma_valid(from req) does not indicate whether
+ * it will set LOV/LMV EA, so we have to check magic */
+ if (le32_to_cpu(lum->lum_magic) == LMV_USER_MAGIC) {
+ ma->ma_valid |= MA_LMV;
+ ma->ma_lmv = (void *)rr->rr_eadata;
+ ma->ma_lmv_size = rr->rr_eadatalen;
+ } else {
+ ma->ma_valid |= MA_LOV;
+ ma->ma_lmm = (void *)rr->rr_eadata;
+ ma->ma_lmm_size = rr->rr_eadatalen;
+ }
+ }
+ }
- rc = mdt_dlmreq_unpack(info);
- RETURN(rc);
+ rc = mdt_dlmreq_unpack(info);
+ RETURN(rc);
}
static int mdt_hsm_release_unpack(struct mdt_thread_info *info)
buf, XATTR_NAME_LOV, 0);
if (rc)
GOTO(out_put, rc);
+ } else if ((ma->ma_valid & MA_LMV) && (ma->ma_valid & MA_INODE)) {
+ struct lu_buf *buf = &info->mti_buf;
+
+ LASSERT(ma->ma_attr.la_valid == 0);
+ buf->lb_buf = ma->ma_lmv;
+ buf->lb_len = ma->ma_lmv_size;
+ rc = mo_xattr_set(info->mti_env, mdt_object_child(mo),
+ buf, XATTR_NAME_DEFAULT_LMV, 0);
+ if (rc)
+ GOTO(out_put, rc);
} else
LBUG();
/* uuid endian insensitive */
}
+/* This structure is always in little-endian */
+static void lustre_swab_lmv_mds_md_v1(struct lmv_mds_md_v1 *lmm1)
+{
+ int i;
+
+ __swab32s(&lmm1->lmv_magic);
+ __swab32s(&lmm1->lmv_stripe_count);
+ __swab32s(&lmm1->lmv_master_mdt_index);
+ __swab32s(&lmm1->lmv_hash_type);
+ __swab32s(&lmm1->lmv_layout_version);
+ for (i = 0; i < lmm1->lmv_stripe_count; i++)
+ lustre_swab_lu_fid(&lmm1->lmv_stripe_fids[i]);
+}
+
+void lustre_swab_lmv_mds_md(union lmv_mds_md *lmm)
+{
+ switch (lmm->lmv_magic) {
+ case LMV_MAGIC_V1:
+ lustre_swab_lmv_mds_md_v1(&lmm->lmv_md_v1);
+ break;
+ default:
+ break;
+ }
+}
+
void lustre_swab_lmv_user_md(struct lmv_user_md *lum)
{
int i;
{"setdirstripe", lfs_setdirstripe, 0,
"To create a remote directory on a specified MDT.\n"
"usage: setdirstripe <--count|-c stripe_count>\n"
- "[--index|-i mdt_index] [--hash-type|-t hash_type] <dir>\n"
+ "[--index|-i mdt_index] [--hash-type|-t hash_type]\n"
+ "[--default_stripe|-D ] <dir>\n"
"\tstripe_count: stripe count of the striped directory\n"
"\tmdt_index: MDT index of first stripe\n"
- "\thash_type: hash type of the striped directory\n"},
+ "\thash_type: hash type of the striped directory\n"
+ "\tdefault_stripe: set default dirstripe of the directory\n"},
{"getdirstripe", lfs_getdirstripe, 0,
"To list the striping info for a given directory\n"
"or recursively for all directories in a directory tree.\n"
"usage: getdirstripe [--obd|-O <uuid>] [--quiet|-q] [--verbose|-v]\n"
" [--count|-c ] [--index|-i ] [--raw|-R]\n"
- " [--recursive | -r] <dir> ..."},
+ " [--recursive | -r] [ --default_stripe | -D ] <dir> "},
{"mkdir", lfs_setdirstripe, 0,
"To create a remote directory on a specified MDT. And this can only\n"
"be done on MDT0 by administrator.\n"
{"stripe-count", no_argument, 0, 'c'},
{"stripe_count", no_argument, 0, 'c'},
{"directory", no_argument, 0, 'd'},
+ {"default", no_argument, 0, 'D'},
{"generation", no_argument, 0, 'g'},
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 53, 0)
/* This formerly implied "stripe-index", but was explicitly
param->maxdepth = 1;
optind = 0;
- while ((c = getopt_long(argc, argv, "cdghiLMoO:pqrRsSv",
+ while ((c = getopt_long(argc, argv, "cdDghiLMoO:pqrRsSv",
long_opts, NULL)) != -1) {
switch (c) {
case 'O':
case 'd':
param->maxdepth = 0;
break;
+ case 'D':
+ param->get_default_lmv = 1;
+ break;
case 'r':
param->recursive = 1;
break;
char *stripe_offset_opt = NULL;
char *stripe_count_opt = NULL;
char *stripe_hash_opt = NULL;
- int flags = 0;
+ int default_stripe = 0;
struct option long_opts[] = {
{"count", required_argument, 0, 'c'},
{"index", required_argument, 0, 'i'},
{"hash-type", required_argument, 0, 't'},
+ {"default_stripe", required_argument, 0, 'D'},
{0, 0, 0, 0}
};
optind = 0;
- while ((c = getopt_long(argc, argv, "c:i:t:", long_opts, NULL)) >= 0) {
+ while ((c = getopt_long(argc, argv, "c:Di:t:", long_opts, NULL)) >= 0) {
switch (c) {
case 0:
/* Long options. */
case 'c':
stripe_count_opt = optarg;
break;
+ case 'D':
+ default_stripe = 1;
+ break;
case 'i':
stripe_offset_opt = optarg;
break;
dname = argv[optind];
do {
- result = llapi_dir_create_pool(dname, flags, stripe_offset,
- stripe_count, hash_type, NULL);
+ if (default_stripe == 1) {
+ result = llapi_dir_set_default_lmv_stripe(dname,
+ stripe_offset, stripe_count,
+ hash_type, NULL);
+ } else {
+ result = llapi_dir_create_pool(dname, 0, stripe_offset,
+ stripe_count, hash_type,
+ NULL);
+ }
+
if (result) {
fprintf(stderr, "error: %s: create stripe dir '%s' "
"failed\n", argv[0], dname);
return 0;
}
+int llapi_dir_set_default_lmv_stripe(const char *name, int stripe_offset,
+ int stripe_count, int stripe_pattern,
+ const char *pool_name)
+{
+ struct lmv_user_md lum = { 0 };
+ int fd;
+ int rc = 0;
+
+ lum.lum_magic = LMV_USER_MAGIC;
+ lum.lum_stripe_offset = stripe_offset;
+ lum.lum_stripe_count = stripe_count;
+ lum.lum_hash_type = stripe_pattern;
+ if (pool_name != NULL) {
+ if (strlen(pool_name) >= sizeof(lum.lum_pool_name)) {
+ llapi_err_noerrno(LLAPI_MSG_ERROR,
+ "error LL_IOC_LMV_SET_DEFAULT_STRIPE '%s'"
+ ": too large pool name: %s", name, pool_name);
+ return -E2BIG;
+ }
+ strncpy(lum.lum_pool_name, pool_name, strlen(pool_name));
+ }
+
+ fd = open(name, O_DIRECTORY | O_RDONLY);
+ if (fd < 0) {
+ rc = -errno;
+ llapi_error(LLAPI_MSG_ERROR, rc, "unable to open '%s'", name);
+ return rc;
+ }
+
+ rc = ioctl(fd, LL_IOC_LMV_SET_DEFAULT_STRIPE, &lum);
+ if (rc < 0) {
+ char *errmsg = "stripe already set";
+ rc = -errno;
+ if (errno != EEXIST && errno != EALREADY)
+ errmsg = strerror(errno);
+
+ llapi_err_noerrno(LLAPI_MSG_ERROR,
+ "error on LL_IOC_LMV_SETSTRIPE '%s' (%d): %s",
+ name, fd, errmsg);
+ }
+ close(fd);
+ return rc;
+}
+
int llapi_dir_create_pool(const char *name, int flags, int stripe_offset,
int stripe_count, int stripe_pattern,
const char *pool_name)
int ret = 0;
lmv->lum_stripe_count = param->fp_lmv_count;
- lmv->lum_magic = LMV_MAGIC_V1;
+ if (param->get_default_lmv)
+ lmv->lum_magic = LMV_USER_MAGIC;
+ else
+ lmv->lum_magic = LMV_MAGIC_V1;
ret = ioctl(dirfd(d), LL_IOC_LMV_GETSTRIPE, lmv);
+
return ret;
}
verbose = VERBOSE_OBJID;
}
- if (lum->lum_magic == LMV_USER_MAGIC)
- verbose &= ~VERBOSE_OBJID;
-
if (depth && path && ((verbose != VERBOSE_OBJID)))
- llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
+ llapi_printf(LLAPI_MSG_NORMAL, "%s%s\n", prefix, path);
if (verbose & VERBOSE_COUNT) {
if (verbose & ~VERBOSE_COUNT)
(int)lum->lum_stripe_offset);
}
- if (verbose & VERBOSE_OBJID) {
+ if (verbose & VERBOSE_OBJID && lum->lum_magic != LMV_USER_MAGIC) {
if ((obdstripe == 1))
llapi_printf(LLAPI_MSG_NORMAL,
- "\tmdtidx\t\t FID[seq:oid:ver]\n");
+ "mdtidx\t\t FID[seq:oid:ver]\n");
for (i = 0; i < lum->lum_stripe_count; i++) {
int idx = objects[i].lum_mds;
struct lu_fid *fid = &objects[i].lum_fid;
if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx))
llapi_printf(LLAPI_MSG_NORMAL,
- "\t%6u\t\t "DFID"\t\t%s\n",
+ "%6u\t\t "DFID"\t\t%s\n",
idx, PFID(fid),
obdindex == idx ? " *" : "");
}
{
__u32 magic;
- if (param->get_lmv)
+ if (param->get_lmv || param->get_default_lmv)
magic = (__u32)param->fp_lmv_md->lum_magic;
else
magic = *(__u32 *)¶m->lmd->lmd_lmm; /* lum->lmm_magic */
}
if (d) {
- if (param->get_lmv) {
+ if (param->get_lmv || param->get_default_lmv) {
ret = cb_get_dirstripe(path, d, param);
} else {
ret = ioctl(dirfd(d), LL_IOC_LOV_GETSTRIPE,
* a check later on in the code path.
* The object_seq needs to be set for the "(Default)"
* prefix to be displayed. */
- struct lov_user_md *lmm = ¶m->lmd->lmd_lmm;
- lmm->lmm_magic = LOV_USER_MAGIC_V1;
- if (!param->raw)
- ostid_set_seq(&lmm->lmm_oi,
- FID_SEQ_LOV_DEFAULT);
- lmm->lmm_stripe_count = 0;
- lmm->lmm_stripe_size = 0;
- lmm->lmm_stripe_offset = -1;
- goto dump;
+ if (param->get_default_lmv) {
+ struct lmv_user_md *lum = param->fp_lmv_md;
+
+ lum->lum_magic = LMV_USER_MAGIC;
+ lum->lum_stripe_count = 0;
+ lum->lum_stripe_offset = -1;
+ goto dump;
+ } else {
+ struct lov_user_md *lmm = ¶m->lmd->lmd_lmm;
+ lmm->lmm_magic = LOV_USER_MAGIC_V1;
+ if (!param->raw)
+ ostid_set_seq(&lmm->lmm_oi,
+ FID_SEQ_LOV_DEFAULT);
+ lmm->lmm_stripe_count = 0;
+ lmm->lmm_stripe_size = 0;
+ lmm->lmm_stripe_offset = -1;
+ goto dump;
+ }
} else if (errno == ENODATA && parent != NULL) {
if (!param->obduuid && !param->mdtuuid)
llapi_printf(LLAPI_MSG_NORMAL,