#endif
#include <linux/lustre_dlm.h>
-#include <linux/kp30.h>
+#include <libcfs/kp30.h>
#include <linux/lustre_net.h>
+#include <linux/lustre_sec.h>
#include <lustre/lustre_user.h>
#include <linux/obd_ost.h>
#include <linux/obd_lov.h>
request->rq_replen = lustre_msg_size(1, &size);
- rc = ptlrpc_queue_wait(request);
- if (rc)
- GOTO(out, rc);
-
- body = lustre_swab_repbuf(request, 0, sizeof(*body),
- lustre_swab_ost_body);
- if (body == NULL)
- GOTO(out, rc = -EPROTO);
+ if (oti != NULL && (oti->oti_flags & OBD_MODE_ASYNC)) {
+ ptlrpcd_add_req(request);
+ rc = 0;
+ } else {
+ rc = ptlrpc_queue_wait(request);
+ if (rc)
+ GOTO(out, rc);
- memcpy(oa, &body->oa, sizeof(*oa));
+ body = lustre_swab_repbuf(request, 0, sizeof(*body),
+ lustre_swab_ost_body);
+ if (body == NULL)
+ GOTO(out, rc = -EPROTO);
+ memcpy(oa, &body->oa, sizeof(*oa));
+ }
EXIT;
out:
ptlrpc_req_finished(request);
int osc_real_create(struct obd_export *exp, struct obdo *oa,
struct lov_stripe_md **ea, struct obd_trans_info *oti)
{
+ struct osc_creator *oscc = &exp->exp_obd->u.cli.cl_oscc;
struct ptlrpc_request *request;
struct ost_body *body;
struct lov_stripe_md *lsm;
GOTO (out_req, rc = -EPROTO);
}
+ if ((oa->o_valid & OBD_MD_FLFLAGS) && oa->o_flags == OBD_FL_DELORPHAN) {
+ struct obd_import *imp = class_exp2cliimp(exp);
+ /* MDS declares last known object, OSS responses
+ * with next possible object -bzzz */
+ spin_lock(&oscc->oscc_lock);
+ oscc->oscc_next_id = body->oa.o_id;
+ spin_unlock(&oscc->oscc_lock);
+ CDEBUG(D_HA, "%s: set nextid "LPD64" after recovery\n",
+ imp->imp_target_uuid.uuid, oa->o_id);
+ }
memcpy(oa, &body->oa, sizeof(*oa));
/* This should really be sent by the OST */
}
static int osc_sync(struct obd_export *exp, struct obdo *oa,
- struct lov_stripe_md *md, obd_size start, obd_size end)
+ struct lov_stripe_md *md, obd_size start,
+ obd_size end)
{
struct ptlrpc_request *request;
struct ost_body *body;
memcpy(&body->oa, oa, sizeof(*oa));
request->rq_replen = lustre_msg_size(1, &size);
- rc = ptlrpc_queue_wait(request);
-
- if (rc == -ENOENT)
+ if (oti != NULL && (oti->oti_flags & OBD_MODE_ASYNC)) {
+ ptlrpcd_add_req(request);
rc = 0;
- if (rc)
- GOTO(out, rc);
+ } else {
+ rc = ptlrpc_queue_wait(request);
+
+ if (rc == -ENOENT)
+ rc = 0;
- body = lustre_swab_repbuf(request, 0, sizeof(*body),
- lustre_swab_ost_body);
- if (body == NULL) {
- CERROR ("Can't unpack body\n");
- GOTO (out, rc = -EPROTO);
- }
+ if (rc) {
+ ptlrpc_req_finished(request);
+ RETURN(rc);
+ }
- memcpy(oa, &body->oa, sizeof(*oa));
+ body = lustre_swab_repbuf(request, 0, sizeof(*body),
+ lustre_swab_ost_body);
+ if (body == NULL) {
+ CERROR ("Can't unpack body\n");
+ ptlrpc_req_finished(request);
+ RETURN(-EPROTO);
+ }
- EXIT;
- out:
- ptlrpc_req_finished(request);
- return rc;
+ memcpy(oa, &body->oa, sizeof(*oa));
+ ptlrpc_req_finished(request);
+ }
+ RETURN(rc);
}
static void osc_announce_cached(struct client_obd *cli, struct obdo *oa,
long writing_bytes)
{
- obd_flag bits = OBD_MD_FLBLOCKS|OBD_MD_FLGRANT;
+ obd_valid bits = OBD_MD_FLBLOCKS|OBD_MD_FLGRANT;
LASSERT(!(oa->o_valid & bits));
int requested_nob, int niocount,
obd_count page_count, struct brw_page *pga)
{
- int *remote_rcs, i;
+ int *remote_rcs, i;
/* return error if any niobuf was in error */
remote_rcs = lustre_swab_repbuf(request, 1,
}
if (lustre_msg_swabbed(request->rq_repmsg))
for (i = 0; i < niocount; i++)
- __swab32s(&remote_rcs[i]);
+ __swab32s((__u32 *)&remote_rcs[i]);
for (i = 0; i < niocount; i++) {
if (remote_rcs[i] < 0)
}
static int osc_brw(int cmd, struct obd_export *exp, struct obdo *oa,
- struct lov_stripe_md *md, obd_count page_count,
+ struct lov_stripe_md *lsm, obd_count page_count,
struct brw_page *pga, struct obd_trans_info *oti)
{
ENTRY;
sort_brw_pages(pga, pages_per_brw);
pages_per_brw = check_elan_limit(pga, pages_per_brw);
- rc = osc_brw_internal(cmd, exp, oa, md, pages_per_brw, pga);
+ rc = osc_brw_internal(cmd, exp, oa, lsm, pages_per_brw, pga);
if (rc != 0)
RETURN(rc);
}
static int osc_brw_async(int cmd, struct obd_export *exp, struct obdo *oa,
- struct lov_stripe_md *md, obd_count page_count,
+ struct lov_stripe_md *lsm, obd_count page_count,
struct brw_page *pga, struct ptlrpc_request_set *set,
struct obd_trans_info *oti)
{
sort_brw_pages(pga, pages_per_brw);
pages_per_brw = check_elan_limit(pga, pages_per_brw);
- rc = async_internal(cmd, exp, oa, md, pages_per_brw, pga, set);
+ rc = async_internal(cmd, exp, oa, lsm, pages_per_brw, pga, set);
if (rc != 0)
RETURN(rc);
osc_wake_cache_waiters(cli);
osc_check_rpcs(cli);
-
spin_unlock(&cli->cl_loi_list_lock);
obdo_free(aa->aa_oa);
RETURN(0);
}
-struct osc_async_page *oap_from_cookie(void *cookie)
-{
- struct osc_async_page *oap = cookie;
- if (oap->oap_magic != OAP_MAGIC)
- return ERR_PTR(-EINVAL);
- return oap;
-};
-
static int osc_queue_async_io(struct obd_export *exp, struct lov_stripe_md *lsm,
struct lov_oinfo *loi, void *cookie,
int cmd, obd_off off, int count,
- obd_flag brw_flags, enum async_flags async_flags)
+ obd_flags brw_flags, enum async_flags async_flags)
{
struct client_obd *cli = &exp->exp_obd->u.cli;
struct osc_async_page *oap;
int rc;
ENTRY;
- oap = oap_from_cookie(cookie);
- if (IS_ERR(oap))
- RETURN(PTR_ERR(oap));
+ oap = OAP_FROM_COOKIE(cookie);
if (cli->cl_import == NULL || cli->cl_import->imp_invalid)
RETURN(-EIO);
static int osc_set_async_flags(struct obd_export *exp,
struct lov_stripe_md *lsm,
struct lov_oinfo *loi, void *cookie,
- obd_flag async_flags)
+ obd_flags async_flags)
{
struct client_obd *cli = &exp->exp_obd->u.cli;
struct loi_oap_pages *lop;
int rc = 0;
ENTRY;
- oap = oap_from_cookie(cookie);
- if (IS_ERR(oap))
- RETURN(PTR_ERR(oap));
+ oap = OAP_FROM_COOKIE(cookie);
if (cli->cl_import == NULL || cli->cl_import->imp_invalid)
RETURN(-EIO);
struct lov_oinfo *loi,
struct obd_io_group *oig, void *cookie,
int cmd, obd_off off, int count,
- obd_flag brw_flags,
- obd_flag async_flags)
+ obd_flags brw_flags,
+ obd_flags async_flags)
{
struct client_obd *cli = &exp->exp_obd->u.cli;
struct osc_async_page *oap;
struct loi_oap_pages *lop;
ENTRY;
- oap = oap_from_cookie(cookie);
- if (IS_ERR(oap))
- RETURN(PTR_ERR(oap));
+ oap = OAP_FROM_COOKIE(cookie);
if (cli->cl_import == NULL || cli->cl_import->imp_invalid)
RETURN(-EIO);
int rc = 0;
ENTRY;
- oap = oap_from_cookie(cookie);
- if (IS_ERR(oap))
- RETURN(PTR_ERR(oap));
+ oap = OAP_FROM_COOKIE(cookie);
if (loi == NULL)
loi = &lsm->lsm_oinfo[0];
if (lock->l_ast_data && lock->l_ast_data != data) {
struct inode *new_inode = data;
struct inode *old_inode = lock->l_ast_data;
+ if (!(old_inode->i_state & I_FREEING))
+ LDLM_ERROR(lock, "inconsistent l_ast_data found");
LASSERTF(old_inode->i_state & I_FREEING,
"Found existing inode %p/%lu/%u state %lu in lock: "
"setting data to %p/%lu/%u\n", old_inode,
rc = ldlm_lock_match(obd->obd_namespace, 0, &res_id, type, policy, mode,
lockh);
if (rc == 1) {
+ if (ptlrpcs_check_cred(obd->u.cli.cl_import)) {
+ /* return immediately if no credential held */
+ ldlm_lock_decref(lockh, mode);
+ RETURN(-EACCES);
+ }
+
osc_set_data_with_check(lockh, data);
if (*flags & LDLM_FL_HAS_INTENT) {
/* I would like to be able to ASSERT here that rss <=
rc = ldlm_lock_match(obd->obd_namespace, 0, &res_id, type,
policy, LCK_PW, lockh);
if (rc == 1) {
+ if (ptlrpcs_check_cred(obd->u.cli.cl_import)) {
+ /* return immediately if no credential held */
+ ldlm_lock_decref(lockh, LCK_PW);
+ RETURN(-EACCES);
+ }
+
/* FIXME: This is not incredibly elegant, but it might
* be more elegant than adding another parameter to
* lock_match. I want a second opinion. */
RETURN(ELDLM_OK);
}
}
+ if (mode == LCK_PW) {
+ rc = ldlm_lock_match(obd->obd_namespace, 0, &res_id, type,
+ policy, LCK_PR, lockh);
+ if (rc == 1) {
+ rc = ldlm_cli_convert(lockh, mode, flags);
+ if (!rc) {
+ /* Update readers/writers accounting */
+ ldlm_lock_addref(lockh, LCK_PW);
+ ldlm_lock_decref(lockh, LCK_PR);
+ osc_set_data_with_check(lockh, data);
+ RETURN(ELDLM_OK);
+ }
+ /* If the conversion failed, we need to drop refcount
+ on matched lock before we get new one */
+ /* XXX Won't it save us some efforts if we cancel PR
+ lock here? We are going to take PW lock anyway and it
+ will invalidate PR lock */
+ ldlm_lock_decref(lockh, LCK_PR);
+ if (rc != EDEADLOCK) {
+ RETURN(rc);
+ }
+ }
+ }
+
+ if (mode == LCK_PW) {
+ rc = ldlm_lock_match(obd->obd_namespace, 0, &res_id, type,
+ policy, LCK_PR, lockh);
+ if (rc == 1) {
+ rc = ldlm_cli_convert(lockh, mode, flags);
+ if (!rc) {
+ /* Update readers/writers accounting */
+ ldlm_lock_addref(lockh, LCK_PW);
+ ldlm_lock_decref(lockh, LCK_PR);
+ osc_set_data_with_check(lockh, data);
+ RETURN(ELDLM_OK);
+ }
+ /* If the conversion failed, we need to drop refcount
+ on matched lock before we get new one */
+ /* XXX Won't it save us some efforts if we cancel PR
+ lock here? We are going to take PW lock anyway and it
+ will invalidate PR lock */
+ ldlm_lock_decref(lockh, LCK_PR);
+ if (rc != EDEADLOCK) {
+ RETURN(rc);
+ }
+ }
+ }
no_match:
if (*flags & LDLM_FL_HAS_INTENT) {
}
static int osc_cancel_unused(struct obd_export *exp,
- struct lov_stripe_md *lsm, int flags, void *opaque)
+ struct lov_stripe_md *lsm,
+ int flags, void *opaque)
{
struct obd_device *obd = class_exp2obd(exp);
struct ldlm_res_id res_id = { .name = {0} }, *resp = NULL;
err = ptlrpc_set_import_active(obd->u.cli.cl_import,
data->ioc_offset);
GOTO(out, err);
+ case IOC_OSC_CTL_RECOVERY:
+ err = ptlrpc_import_control_recovery(obd->u.cli.cl_import,
+ data->ioc_offset);
+ GOTO(out, err);
default:
CDEBUG(D_INODE, "unrecognised ioctl %#x by %s\n", cmd, current->comm);
GOTO(out, err = -ENOTTY);
return err;
}
-static int osc_get_info(struct obd_export *exp, obd_count keylen,
+static int osc_get_info(struct obd_export *exp, __u32 keylen,
void *key, __u32 *vallen, void *val)
{
ENTRY;
char *bufs[1] = {key};
int rc;
req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_OBD_VERSION,
- OST_GET_INFO, 1, &keylen, bufs);
+ OST_GET_INFO, 1, (int *)&keylen, bufs);
if (req == NULL)
RETURN(-ENOMEM);
- req->rq_replen = lustre_msg_size(1, vallen);
+ req->rq_replen = lustre_msg_size(1, (int *)vallen);
rc = ptlrpc_queue_wait(req);
if (rc)
GOTO(out, rc);
int rc = 0;
ENTRY;
- if (keylen == strlen("next_id") &&
- memcmp(key, "next_id", strlen("next_id")) == 0) {
- if (vallen != sizeof(obd_id))
- RETURN(-EINVAL);
- obd->u.cli.cl_oscc.oscc_next_id = *((obd_id*)val) + 1;
- CDEBUG(D_HA, "%s: set oscc_next_id = "LPU64"\n",
- exp->exp_obd->obd_name,
- obd->u.cli.cl_oscc.oscc_next_id);
-
- RETURN(0);
- }
-
- if (keylen == strlen("growth_count") &&
- memcmp(key, "growth_count", strlen("growth_count")) == 0) {
- if (vallen != sizeof(int))
- RETURN(-EINVAL);
- obd->u.cli.cl_oscc.oscc_max_grow_count = *((int*)val);
- RETURN(0);
- }
-
if (keylen == strlen("unlinked") &&
memcmp(key, "unlinked", keylen) == 0) {
struct osc_creator *oscc = &obd->u.cli.cl_oscc;
RETURN(0);
}
+ if (keylen == strlen("async") &&
+ memcmp(key, "async", keylen) == 0) {
+ struct client_obd *cl = &obd->u.cli;
+ if (vallen != sizeof(int))
+ RETURN(-EINVAL);
+ cl->cl_async = *(int *)val;
+ CDEBUG(D_HA, "%s: set async = %d\n",
+ obd->obd_name, cl->cl_async);
+ RETURN(0);
+ }
+
+ if (keylen == strlen("sec") &&
+ memcmp(key, "sec", keylen) == 0) {
+ struct client_obd *cli = &exp->exp_obd->u.cli;
+
+ if (vallen == strlen("null") &&
+ memcmp(val, "null", vallen) == 0) {
+ cli->cl_sec_flavor = PTLRPC_SEC_NULL;
+ cli->cl_sec_subflavor = 0;
+ RETURN(0);
+ }
+ if (vallen == strlen("krb5i") &&
+ memcmp(val, "krb5i", vallen) == 0) {
+ cli->cl_sec_flavor = PTLRPC_SEC_GSS;
+ cli->cl_sec_subflavor = PTLRPC_SEC_GSS_KRB5I;
+ RETURN(0);
+ }
+ if (vallen == strlen("krb5p") &&
+ memcmp(val, "krb5p", vallen) == 0) {
+ cli->cl_sec_flavor = PTLRPC_SEC_GSS;
+ cli->cl_sec_subflavor = PTLRPC_SEC_GSS_KRB5P;
+ RETURN(0);
+ }
+ CERROR("unrecognized security type %s\n", (char*) val);
+ RETURN(-EINVAL);
+ }
+
+ if (keylen == strlen("flush_cred") &&
+ memcmp(key, "flush_cred", keylen) == 0) {
+ struct client_obd *cli = &exp->exp_obd->u.cli;
+
+ if (cli->cl_import)
+ ptlrpcs_import_flush_creds(cli->cl_import,
+ *((uid_t *) val));
+ RETURN(0);
+ }
+
if (keylen < strlen("mds_conn") ||
- memcmp(key, "mds_conn", strlen("mds_conn")) != 0)
+ memcmp(key, "mds_conn", keylen) != 0)
RETURN(-EINVAL);
- ctxt = llog_get_context(&exp->exp_obd->obd_llogs, LLOG_UNLINK_ORIG_CTXT);
+ ctxt = llog_get_context(&exp->exp_obd->obd_llogs,
+ LLOG_UNLINK_ORIG_CTXT);
if (ctxt) {
if (rc == 0)
rc = llog_initiator_connect(ctxt);
else
- CERROR("cannot establish the connect for ctxt %p: %d\n",
- ctxt, rc);
+ CERROR("cannot establish the connect for "
+ "ctxt %p: %d\n", ctxt, rc);
}
imp->imp_server_timeout = 1;
};
static struct llog_operations osc_unlink_orig_logops;
+
static int osc_llog_init(struct obd_device *obd, struct obd_llogs *llogs,
struct obd_device *tgt, int count,
struct llog_catid *catid)
RETURN(rc);
}
-
static int osc_connect(struct lustre_handle *exph,
struct obd_device *obd, struct obd_uuid *cluuid,
+ struct obd_connect_data *data,
unsigned long connect_flags)
{
int rc;
ENTRY;
- rc = client_connect_import(exph, obd, cluuid, connect_flags);
+ rc = client_connect_import(exph, obd, cluuid, data, connect_flags);
RETURN(rc);
}
-static int osc_disconnect(struct obd_export *exp, int flags)
+static int osc_disconnect(struct obd_export *exp, unsigned long flags)
{
struct obd_device *obd = class_exp2obd(exp);
struct llog_ctxt *ctxt;
static int osc_cleanup(struct obd_device *obd, int flags)
{
+ struct osc_creator *oscc = &obd->u.cli.cl_oscc;
int rc;
rc = ldlm_cli_cancel_unused(obd->obd_namespace, NULL,
if (rc)
RETURN(rc);
+ spin_lock(&oscc->oscc_lock);
+ oscc->oscc_flags &= ~OSCC_FLAG_RECOVERING;
+ oscc->oscc_flags |= OSCC_FLAG_EXITING;
+ spin_unlock(&oscc->oscc_lock);
+
rc = client_obd_cleanup(obd, flags);
ptlrpcd_decref();
RETURN(rc);