Whamcloud - gitweb
LU-7623 lov: Get rid of an ugly statfs hack in lov_iocontrol
[fs/lustre-release.git] / lustre / lov / lov_obd.c
index 49f332e..7c00acf 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2014, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 #define DEBUG_SUBSYSTEM S_LOV
 #include <libcfs/libcfs.h>
 
-#include <obd_support.h>
-#include <lustre_ioctl.h>
-#include <lustre_lib.h>
-#include <lustre_net.h>
 #include <lustre/lustre_idl.h>
+
+#include <cl_object.h>
 #include <lustre_dlm.h>
+#include <lustre_fid.h>
+#include <lustre_ioctl.h>
+#include <lustre_lib.h>
 #include <lustre_mds.h>
-#include <obd_class.h>
-#include <lprocfs_status.h>
+#include <lustre_net.h>
 #include <lustre_param.h>
-#include <cl_object.h>
-#include <lustre_fid.h>
+#include <lustre_swab.h>
+#include <lprocfs_status.h>
+#include <obd_class.h>
+#include <obd_support.h>
 
 #include "lov_internal.h"
 
@@ -881,31 +883,6 @@ out:
        return rc;
 }
 
-static int lov_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
-{
-        int rc = 0;
-        struct lov_obd *lov = &obd->u.lov;
-
-        ENTRY;
-
-        switch (stage) {
-        case OBD_CLEANUP_EARLY: {
-                int i;
-                for (i = 0; i < lov->desc.ld_tgt_count; i++) {
-                        if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active)
-                                continue;
-                        obd_precleanup(class_exp2obd(lov->lov_tgts[i]->ltd_exp),
-                                       OBD_CLEANUP_EARLY);
-                }
-                break;
-       }
-       default:
-               break;
-       }
-
-       RETURN(rc);
-}
-
 static int lov_cleanup(struct obd_device *obd)
 {
         struct lov_obd *lov = &obd->u.lov;
@@ -1021,171 +998,6 @@ out:
         RETURN(rc);
 }
 
-#define ASSERT_LSM_MAGIC(lsmp)                                                  \
-do {                                                                            \
-        LASSERT((lsmp) != NULL);                                                \
-        LASSERTF(((lsmp)->lsm_magic == LOV_MAGIC_V1 ||                          \
-                 (lsmp)->lsm_magic == LOV_MAGIC_V3),                            \
-                 "%p->lsm_magic=%x\n", (lsmp), (lsmp)->lsm_magic);              \
-} while (0)
-
-static int lov_getattr_interpret(struct ptlrpc_request_set *rqset,
-                                void *data, int rc)
-{
-       struct lov_request_set *lovset = (struct lov_request_set *)data;
-       int err;
-       ENTRY;
-
-       /* don't do attribute merge if this aysnc op failed */
-       if (rc)
-               atomic_set(&lovset->set_completes, 0);
-       err = lov_fini_getattr_set(lovset);
-       RETURN(rc ? rc : err);
-}
-
-static int lov_getattr_async(struct obd_export *exp, struct obd_info *oinfo,
-                              struct ptlrpc_request_set *rqset)
-{
-        struct lov_request_set *lovset;
-        struct lov_obd *lov;
-       struct list_head *pos;
-        struct lov_request *req;
-        int rc = 0, err;
-        ENTRY;
-
-        LASSERT(oinfo);
-        ASSERT_LSM_MAGIC(oinfo->oi_md);
-
-        if (!exp || !exp->exp_obd)
-                RETURN(-ENODEV);
-
-        lov = &exp->exp_obd->u.lov;
-
-        rc = lov_prep_getattr_set(exp, oinfo, &lovset);
-        if (rc)
-                RETURN(rc);
-
-       CDEBUG(D_INFO, "objid "DOSTID": %ux%u byte stripes\n",
-              POSTID(&oinfo->oi_md->lsm_oi), oinfo->oi_md->lsm_stripe_count,
-              oinfo->oi_md->lsm_stripe_size);
-
-       list_for_each(pos, &lovset->set_list) {
-               req = list_entry(pos, struct lov_request, rq_link);
-
-               CDEBUG(D_INFO, "objid "DOSTID"[%d] has subobj "DOSTID" at idx"
-                      "%u\n", POSTID(&oinfo->oi_oa->o_oi), req->rq_stripe,
-                      POSTID(&req->rq_oi.oi_oa->o_oi), req->rq_idx);
-               rc = obd_getattr_async(lov->lov_tgts[req->rq_idx]->ltd_exp,
-                                      &req->rq_oi, rqset);
-               if (rc) {
-                       CERROR("%s: getattr objid "DOSTID" subobj"
-                              DOSTID" on OST idx %d: rc = %d\n",
-                              exp->exp_obd->obd_name,
-                              POSTID(&oinfo->oi_oa->o_oi),
-                              POSTID(&req->rq_oi.oi_oa->o_oi),
-                              req->rq_idx, rc);
-                       GOTO(out, rc);
-               }
-       }
-
-       if (!list_empty(&rqset->set_requests)) {
-                LASSERT(rc == 0);
-                LASSERT (rqset->set_interpret == NULL);
-                rqset->set_interpret = lov_getattr_interpret;
-                rqset->set_arg = (void *)lovset;
-                RETURN(rc);
-        }
-out:
-       if (rc)
-               atomic_set(&lovset->set_completes, 0);
-       err = lov_fini_getattr_set(lovset);
-       RETURN(rc ? rc : err);
-}
-
-static int lov_setattr_interpret(struct ptlrpc_request_set *rqset,
-                                void *data, int rc)
-{
-       struct lov_request_set *lovset = (struct lov_request_set *)data;
-       int err;
-       ENTRY;
-
-       if (rc)
-               atomic_set(&lovset->set_completes, 0);
-       err = lov_fini_setattr_set(lovset);
-       RETURN(rc ? rc : err);
-}
-
-/* If @oti is given, the request goes from MDS and responses from OSTs are not
-   needed. Otherwise, a client is waiting for responses. */
-static int lov_setattr_async(struct obd_export *exp, struct obd_info *oinfo,
-                             struct obd_trans_info *oti,
-                             struct ptlrpc_request_set *rqset)
-{
-        struct lov_request_set *set;
-        struct lov_request *req;
-       struct list_head *pos;
-        struct lov_obd *lov;
-        int rc = 0;
-        ENTRY;
-
-        LASSERT(oinfo);
-        ASSERT_LSM_MAGIC(oinfo->oi_md);
-        if (oinfo->oi_oa->o_valid & OBD_MD_FLCOOKIE) {
-                LASSERT(oti);
-                LASSERT(oti->oti_logcookies);
-        }
-
-        if (!exp || !exp->exp_obd)
-                RETURN(-ENODEV);
-
-        lov = &exp->exp_obd->u.lov;
-        rc = lov_prep_setattr_set(exp, oinfo, oti, &set);
-        if (rc)
-                RETURN(rc);
-
-       CDEBUG(D_INFO, "objid "DOSTID": %ux%u byte stripes\n",
-              POSTID(&oinfo->oi_md->lsm_oi),
-              oinfo->oi_md->lsm_stripe_count,
-              oinfo->oi_md->lsm_stripe_size);
-
-       list_for_each(pos, &set->set_list) {
-               req = list_entry(pos, struct lov_request, rq_link);
-
-               if (oinfo->oi_oa->o_valid & OBD_MD_FLCOOKIE)
-                       oti->oti_logcookies = set->set_cookies + req->rq_stripe;
-
-               CDEBUG(D_INFO, "objid "DOSTID"[%d] has subobj "DOSTID" at idx"
-                      "%u\n", POSTID(&oinfo->oi_oa->o_oi), req->rq_stripe,
-                      POSTID(&req->rq_oi.oi_oa->o_oi), req->rq_idx);
-
-               rc = obd_setattr_async(lov->lov_tgts[req->rq_idx]->ltd_exp,
-                                      &req->rq_oi, oti, rqset);
-               if (rc) {
-                       CERROR("error: setattr objid "DOSTID" subobj"
-                              DOSTID" on OST idx %d: rc = %d\n",
-                              POSTID(&set->set_oi->oi_oa->o_oi),
-                              POSTID(&req->rq_oi.oi_oa->o_oi),
-                              req->rq_idx, rc);
-                       break;
-               }
-       }
-
-       /* If we are not waiting for responses on async requests, return. */
-       if (rc || !rqset || list_empty(&rqset->set_requests)) {
-               int err;
-               if (rc)
-                       atomic_set(&set->set_completes, 0);
-               err = lov_fini_setattr_set(set);
-               RETURN(rc ? rc : err);
-       }
-
-       LASSERT(rqset->set_interpret == NULL);
-       rqset->set_interpret = lov_setattr_interpret;
-       rqset->set_arg = (void *)set;
-
-       RETURN(0);
-}
-
 int lov_statfs_interpret(struct ptlrpc_request_set *rqset, void *data, int rc)
 {
        struct lov_request_set *lovset = (struct lov_request_set *)data;
@@ -1241,28 +1053,30 @@ static int lov_statfs_async(struct obd_export *exp, struct obd_info *oinfo,
 }
 
 static int lov_statfs(const struct lu_env *env, struct obd_export *exp,
-                      struct obd_statfs *osfs, __u64 max_age, __u32 flags)
+                     struct obd_statfs *osfs, __u64 max_age, __u32 flags)
 {
-        struct ptlrpc_request_set *set = NULL;
-        struct obd_info oinfo = { { { 0 } } };
-        int rc = 0;
-        ENTRY;
+       struct ptlrpc_request_set *set = NULL;
+       struct obd_info oinfo = {
+               .oi_osfs = osfs,
+               .oi_flags = flags,
+       };
+       int rc = 0;
 
+       ENTRY;
 
-        /* for obdclass we forbid using obd_statfs_rqset, but prefer using async
-         * statfs requests */
-        set = ptlrpc_prep_set();
-        if (set == NULL)
-                RETURN(-ENOMEM);
+       /* for obdclass we forbid using obd_statfs_rqset, but prefer using async
+        * statfs requests */
+       set = ptlrpc_prep_set();
+       if (set == NULL)
+               RETURN(-ENOMEM);
 
-        oinfo.oi_osfs = osfs;
-        oinfo.oi_flags = flags;
-        rc = lov_statfs_async(exp, &oinfo, max_age, set);
-        if (rc == 0)
-                rc = ptlrpc_set_wait(set);
-        ptlrpc_set_destroy(set);
+       rc = lov_statfs_async(exp, &oinfo, max_age, set);
+       if (rc == 0)
+               rc = ptlrpc_set_wait(set);
 
-        RETURN(rc);
+       ptlrpc_set_destroy(set);
+
+       RETURN(rc);
 }
 
 static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
@@ -1282,7 +1096,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                 __u32 index;
                __u32 flags;
 
-                memcpy(&index, data->ioc_inlbuf2, sizeof(__u32));
+                memcpy(&index, data->ioc_inlbuf2, sizeof(index));
                 if ((index >= count))
                         RETURN(-ENODEV);
 
@@ -1298,11 +1112,13 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
 
                 /* copy UUID */
                if (copy_to_user(data->ioc_pbuf2, obd2cli_tgt(osc_obd),
-                                min((int)data->ioc_plen2,
-                                    (int)sizeof(struct obd_uuid))))
-                        RETURN(-EFAULT);
+                                min_t(unsigned long, data->ioc_plen2,
+                                      sizeof(struct obd_uuid))))
+                       RETURN(-EFAULT);
+
+               memcpy(&flags, data->ioc_inlbuf1, sizeof(flags));
+               flags = flags & LL_STATFS_NODELAY ? OBD_STATFS_NODELAY : 0;
 
-               flags = uarg ? *(__u32 __user *)uarg : 0;
                 /* got statfs data */
                 rc = obd_statfs(NULL, lov->lov_tgts[index]->ltd_exp, &stat_buf,
                                 cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
@@ -1310,10 +1126,10 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                 if (rc)
                         RETURN(rc);
                if (copy_to_user(data->ioc_pbuf1, &stat_buf,
-                                     min((int) data->ioc_plen1,
-                                         (int) sizeof(stat_buf))))
-                        RETURN(-EFAULT);
-                break;
+                                min_t(unsigned long, data->ioc_plen1,
+                                      sizeof(struct obd_statfs))))
+                       RETURN(-EFAULT);
+               break;
         }
         case OBD_IOC_LOV_GET_CONFIG: {
                 struct obd_ioctl_data *data;
@@ -1427,9 +1243,7 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                         osc_obd->obd_force = obddev->obd_force;
                         err = obd_iocontrol(cmd, lov->lov_tgts[i]->ltd_exp,
                                             len, karg, uarg);
-                        if (err == -ENODATA && cmd == OBD_IOC_POLL_QUOTACHECK) {
-                                RETURN(err);
-                        } else if (err) {
+                       if (err) {
                                 if (lov->lov_tgts[i]->ltd_active) {
                                         CDEBUG(err == -ENOTTY ?
                                                D_IOCTL : D_WARNING,
@@ -1453,35 +1267,38 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
 }
 
 static int lov_get_info(const struct lu_env *env, struct obd_export *exp,
-                       __u32 keylen, void *key,
-                       __u32 *vallen, void *val,
-                       struct lov_stripe_md *lsm)
+                       __u32 keylen, void *key, __u32 *vallen, void *val)
 {
        struct obd_device *obddev = class_exp2obd(exp);
        struct lov_obd *lov = &obddev->u.lov;
-       int rc;
-        ENTRY;
+       struct lov_desc *ld = &lov->desc;
+       int rc = 0;
+       ENTRY;
 
-        if (!vallen || !val)
-                RETURN(-EFAULT);
+       if (vallen == NULL || val == NULL)
+               RETURN(-EFAULT);
 
-        obd_getref(obddev);
+       obd_getref(obddev);
 
-       if (KEY_IS(KEY_LOVDESC)) {
-                struct lov_desc *desc_ret = val;
-                *desc_ret = lov->desc;
+       if (KEY_IS(KEY_MAX_EASIZE)) {
+               u32 max_stripe_count = min_t(u32, ld->ld_active_tgt_count,
+                                            LOV_MAX_STRIPE_COUNT);
 
-                GOTO(out, rc = 0);
-        } else if (KEY_IS(KEY_TGT_COUNT)) {
-                *((int *)val) = lov->desc.ld_tgt_count;
-                GOTO(out, rc = 0);
-        }
+               *((u32 *)val) = lov_mds_md_size(max_stripe_count, LOV_MAGIC_V3);
+       } else if (KEY_IS(KEY_DEFAULT_EASIZE)) {
+               u32 def_stripe_count = min_t(u32, ld->ld_default_stripe_count,
+                                            LOV_MAX_STRIPE_COUNT);
 
-        rc = -EINVAL;
+               *((u32 *)val) = lov_mds_md_size(def_stripe_count, LOV_MAGIC_V3);
+       } else if (KEY_IS(KEY_TGT_COUNT)) {
+               *((int *)val) = lov->desc.ld_tgt_count;
+       } else {
+               rc = -EINVAL;
+       }
 
-out:
-        obd_putref(obddev);
-        RETURN(rc);
+       obd_putref(obddev);
+
+       RETURN(rc);
 }
 
 static int lov_set_info_async(const struct lu_env *env, struct obd_export *exp,
@@ -1573,12 +1390,8 @@ static int lov_quotactl(struct obd_device *obd, struct obd_export *exp,
         int                  i, rc = 0;
         ENTRY;
 
-        if (oqctl->qc_cmd != LUSTRE_Q_QUOTAON &&
-            oqctl->qc_cmd != LUSTRE_Q_QUOTAOFF &&
-            oqctl->qc_cmd != Q_GETOQUOTA &&
-            oqctl->qc_cmd != Q_INITQUOTA &&
-            oqctl->qc_cmd != LUSTRE_Q_SETQUOTA &&
-            oqctl->qc_cmd != Q_FINVALIDATE) {
+       if (oqctl->qc_cmd != Q_GETOQUOTA &&
+           oqctl->qc_cmd != LUSTRE_Q_SETQUOTA) {
                CERROR("%s: bad quota opc %x for lov obd\n",
                       obd->obd_name, oqctl->qc_cmd);
                RETURN(-EFAULT);
@@ -1626,63 +1439,14 @@ static int lov_quotactl(struct obd_device *obd, struct obd_export *exp,
         RETURN(rc);
 }
 
-static int lov_quotacheck(struct obd_device *obd, struct obd_export *exp,
-                          struct obd_quotactl *oqctl)
-{
-        struct lov_obd *lov = &obd->u.lov;
-        int             i, rc = 0;
-        ENTRY;
-
-        obd_getref(obd);
-
-        for (i = 0; i < lov->desc.ld_tgt_count; i++) {
-                if (!lov->lov_tgts[i])
-                        continue;
-
-                /* Skip quota check on the administratively disabled OSTs. */
-                if (!lov->lov_tgts[i]->ltd_activate) {
-                        CWARN("lov idx %d was administratively disabled, "
-                              "skip quotacheck on it.\n", i);
-                        continue;
-                }
-
-                if (!lov->lov_tgts[i]->ltd_active) {
-                        CERROR("lov idx %d inactive\n", i);
-                        rc = -EIO;
-                        goto out;
-                }
-        }
-
-        for (i = 0; i < lov->desc.ld_tgt_count; i++) {
-                int err;
-
-                if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_activate)
-                        continue;
-
-                err = obd_quotacheck(lov->lov_tgts[i]->ltd_exp, oqctl);
-                if (err && !rc)
-                        rc = err;
-        }
-
-out:
-        obd_putref(obd);
-
-        RETURN(rc);
-}
-
 static struct obd_ops lov_obd_ops = {
        .o_owner                = THIS_MODULE,
        .o_setup                = lov_setup,
-       .o_precleanup           = lov_precleanup,
        .o_cleanup              = lov_cleanup,
        .o_connect              = lov_connect,
        .o_disconnect           = lov_disconnect,
        .o_statfs               = lov_statfs,
        .o_statfs_async         = lov_statfs_async,
-       .o_packmd               = lov_packmd,
-       .o_unpackmd             = lov_unpackmd,
-       .o_getattr_async        = lov_getattr_async,
-       .o_setattr_async        = lov_setattr_async,
        .o_iocontrol            = lov_iocontrol,
        .o_get_info             = lov_get_info,
        .o_set_info_async       = lov_set_info_async,
@@ -1694,7 +1458,6 @@ static struct obd_ops lov_obd_ops = {
        .o_getref               = lov_getref,
        .o_putref               = lov_putref,
        .o_quotactl             = lov_quotactl,
-       .o_quotacheck           = lov_quotacheck,
 };
 
 struct kmem_cache *lov_oinfo_slab;
@@ -1738,15 +1501,17 @@ static int __init lov_init(void)
         RETURN(rc);
 }
 
-static void /*__exit*/ lov_exit(void)
+static void __exit lov_exit(void)
 {
        class_unregister_type(LUSTRE_LOV_NAME);
        kmem_cache_destroy(lov_oinfo_slab);
        lu_kmem_fini(lov_caches);
 }
 
-MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
-MODULE_DESCRIPTION("Lustre Logical Object Volume OBD driver");
+MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
+MODULE_DESCRIPTION("Lustre Logical Object Volume");
+MODULE_VERSION(LUSTRE_VERSION_STRING);
 MODULE_LICENSE("GPL");
 
-cfs_module(lov, LUSTRE_VERSION_STRING, lov_init, lov_exit);
+module_init(lov_init);
+module_exit(lov_exit);