Whamcloud - gitweb
LU-4388 io: pass fsync() range through RPC/IO stack
[fs/lustre-release.git] / lustre / target / tgt_handler.c
index 376f345..4ab8dc2 100644 (file)
@@ -37,6 +37,8 @@
 #include <obd.h>
 #include <obd_class.h>
 #include <obd_cksum.h>
+#include <md_object.h>
+#include <lustre_lfsck.h>
 
 #include "tgt_internal.h"
 
@@ -130,43 +132,54 @@ static int tgt_mdt_body_unpack(struct tgt_session_info *tsi, __u32 flags)
  */
 int tgt_validate_obdo(struct tgt_session_info *tsi, struct obdo *oa)
 {
-       int rc;
-
+       struct ost_id   *oi     = &oa->o_oi;
+       obd_seq          seq    = ostid_seq(oi);
+       obd_id           id     = ostid_id(oi);
+       int              rc;
        ENTRY;
 
        if (unlikely(!(exp_connect_flags(tsi->tsi_exp) & OBD_CONNECT_FID) &&
-                    fid_seq_is_echo(oa->o_oi.oi.oi_seq))) {
+                    fid_seq_is_echo(seq))) {
                /* Sigh 2.[123] client still sends echo req with oi_id = 0
                 * during create, and we will reset this to 1, since this
                 * oi_id is basically useless in the following create process,
                 * but oi_id == 0 will make it difficult to tell whether it is
                 * real FID or ost_id. */
-               oa->o_oi.oi_fid.f_oid = oa->o_oi.oi.oi_id ?: 1;
-               oa->o_oi.oi_fid.f_seq = FID_SEQ_ECHO;
-               oa->o_oi.oi_fid.f_ver = 0;
+               oi->oi_fid.f_seq = FID_SEQ_ECHO;
+               oi->oi_fid.f_oid = id ?: 1;
+               oi->oi_fid.f_ver = 0;
        } else {
-               if (unlikely((oa->o_valid & OBD_MD_FLID &&
-                             ostid_id(&oa->o_oi) == 0)))
+               struct tgt_thread_info *tti = tgt_th_info(tsi->tsi_env);
+
+               if (unlikely((oa->o_valid & OBD_MD_FLID) && id == 0))
                        GOTO(out, rc = -EPROTO);
 
                /* Note: this check might be forced in 2.5 or 2.6, i.e.
                 * all of the requests are required to setup FLGROUP */
                if (unlikely(!(oa->o_valid & OBD_MD_FLGROUP))) {
-                       ostid_set_seq_mdt0(&oa->o_oi);
+                       ostid_set_seq_mdt0(oi);
                        oa->o_valid |= OBD_MD_FLGROUP;
+                       seq = ostid_seq(oi);
                }
 
-               if (unlikely(!(fid_seq_is_idif(ostid_seq(&oa->o_oi)) ||
-                              fid_seq_is_mdt0(ostid_seq(&oa->o_oi)) ||
-                              fid_seq_is_norm(ostid_seq(&oa->o_oi)) ||
-                              fid_seq_is_echo(ostid_seq(&oa->o_oi)))))
+               if (unlikely(!(fid_seq_is_idif(seq) || fid_seq_is_mdt0(seq) ||
+                              fid_seq_is_norm(seq) || fid_seq_is_echo(seq))))
                        GOTO(out, rc = -EPROTO);
+
+               rc = ostid_to_fid(&tti->tti_fid1, oi,
+                                 tsi->tsi_tgt->lut_lsd.lsd_osd_index);
+               if (unlikely(rc != 0))
+                       GOTO(out, rc);
+
+               oi->oi_fid = tti->tti_fid1;
        }
+
        RETURN(0);
+
 out:
        CERROR("%s: client %s sent bad object "DOSTID": rc = %d\n",
               tgt_name(tsi->tsi_tgt), obd_export_nid2str(tsi->tsi_exp),
-              ostid_seq(&oa->o_oi), ostid_id(&oa->o_oi), rc);
+              seq, id, rc);
        return rc;
 }
 EXPORT_SYMBOL(tgt_validate_obdo);
@@ -251,6 +264,7 @@ static int tgt_ost_body_unpack(struct tgt_session_info *tsi, __u32 flags)
        }
 
        tsi->tsi_ost_body = body;
+       tsi->tsi_fid = body->oa.o_oi.oi_fid;
 
        if (req_capsule_has_field(pill, &RMF_OBD_IOOBJ, RCL_CLIENT)) {
                rc = tgt_io_data_unpack(tsi, &body->oa.o_oi);
@@ -269,16 +283,6 @@ static int tgt_ost_body_unpack(struct tgt_session_info *tsi, __u32 flags)
                }
        }
 
-       rc = ostid_to_fid(&tsi->tsi_fid, &body->oa.o_oi, 0);
-       if (rc != 0)
-               RETURN(rc);
-
-       if (!fid_is_sane(&tsi->tsi_fid)) {
-               CERROR("%s: invalid FID: "DFID"\n", tgt_name(tsi->tsi_tgt),
-                      PFID(&tsi->tsi_fid));
-               RETURN(-EINVAL);
-       }
-
        ost_fid_build_resid(&tsi->tsi_fid, &tsi->tsi_resid);
 
        /*
@@ -457,7 +461,7 @@ static int tgt_filter_recovery_request(struct ptlrpc_request *req,
        case MDS_SYNC: /* used in unmounting */
        case OBD_PING:
        case MDS_REINT:
-       case UPDATE_OBJ:
+       case OUT_UPDATE:
        case SEQ_QUERY:
        case FLD_QUERY:
        case LDLM_ENQUEUE:
@@ -793,7 +797,7 @@ static int tgt_init_sec_level(struct ptlrpc_request *req)
                        RETURN(-EACCES);
                }
        } else {
-               if (req->rq_auth_uid == INVALID_UID) {
+               if (!uid_valid(make_kuid(&init_user_ns, req->rq_auth_uid))) {
                        CDEBUG(D_SEC, "client %s -> target %s: user is not "
                               "authenticated!\n", client, tgt_name(tgt));
                        RETURN(-EACCES);
@@ -1122,7 +1126,7 @@ TGT_OBD_HDL    (0,        OBD_IDX_READ,           tgt_obd_idx_read)
 EXPORT_SYMBOL(tgt_obd_handlers);
 
 int tgt_sync(const struct lu_env *env, struct lu_target *tgt,
-            struct dt_object *obj)
+            struct dt_object *obj, __u64 start, __u64 end)
 {
        int rc = 0;
 
@@ -1133,7 +1137,7 @@ int tgt_sync(const struct lu_env *env, struct lu_target *tgt,
                rc = dt_sync(env, tgt->lut_bottom);
        } else if (dt_version_get(env, obj) >
                   tgt->lut_obd->obd_last_committed) {
-               rc = dt_object_sync(env, obj);
+               rc = dt_object_sync(env, obj, start, end);
        }
 
        RETURN(rc);
@@ -1163,11 +1167,15 @@ int tgt_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
            (tgt->lut_sync_lock_cancel == ALWAYS_SYNC_ON_CANCEL ||
             (tgt->lut_sync_lock_cancel == BLOCKING_SYNC_ON_CANCEL &&
              lock->l_flags & LDLM_FL_CBPENDING))) {
+               __u64 start = 0;
+               __u64 end = OBD_OBJECT_EOF;
+
                rc = lu_env_init(&env, LCT_DT_THREAD);
                if (unlikely(rc != 0))
                        RETURN(rc);
 
-               ost_fid_from_resid(&fid, &lock->l_resource->lr_name);
+               ost_fid_from_resid(&fid, &lock->l_resource->lr_name,
+                                  tgt->lut_lsd.lsd_osd_index);
                obj = dt_locate(&env, tgt->lut_bottom, &fid);
                if (IS_ERR(obj))
                        GOTO(err_env, rc = PTR_ERR(obj));
@@ -1175,10 +1183,18 @@ int tgt_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
                if (!dt_object_exists(obj))
                        GOTO(err_put, rc = -ENOENT);
 
-               rc = tgt_sync(&env, tgt, obj);
+               if (lock->l_resource->lr_type == LDLM_EXTENT) {
+                       start = lock->l_policy_data.l_extent.start;
+                       end = lock->l_policy_data.l_extent.end;
+               }
+
+               rc = tgt_sync(&env, tgt, obj, start, end);
                if (rc < 0) {
-                       CERROR("%s: sync failed on lock cancel: rc = %d\n",
-                              tgt_name(tgt), rc);
+                       CERROR("%s: syncing "DFID" ("LPU64"-"LPU64") on lock "
+                              "cancel: rc = %d\n",
+                              tgt_name(tgt), PFID(&fid),
+                              lock->l_policy_data.l_extent.start,
+                              lock->l_policy_data.l_extent.end, rc);
                }
 err_put:
                lu_object_put(&env, &obj->do_lu);
@@ -1355,6 +1371,77 @@ TGT_SEC_HDL_VAR(0,       SEC_CTX_FINI,           tgt_sec_ctx_handle),
 };
 EXPORT_SYMBOL(tgt_sec_ctx_handlers);
 
+int (*tgt_lfsck_in_notify)(const struct lu_env *env,
+                          struct dt_device *key,
+                          struct lfsck_request *lr) = NULL;
+
+void tgt_register_lfsck_in_notify(int (*notify)(const struct lu_env *,
+                                               struct dt_device *,
+                                               struct lfsck_request *))
+{
+       tgt_lfsck_in_notify = notify;
+}
+EXPORT_SYMBOL(tgt_register_lfsck_in_notify);
+
+static int (*tgt_lfsck_query)(const struct lu_env *env,
+                             struct dt_device *key,
+                             struct lfsck_request *lr) = NULL;
+
+void tgt_register_lfsck_query(int (*query)(const struct lu_env *,
+                                          struct dt_device *,
+                                          struct lfsck_request *))
+{
+       tgt_lfsck_query = query;
+}
+EXPORT_SYMBOL(tgt_register_lfsck_query);
+
+/* LFSCK request handlers */
+static int tgt_handle_lfsck_notify(struct tgt_session_info *tsi)
+{
+       const struct lu_env     *env = tsi->tsi_env;
+       struct dt_device        *key = tsi->tsi_tgt->lut_bottom;
+       struct lfsck_request    *lr;
+       int                      rc;
+       ENTRY;
+
+       lr = req_capsule_client_get(tsi->tsi_pill, &RMF_LFSCK_REQUEST);
+       if (lr == NULL)
+               RETURN(-EPROTO);
+
+       rc = tgt_lfsck_in_notify(env, key, lr);
+
+       RETURN(rc);
+}
+
+static int tgt_handle_lfsck_query(struct tgt_session_info *tsi)
+{
+       struct lfsck_request    *request;
+       struct lfsck_reply      *reply;
+       int                      rc      = 0;
+       ENTRY;
+
+       request = req_capsule_client_get(tsi->tsi_pill, &RMF_LFSCK_REQUEST);
+       if (request == NULL)
+               RETURN(-EPROTO);
+
+       reply = req_capsule_server_get(tsi->tsi_pill, &RMF_LFSCK_REPLY);
+       if (reply == NULL)
+               RETURN(-ENOMEM);
+
+       reply->lr_status = tgt_lfsck_query(tsi->tsi_env,
+                                          tsi->tsi_tgt->lut_bottom, request);
+       if (reply->lr_status < 0)
+               rc = reply->lr_status;
+
+       RETURN(rc);
+}
+
+struct tgt_handler tgt_lfsck_handlers[] = {
+TGT_LFSCK_HDL(HABEO_REFERO,    LFSCK_NOTIFY,   tgt_handle_lfsck_notify),
+TGT_LFSCK_HDL(HABEO_REFERO,    LFSCK_QUERY,    tgt_handle_lfsck_query),
+};
+EXPORT_SYMBOL(tgt_lfsck_handlers);
+
 /*
  * initialize per-thread page pool (bug 5137).
  */