OBD_CONNECT_SOM | OBD_CONNECT_FULL20 | \
OBD_CONNECT_64BITHASH | OBD_CONNECT_JOBSTATS | \
OBD_CONNECT_EINPROGRESS | \
- OBD_CONNECT_LIGHTWEIGHT | OBD_CONNECT_UMASK)
+ OBD_CONNECT_LIGHTWEIGHT | OBD_CONNECT_UMASK | \
+ OBD_CONNECT_LVB_TYPE)
#define OST_CONNECT_SUPPORTED (OBD_CONNECT_SRVLOCK | OBD_CONNECT_GRANT | \
OBD_CONNECT_REQPORTAL | OBD_CONNECT_VERSION | \
OBD_CONNECT_TRUNCLOCK | OBD_CONNECT_INDEX | \
OBD_CONNECT_64BITHASH | OBD_CONNECT_MAXBYTES | \
OBD_CONNECT_MAX_EASIZE | \
OBD_CONNECT_EINPROGRESS | \
- OBD_CONNECT_JOBSTATS | OBD_CONNECT_LIGHTWEIGHT)
+ OBD_CONNECT_JOBSTATS | \
+ OBD_CONNECT_LIGHTWEIGHT | OBD_CONNECT_LVB_TYPE)
#define ECHO_CONNECT_SUPPORTED (0)
#define MGS_CONNECT_SUPPORTED (OBD_CONNECT_VERSION | OBD_CONNECT_AT | \
OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV | \
do { blocks = OST_LVB_ERR_INIT + rc; } while (0)
#define OST_LVB_GET_ERR(blocks) (int)(blocks - OST_LVB_ERR_INIT)
+struct ost_lvb_v1 {
+ __u64 lvb_size;
+ obd_time lvb_mtime;
+ obd_time lvb_atime;
+ obd_time lvb_ctime;
+ __u64 lvb_blocks;
+};
+
+extern void lustre_swab_ost_lvb_v1(struct ost_lvb_v1 *lvb);
+
struct ost_lvb {
- __u64 lvb_size;
- obd_time lvb_mtime;
- obd_time lvb_atime;
- obd_time lvb_ctime;
- __u64 lvb_blocks;
+ __u64 lvb_size;
+ obd_time lvb_mtime;
+ obd_time lvb_atime;
+ obd_time lvb_ctime;
+ __u64 lvb_blocks;
+ __u32 lvb_mtime_ns;
+ __u32 lvb_atime_ns;
+ __u32 lvb_ctime_ns;
+ __u32 lvb_padding;
};
+extern void lustre_swab_ost_lvb(struct ost_lvb *lvb);
+
/*
* lquota data structures
*/
__u64 lvb_pad1;
};
+extern void lustre_swab_lquota_lvb(struct lquota_lvb *lvb);
+
/* LVB used with global quota lock */
#define lvb_glb_ver lvb_id_may_rel /* current version of the global index */
extern void lustre_swab_ldlm_policy_data (ldlm_wire_policy_data_t *d);
-/* Similarly to ldlm_wire_policy_data_t, there is one common swabber for all
- * LVB types. As a result, any new LVB structure must match the fields of the
- * ost_lvb structure. */
-union ldlm_wire_lvb {
- struct ost_lvb l_ost;
- struct lquota_lvb l_lquota;
-};
-
-extern void lustre_swab_lvb(union ldlm_wire_lvb *);
-
union ldlm_gl_desc {
struct ldlm_gl_lquota_desc lquota_desc;
};
const ldlm_wire_policy_data_t *wpolicy,
ldlm_policy_data_t *lpolicy);
+enum lvb_type {
+ LVB_T_NONE = 0,
+ LVB_T_OST = 1,
+ LVB_T_LQUOTA = 2,
+ LVB_T_LAYOUT = 3,
+};
+
struct ldlm_lock {
/**
* Must be first in the structure.
* Client-side-only members.
*/
+ enum lvb_type l_lvb_type;
/**
* Temporary storage for an LVB received during an enqueue operation.
*/
struct ldlm_enqueue_info *einfo,
const struct ldlm_res_id *res_id,
ldlm_policy_data_t const *policy, __u64 *flags,
- void *lvb, __u32 lvb_len, struct lustre_handle *lockh,
- int async);
+ void *lvb, __u32 lvb_len, enum lvb_type lvb_type,
+ struct lustre_handle *lockh, int async);
int ldlm_prep_enqueue_req(struct obd_export *exp,
struct ptlrpc_request *req,
cfs_list_t *cancels,
ldlm_blocking_callback blocking,
ldlm_completion_callback completion,
ldlm_glimpse_callback glimpse,
- void *data, __u32 lvb_len,
+ void *data, __u32 lvb_len, enum lvb_type lvb_type,
const __u64 *client_cookie,
struct lustre_handle *lockh);
int ldlm_server_ast(struct lustre_handle *lockh, struct ldlm_lock_desc *new,
return !!(ocd->ocd_connect_flags & OBD_CONNECT_LRU_RESIZE);
}
+static inline bool exp_connect_lvb_type(struct obd_export *exp)
+{
+ LASSERT(exp != NULL);
+ if (exp->exp_connect_flags & OBD_CONNECT_LVB_TYPE)
+ return true;
+ else
+ return false;
+}
+
+static inline bool imp_connect_lvb_type(struct obd_import *imp)
+{
+ struct obd_connect_data *ocd;
+
+ LASSERT(imp != NULL);
+ ocd = &imp->imp_connect_data;
+ if (ocd->ocd_connect_flags & OBD_CONNECT_LVB_TYPE)
+ return true;
+ else
+ return false;
+}
+
extern struct obd_export *class_conn2export(struct lustre_handle *conn);
extern struct obd_device *class_conn2obd(struct lustre_handle *conn);
void *req_capsule_client_get(struct req_capsule *pill,
const struct req_msg_field *field);
void *req_capsule_client_swab_get(struct req_capsule *pill,
- const struct req_msg_field *field,
- void (*swabber)(void*));
+ const struct req_msg_field *field,
+ void *swabber);
void *req_capsule_client_sized_get(struct req_capsule *pill,
const struct req_msg_field *field,
int len);
void *req_capsule_server_swab_get(struct req_capsule *pill,
const struct req_msg_field *field,
void *swabber);
+void *req_capsule_server_sized_swab_get(struct req_capsule *pill,
+ const struct req_msg_field *field,
+ int len, void *swabber);
const void *req_capsule_other_get(struct req_capsule *pill,
const struct req_msg_field *field);
* and restart processing this lock. */
if (!new2) {
unlock_res_and_lock(req);
- new2 = ldlm_lock_create(ns, &res->lr_name, LDLM_FLOCK,
- lock->l_granted_mode, &null_cbs,
- NULL, 0);
+ new2 = ldlm_lock_create(ns, &res->lr_name, LDLM_FLOCK,
+ lock->l_granted_mode, &null_cbs,
+ NULL, 0, LVB_T_NONE);
lock_res_and_lock(req);
if (!new2) {
ldlm_flock_destroy(req, lock->l_granted_mode,
} ldlm_desc_ast_t;
void ldlm_grant_lock(struct ldlm_lock *lock, cfs_list_t *work_list);
+int ldlm_fill_lvb(struct ldlm_lock *lock, struct req_capsule *pill,
+ enum req_location loc, void *data, int size);
struct ldlm_lock *
ldlm_lock_create(struct ldlm_namespace *ns, const struct ldlm_res_id *,
ldlm_type_t type, ldlm_mode_t,
const struct ldlm_callback_suite *cbs,
- void *data, __u32 lvb_len);
+ void *data, __u32 lvb_len, enum lvb_type lvb_type);
ldlm_error_t ldlm_lock_enqueue(struct ldlm_namespace *, struct ldlm_lock **,
void *cookie, __u64 *flags);
void ldlm_lock_addref_internal(struct ldlm_lock *, __u32 mode);
}
EXPORT_SYMBOL(ldlm_revalidate_lock_handle);
+/* The caller's duty to guarantee the buffer is large enough. */
+int ldlm_fill_lvb(struct ldlm_lock *lock, struct req_capsule *pill,
+ enum req_location loc, void *data, int size)
+{
+ void *lvb;
+ ENTRY;
+
+ LASSERT(data != NULL);
+ LASSERT(size >= 0);
+
+ switch (lock->l_lvb_type) {
+ case LVB_T_OST:
+ if (size == sizeof(struct ost_lvb)) {
+ if (loc == RCL_CLIENT)
+ lvb = req_capsule_client_swab_get(pill,
+ &RMF_DLM_LVB,
+ lustre_swab_ost_lvb);
+ else
+ lvb = req_capsule_server_swab_get(pill,
+ &RMF_DLM_LVB,
+ lustre_swab_ost_lvb);
+ if (unlikely(lvb == NULL)) {
+ LDLM_ERROR(lock, "no LVB");
+ RETURN(-EPROTO);
+ }
+
+ memcpy(data, lvb, size);
+ } else if (size == sizeof(struct ost_lvb_v1)) {
+ struct ost_lvb *olvb = data;
+
+ if (loc == RCL_CLIENT)
+ lvb = req_capsule_client_swab_get(pill,
+ &RMF_DLM_LVB,
+ lustre_swab_ost_lvb_v1);
+ else
+ lvb = req_capsule_server_sized_swab_get(pill,
+ &RMF_DLM_LVB, size,
+ lustre_swab_ost_lvb_v1);
+ if (unlikely(lvb == NULL)) {
+ LDLM_ERROR(lock, "no LVB");
+ RETURN(-EPROTO);
+ }
+
+ memcpy(data, lvb, size);
+ olvb->lvb_mtime_ns = 0;
+ olvb->lvb_atime_ns = 0;
+ olvb->lvb_ctime_ns = 0;
+ } else {
+ LDLM_ERROR(lock, "Replied unexpected ost LVB size %d",
+ size);
+ RETURN(-EINVAL);
+ }
+ break;
+ case LVB_T_LQUOTA:
+ if (size == sizeof(struct lquota_lvb)) {
+ if (loc == RCL_CLIENT)
+ lvb = req_capsule_client_swab_get(pill,
+ &RMF_DLM_LVB,
+ lustre_swab_lquota_lvb);
+ else
+ lvb = req_capsule_server_swab_get(pill,
+ &RMF_DLM_LVB,
+ lustre_swab_lquota_lvb);
+ if (unlikely(lvb == NULL)) {
+ LDLM_ERROR(lock, "no LVB");
+ RETURN(-EPROTO);
+ }
+
+ memcpy(data, lvb, size);
+ } else {
+ LDLM_ERROR(lock, "Replied unexpected lquota LVB size %d",
+ size);
+ RETURN(-EINVAL);
+ }
+ break;
+ case LVB_T_LAYOUT:
+ if (size == 0)
+ break;
+
+ if (loc == RCL_CLIENT)
+ lvb = req_capsule_client_get(pill, &RMF_DLM_LVB);
+ else
+ lvb = req_capsule_server_get(pill, &RMF_DLM_LVB);
+ if (unlikely(lvb == NULL)) {
+ LDLM_ERROR(lock, "no LVB");
+ RETURN(-EPROTO);
+ }
+
+ memcpy(data, lvb, size);
+ break;
+ default:
+ LDLM_ERROR(lock, "Unexpected LVB type");
+ RETURN(-EINVAL);
+ }
+
+ RETURN(0);
+}
+
/* Returns a referenced lock */
struct ldlm_lock *ldlm_lock_create(struct ldlm_namespace *ns,
const struct ldlm_res_id *res_id,
ldlm_type_t type,
ldlm_mode_t mode,
const struct ldlm_callback_suite *cbs,
- void *data, __u32 lvb_len)
+ void *data, __u32 lvb_len,
+ enum lvb_type lvb_type)
{
struct ldlm_lock *lock;
struct ldlm_resource *res;
GOTO(out, 0);
}
+ lock->l_lvb_type = lvb_type;
if (OBD_FAIL_CHECK(OBD_FAIL_LDLM_NEW_LOCK))
GOTO(out, 0);
libcfs_debug_vmsg2(msgdata, fmt, args,
" ns: \?\? lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
"res: \?\? rrc=\?\? type: \?\?\? flags: "LPX64" nid: %s "
- "remote: "LPX64" expref: %d pid: %u timeout: %lu\n",
+ "remote: "LPX64" expref: %d pid: %u timeout: %lu "
+ "lvb_type: %d\n",
lock,
lock->l_handle.h_cookie, cfs_atomic_read(&lock->l_refc),
lock->l_readers, lock->l_writers,
ldlm_lockname[lock->l_req_mode],
lock->l_flags, nid, lock->l_remote_handle.cookie,
exp ? cfs_atomic_read(&exp->exp_refcount) : -99,
- lock->l_pid, lock->l_callback_timeout);
+ lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type);
va_end(args);
return;
}
" ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
"res: "LPU64"/"LPU64" rrc: %d type: %s ["LPU64"->"LPU64
"] (req "LPU64"->"LPU64") flags: "LPX64" nid: %s remote:"
- " "LPX64" expref: %d pid: %u timeout %lu\n",
+ " "LPX64" expref: %d pid: %u timeout: %lu lvb_type: %d\n",
ldlm_lock_to_ns_name(lock), lock,
lock->l_handle.h_cookie, cfs_atomic_read(&lock->l_refc),
lock->l_readers, lock->l_writers,
lock->l_req_extent.start, lock->l_req_extent.end,
lock->l_flags, nid, lock->l_remote_handle.cookie,
exp ? cfs_atomic_read(&exp->exp_refcount) : -99,
- lock->l_pid, lock->l_callback_timeout);
+ lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type);
break;
case LDLM_FLOCK:
" ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
"res: "LPU64"/"LPU64" bits "LPX64" rrc: %d type: %s "
"flags: "LPX64" nid: %s remote: "LPX64" expref: %d "
- "pid: %u timeout: %lu\n",
+ "pid: %u timeout: %lu lvb_type: %d\n",
ldlm_lock_to_ns_name(lock),
lock, lock->l_handle.h_cookie,
cfs_atomic_read (&lock->l_refc),
ldlm_typename[resource->lr_type],
lock->l_flags, nid, lock->l_remote_handle.cookie,
exp ? cfs_atomic_read(&exp->exp_refcount) : -99,
- lock->l_pid, lock->l_callback_timeout);
+ lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type);
break;
default:
libcfs_debug_vmsg2(msgdata, fmt, args,
" ns: %s lock: %p/"LPX64" lrc: %d/%d,%d mode: %s/%s "
"res: "LPU64"/"LPU64" rrc: %d type: %s flags: "LPX64" "
- "nid: %s remote: "LPX64" expref: %d pid: %u timeout %lu"
- "\n",
+ "nid: %s remote: "LPX64" expref: %d pid: %u timeout: %lu"
+ "lvb_type: %d\n",
ldlm_lock_to_ns_name(lock),
lock, lock->l_handle.h_cookie,
cfs_atomic_read (&lock->l_refc),
ldlm_typename[resource->lr_type],
lock->l_flags, nid, lock->l_remote_handle.cookie,
exp ? cfs_atomic_read(&exp->exp_refcount) : -99,
- lock->l_pid, lock->l_callback_timeout);
+ lock->l_pid, lock->l_callback_timeout, lock->l_lvb_type);
break;
}
va_end(args);
/* server namespace, doesn't need lock */
lvb_len = ldlm_lvbo_size(lock);
- if (lvb_len > 0)
- req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_CLIENT,
- lvb_len);
-
+ req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_CLIENT, lvb_len);
rc = ptlrpc_request_pack(req, LUSTRE_DLM_VERSION, LDLM_CP_CALLBACK);
if (rc) {
ptlrpc_request_free(req);
lock = ldlm_lock_create(ns, &dlm_req->lock_desc.l_resource.lr_name,
dlm_req->lock_desc.l_resource.lr_type,
dlm_req->lock_desc.l_req_mode,
- cbs, NULL, 0);
-
+ cbs, NULL, 0, LVB_T_NONE);
if (!lock)
GOTO(out, rc = -ENOMEM);
{
int lvb_len;
CFS_LIST_HEAD(ast_list);
+ int rc = 0;
ENTRY;
LDLM_DEBUG(lock, "client completion callback handler START");
}
lvb_len = req_capsule_get_size(&req->rq_pill, &RMF_DLM_LVB, RCL_CLIENT);
- if (lvb_len > 0) {
+ if (lvb_len < 0) {
+ LDLM_ERROR(lock, "Fail to get lvb_len, rc = %d", lvb_len);
+ GOTO(out, rc = lvb_len);
+ } else if (lvb_len > 0) {
if (lock->l_lvb_len > 0) {
/* for extent lock, lvb contains ost_lvb{}. */
LASSERT(lock->l_lvb_data != NULL);
- LASSERTF(lock->l_lvb_len == lvb_len,
- "preallocated %d, actual %d.\n",
- lock->l_lvb_len, lvb_len);
+
+ if (unlikely(lock->l_lvb_len < lvb_len)) {
+ LDLM_ERROR(lock, "Replied LVB is larger than "
+ "expectation, expected = %d, "
+ "replied = %d",
+ lock->l_lvb_len, lvb_len);
+ GOTO(out, rc = -EINVAL);
+ }
} else { /* for layout lock, lvb has variable length */
void *lvb_data;
OBD_ALLOC(lvb_data, lvb_len);
- if (lvb_data == NULL)
- LDLM_ERROR(lock, "no memory.\n");
-
- lock_res_and_lock(lock);
if (lvb_data == NULL) {
- lock->l_flags |= LDLM_FL_FAILED;
- } else {
- LASSERT(lock->l_lvb_data == NULL);
- lock->l_lvb_data = lvb_data;
- lock->l_lvb_len = lvb_len;
+ LDLM_ERROR(lock, "No memory.\n");
+ GOTO(out, rc = -ENOMEM);
}
+
+ lock_res_and_lock(lock);
+ LASSERT(lock->l_lvb_data == NULL);
+ lock->l_lvb_data = lvb_data;
+ lock->l_lvb_len = lvb_len;
unlock_res_and_lock(lock);
}
}
/* bug 11300: the lock has already been granted */
unlock_res_and_lock(lock);
LDLM_DEBUG(lock, "Double grant race happened");
- LDLM_LOCK_RELEASE(lock);
- EXIT;
- return;
+ GOTO(out, rc = 0);
}
/* If we receive the completion AST before the actual enqueue returned,
&lock->l_resource->lr_name,
sizeof(lock->l_resource->lr_name)) != 0) {
unlock_res_and_lock(lock);
- if (ldlm_lock_change_resource(ns, lock,
- &dlm_req->lock_desc.l_resource.lr_name) != 0) {
- LDLM_ERROR(lock, "Failed to allocate resource");
- LDLM_LOCK_RELEASE(lock);
- EXIT;
- return;
- }
+ rc = ldlm_lock_change_resource(ns, lock,
+ &dlm_req->lock_desc.l_resource.lr_name);
+ if (rc < 0) {
+ LDLM_ERROR(lock, "Failed to allocate resource");
+ GOTO(out, rc);
+ }
LDLM_DEBUG(lock, "completion AST, new resource");
CERROR("change resource!\n");
lock_res_and_lock(lock);
LDLM_DEBUG(lock, "completion AST includes blocking AST");
}
- if (lock->l_lvb_len) {
- if (req_capsule_get_size(&req->rq_pill, &RMF_DLM_LVB,
- RCL_CLIENT) < lock->l_lvb_len) {
- LDLM_ERROR(lock, "completion AST did not contain "
- "expected LVB!");
- } else {
- void *lvb = req_capsule_client_get(&req->rq_pill,
- &RMF_DLM_LVB);
- memcpy(lock->l_lvb_data, lvb, lock->l_lvb_len);
- }
- }
+ if (lock->l_lvb_len > 0) {
+ rc = ldlm_fill_lvb(lock, &req->rq_pill, RCL_CLIENT,
+ lock->l_lvb_data, lvb_len);
+ if (rc < 0) {
+ unlock_res_and_lock(lock);
+ GOTO(out, rc);
+ }
+ }
ldlm_grant_lock(lock, &ast_list);
unlock_res_and_lock(lock);
LDLM_DEBUG_NOLOCK("client completion callback handler END (lock %p)",
lock);
- LDLM_LOCK_RELEASE(lock);
- EXIT;
+ GOTO(out, rc);
+
+out:
+ if (rc < 0) {
+ lock_res_and_lock(lock);
+ lock->l_flags |= LDLM_FL_FAILED;
+ unlock_res_and_lock(lock);
+ }
+ LDLM_LOCK_RELEASE(lock);
}
static void ldlm_handle_gl_callback(struct ptlrpc_request *req,
ldlm_blocking_callback blocking,
ldlm_completion_callback completion,
ldlm_glimpse_callback glimpse,
- void *data, __u32 lvb_len,
+ void *data, __u32 lvb_len, enum lvb_type lvb_type,
const __u64 *client_cookie,
struct lustre_handle *lockh)
{
LBUG();
}
- lock = ldlm_lock_create(ns, res_id, type, mode, &cbs, data, lvb_len);
+ lock = ldlm_lock_create(ns, res_id, type, mode, &cbs, data, lvb_len,
+ lvb_type);
if (unlikely(!lock))
GOTO(out_nolock, err = -ENOMEM);
int is_replay = *flags & LDLM_FL_REPLAY;
struct ldlm_lock *lock;
struct ldlm_reply *reply;
- struct ost_lvb *tmplvb;
int cleanup_phase = 1;
+ int size = 0;
ENTRY;
lock = ldlm_handle2lock(lockh);
RETURN(-ENOLCK);
}
+ LASSERTF(ergo(lvb_len != 0, lvb_len == lock->l_lvb_len),
+ "lvb_len = %d, l_lvb_len = %d\n", lvb_len, lock->l_lvb_len);
+
if (rc != ELDLM_OK) {
LASSERT(!is_replay);
LDLM_DEBUG(lock, "client-side enqueue END (%s)",
rc == ELDLM_LOCK_ABORTED ? "ABORTED" : "FAILED");
- if (rc == ELDLM_LOCK_ABORTED) {
- /* Before we return, swab the reply */
- reply = req_capsule_server_get(&req->rq_pill,
- &RMF_DLM_REP);
- if (reply == NULL)
- rc = -EPROTO;
- if (lvb_len) {
-
- req_capsule_set_size(&req->rq_pill,
- &RMF_DLM_LVB, RCL_SERVER,
- lvb_len);
- tmplvb = req_capsule_server_get(&req->rq_pill,
- &RMF_DLM_LVB);
- if (tmplvb == NULL)
- GOTO(cleanup, rc = -EPROTO);
- if (lvb != NULL)
- memcpy(lvb, tmplvb, lvb_len);
- }
- }
- GOTO(cleanup, rc);
- }
- reply = req_capsule_server_get(&req->rq_pill, &RMF_DLM_REP);
- if (reply == NULL)
- GOTO(cleanup, rc = -EPROTO);
+ if (rc != ELDLM_LOCK_ABORTED)
+ GOTO(cleanup, rc);
+ }
+
+ /* Before we return, swab the reply */
+ reply = req_capsule_server_get(&req->rq_pill, &RMF_DLM_REP);
+ if (reply == NULL)
+ GOTO(cleanup, rc = -EPROTO);
+
+ if (lvb_len != 0) {
+ LASSERT(lvb != NULL);
+
+ size = req_capsule_get_size(&req->rq_pill, &RMF_DLM_LVB,
+ RCL_SERVER);
+ if (size < 0) {
+ LDLM_ERROR(lock, "Fail to get lvb_len, rc = %d", size);
+ GOTO(cleanup, rc = size);
+ } else if (unlikely(size > lvb_len)) {
+ LDLM_ERROR(lock, "Replied LVB is larger than "
+ "expectation, expected = %d, replied = %d",
+ lvb_len, size);
+ GOTO(cleanup, rc = -EINVAL);
+ }
+ }
+
+ if (rc == ELDLM_LOCK_ABORTED) {
+ if (lvb_len != 0)
+ rc = ldlm_fill_lvb(lock, &req->rq_pill, RCL_SERVER,
+ lvb, size);
+ GOTO(cleanup, rc = (rc != 0 ? rc : ELDLM_LOCK_ABORTED));
+ }
/* lock enqueued on the server */
cleanup_phase = 0;
/* If the lock has already been granted by a completion AST, don't
* clobber the LVB with an older one. */
- if (lvb_len) {
- /* We must lock or a racing completion might update lvb
- without letting us know and we'll clobber the correct value.
- Cannot unlock after the check either, a that still leaves
- a tiny window for completion to get in */
- lock_res_and_lock(lock);
- if (lock->l_req_mode != lock->l_granted_mode) {
-
- req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB,
- RCL_SERVER, lvb_len);
- tmplvb = req_capsule_server_get(&req->rq_pill,
- &RMF_DLM_LVB);
- if (tmplvb == NULL) {
- unlock_res_and_lock(lock);
- GOTO(cleanup, rc = -EPROTO);
- }
- memcpy(lock->l_lvb_data, tmplvb, lvb_len);
- }
- unlock_res_and_lock(lock);
+ if (lvb_len != 0) {
+ /* We must lock or a racing completion might update lvb without
+ * letting us know and we'll clobber the correct value.
+ * Cannot unlock after the check either, a that still leaves
+ * a tiny window for completion to get in */
+ lock_res_and_lock(lock);
+ if (lock->l_req_mode != lock->l_granted_mode)
+ rc = ldlm_fill_lvb(lock, &req->rq_pill, RCL_SERVER,
+ lock->l_lvb_data, size);
+ unlock_res_and_lock(lock);
+ if (rc < 0)
+ GOTO(cleanup, rc);
}
if (!is_replay) {
struct ldlm_enqueue_info *einfo,
const struct ldlm_res_id *res_id,
ldlm_policy_data_t const *policy, __u64 *flags,
- void *lvb, __u32 lvb_len, struct lustre_handle *lockh,
- int async)
+ void *lvb, __u32 lvb_len, enum lvb_type lvb_type,
+ struct lustre_handle *lockh, int async)
{
struct ldlm_namespace *ns = exp->exp_obd->obd_namespace;
struct ldlm_lock *lock;
};
lock = ldlm_lock_create(ns, res_id, einfo->ei_type,
einfo->ei_mode, &cbs, einfo->ei_cbdata,
- lvb_len);
+ lvb_len, lvb_type);
if (lock == NULL)
RETURN(-ENOMEM);
/* for the local lock, add the reference */
/* Continue as normal. */
if (!req_passed_in) {
- if (lvb_len > 0) {
- req_capsule_extend(&req->rq_pill,
- &RQF_LDLM_ENQUEUE_LVB);
- req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB,
- RCL_SERVER, lvb_len);
- }
- ptlrpc_request_set_replen(req);
+ if (lvb_len > 0)
+ req_capsule_extend(&req->rq_pill,
+ &RQF_LDLM_ENQUEUE_LVB);
+ req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
+ lvb_len);
+ ptlrpc_request_set_replen(req);
}
/*
ldlm_lock_cancel(lock);
RETURN(0);
}
+
/*
* If granted mode matches the requested mode, this lock is granted.
*
body->lock_flags = ldlm_flags_to_wire(flags);
ldlm_lock2handle(lock, &body->lock_handle[0]);
- if (lock->l_lvb_len != 0) {
- req_capsule_extend(&req->rq_pill, &RQF_LDLM_ENQUEUE_LVB);
- req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
- lock->l_lvb_len);
- }
+ if (lock->l_lvb_len > 0)
+ req_capsule_extend(&req->rq_pill, &RQF_LDLM_ENQUEUE_LVB);
+ req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
+ lock->l_lvb_len);
ptlrpc_request_set_replen(req);
/* notify the server we've replayed all requests.
* also, we mark the request to be put on a dedicated
GOTO(iput, rc = -ELDLM_NO_LOCK_DATA);
req_capsule_extend(&req->rq_pill, &RQF_LDLM_GL_CALLBACK);
- req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
- sizeof(*lvb));
+ if (exp_connect_lvb_type(req->rq_export))
+ req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
+ sizeof(*lvb));
+ else
+ req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
+ sizeof(struct ost_lvb_v1));
rc = req_capsule_server_pack(&req->rq_pill);
if (rc) {
CERROR("failed pack reply: %d\n", rc);
RETURN(rc = -ENODEV);
if (lmv->tgts[0].ltd_exp != NULL)
- rc = ldlm_cli_enqueue(lmv->tgts[0].ltd_exp, NULL, &einfo, &res_id,
- &flock, &flags, NULL, 0, &lockh, 0);
+ rc = ldlm_cli_enqueue(lmv->tgts[0].ltd_exp, NULL,
+ &einfo, &res_id, &flock, &flags,
+ NULL, 0, LVB_T_NONE, &lockh, 0);
else
rc = -ENODEV;
}
ocd.ocd_connect_flags = OBD_CONNECT_IBITS | OBD_CONNECT_VERSION |
OBD_CONNECT_FID | OBD_CONNECT_AT |
- OBD_CONNECT_VBR | OBD_CONNECT_FULL20;
+ OBD_CONNECT_VBR | OBD_CONNECT_FULL20 |
+ OBD_CONNECT_LVB_TYPE;
#ifdef LIBLUSTRE_POSIX_ACL
ocd.ocd_connect_flags |= OBD_CONNECT_ACL;
ocd.ocd_connect_flags = OBD_CONNECT_SRVLOCK | OBD_CONNECT_REQPORTAL |
OBD_CONNECT_VERSION | OBD_CONNECT_TRUNCLOCK |
OBD_CONNECT_FID | OBD_CONNECT_AT |
- OBD_CONNECT_FULL20 | OBD_CONNECT_EINPROGRESS;
+ OBD_CONNECT_FULL20 | OBD_CONNECT_EINPROGRESS |
+ OBD_CONNECT_LVB_TYPE;
ocd.ocd_version = LUSTRE_VERSION_CODE;
err = obd_connect(NULL, &sbi->ll_dt_exp, obd, &sbi->ll_sb_uuid, &ocd, NULL);
OBD_CONNECT_RMT_CLIENT | OBD_CONNECT_VBR |
OBD_CONNECT_FULL20 | OBD_CONNECT_64BITHASH|
OBD_CONNECT_EINPROGRESS |
- OBD_CONNECT_JOBSTATS;
+ OBD_CONNECT_JOBSTATS | OBD_CONNECT_LVB_TYPE;
if (sbi->ll_flags & LL_SBI_SOM_PREVIEW)
data->ocd_connect_flags |= OBD_CONNECT_SOM;
OBD_CONNECT_FULL20 | OBD_CONNECT_64BITHASH |
OBD_CONNECT_MAXBYTES |
OBD_CONNECT_EINPROGRESS |
- OBD_CONNECT_JOBSTATS;
+ OBD_CONNECT_JOBSTATS | OBD_CONNECT_LVB_TYPE;
if (sbi->ll_flags & LL_SBI_SOM_PREVIEW)
data->ocd_connect_flags |= OBD_CONNECT_SOM;
RETURN(req);
}
-static struct ptlrpc_request *ldlm_enqueue_pack(struct obd_export *exp)
+static struct ptlrpc_request *
+mdc_enqueue_pack(struct obd_export *exp, int lvb_len)
{
struct ptlrpc_request *req;
int rc;
RETURN(ERR_PTR(rc));
}
+ req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER, lvb_len);
ptlrpc_request_set_replen(req);
RETURN(req);
}
void *lvb;
void *lmm;
- lvb = req_capsule_server_get(pill,
- &RMF_DLM_LVB);
+ lvb = req_capsule_server_sized_get(pill,
+ &RMF_DLM_LVB, lvb_len);
if (lvb == NULL) {
LDLM_LOCK_PUT(lock);
RETURN(-EPROTO);
ldlm_policy_data_t const *policy = &lookup_policy;
int generation, resends = 0;
struct ldlm_reply *lockrep;
+ enum lvb_type lvb_type = 0;
ENTRY;
LASSERTF(!it || einfo->ei_type == LDLM_IBITS, "lock type %d\n",
policy = &update_policy;
einfo->ei_cbdata = NULL;
lmm = NULL;
- } else if (it->it_op & IT_UNLINK)
- req = mdc_intent_unlink_pack(exp, it, op_data);
- else if (it->it_op & (IT_GETATTR | IT_LOOKUP))
+ } else if (it->it_op & IT_UNLINK) {
+ req = mdc_intent_unlink_pack(exp, it, op_data);
+ } else if (it->it_op & (IT_GETATTR | IT_LOOKUP)) {
req = mdc_intent_getattr_pack(exp, it, op_data);
- else if (it->it_op & (IT_READDIR | IT_LAYOUT))
- req = ldlm_enqueue_pack(exp);
- else {
+ } else if (it->it_op & IT_READDIR) {
+ req = mdc_enqueue_pack(exp, 0);
+ } else if (it->it_op & IT_LAYOUT) {
+ if (!imp_connect_lvb_type(class_exp2cliimp(exp)))
+ RETURN(-EOPNOTSUPP);
+
+ req = mdc_enqueue_pack(exp, obddev->u.cli.cl_max_mds_easize);
+ lvb_type = LVB_T_LAYOUT;
+ } else {
LBUG();
RETURN(-EINVAL);
}
}
rc = ldlm_cli_enqueue(exp, &req, einfo, &res_id, policy, &flags, NULL,
- 0, lockh, 0);
+ 0, lvb_type, lockh, 0);
if (!it) {
/* For flock requests we immediatelly return without further
delay and let caller deal with the rest, since rest of
}
rc = ldlm_cli_enqueue(exp, &req, einfo, &res_id, &policy, &flags, NULL,
- 0, &minfo->mi_lockh, 1);
+ 0, LVB_T_NONE, &minfo->mi_lockh, 1);
if (rc < 0) {
mdc_exit_request(&obddev->u.cli);
ptlrpc_req_finished(req);
if (qmt == NULL)
RETURN(-EOPNOTSUPP);
+ (*lockp)->l_lvb_type = LVB_T_LQUOTA;
/* pass the request to quota master */
rc = qmt_hdls.qmth_intent_policy(info->mti_env, qmt,
mdt_info_req(info), lockp,
RETURN(rc);
}
+ if (opc == MDT_IT_LAYOUT) {
+ (*lockp)->l_lvb_type = LVB_T_LAYOUT;
+ /* XXX: set replay RMF_DLM_LVB as the real EA size when LAYOUT
+ * lock enabled. */
+ } else if (opc == MDT_IT_READDIR) {
+ req_capsule_set_size(pill, &RMF_DLM_LVB, RCL_SERVER, 0);
+ }
+
flv = &mdt_it_flavor[opc];
if (flv->it_fmt != NULL)
req_capsule_extend(pill, flv->it_fmt);
} else {
/* No intent was provided */
LASSERT(pill->rc_fmt == &RQF_LDLM_ENQUEUE);
+ req_capsule_set_size(pill, &RMF_DLM_LVB, RCL_SERVER, 0);
rc = req_capsule_server_pack(pill);
if (rc)
rc = err_serious(rc);
rc = ldlm_cli_enqueue_local(ns, res_id, LDLM_IBITS, policy,
mode, &flags, mdt_blocking_ast,
ldlm_completion_ast, NULL, NULL, 0,
- client_cookie, lh);
+ LVB_T_NONE, client_cookie, lh);
return rc == ELDLM_OK ? 0 : -EIO;
}
rc = ldlm_cli_enqueue_local(ns, res_id, LDLM_IBITS, policy,
LCK_EX, &flags, ldlm_blocking_ast,
ldlm_completion_ast, NULL, NULL, 0,
- &info->mti_exp->exp_handle.h_cookie,
+ LVB_T_NONE,
+ &info->mti_exp->exp_handle.h_cookie,
lh);
} else {
struct ldlm_enqueue_info einfo = { LDLM_IBITS, LCK_EX,
* other clients.
*/
rc = ldlm_cli_enqueue(ms->ms_control_exp, NULL, &einfo, res_id,
- policy, &flags, NULL, 0, lh, 0);
+ policy, &flags, NULL, 0, LVB_T_NONE, lh,
+ 0);
}
RETURN(rc);
LDLM_ENQUEUE);
if (req == NULL)
RETURN(-ENOMEM);
+
+ req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER, 0);
ptlrpc_request_set_replen(req);
/* check if this is server or client */
/* Limit how long we will wait for the enqueue to complete */
req->rq_delay_limit = short_limit ? 5 : MGC_ENQUEUE_LIMIT;
rc = ldlm_cli_enqueue(exp, &req, &einfo, &cld->cld_resid, NULL, flags,
- NULL, 0, lockh, 0);
+ NULL, 0, LVB_T_NONE, lockh, 0);
/* A failed enqueue should still call the mgc_blocking_ast,
where it will be requeued if needed ("grant failed"). */
ptlrpc_req_finished(req);
rc = ldlm_cli_enqueue_local(mgs->mgs_obd->obd_namespace,
&res_id, LDLM_PLAIN, NULL, LCK_EX,
&flags, ldlm_blocking_ast, cp,
- NULL, fsdb, 0, NULL, &lockh);
+ NULL, fsdb, 0, LVB_T_NONE, NULL,
+ &lockh);
if (rc != ELDLM_OK) {
CERROR("can't take cfg lock for "LPX64"/"LPX64"(%d)\n",
le64_to_cpu(res_id.name[0]),
/* We connect to the MGS at setup, and don't disconnect until cleanup */
data->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_AT |
- OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV;
+ OBD_CONNECT_FULL20 | OBD_CONNECT_IMP_RECOV |
+ OBD_CONNECT_LVB_TYPE;
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 2, 50, 0)
data->ocd_connect_flags |= OBD_CONNECT_MNE_SWAB;
data->ocd_connect_flags |= OBD_CONNECT_ACL | OBD_CONNECT_IBITS |
OBD_CONNECT_MDS_MDS | OBD_CONNECT_FID |
OBD_CONNECT_AT | OBD_CONNECT_FULL20 |
+ OBD_CONNECT_LVB_TYPE |
OBD_CONNECT_LIGHTWEIGHT;
OBD_ALLOC_PTR(uuid);
if (uuid == NULL)
rc = ldlm_cli_enqueue_local(obd->obd_namespace, &res_id, LDLM_PLAIN,
NULL, LCK_NL, &lock_flags, NULL,
- ldlm_completion_ast, NULL, NULL, 0, NULL,
- &obd->u.echo.eo_nl_lock);
+ ldlm_completion_ast, NULL, NULL, 0,
+ LVB_T_NONE, NULL, &obd->u.echo.eo_nl_lock);
LASSERT (rc == ELDLM_OK);
lprocfs_echo_init_vars(&lvars);
ocd->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_REQPORTAL |
OBD_CONNECT_GRANT | OBD_CONNECT_FULL20 |
- OBD_CONNECT_64BITHASH;
+ OBD_CONNECT_64BITHASH | OBD_CONNECT_LVB_TYPE;
ocd->ocd_version = LUSTRE_VERSION_CODE;
ocd->ocd_group = FID_SEQ_ECHO;
CFS_LIST_HEAD(gl_list);
ENTRY;
+ lock->l_lvb_type = LVB_T_OST;
policy = ldlm_get_processing_policy(res);
LASSERT(policy != NULL);
LASSERT(req != NULL);
/* Space used by the I/O, used by grant code */
unsigned long fti_used;
+ struct ost_lvb fti_lvb;
};
extern void target_recovery_fini(struct obd_device *obd);
/* Update the LVB from the network message */
if (req != NULL) {
struct ost_lvb *rpc_lvb;
-
- /* XXX update always from reply buffer */
- rpc_lvb = req_capsule_server_get(&req->rq_pill, &RMF_DLM_LVB);
- if (rpc_lvb == NULL) {
- CERROR("lustre_swab_buf failed\n");
- goto disk_update;
+ bool lvb_type;
+
+ if (req->rq_import != NULL)
+ lvb_type = imp_connect_lvb_type(req->rq_import);
+ else
+ lvb_type = exp_connect_lvb_type(req->rq_export);
+
+ if (!lvb_type) {
+ struct ost_lvb_v1 *lvb_v1;
+
+ lvb_v1 = req_capsule_server_swab_get(&req->rq_pill,
+ &RMF_DLM_LVB, lustre_swab_ost_lvb_v1);
+ if (lvb_v1 == NULL)
+ goto disk_update;
+
+ rpc_lvb = &info->fti_lvb;
+ memcpy(rpc_lvb, lvb_v1, sizeof *lvb_v1);
+ rpc_lvb->lvb_mtime_ns = 0;
+ rpc_lvb->lvb_atime_ns = 0;
+ rpc_lvb->lvb_ctime_ns = 0;
+ } else {
+ rpc_lvb = req_capsule_server_swab_get(&req->rq_pill,
+ &RMF_DLM_LVB,
+ lustre_swab_ost_lvb);
+ if (rpc_lvb == NULL)
+ goto disk_update;
}
+
lock_res(res);
if (rpc_lvb->lvb_size > lvb->lvb_size || !increase_only) {
CDEBUG(D_DLMTRACE, "res: "LPU64" updating lvb size: "
return rc;
}
-static int ofd_lvbo_size(struct ldlm_lock *unused)
+static int ofd_lvbo_size(struct ldlm_lock *lock)
{
- return sizeof(struct ost_lvb);
+ if (lock->l_export != NULL && exp_connect_lvb_type(lock->l_export))
+ return sizeof(struct ost_lvb);
+ else
+ return sizeof(struct ost_lvb_v1);
}
static int ofd_lvbo_fill(struct ldlm_lock *lock, void *buf, int buflen)
{
struct ldlm_resource *res = lock->l_resource;
+ int lvb_len = min_t(int, res->lr_lvb_len, buflen);
lock_res(res);
- LASSERTF(buflen >= res->lr_lvb_len,
- "actual %d, want %d\n", buflen, res->lr_lvb_len);
- memcpy(buf, res->lr_lvb_data, res->lr_lvb_len);
+ memcpy(buf, res->lr_lvb_data, lvb_len);
unlock_res(res);
- return res->lr_lvb_len;
+ return lvb_len;
}
struct ldlm_valblock_ops ofd_lvbo = {
rc = ldlm_cli_enqueue_local(ofd->ofd_namespace, &info->fti_resid,
LDLM_EXTENT, &policy, LCK_PW, &flags,
ldlm_blocking_ast, ldlm_completion_ast,
- NULL, NULL, 0, NULL, &lockh);
+ NULL, NULL, 0, LVB_T_NONE, NULL, &lockh);
/* We only care about the side-effects, just drop the lock. */
if (rc == ELDLM_OK)
obj = lock->cll_descr.cld_obj;
result = cl_object_glimpse(env, obj, lvb);
}
+ if (!exp_connect_lvb_type(req->rq_export))
+ req_capsule_shrink(&req->rq_pill,
+ &RMF_DLM_LVB,
+ sizeof(struct ost_lvb_v1),
+ RCL_SERVER);
osc_ast_data_put(env, olck);
} else {
/*
*flags &= ~LDLM_FL_BLOCK_GRANTED;
rc = ldlm_cli_enqueue(exp, &req, einfo, res_id, policy, flags, lvb,
- sizeof(*lvb), lockh, async);
+ sizeof(*lvb), LVB_T_OST, lockh, async);
if (rqset) {
if (!rc) {
struct osc_enqueue_args *aa;
OBD_CONNECT_REQPORTAL |
OBD_CONNECT_SKIP_ORPHAN |
OBD_CONNECT_VERSION |
- OBD_CONNECT_FID;
+ OBD_CONNECT_FID |
+ OBD_CONNECT_LVB_TYPE;
if (is_osp_on_ost(osp->opd_obd->obd_name))
ocd->ocd_connect_flags |= OBD_CONNECT_LIGHTWEIGHT;
RETURN(ldlm_cli_enqueue_local(exp->exp_obd->obd_namespace, &res_id,
LDLM_EXTENT, &policy, mode, &flags,
ldlm_blocking_ast, ldlm_completion_ast,
- ldlm_glimpse_ast, NULL, 0, NULL, lh));
+ ldlm_glimpse_ast, NULL, 0, LVB_T_NONE,
+ NULL, lh));
}
/* Helper function: release lock, if any. */
RETURN(ldlm_cli_enqueue_local(exp->exp_obd->obd_namespace, &res_id,
LDLM_EXTENT, &policy, mode, &flags,
ldlm_blocking_ast, ldlm_completion_ast,
- ldlm_glimpse_ast, NULL, 0, NULL, lh));
+ ldlm_glimpse_ast, NULL, 0, LVB_T_NONE,
+ NULL, lh));
}
static void ost_brw_lock_put(int mode,
EXPORT_SYMBOL(RMF_LDLM_INTENT);
struct req_msg_field RMF_DLM_LVB =
- DEFINE_MSGF("dlm_lvb", 0, sizeof(union ldlm_wire_lvb), lustre_swab_lvb,
- NULL);
+ DEFINE_MSGF("dlm_lvb", 0, -1, NULL, NULL);
EXPORT_SYMBOL(RMF_DLM_LVB);
struct req_msg_field RMF_DLM_GL_DESC =
* unused too.
*/
void *req_capsule_client_swab_get(struct req_capsule *pill,
- const struct req_msg_field *field,
- void (*swabber)(void* ))
+ const struct req_msg_field *field,
+ void *swabber)
{
return __req_capsule_get(pill, field, RCL_CLIENT, swabber, 0);
}
}
EXPORT_SYMBOL(req_capsule_server_sized_get);
+void *req_capsule_server_sized_swab_get(struct req_capsule *pill,
+ const struct req_msg_field *field,
+ int len, void *swabber)
+{
+ req_capsule_set_size(pill, field, RCL_SERVER, len);
+ return __req_capsule_get(pill, field, RCL_SERVER, swabber, 0);
+}
+EXPORT_SYMBOL(req_capsule_server_sized_swab_get);
+
/**
* Returns the buffer of a \a pill corresponding to the given \a field from the
* request (if the caller is executing on the server-side) or reply (if the
CLASSERT(offsetof(typeof(desc->lquota_desc), gl_pad2) != 0);
}
-void lustre_swab_lvb(union ldlm_wire_lvb *lvb)
+void lustre_swab_ost_lvb_v1(struct ost_lvb_v1 *lvb)
{
- /* The ldlm_wire_lvb union represents all the possible LVB types.
- * Unfortunately, there is no way to know what member of the union we
- * are dealing with at this point. Therefore, all LVB structures must
- * have fields of the same types, although used for different purposes
- */
- __swab64s(&lvb->l_ost.lvb_size);
- __swab64s(&lvb->l_ost.lvb_mtime);
- __swab64s(&lvb->l_ost.lvb_atime);
- __swab64s(&lvb->l_ost.lvb_ctime);
- __swab64s(&lvb->l_ost.lvb_blocks);
+ __swab64s(&lvb->lvb_size);
+ __swab64s(&lvb->lvb_mtime);
+ __swab64s(&lvb->lvb_atime);
+ __swab64s(&lvb->lvb_ctime);
+ __swab64s(&lvb->lvb_blocks);
+}
+EXPORT_SYMBOL(lustre_swab_ost_lvb_v1);
+
+void lustre_swab_ost_lvb(struct ost_lvb *lvb)
+{
+ __swab64s(&lvb->lvb_size);
+ __swab64s(&lvb->lvb_mtime);
+ __swab64s(&lvb->lvb_atime);
+ __swab64s(&lvb->lvb_ctime);
+ __swab64s(&lvb->lvb_blocks);
+ __swab32s(&lvb->lvb_mtime_ns);
+ __swab32s(&lvb->lvb_atime_ns);
+ __swab32s(&lvb->lvb_ctime_ns);
+ __swab32s(&lvb->lvb_padding);
+}
+EXPORT_SYMBOL(lustre_swab_ost_lvb);
+
+void lustre_swab_lquota_lvb(struct lquota_lvb *lvb)
+{
+ __swab64s(&lvb->lvb_flags);
+ __swab64s(&lvb->lvb_id_may_rel);
+ __swab64s(&lvb->lvb_id_rel);
+ __swab64s(&lvb->lvb_id_qunit);
+ __swab64s(&lvb->lvb_pad1);
}
-EXPORT_SYMBOL(lustre_swab_lvb);
+EXPORT_SYMBOL(lustre_swab_lquota_lvb);
void lustre_swab_mdt_body (struct mdt_body *b)
{
{
/* Wire protocol assertions generated by 'wirecheck'
* (make -C lustre/utils newwiretest)
- * running on Linux chopin 2.6.32.wc #9 SMP Thu Feb 9 14:43:41 CST 2012 x86_64 x86_64 x86_64
- * with gcc version 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC) */
+ * running on Linux mercury 2.6.32-279.5.1.el6_lustre.x86_64 #1 SMP Tue Aug 21 00:00:41 PDT 2
+ * with gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC) */
/* Constants... */
LASSERTF((int)sizeof(((struct ldlm_reply *)0)->lock_policy_res2) == 8, "found %lld\n",
(long long)(int)sizeof(((struct ldlm_reply *)0)->lock_policy_res2));
+ /* Checks for struct ost_lvb_v1 */
+ LASSERTF((int)sizeof(struct ost_lvb_v1) == 40, "found %lld\n",
+ (long long)(int)sizeof(struct ost_lvb_v1));
+ LASSERTF((int)offsetof(struct ost_lvb_v1, lvb_size) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb_v1, lvb_size));
+ LASSERTF((int)sizeof(((struct ost_lvb_v1 *)0)->lvb_size) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb_v1 *)0)->lvb_size));
+ LASSERTF((int)offsetof(struct ost_lvb_v1, lvb_mtime) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb_v1, lvb_mtime));
+ LASSERTF((int)sizeof(((struct ost_lvb_v1 *)0)->lvb_mtime) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb_v1 *)0)->lvb_mtime));
+ LASSERTF((int)offsetof(struct ost_lvb_v1, lvb_atime) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb_v1, lvb_atime));
+ LASSERTF((int)sizeof(((struct ost_lvb_v1 *)0)->lvb_atime) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb_v1 *)0)->lvb_atime));
+ LASSERTF((int)offsetof(struct ost_lvb_v1, lvb_ctime) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb_v1, lvb_ctime));
+ LASSERTF((int)sizeof(((struct ost_lvb_v1 *)0)->lvb_ctime) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb_v1 *)0)->lvb_ctime));
+ LASSERTF((int)offsetof(struct ost_lvb_v1, lvb_blocks) == 32, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb_v1, lvb_blocks));
+ LASSERTF((int)sizeof(((struct ost_lvb_v1 *)0)->lvb_blocks) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb_v1 *)0)->lvb_blocks));
+
/* Checks for struct ost_lvb */
- LASSERTF((int)sizeof(struct ost_lvb) == 40, "found %lld\n",
+ LASSERTF((int)sizeof(struct ost_lvb) == 56, "found %lld\n",
(long long)(int)sizeof(struct ost_lvb));
LASSERTF((int)offsetof(struct ost_lvb, lvb_size) == 0, "found %lld\n",
(long long)(int)offsetof(struct ost_lvb, lvb_size));
(long long)(int)offsetof(struct ost_lvb, lvb_blocks));
LASSERTF((int)sizeof(((struct ost_lvb *)0)->lvb_blocks) == 8, "found %lld\n",
(long long)(int)sizeof(((struct ost_lvb *)0)->lvb_blocks));
+ LASSERTF((int)offsetof(struct ost_lvb, lvb_mtime_ns) == 40, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb, lvb_mtime_ns));
+ LASSERTF((int)sizeof(((struct ost_lvb *)0)->lvb_mtime_ns) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb *)0)->lvb_mtime_ns));
+ LASSERTF((int)offsetof(struct ost_lvb, lvb_atime_ns) == 44, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb, lvb_atime_ns));
+ LASSERTF((int)sizeof(((struct ost_lvb *)0)->lvb_atime_ns) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb *)0)->lvb_atime_ns));
+ LASSERTF((int)offsetof(struct ost_lvb, lvb_ctime_ns) == 48, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb, lvb_ctime_ns));
+ LASSERTF((int)sizeof(((struct ost_lvb *)0)->lvb_ctime_ns) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb *)0)->lvb_ctime_ns));
+ LASSERTF((int)offsetof(struct ost_lvb, lvb_padding) == 52, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb, lvb_padding));
+ LASSERTF((int)sizeof(((struct ost_lvb *)0)->lvb_padding) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb *)0)->lvb_padding));
/* Checks for struct lquota_lvb */
LASSERTF((int)sizeof(struct lquota_lvb) == 40, "found %lld\n",
ENTRY;
req_capsule_extend(&req->rq_pill, &RQF_LDLM_INTENT_QUOTA);
+ req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
+ ldlm_lvbo_size(*lockp));
/* extract quota body and intent opc */
it = req_capsule_client_get(&req->rq_pill, &RMF_LDLM_INTENT);
}
/* on success, pack lvb in reply */
- req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
- ldlm_lvbo_size(*lockp));
lvb = req_capsule_server_get(&req->rq_pill, &RMF_DLM_LVB);
ldlm_lvbo_fill(*lockp, lvb, ldlm_lvbo_size(*lockp));
EXIT;
/* no need to update lvb for global quota locks */
RETURN(0);
- lvb = req_capsule_server_get(&req->rq_pill, &RMF_DLM_LVB);
+ lvb = req_capsule_server_swab_get(&req->rq_pill, &RMF_DLM_LVB,
+ lustre_swab_lquota_lvb);
if (lvb == NULL) {
CERROR("%s: failed to extract lvb from request\n",
qmt->qmt_svname);
struct quota_body *reqbody,
struct quota_body *repbody,
struct lustre_handle *lockh,
- union ldlm_wire_lvb *lvb,
+ struct lquota_lvb *lvb,
void *arg, int ret)
{
struct lquota_entry *lqe = (struct lquota_entry *)arg;
/* extract information from lvb */
if (ret == 0 && lvb != 0) {
- if (lvb->l_lquota.lvb_id_qunit != 0)
- qsd_set_qunit(lqe, lvb->l_lquota.lvb_id_qunit);
- if (lvb->l_lquota.lvb_flags & LQUOTA_FL_EDQUOT)
+ if (lvb->lvb_id_qunit != 0)
+ qsd_set_qunit(lqe, lvb->lvb_id_qunit);
+ if (lvb->lvb_flags & LQUOTA_FL_EDQUOT)
lqe->lqe_edquot = true;
else
lqe->lqe_edquot = false;
/* check whether we already own a valid lock for this ID */
rc = qsd_id_lock_match(&qti->qti_lockh, &qbody->qb_lockh);
if (rc) {
- union ldlm_wire_lvb *lvb;
+ struct lquota_lvb *lvb;
OBD_ALLOC_PTR(lvb);
if (lvb == NULL) {
qsd_req_completion, qqi, &qti->qti_lockh,
lqe);
} else {
- union ldlm_wire_lvb *lvb;
+ struct lquota_lvb *lvb;
OBD_ALLOC_PTR(lvb);
if (lvb == NULL)
struct ldlm_enqueue_info qti_einfo;
struct lustre_handle qti_lockh;
__u64 qti_slv_ver;
- union ldlm_wire_lvb qti_lvb;
+ struct lquota_lvb qti_lvb;
union {
struct quota_body qti_body;
struct idx_info qti_ii;
struct qsd_qtype_info *,
struct quota_body *, struct quota_body *,
struct lustre_handle *,
- union ldlm_wire_lvb *, void *, int);
+ struct lquota_lvb *, void *, int);
int qsd_send_dqacq(const struct lu_env *, struct obd_export *,
struct quota_body *, bool, qsd_req_completion_t,
struct qsd_qtype_info *, struct lustre_handle *,
struct lquota_entry *);
int qsd_intent_lock(const struct lu_env *, struct obd_export *,
struct quota_body *, bool, int, qsd_req_completion_t,
- struct qsd_qtype_info *, union ldlm_wire_lvb *, void *);
+ struct qsd_qtype_info *, struct lquota_lvb *, void *);
int qsd_fetch_index(const struct lu_env *, struct obd_export *,
struct idx_info *, unsigned int, cfs_page_t **, bool *);
RETURN(-EFAULT);
/* prepare reply */
+ req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
+ sizeof(struct lquota_lvb));
rc = req_capsule_server_pack(&req->rq_pill);
if (rc != 0) {
CERROR("Can't pack response, rc %d\n", rc);
struct quota_body *req_qbody,
struct quota_body *rep_qbody,
struct lustre_handle *lockh,
- union ldlm_wire_lvb *lvb,
+ struct lquota_lvb *lvb,
void *arg, int rc)
{
struct qsd_instance *qsd = qqi->qqi_qsd;
CDEBUG(D_QUOTA, "%s: global quota lock successfully acquired, glb "
"fid:"DFID", glb ver:"LPU64", slv fid:"DFID", slv ver:"LPU64"\n",
qsd->qsd_svname, PFID(&req_qbody->qb_fid),
- lvb->l_lquota.lvb_glb_ver, PFID(&rep_qbody->qb_slv_fid),
+ lvb->lvb_glb_ver, PFID(&rep_qbody->qb_slv_fid),
rep_qbody->qb_slv_ver);
*slv_ver = rep_qbody->qb_slv_ver;
ldlm_lock_addref_try(&qqi->qqi_lockh, qsd_glb_einfo.ei_mode) == 0) {
read_unlock(&qsd->qsd_lock);
/* force refresh of global & slave index copy */
- qti->qti_lvb.l_lquota.lvb_glb_ver = ~0ULL;
+ qti->qti_lvb.lvb_glb_ver = ~0ULL;
qti->qti_slv_ver = ~0ULL;
} else {
/* no valid lock found, let's enqueue a new one */
CDEBUG(D_QUOTA, "%s: glb_ver:"LPU64"/"LPU64",slv_ver:"LPU64"/"
LPU64"\n", qsd->qsd_svname,
- qti->qti_lvb.l_lquota.lvb_glb_ver, qqi->qqi_glb_ver,
+ qti->qti_lvb.lvb_glb_ver, qqi->qqi_glb_ver,
qti->qti_slv_ver, qqi->qqi_slv_ver);
}
OBD_FAIL_TIMEOUT(OBD_FAIL_QUOTA_DELAY_REINT, 10);
- if (qqi->qqi_glb_ver != qti->qti_lvb.l_lquota.lvb_glb_ver) {
+ if (qqi->qqi_glb_ver != qti->qti_lvb.lvb_glb_ver) {
rc = qsd_reint_index(env, qqi, true);
if (rc) {
CWARN("%s: reint global for "DFID" failed. %d\n",
struct obd_export *aa_exp;
struct qsd_qtype_info *aa_qqi;
void *aa_arg;
- union ldlm_wire_lvb *aa_lvb;
+ struct lquota_lvb *aa_lvb;
struct lustre_handle aa_lockh;
qsd_req_completion_t aa_completion;
};
rc = ldlm_cli_enqueue_fini(aa->aa_exp, req, LDLM_PLAIN, 0, LCK_CR,
&flags, (void *)aa->aa_lvb,
- sizeof(union ldlm_wire_lvb), lockh, rc);
+ sizeof(struct lquota_lvb), lockh, rc);
if (rc < 0)
/* the lock has been destroyed, forget about the lock handle */
memset(lockh, 0, sizeof(*lockh));
int qsd_intent_lock(const struct lu_env *env, struct obd_export *exp,
struct quota_body *qbody, bool sync, int it_op,
qsd_req_completion_t completion, struct qsd_qtype_info *qqi,
- union ldlm_wire_lvb *lvb, void *arg)
+ struct lquota_lvb *lvb, void *arg)
{
struct qsd_thread_info *qti = qsd_info(env);
struct ptlrpc_request *req;
req_qbody = req_capsule_client_get(&req->rq_pill, &RMF_QUOTA_BODY);
*req_qbody = *qbody;
+ req_capsule_set_size(&req->rq_pill, &RMF_DLM_LVB, RCL_SERVER,
+ sizeof(*lvb));
ptlrpc_request_set_replen(req);
switch(it_op) {
/* build lock enqueue request */
rc = ldlm_cli_enqueue(exp, &req, &qti->qti_einfo, &qti->qti_resid, NULL,
- &flags, (void *)lvb, sizeof(*lvb), &qti->qti_lockh,
- 1);
+ &flags, (void *)lvb, sizeof(*lvb), LVB_T_LQUOTA,
+ &qti->qti_lockh, 1);
if (rc < 0) {
ptlrpc_req_finished(req);
GOTO(out, rc);
#define lustre_swab_idx_info NULL
#define lustre_swab_qdata NULL
#define lustre_swab_quota_body NULL
-#define lustre_swab_lvb NULL
+#define lustre_swab_ost_lvb_v1 NULL
+#define lustre_swab_ost_lvb NULL
#define lustre_swab_gl_desc NULL
#define lustre_swab_mgs_config_body NULL
#define lustre_swab_mgs_config_res NULL
CHECK_DEFINE_64X(OBD_CONNECT_EINPROGRESS);
CHECK_DEFINE_64X(OBD_CONNECT_GRANT_PARAM);
CHECK_DEFINE_64X(OBD_CONNECT_FLOCK_OWNER);
- CHECK_DEFINE_64X(OBD_CONNECT_LVB_TYPE);
- CHECK_DEFINE_64X(OBD_CONNECT_NANOSEC_TIME);
- CHECK_DEFINE_64X(OBD_CONNECT_LIGHTWEIGHT);
+ CHECK_DEFINE_64X(OBD_CONNECT_LVB_TYPE);
+ CHECK_DEFINE_64X(OBD_CONNECT_NANOSEC_TIME);
+ CHECK_DEFINE_64X(OBD_CONNECT_LIGHTWEIGHT);
CHECK_DEFINE_64X(OBD_CONNECT_SHORTIO);
CHECK_VALUE_X(OBD_CKSUM_CRC32);
}
static void
+check_ldlm_ost_lvb_v1(void)
+{
+ BLANK_LINE();
+ CHECK_STRUCT(ost_lvb_v1);
+ CHECK_MEMBER(ost_lvb_v1, lvb_size);
+ CHECK_MEMBER(ost_lvb_v1, lvb_mtime);
+ CHECK_MEMBER(ost_lvb_v1, lvb_atime);
+ CHECK_MEMBER(ost_lvb_v1, lvb_ctime);
+ CHECK_MEMBER(ost_lvb_v1, lvb_blocks);
+}
+
+static void
check_ldlm_ost_lvb(void)
{
- BLANK_LINE();
- CHECK_STRUCT(ost_lvb);
- CHECK_MEMBER(ost_lvb, lvb_size);
- CHECK_MEMBER(ost_lvb, lvb_mtime);
- CHECK_MEMBER(ost_lvb, lvb_atime);
- CHECK_MEMBER(ost_lvb, lvb_ctime);
- CHECK_MEMBER(ost_lvb, lvb_blocks);
+ BLANK_LINE();
+ CHECK_STRUCT(ost_lvb);
+ CHECK_MEMBER(ost_lvb, lvb_size);
+ CHECK_MEMBER(ost_lvb, lvb_mtime);
+ CHECK_MEMBER(ost_lvb, lvb_atime);
+ CHECK_MEMBER(ost_lvb, lvb_ctime);
+ CHECK_MEMBER(ost_lvb, lvb_blocks);
+ CHECK_MEMBER(ost_lvb, lvb_mtime_ns);
+ CHECK_MEMBER(ost_lvb, lvb_atime_ns);
+ CHECK_MEMBER(ost_lvb, lvb_ctime_ns);
+ CHECK_MEMBER(ost_lvb, lvb_padding);
}
static void
check_ldlm_lock_desc();
check_ldlm_request();
check_ldlm_reply();
+ check_ldlm_ost_lvb_v1();
check_ldlm_ost_lvb();
check_ldlm_lquota_lvb();
check_ldlm_gl_lquota_desc();
{
/* Wire protocol assertions generated by 'wirecheck'
* (make -C lustre/utils newwiretest)
- * running on Linux chopin 2.6.32.wc #9 SMP Thu Feb 9 14:43:41 CST 2012 x86_64 x86_64 x86_64
- * with gcc version 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC) */
+ * running on Linux mercury 2.6.32-279.5.1.el6_lustre.x86_64 #1 SMP Tue Aug 21 00:00:41 PDT 2
+ * with gcc version 4.4.6 20120305 (Red Hat 4.4.6-4) (GCC) */
/* Constants... */
LASSERTF((int)sizeof(((struct ldlm_reply *)0)->lock_policy_res2) == 8, "found %lld\n",
(long long)(int)sizeof(((struct ldlm_reply *)0)->lock_policy_res2));
+ /* Checks for struct ost_lvb_v1 */
+ LASSERTF((int)sizeof(struct ost_lvb_v1) == 40, "found %lld\n",
+ (long long)(int)sizeof(struct ost_lvb_v1));
+ LASSERTF((int)offsetof(struct ost_lvb_v1, lvb_size) == 0, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb_v1, lvb_size));
+ LASSERTF((int)sizeof(((struct ost_lvb_v1 *)0)->lvb_size) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb_v1 *)0)->lvb_size));
+ LASSERTF((int)offsetof(struct ost_lvb_v1, lvb_mtime) == 8, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb_v1, lvb_mtime));
+ LASSERTF((int)sizeof(((struct ost_lvb_v1 *)0)->lvb_mtime) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb_v1 *)0)->lvb_mtime));
+ LASSERTF((int)offsetof(struct ost_lvb_v1, lvb_atime) == 16, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb_v1, lvb_atime));
+ LASSERTF((int)sizeof(((struct ost_lvb_v1 *)0)->lvb_atime) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb_v1 *)0)->lvb_atime));
+ LASSERTF((int)offsetof(struct ost_lvb_v1, lvb_ctime) == 24, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb_v1, lvb_ctime));
+ LASSERTF((int)sizeof(((struct ost_lvb_v1 *)0)->lvb_ctime) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb_v1 *)0)->lvb_ctime));
+ LASSERTF((int)offsetof(struct ost_lvb_v1, lvb_blocks) == 32, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb_v1, lvb_blocks));
+ LASSERTF((int)sizeof(((struct ost_lvb_v1 *)0)->lvb_blocks) == 8, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb_v1 *)0)->lvb_blocks));
+
/* Checks for struct ost_lvb */
- LASSERTF((int)sizeof(struct ost_lvb) == 40, "found %lld\n",
+ LASSERTF((int)sizeof(struct ost_lvb) == 56, "found %lld\n",
(long long)(int)sizeof(struct ost_lvb));
LASSERTF((int)offsetof(struct ost_lvb, lvb_size) == 0, "found %lld\n",
(long long)(int)offsetof(struct ost_lvb, lvb_size));
(long long)(int)offsetof(struct ost_lvb, lvb_blocks));
LASSERTF((int)sizeof(((struct ost_lvb *)0)->lvb_blocks) == 8, "found %lld\n",
(long long)(int)sizeof(((struct ost_lvb *)0)->lvb_blocks));
+ LASSERTF((int)offsetof(struct ost_lvb, lvb_mtime_ns) == 40, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb, lvb_mtime_ns));
+ LASSERTF((int)sizeof(((struct ost_lvb *)0)->lvb_mtime_ns) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb *)0)->lvb_mtime_ns));
+ LASSERTF((int)offsetof(struct ost_lvb, lvb_atime_ns) == 44, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb, lvb_atime_ns));
+ LASSERTF((int)sizeof(((struct ost_lvb *)0)->lvb_atime_ns) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb *)0)->lvb_atime_ns));
+ LASSERTF((int)offsetof(struct ost_lvb, lvb_ctime_ns) == 48, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb, lvb_ctime_ns));
+ LASSERTF((int)sizeof(((struct ost_lvb *)0)->lvb_ctime_ns) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb *)0)->lvb_ctime_ns));
+ LASSERTF((int)offsetof(struct ost_lvb, lvb_padding) == 52, "found %lld\n",
+ (long long)(int)offsetof(struct ost_lvb, lvb_padding));
+ LASSERTF((int)sizeof(((struct ost_lvb *)0)->lvb_padding) == 4, "found %lld\n",
+ (long long)(int)sizeof(((struct ost_lvb *)0)->lvb_padding));
/* Checks for struct lquota_lvb */
LASSERTF((int)sizeof(struct lquota_lvb) == 40, "found %lld\n",