* 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"
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;
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;
}
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,
__u32 index;
__u32 flags;
- memcpy(&index, data->ioc_inlbuf2, sizeof(__u32));
+ memcpy(&index, data->ioc_inlbuf2, sizeof(index));
if ((index >= count))
RETURN(-ENODEV);
/* 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),
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;
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,
}
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,
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);
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,
.o_getref = lov_getref,
.o_putref = lov_putref,
.o_quotactl = lov_quotactl,
- .o_quotacheck = lov_quotacheck,
};
struct kmem_cache *lov_oinfo_slab;
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);