From 0ebf1f42ce05afa1f8dc1e8caa32aeea1961763f Mon Sep 17 00:00:00 2001 From: green Date: Sun, 4 Dec 2005 22:54:59 +0000 Subject: [PATCH] b=8001 r=adilger Landing Inode bits compatibility stuff --- lustre/include/linux/lustre_export.h | 1 + lustre/include/linux/lustre_idl.h | 19 +++++++++++---- lustre/ldlm/ldlm_lock.c | 47 ++++++++++++++++++++++++++++++++---- lustre/ldlm/ldlm_lockd.c | 12 +++++++++ lustre/ldlm/ldlm_request.c | 32 +++++++++++++++++------- lustre/liblustre/super.c | 7 ++++-- lustre/llite/llite_lib.c | 4 +++ lustre/mds/handler.c | 12 +++++++++ lustre/ptlrpc/import.c | 5 ++++ 9 files changed, 118 insertions(+), 21 deletions(-) diff --git a/lustre/include/linux/lustre_export.h b/lustre/include/linux/lustre_export.h index 061b96f..5804902 100644 --- a/lustre/include/linux/lustre_export.h +++ b/lustre/include/linux/lustre_export.h @@ -14,6 +14,7 @@ struct mds_export_data { struct list_head med_open_head; spinlock_t med_open_lock; /* lock med_open_head, mfd_list*/ struct mds_client_data *med_mcd; + __u64 med_ibits_known; loff_t med_lr_off; int med_lr_idx; }; diff --git a/lustre/include/linux/lustre_idl.h b/lustre/include/linux/lustre_idl.h index 00ea432..b3300f1 100644 --- a/lustre/include/linux/lustre_idl.h +++ b/lustre/include/linux/lustre_idl.h @@ -211,10 +211,12 @@ static inline void lustre_msg_set_op_flags(struct lustre_msg *msg, int flags) #define OBD_CONNECT_ACL 0x0080ULL #define OBD_CONNECT_USER_XATTR 0x0100ULL #define OBD_CONNECT_CROW 0x0200ULL /* OST is CROW able */ +#define OBD_CONNECT_IBITS 0x1000ULL /* support for inodebits locks */ #define MDS_CONNECT_SUPPORTED (OBD_CONNECT_RDONLY | \ OBD_CONNECT_ACL | \ - OBD_CONNECT_USER_XATTR) + OBD_CONNECT_USER_XATTR | \ + OBD_CONNECT_IBITS) #define OST_CONNECT_SUPPORTED (OBD_CONNECT_SRVLOCK | OBD_CONNECT_CROW) #define ECHO_CONNECT_SUPPORTED (0) @@ -223,10 +225,17 @@ static inline void lustre_msg_set_op_flags(struct lustre_msg *msg, int flags) * If we eventually have separate connect data for different types, which we * almost certainly will, then perhaps we stick a union in here. */ struct obd_connect_data { - __u64 ocd_connect_flags; /* connection flags, server should return - * subset of what is asked for. */ - - __u64 padding[8]; + __u64 ocd_connect_flags; /* OBD_CONNECT_* per above */ + __u32 ocd_version; /* lustre release version number */ + __u32 ocd_grant; /* initial cache grant amount (bytes) */ + __u32 ocd_index; /* LOV index to connect to */ + __u32 ocd_unused; + __u64 ocd_ibits_known; /* inode bits this client understands */ + __u64 padding2; /* also fix lustre_swab_connect */ + __u64 padding3; /* also fix lustre_swab_connect */ + __u64 padding4; /* also fix lustre_swab_connect */ + __u64 padding5; /* also fix lustre_swab_connect */ + __u64 padding6; /* also fix lustre_swab_connect */ }; extern void lustre_swab_connect(struct obd_connect_data *ocd); diff --git a/lustre/ldlm/ldlm_lock.c b/lustre/ldlm/ldlm_lock.c index 28a4a2f..b8312eb 100644 --- a/lustre/ldlm/ldlm_lock.c +++ b/lustre/ldlm/ldlm_lock.c @@ -382,11 +382,48 @@ struct ldlm_lock *ldlm_handle2lock_ns(struct ldlm_namespace *ns, void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc) { - ldlm_res2desc(lock->l_resource, &desc->l_resource); - desc->l_req_mode = lock->l_req_mode; - desc->l_granted_mode = lock->l_granted_mode; - memcpy(&desc->l_policy_data, &lock->l_policy_data, - sizeof(desc->l_policy_data)); + struct obd_export *exp = lock->l_export?:lock->l_conn_export; + /* INODEBITS_INTEROP: If the other side does not support + * inodebits, reply with a plain lock descriptor. + */ + if ((lock->l_resource->lr_type == LDLM_IBITS) && + (exp && !(exp->exp_connect_flags & OBD_CONNECT_IBITS))) { + struct ldlm_resource res = *lock->l_resource; + + /* Make sure all the right bits are set in this lock we + are going to pass to client */ + LASSERTF(lock->l_policy_data.l_inodebits.bits == + (MDS_INODELOCK_LOOKUP|MDS_INODELOCK_UPDATE), + "Inappropriate inode lock bits during " + "conversion " LPU64 "\n", + lock->l_policy_data.l_inodebits.bits); + res.lr_type = LDLM_PLAIN; + ldlm_res2desc(&res, &desc->l_resource); + /* Convert "new" lock mode to something old client can + understand */ + if ((lock->l_req_mode == LCK_CR) || + (lock->l_req_mode == LCK_CW)) + desc->l_req_mode = LCK_PR; + else + desc->l_req_mode = lock->l_req_mode; + if ((lock->l_granted_mode == LCK_CR) || + (lock->l_granted_mode == LCK_CW)) { + desc->l_granted_mode = LCK_PR; + } else { + /* We never grant PW/EX locks to clients */ + LASSERT((lock->l_granted_mode != LCK_PW) && + (lock->l_granted_mode != LCK_EX)); + desc->l_granted_mode = lock->l_granted_mode; + } + + /* We do not copy policy here, because there is no + policy for plain locks */ + } else { + ldlm_res2desc(lock->l_resource, &desc->l_resource); + desc->l_req_mode = lock->l_req_mode; + desc->l_granted_mode = lock->l_granted_mode; + desc->l_policy_data = lock->l_policy_data; + } } void ldlm_add_ast_work_item(struct ldlm_lock *lock, struct ldlm_lock *new, diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c index 770c91b..109584c 100644 --- a/lustre/ldlm/ldlm_lockd.c +++ b/lustre/ldlm/ldlm_lockd.c @@ -697,6 +697,18 @@ int ldlm_handle_enqueue(struct ptlrpc_request *req, GOTO(out, rc = -EFAULT); } + /* INODEBITS_INTEROP: Perform conversion from plain lock to + * inodebits lock if client does not support them. + */ + if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_IBITS) && + (dlm_req->lock_desc.l_resource.lr_type == LDLM_PLAIN)) { + dlm_req->lock_desc.l_resource.lr_type = LDLM_IBITS; + dlm_req->lock_desc.l_policy_data.l_inodebits.bits = + MDS_INODELOCK_LOOKUP | MDS_INODELOCK_UPDATE; + if (dlm_req->lock_desc.l_req_mode == LCK_PR) + dlm_req->lock_desc.l_req_mode = LCK_CR; + } + /* The lock's callback data might be set in the policy function */ lock = ldlm_lock_create(obddev->obd_namespace, &dlm_req->lock_handle2, dlm_req->lock_desc.l_resource.lr_name, diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index 1629314..3aedfc5 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -353,8 +353,21 @@ int ldlm_cli_enqueue(struct obd_export *exp, ldlm_lock_addref_internal(lock, mode); ldlm_lock2handle(lock, lockh); lock->l_lvb_swabber = lvb_swabber; - if (policy != NULL) - memcpy(&lock->l_policy_data, policy, sizeof(*policy)); + if (policy != NULL) { + /* INODEBITS_INTEROP: If the server does not support + * inodebits, we will request a plain lock in the + * descriptor (ldlm_lock2desc() below) but use an + * inodebits lock internally with both bits set. + */ + if (type == LDLM_IBITS && !(exp->exp_connect_flags & + OBD_CONNECT_IBITS)) + lock->l_policy_data.l_inodebits.bits = + MDS_INODELOCK_LOOKUP | + MDS_INODELOCK_UPDATE; + else + lock->l_policy_data = *policy; + } + if (type == LDLM_EXTENT) memcpy(&lock->l_req_extent, &policy->l_extent, sizeof(policy->l_extent)); @@ -378,6 +391,10 @@ int ldlm_cli_enqueue(struct obd_export *exp, sizeof(*body)); } + lock->l_conn_export = exp; + lock->l_export = NULL; + lock->l_blocking_ast = blocking; + /* Dump lock data into the request buffer */ body = lustre_msg_buf(req->rq_reqmsg, MDS_REQ_INTENT_LOCKREQ_OFF, sizeof(*body)); @@ -391,10 +408,6 @@ int ldlm_cli_enqueue(struct obd_export *exp, size[0] = sizeof(*reply); req->rq_replen = lustre_msg_size(1 + (lvb_len > 0), size); } - lock->l_conn_export = exp; - lock->l_export = NULL; - lock->l_blocking_ast = blocking; - LDLM_DEBUG(lock, "sending request"); rc = ptlrpc_queue_wait(req); @@ -477,9 +490,10 @@ int ldlm_cli_enqueue(struct obd_export *exp, LDLM_DEBUG(lock, "client-side enqueue, new resource"); } if (policy != NULL) - memcpy(&lock->l_policy_data, - &reply->lock_desc.l_policy_data, - sizeof(reply->lock_desc.l_policy_data)); + if (!(type == LDLM_IBITS && !(exp->exp_connect_flags & + OBD_CONNECT_IBITS))) + lock->l_policy_data = + reply->lock_desc.l_policy_data; if (type != LDLM_PLAIN) LDLM_DEBUG(lock,"client-side enqueue, new policy data"); } diff --git a/lustre/liblustre/super.c b/lustre/liblustre/super.c index 0944ba6..8889cd1 100644 --- a/lustre/liblustre/super.c +++ b/lustre/liblustre/super.c @@ -1744,8 +1744,11 @@ llu_fsswop_mount(const char *source, obd_set_info(obd->obd_self_export, strlen("async"), "async", sizeof(async), &async); + ocd.ocd_connect_flags = OBD_CONNECT_IBITS; + ocd.ocd_ibits_known = MDS_INODELOCK_FULL; + /* setup mdc */ - err = obd_connect(&mdc_conn, obd, &sbi->ll_sb_uuid, NULL /* ocd */); + err = obd_connect(&mdc_conn, obd, &sbi->ll_sb_uuid, &ocd); if (err) { CERROR("cannot connect to %s: rc = %d\n", mdc, err); GOTO(out_free, err); @@ -1769,7 +1772,7 @@ llu_fsswop_mount(const char *source, obd_set_info(obd->obd_self_export, strlen("async"), "async", sizeof(async), &async); - ocd.ocd_connect_flags |= OBD_CONNECT_SRVLOCK; + ocd.ocd_connect_flags = OBD_CONNECT_SRVLOCK; err = obd_connect(&osc_conn, obd, &sbi->ll_sb_uuid, &ocd); if (err) { CERROR("cannot connect to %s: rc = %d\n", osc, err); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 2711352..024655f 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -153,6 +153,10 @@ int lustre_common_fill_super(struct super_block *sb, char *mdc, char *osc) CERROR("could not register mount in /proc/lustre"); } + /* indicate that inodebits locking is supported by this client */ + data->ocd_connect_flags |= OBD_CONNECT_IBITS; + data->ocd_ibits_known = MDS_INODELOCK_FULL; + if (sb->s_flags & MS_RDONLY) data->ocd_connect_flags |= OBD_CONNECT_RDONLY; if (sbi->ll_flags & LL_SBI_USER_XATTR) diff --git a/lustre/mds/handler.c b/lustre/mds/handler.c index 0704bd2..fc7d151 100644 --- a/lustre/mds/handler.c +++ b/lustre/mds/handler.c @@ -293,6 +293,7 @@ static int mds_connect(struct lustre_handle *conn, struct obd_device *obd, if (data != NULL) { data->ocd_connect_flags &= MDS_CONNECT_SUPPORTED; + data->ocd_ibits_known &= MDS_INODELOCK_FULL; if (!obd->u.mds.mds_fl_acl) data->ocd_connect_flags &= ~OBD_CONNECT_ACL; @@ -301,6 +302,7 @@ static int mds_connect(struct lustre_handle *conn, struct obd_device *obd, data->ocd_connect_flags &= ~OBD_CONNECT_USER_XATTR; exp->exp_connect_flags = data->ocd_connect_flags; + exp->exp_mds_data.med_ibits_known = data->ocd_ibits_known; } if (obd->u.mds.mds_fl_acl && @@ -2224,6 +2226,16 @@ static int mds_intent_policy(struct ldlm_namespace *ns, case IT_READDIR: fixup_handle_for_resent_req(req, MDS_REQ_INTENT_LOCKREQ_OFF, lock, &new_lock, &lockh); + + /* INODEBITS_INTEROP: if this lock was converted from a + * plain lock (client does not support inodebits), then + * child lock must be taken with both lookup and update + * bits set for all operations. + */ + if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_IBITS)) + getattr_part = MDS_INODELOCK_LOOKUP | + MDS_INODELOCK_UPDATE; + rep->lock_policy_res2 = mds_getattr_name(offset, req, getattr_part, &lockh); diff --git a/lustre/ptlrpc/import.c b/lustre/ptlrpc/import.c index fd7bc1e..906f2f5 100644 --- a/lustre/ptlrpc/import.c +++ b/lustre/ptlrpc/import.c @@ -541,6 +541,7 @@ finish: } } else { struct obd_connect_data *ocd; + struct obd_export *exp; ocd = lustre_swab_repbuf(request, 0, sizeof *ocd, lustre_swab_connect); @@ -559,6 +560,10 @@ finish: ocd->ocd_connect_flags); imp->imp_connect_data = *ocd; + exp = class_conn2export(&imp->imp_dlm_handle); + LASSERT(exp); + exp->exp_connect_flags = ocd->ocd_connect_flags; + class_export_put(exp); if (IMP_CROW_ABLE(imp)) { CDEBUG(D_HA, "connected to CROW capable target: %s\n", -- 1.8.3.1