Whamcloud - gitweb
LU-4684 xattr: add list support for remote object 26/31426/9
authorLai Siyao <lai.siyao@intel.com>
Sun, 21 Jan 2018 07:57:22 +0000 (15:57 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 29 May 2018 04:53:35 +0000 (04:53 +0000)
XATTR_LIST may be issued to a remote object in directory migration,
add this support for OSP and OUT.

Signed-off-by: Lai Siyao <lai.siyao@intel.com>
Change-Id: I9681e149703de2837a04dc1448d1bd583659205d
Reviewed-on: https://review.whamcloud.com/31426
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/include/lustre_update.h
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/osp/osp_md_object.c
lustre/ptlrpc/wiretest.c
lustre/target/out_handler.c
lustre/target/out_lib.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index f8766f6..78cd3d4 100644 (file)
@@ -454,6 +454,9 @@ int out_xattr_get_pack(const struct lu_env *env,
                       struct object_update *update, size_t *max_update_size,
                       const struct lu_fid *fid, const char *name,
                       const int bufsize);
+int out_xattr_list_pack(const struct lu_env *env, struct object_update *update,
+                      size_t *max_update_size, const struct lu_fid *fid,
+                      const int bufsize);
 int out_read_pack(const struct lu_env *env, struct object_update *update,
                  size_t *max_update_length, const struct lu_fid *fid,
                  size_t size, loff_t pos);
index 8ddc060..b2423fc 100644 (file)
@@ -3305,6 +3305,7 @@ enum update_type {
        OUT_PUNCH               = 14,
        OUT_READ                = 15,
        OUT_NOOP                = 16,
+       OUT_XATTR_LIST          = 17,
        OUT_LAST
 };
 
index eabec88..7acbc51 100644 (file)
@@ -818,6 +818,95 @@ const struct dt_index_operations osp_md_index_ops = {
 };
 
 /**
+ * Implement OSP layer dt_object_operations::do_xattr_list() interface.
+ *
+ * List extended attribute from the specified MDT/OST object, result is not
+ * cached because this is called by directory migration only.
+ *
+ * \param[in] env      pointer to the thread context
+ * \param[in] dt       pointer to the OSP layer dt_object
+ * \param[out] buf     pointer to the lu_buf to hold the extended attribute
+ *
+ * \retval             positive bytes used/required in the buffer
+ * \retval             negative error number on failure
+ */
+static int osp_md_xattr_list(const struct lu_env *env, struct dt_object *dt,
+                            const struct lu_buf *buf)
+{
+       struct osp_device *osp = lu2osp_dev(dt->do_lu.lo_dev);
+       struct osp_object *obj = dt2osp_obj(dt);
+       struct dt_device *dev = &osp->opd_dt_dev;
+       struct lu_buf *rbuf = &osp_env_info(env)->osi_lb2;
+       struct osp_update_request *update = NULL;
+       struct ptlrpc_request *req = NULL;
+       struct object_update_reply *reply;
+       const char *dname  = dt->do_lu.lo_dev->ld_obd->obd_name;
+       int rc = 0;
+
+       ENTRY;
+
+       LASSERT(buf);
+
+       if (unlikely(obj->opo_non_exist))
+               RETURN(-ENOENT);
+
+       update = osp_update_request_create(dev);
+       if (IS_ERR(update))
+               RETURN(PTR_ERR(update));
+
+       rc = osp_update_rpc_pack(env, xattr_list, update, OUT_XATTR_LIST,
+                                lu_object_fid(&dt->do_lu), buf->lb_len);
+       if (rc) {
+               CERROR("%s: Insert update error "DFID": rc = %d\n",
+                      dname, PFID(lu_object_fid(&dt->do_lu)), rc);
+               GOTO(out, rc);
+       }
+
+       rc = osp_remote_sync(env, osp, update, &req);
+       if (rc < 0) {
+               if (rc == -ENOENT) {
+                       dt->do_lu.lo_header->loh_attr &= ~LOHA_EXISTS;
+                       obj->opo_non_exist = 1;
+               }
+               GOTO(out, rc);
+       }
+
+       reply = req_capsule_server_sized_get(&req->rq_pill,
+                                            &RMF_OUT_UPDATE_REPLY,
+                                            OUT_UPDATE_REPLY_SIZE);
+       if (reply->ourp_magic != UPDATE_REPLY_MAGIC) {
+               DEBUG_REQ(D_ERROR, req,
+                         "%s: Wrong version %x expected %x "DFID": rc = %d\n",
+                         dname, reply->ourp_magic, UPDATE_REPLY_MAGIC,
+                         PFID(lu_object_fid(&dt->do_lu)), -EPROTO);
+
+               GOTO(out, rc = -EPROTO);
+       }
+
+       rc = object_update_result_data_get(reply, rbuf, 0);
+       if (rc < 0)
+               GOTO(out, rc);
+
+       if (!buf->lb_buf)
+               GOTO(out, rc);
+
+       if (unlikely(buf->lb_len < rbuf->lb_len))
+               GOTO(out, rc = -ERANGE);
+
+       memcpy(buf->lb_buf, rbuf->lb_buf, rbuf->lb_len);
+       EXIT;
+
+out:
+       if (req)
+               ptlrpc_req_finished(req);
+
+       if (update && !IS_ERR(update))
+               osp_update_request_destroy(env, update);
+
+       return rc;
+}
+
+/**
  * Implementation of dt_object_operations::do_index_try
  *
  * Try to initialize the index API pointer for the given object. This
@@ -994,6 +1083,7 @@ struct dt_object_operations osp_md_obj_ops = {
        .do_declare_attr_set  = osp_md_declare_attr_set,
        .do_attr_set          = osp_md_attr_set,
        .do_xattr_get         = osp_xattr_get,
+       .do_xattr_list        = osp_md_xattr_list,
        .do_declare_xattr_set = osp_declare_xattr_set,
        .do_xattr_set         = osp_xattr_set,
        .do_declare_xattr_del = osp_declare_xattr_del,
index fed37ca..0e4321a 100644 (file)
@@ -499,6 +499,10 @@ void lustre_assert_wire_constants(void)
                 (long long)OUT_PUNCH);
        LASSERTF(OUT_READ == 15, "found %lld\n",
                 (long long)OUT_READ);
+       LASSERTF(OUT_NOOP == 16, "found %lld\n",
+                (long long)OUT_NOOP);
+       LASSERTF(OUT_XATTR_LIST == 17, "found %lld\n",
+                (long long)OUT_XATTR_LIST);
 
        /* Checks for struct hsm_attrs */
        LASSERTF((int)sizeof(struct hsm_attrs) == 24, "found %lld\n",
index 91f0012..7dc9d42 100644 (file)
@@ -289,10 +289,62 @@ static int out_xattr_get(struct tgt_session_info *tsi)
        } else if (lbuf->lb_buf) {
                lbuf->lb_len = rc;
        }
-
-       CDEBUG(D_INFO, "%s: "DFID" get xattr %s len %d: rc = %d\n",
+       CDEBUG(D_INFO, "%s: "DFID" get xattr %s len %d\n",
               tgt_name(tsi->tsi_tgt), PFID(lu_object_fid(&obj->do_lu)),
-              name, (int)lbuf->lb_len, rc);
+              name, rc);
+
+       GOTO(out, rc);
+
+out:
+       object_update_result_insert(reply, lbuf->lb_buf, lbuf->lb_len, idx, rc);
+       RETURN(0);
+}
+
+static int out_xattr_list(struct tgt_session_info *tsi)
+{
+       const struct lu_env *env = tsi->tsi_env;
+       struct tgt_thread_info *tti = tgt_th_info(env);
+       struct lu_buf *lbuf = &tti->tti_buf;
+       struct object_update_reply *reply = tti->tti_u.update.tti_update_reply;
+       struct dt_object *obj = tti->tti_u.update.tti_dt_object;
+       struct object_update_result *update_result;
+       int idx = tti->tti_u.update.tti_update_reply_index;
+       int rc;
+
+       ENTRY;
+
+       if (!lu_object_exists(&obj->do_lu)) {
+               set_bit(LU_OBJECT_HEARD_BANSHEE,
+                       &obj->do_lu.lo_header->loh_flags);
+               RETURN(-ENOENT);
+       }
+
+       update_result = object_update_result_get(reply, 0, NULL);
+       if (!update_result) {
+               rc = -EPROTO;
+               CERROR("%s: empty buf for xattr list: rc = %d\n",
+                      tgt_name(tsi->tsi_tgt), rc);
+               RETURN(rc);
+       }
+
+       lbuf->lb_len = (int)tti->tti_u.update.tti_update->ou_result_size;
+       lbuf->lb_buf = update_result->our_data;
+       if (lbuf->lb_len == 0)
+               lbuf->lb_buf = 0;
+
+       dt_read_lock(env, obj, MOR_TGT_CHILD);
+       rc = dt_xattr_list(env, obj, lbuf);
+       dt_read_unlock(env, obj);
+       if (rc <= 0) {
+               lbuf->lb_len = 0;
+               if (unlikely(!rc))
+                       rc = -ENODATA;
+       } else if (lbuf->lb_buf) {
+               lbuf->lb_len = rc;
+       }
+
+       CDEBUG(D_INFO, "%s: "DFID" list xattr len %d\n",
+              tgt_name(tsi->tsi_tgt), PFID(lu_object_fid(&obj->do_lu)), rc);
 
        /* Since we directly use update_result->our_data as the lbuf->lb_buf,
         * then use NULL for result_insert to avoid unnecessary memory copy. */
@@ -759,6 +811,8 @@ static struct tgt_handler out_update_ops[] = {
        DEF_OUT_HNDL(OUT_WRITE, "out_write", MUTABOR | HABEO_REFERO, out_write),
        DEF_OUT_HNDL(OUT_READ, "out_read", HABEO_REFERO, out_read),
        DEF_OUT_HNDL(OUT_NOOP, "out_noop", HABEO_REFERO, out_noop),
+       DEF_OUT_HNDL(OUT_XATTR_LIST, "out_xattr_list", HABEO_REFERO,
+                    out_xattr_list),
 };
 
 static struct tgt_handler *out_handler_find(__u32 opc)
index d1fcffd..57987e1 100644 (file)
@@ -53,6 +53,7 @@ const char *update_op_str(__u16 opc)
                [OUT_ATTR_GET] = "attr_get",
                [OUT_XATTR_SET] = "xattr_set",
                [OUT_XATTR_GET] = "xattr_get",
+               [OUT_XATTR_LIST] = "xattr_list",
                [OUT_INDEX_LOOKUP] = "lookup",
                [OUT_INDEX_INSERT] = "insert",
                [OUT_INDEX_DELETE] = "delete",
@@ -404,6 +405,15 @@ int out_xattr_get_pack(const struct lu_env *env, struct object_update *update,
 }
 EXPORT_SYMBOL(out_xattr_get_pack);
 
+int out_xattr_list_pack(const struct lu_env *env, struct object_update *update,
+                      size_t *max_update_size, const struct lu_fid *fid,
+                      const int bufsize)
+{
+       return out_update_pack(env, update, max_update_size, OUT_XATTR_LIST,
+                              fid, 0, NULL, NULL, bufsize);
+}
+EXPORT_SYMBOL(out_xattr_list_pack);
+
 int out_read_pack(const struct lu_env *env, struct object_update *update,
                  size_t *max_update_size, const struct lu_fid *fid,
                  size_t size, loff_t pos)
index bcb6e55..d43eea0 100644 (file)
@@ -2737,6 +2737,8 @@ main(int argc, char **argv)
        CHECK_VALUE(OUT_XATTR_DEL);
        CHECK_VALUE(OUT_PUNCH);
        CHECK_VALUE(OUT_READ);
+       CHECK_VALUE(OUT_NOOP);
+       CHECK_VALUE(OUT_XATTR_LIST);
 
        check_hsm_attrs();
        check_ost_id();
index b66a928..6e5193e 100644 (file)
@@ -520,6 +520,10 @@ void lustre_assert_wire_constants(void)
                 (long long)OUT_PUNCH);
        LASSERTF(OUT_READ == 15, "found %lld\n",
                 (long long)OUT_READ);
+       LASSERTF(OUT_NOOP == 16, "found %lld\n",
+                (long long)OUT_NOOP);
+       LASSERTF(OUT_XATTR_LIST == 17, "found %lld\n",
+                (long long)OUT_XATTR_LIST);
 
        /* Checks for struct hsm_attrs */
        LASSERTF((int)sizeof(struct hsm_attrs) == 24, "found %lld\n",