#include <dt_object.h>
#include <lustre_acl.h>
#include <lustre_export.h>
-#include <lustre_ioctl.h>
+#include <uapi/linux/lustre_ioctl.h>
#include <lustre_lfsck.h>
#include <lustre_log.h>
#include <lustre_net.h>
lh->mlh_type = MDT_PDO_LOCK;
if (lu_name_is_valid(lname)) {
- lh->mlh_pdo_hash = full_name_hash(lname->ln_name,
- lname->ln_namelen);
+ lh->mlh_pdo_hash = ll_full_name_hash(NULL, lname->ln_name,
+ lname->ln_namelen);
/* XXX Workaround for LU-2856
*
* Zero is a valid return value of full_name_hash, but
const struct lu_env *env = info->mti_env;
struct md_object *next = mdt_object_child(o);
struct lu_buf *buf = &info->mti_buf;
+ struct mdt_device *mdt = info->mti_mdt;
int rc;
+ ENTRY;
+
buf->lb_buf = req_capsule_server_get(info->mti_pill, &RMF_ACL);
buf->lb_len = req_capsule_get_size(info->mti_pill, &RMF_ACL,
RCL_SERVER);
if (buf->lb_len == 0)
- return 0;
+ RETURN(0);
+again:
rc = mo_xattr_get(env, next, buf, XATTR_NAME_ACL_ACCESS);
if (rc < 0) {
if (rc == -ENODATA) {
} else if (rc == -EOPNOTSUPP) {
rc = 0;
} else {
+ if (rc == -ERANGE &&
+ exp_connect_large_acl(info->mti_exp) &&
+ buf->lb_buf != info->mti_big_acl) {
+ if (info->mti_big_acl == NULL) {
+ OBD_ALLOC_LARGE(info->mti_big_acl,
+ mdt->mdt_max_ea_size);
+ if (info->mti_big_acl == NULL) {
+ CERROR("%s: unable to grow "
+ DFID" ACL buffer\n",
+ mdt_obd_name(mdt),
+ PFID(mdt_object_fid(o)));
+ RETURN(-ENOMEM);
+ }
+
+ info->mti_big_aclsize =
+ mdt->mdt_max_ea_size;
+ }
+
+ CDEBUG(D_INODE, "%s: grow the "DFID
+ " ACL buffer to size %d\n",
+ mdt_obd_name(mdt),
+ PFID(mdt_object_fid(o)),
+ mdt->mdt_max_ea_size);
+
+ buf->lb_buf = info->mti_big_acl;
+ buf->lb_len = info->mti_big_aclsize;
+
+ goto again;
+ }
+
CERROR("%s: unable to read "DFID" ACL: rc = %d\n",
- mdt_obd_name(info->mti_mdt),
- PFID(mdt_object_fid(o)), rc);
+ mdt_obd_name(mdt), PFID(mdt_object_fid(o)), rc);
}
} else {
+ if (buf->lb_buf == info->mti_big_acl)
+ info->mti_big_acl_used = 1;
+
rc = nodemap_map_acl(nodemap, buf->lb_buf,
rc, NODEMAP_FS_TO_CLIENT);
/* if all ACLs mapped out, rc is still >= 0 */
if (rc < 0) {
CERROR("%s: nodemap_map_acl unable to parse "DFID
- " ACL: rc = %d\n", mdt_obd_name(info->mti_mdt),
+ " ACL: rc = %d\n", mdt_obd_name(mdt),
PFID(mdt_object_fid(o)), rc);
} else {
repbody->mbo_aclsize = rc;
rc = 0;
}
}
- return rc;
+
+ RETURN(rc);
}
#endif
req_capsule_set_size(pill, &RMF_MDT_MD, RCL_SERVER, rc);
+ /* Set ACL reply buffer size as LUSTRE_POSIX_ACL_MAX_SIZE_OLD
+ * by default. If the target object has more ACL entries, then
+ * enlarge the buffer when necessary. */
+ req_capsule_set_size(pill, &RMF_ACL, RCL_SERVER,
+ LUSTRE_POSIX_ACL_MAX_SIZE_OLD);
+
rc = req_capsule_server_pack(pill);
if (unlikely(rc != 0))
GOTO(out, rc = err_serious(rc));
int rc;
ENTRY;
+ CDEBUG(D_INFO, "got layout change request from client: "
+ "opc:%u flags:%#x extent[%#llx,%#llx)\n",
+ layout->li_opc, layout->li_flags,
+ layout->li_start, layout->li_end);
if (layout->li_start >= layout->li_end) {
CERROR("Recieved an invalid layout change range [%llu, %llu) "
"for "DFID"\n", layout->li_start, layout->li_end,
if (req_capsule_has_field(pill, &RMF_LOGCOOKIES, RCL_SERVER))
req_capsule_set_size(pill, &RMF_LOGCOOKIES, RCL_SERVER, 0);
+ /* Set ACL reply buffer size as LUSTRE_POSIX_ACL_MAX_SIZE_OLD
+ * by default. If the target object has more ACL entries, then
+ * enlarge the buffer when necessary. */
+ if (req_capsule_has_field(pill, &RMF_ACL, RCL_SERVER))
+ req_capsule_set_size(pill, &RMF_ACL, RCL_SERVER,
+ LUSTRE_POSIX_ACL_MAX_SIZE_OLD);
+
rc = req_capsule_server_pack(pill);
if (rc != 0) {
CERROR("Can't pack response, rc %d\n", rc);
NODEMAP_CLIENT_TO_FS, id);
break;
case GRPQUOTA:
- id = nodemap_map_id(nodemap, NODEMAP_UID,
+ id = nodemap_map_id(nodemap, NODEMAP_GID,
NODEMAP_CLIENT_TO_FS, id);
break;
case PRJQUOTA:
* \see ldlm_blocking_ast_nocheck
*/
int mdt_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
- void *data, int flag)
+ void *data, int flag)
{
- struct obd_device *obd = ldlm_lock_to_ns(lock)->ns_obd;
- struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
- int rc;
- ENTRY;
+ struct obd_device *obd = ldlm_lock_to_ns(lock)->ns_obd;
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ bool commit_async = false;
+ int rc;
+ ENTRY;
- if (flag == LDLM_CB_CANCELING)
- RETURN(0);
+ if (flag == LDLM_CB_CANCELING)
+ RETURN(0);
- lock_res_and_lock(lock);
- if (lock->l_blocking_ast != mdt_blocking_ast) {
- unlock_res_and_lock(lock);
- RETURN(0);
- }
+ lock_res_and_lock(lock);
+ if (lock->l_blocking_ast != mdt_blocking_ast) {
+ unlock_res_and_lock(lock);
+ RETURN(0);
+ }
+ /* There is no lock conflict if l_blocking_lock == NULL,
+ * it indicates a blocking ast sent from ldlm_lock_decref_internal
+ * when the last reference to a local lock was released */
if (lock->l_req_mode & (LCK_PW | LCK_EX) &&
lock->l_blocking_lock != NULL) {
- if (mdt_cos_is_enabled(mdt) &&
- lock->l_client_cookie !=
- lock->l_blocking_lock->l_client_cookie)
- mdt_set_lock_sync(lock);
- else if (mdt_slc_is_enabled(mdt) &&
- ldlm_is_cos_incompat(lock->l_blocking_lock))
+ if (mdt_cos_is_enabled(mdt)) {
+ if (lock->l_client_cookie !=
+ lock->l_blocking_lock->l_client_cookie)
+ mdt_set_lock_sync(lock);
+ } else if (mdt_slc_is_enabled(mdt) &&
+ ldlm_is_cos_incompat(lock->l_blocking_lock)) {
mdt_set_lock_sync(lock);
+ /*
+ * we may do extra commit here, but there is a small
+ * window to miss a commit: lock was unlocked (saved),
+ * then a conflict lock queued and we come here, but
+ * REP-ACK not received, so lock was not converted to
+ * COS mode yet.
+ * Fortunately this window is quite small, so the
+ * extra commit should be rare (not to say distributed
+ * operation is rare too).
+ */
+ commit_async = true;
+ }
+ } else if (lock->l_req_mode == LCK_COS &&
+ lock->l_blocking_lock != NULL) {
+ commit_async = true;
}
- rc = ldlm_blocking_ast_nocheck(lock);
- /* There is no lock conflict if l_blocking_lock == NULL,
- * it indicates a blocking ast sent from ldlm_lock_decref_internal
- * when the last reference to a local lock was released */
- if (lock->l_req_mode == LCK_COS && lock->l_blocking_lock != NULL) {
- struct lu_env env;
+ rc = ldlm_blocking_ast_nocheck(lock);
+
+ if (commit_async) {
+ struct lu_env env;
rc = lu_env_init(&env, LCT_LOCAL);
if (unlikely(rc != 0))
CWARN("%s: lu_env initialization failed, cannot "
"start asynchronous commit: rc = %d\n",
obd->obd_name, rc);
- else
- mdt_device_commit_async(&env, mdt);
- lu_env_fini(&env);
- }
- RETURN(rc);
+ else
+ mdt_device_commit_async(&env, mdt);
+ lu_env_fini(&env);
+ }
+ RETURN(rc);
}
/*
struct mdt_device *mdt = info->mti_mdt;
struct ldlm_lock *lock = ldlm_handle2lock(h);
struct ptlrpc_request *req = mdt_info_req(info);
- int cos;
-
- cos = (mdt_cos_is_enabled(mdt) ||
- mdt_slc_is_enabled(mdt));
+ bool cos = mdt_cos_is_enabled(mdt);
+ bool convert_lock = !cos && mdt_slc_is_enabled(mdt);
LASSERTF(lock != NULL, "no lock for cookie %#llx\n",
h->cookie);
/* there is no request if mdt_object_unlock() is called
* from mdt_export_cleanup()->mdt_add_dirty_flag() */
if (likely(req != NULL)) {
- CDEBUG(D_HA, "request = %p reply state = %p"
- " transno = %lld\n", req,
- req->rq_reply_state, req->rq_transno);
+ LDLM_DEBUG(lock, "save lock request %p reply "
+ "state %p transno %lld\n", req,
+ req->rq_reply_state, req->rq_transno);
if (cos) {
ldlm_lock_downgrade(lock, LCK_COS);
mode = LCK_COS;
}
- ptlrpc_save_lock(req, h, mode, cos);
+ ptlrpc_save_lock(req, h, mode, cos,
+ convert_lock);
} else {
mdt_fid_unlock(h, mode);
}
req_capsule_set_size(pill, &RMF_LOGCOOKIES,
RCL_SERVER, 0);
+ /* Set ACL reply buffer size as LUSTRE_POSIX_ACL_MAX_SIZE_OLD
+ * by default. If the target object has more ACL entries, then
+ * enlarge the buffer when necessary. */
+ if (req_capsule_has_field(pill, &RMF_ACL, RCL_SERVER))
+ req_capsule_set_size(pill, &RMF_ACL, RCL_SERVER,
+ LUSTRE_POSIX_ACL_MAX_SIZE_OLD);
+
rc = req_capsule_server_pack(pill);
}
RETURN(rc);
info->mti_cross_ref = 0;
info->mti_opdata = 0;
info->mti_big_lmm_used = 0;
+ info->mti_big_acl_used = 0;
info->mti_spec.no_create = 0;
info->mti_spec.sp_rm_entry = 0;
if (layout_change) {
struct lu_buf *buf = &info->mti_buf;
+ /**
+ * mdt_layout_change is a reint operation, when the request
+ * is resent, layout write shouldn't reprocess it again.
+ */
+ rc = mdt_check_resent(info, mdt_reconstruct_generic, lhc);
+ if (rc)
+ GOTO(out_obj, rc = rc < 0 ? rc : 0);
+
+ /**
+ * There is another resent case: the client's job has been
+ * done by another client, referring lod_declare_layout_change
+ * -EALREADY case, and it became a operation w/o transaction,
+ * so we should not do the layout change, otherwise
+ * mdt_layout_change() will try to cancel the granted server
+ * CR lock whose remote counterpart is still in hold on the
+ * client, and a deadlock ensues.
+ */
+ rc = mdt_check_resent_lock(info, obj, lhc);
+ if (rc <= 0)
+ GOTO(out_obj, rc);
+
buf->lb_buf = NULL;
buf->lb_len = 0;
if (unlikely(req_is_replay(mdt_info_req(info)))) {
if (!mdt->mdt_opts.mo_user_xattr)
data->ocd_connect_flags &= ~OBD_CONNECT_XATTR;
- if (data->ocd_connect_flags & OBD_CONNECT_BRW_SIZE) {
- data->ocd_brw_size = min(data->ocd_brw_size,
- (__u32)MD_MAX_BRW_SIZE);
+ if (OCD_HAS_FLAG(data, BRW_SIZE)) {
+ data->ocd_brw_size = min(data->ocd_brw_size, MD_MAX_BRW_SIZE);
if (data->ocd_brw_size == 0) {
- CERROR("%s: cli %s/%p ocd_connect_flags: %#llx"
- " ocd_version: %x ocd_grant: %d "
- "ocd_index: %u ocd_brw_size is "
- "unexpectedly zero, network data "
- "corruption? Refusing connection of this"
- " client\n",
+ CERROR("%s: cli %s/%p ocd_connect_flags: %#llx "
+ "ocd_version: %x ocd_grant: %d ocd_index: %u "
+ "ocd_brw_size unexpectedly zero, network data "
+ "corruption? Refusing to connect this client\n",
mdt_obd_name(mdt),
exp->exp_client_uuid.uuid,
exp, data->ocd_connect_flags, data->ocd_version,
rc = mdt_ctxt_add_dirty_flag(&env, info, mfd);
/* Don't unlink orphan on failover umount, LU-184 */
- if (exp->exp_flags & OBD_OPT_FAILOVER) {
+ if (exp->exp_obd->obd_fail) {
ma->ma_valid = MA_FLAGS;
ma->ma_attr_flags |= MDS_KEEP_ORPHAN;
}
}
info->mti_mdt = NULL;
/* cleanup client slot early */
- /* Do not erase record for recoverable client. */
- if (!(exp->exp_flags & OBD_OPT_FAILOVER) || exp->exp_failed)
- tgt_client_del(&env, exp);
+ tgt_client_del(&env, exp);
lu_env_fini(&env);
RETURN(rc);
info->mti_big_lmm = NULL;
info->mti_big_lmmsize = 0;
}
+
+ if (info->mti_big_acl) {
+ OBD_FREE_LARGE(info->mti_big_acl, info->mti_big_aclsize);
+ info->mti_big_acl = NULL;
+ info->mti_big_aclsize = 0;
+ }
+
OBD_FREE_PTR(info);
}