From 66371381b1cfc0d7bab3e5c33ec46f9c2745e675 Mon Sep 17 00:00:00 2001 From: pschwan Date: Thu, 22 Aug 2002 20:46:29 +0000 Subject: [PATCH] - removed lock list from inode info - added a function to cleanup unused locks on a resource - fixed readdir --- lustre/include/linux/lustre_dlm.h | 5 ++-- lustre/include/linux/lustre_lite.h | 1 - lustre/ldlm/ldlm_lock.c | 5 ++-- lustre/ldlm/ldlm_request.c | 58 ++++++++++++++++++++++++++++++++++++++ lustre/llite/file.c | 27 +----------------- lustre/llite/super.c | 5 ++-- lustre/osc/osc_request.c | 17 ----------- 7 files changed, 66 insertions(+), 52 deletions(-) diff --git a/lustre/include/linux/lustre_dlm.h b/lustre/include/linux/lustre_dlm.h index d43c366..7db70b2 100644 --- a/lustre/include/linux/lustre_dlm.h +++ b/lustre/include/linux/lustre_dlm.h @@ -121,9 +121,8 @@ struct ldlm_lock { struct list_head l_children; struct list_head l_childof; struct list_head l_res_link; /*position in one of three res lists*/ - struct list_head l_inode_link; /* position in inode info list */ struct list_head l_export_chain; /* per-export chain of locks */ - struct list_head l_pending_chain; /* locks with callbacks pending */ + struct list_head l_pending_chain; /* locks with callbacks pending*/ unsigned long l_callback_timeout; ldlm_mode_t l_req_mode; @@ -271,6 +270,7 @@ do { \ lock; \ }) +struct ldlm_lock *ldlm_lock_get(struct ldlm_lock *lock); void ldlm_lock_put(struct ldlm_lock *lock); void ldlm_lock_destroy(struct ldlm_lock *lock); void ldlm_lock2desc(struct ldlm_lock *lock, struct ldlm_lock_desc *desc); @@ -359,6 +359,7 @@ int ldlm_server_ast(struct lustre_handle *lockh, struct ldlm_lock_desc *new, void *data, __u32 data_len); int ldlm_cli_convert(struct lustre_handle *, int new_mode, int *flags); int ldlm_cli_cancel(struct lustre_handle *lockh); +int ldlm_cli_cancel_unused(struct ldlm_namespace *ns, __u64 *res_id); /* mds/handler.c */ /* This has to be here because recurisve inclusion sucks. */ diff --git a/lustre/include/linux/lustre_lite.h b/lustre/include/linux/lustre_lite.h index d48f32e..6ebd91b 100644 --- a/lustre/include/linux/lustre_lite.h +++ b/lustre/include/linux/lustre_lite.h @@ -47,7 +47,6 @@ struct ll_inode_info { char *lli_symlink_name; struct lustre_handle lli_intent_lock_handle; struct semaphore lli_open_sem; - struct list_head lli_osc_locks; }; #define LL_SUPER_MAGIC 0x0BD00BD0 diff --git a/lustre/ldlm/ldlm_lock.c b/lustre/ldlm/ldlm_lock.c index d1edbdb..0f44c99 100644 --- a/lustre/ldlm/ldlm_lock.c +++ b/lustre/ldlm/ldlm_lock.c @@ -192,7 +192,7 @@ void ldlm_lock_destroy(struct ldlm_lock *lock) list_del(&lock->l_export_chain); lock->l_export = NULL; - lock->l_flags = LDLM_FL_DESTROYED; + lock->l_flags |= LDLM_FL_DESTROYED; l_unlock(&lock->l_resource->lr_namespace->ns_lock); LDLM_LOCK_PUT(lock); @@ -229,7 +229,6 @@ static struct ldlm_lock *ldlm_lock_new(struct ldlm_lock *parent, lock->l_refc = 1; INIT_LIST_HEAD(&lock->l_children); INIT_LIST_HEAD(&lock->l_res_link); - INIT_LIST_HEAD(&lock->l_inode_link); INIT_LIST_HEAD(&lock->l_export_chain); INIT_LIST_HEAD(&lock->l_pending_chain); init_waitqueue_head(&lock->l_waitq); @@ -511,7 +510,7 @@ static struct ldlm_lock *search_queue(struct list_head *queue, ldlm_mode_t mode, list_for_each(tmp, queue) { lock = list_entry(tmp, struct ldlm_lock, l_res_link); - if (lock->l_flags & LDLM_FL_CBPENDING) + if (lock->l_flags & (LDLM_FL_CBPENDING | LDLM_FL_DESTROYED)) continue; /* lock_convert() takes the resource lock, so we're sure that diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index c50bb47..cbf3aeb 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -358,6 +358,11 @@ int ldlm_cli_cancel(struct lustre_handle *lockh) if (lock->l_connh) { LDLM_DEBUG(lock, "client-side cancel"); + /* Set this flag to prevent others from getting new references*/ + l_lock(&lock->l_resource->lr_namespace->ns_lock); + lock->l_flags |= LDLM_FL_CBPENDING; + l_unlock(&lock->l_resource->lr_namespace->ns_lock); + req = ptlrpc_prep_req2(lock->l_connh, LDLM_CANCEL, 1, &size, NULL); if (!req) @@ -392,3 +397,56 @@ int ldlm_cli_cancel(struct lustre_handle *lockh) LDLM_LOCK_PUT(lock); return rc; } + +/* Cancel all locks on a given resource that have 0 readers/writers */ +int ldlm_cli_cancel_unused(struct ldlm_namespace *ns, __u64 *res_id) +{ + struct ldlm_resource *res; + struct list_head *tmp, *next, list = LIST_HEAD_INIT(list); + struct ldlm_ast_work *w; + ENTRY; + + res = ldlm_resource_get(ns, NULL, res_id, 0, 0); + if (res == NULL) + RETURN(-ENOMEM); + + l_lock(&ns->ns_lock); + list_for_each(tmp, &res->lr_granted) { + struct ldlm_lock *lock; + lock = list_entry(tmp, struct ldlm_lock, l_res_link); + + if (lock->l_readers || lock->l_writers) + continue; + + /* Setting the CBPENDING flag is a little misleading, but + * prevents an important race; namely, once CBPENDING is set, + * the lock can accumulate no more readers/writers. Since + * readers and writers are already zero here, ldlm_lock_decref + * won't see this flag and call l_blocking_ast */ + lock->l_flags |= LDLM_FL_CBPENDING; + + OBD_ALLOC(w, sizeof(*w)); + LASSERT(w); + + w->w_lock = LDLM_LOCK_GET(lock); + list_add(&w->w_list, &list); + } + l_unlock(&ns->ns_lock); + + list_for_each_safe(tmp, next, &list) { + struct lustre_handle lockh; + int rc; + w = list_entry(tmp, struct ldlm_ast_work, w_list); + + ldlm_lock2handle(w->w_lock, &lockh); + rc = ldlm_cli_cancel(&lockh); + if (rc != ELDLM_OK) + CERROR("ldlm_cli_cancel: %d\n", rc); + + LDLM_LOCK_PUT(w->w_lock); + list_del(&w->w_list); + OBD_FREE(w, sizeof(*w)); + } + + RETURN(0); +} diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 23724c6..f5d8ee6 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -177,8 +177,6 @@ static int ll_file_release(struct inode *inode, struct file *file) struct obdo oa; struct ll_sb_info *sbi = ll_i2sbi(inode); struct ll_inode_info *lli = ll_i2info(inode); - //struct obd_device *obddev = class_conn2obd(&sbi->ll_osc_conn); - struct list_head *tmp, *next; ENTRY; @@ -243,23 +241,7 @@ static int ll_file_release(struct inode *inode, struct file *file) } ptlrpc_free_req(fd->fd_req); - // XXX Phil lov devices have no namespace - //l_lock(&obddev->obd_namespace->ns_lock); - list_for_each_safe(tmp, next, &lli->lli_osc_locks) { - struct ldlm_lock *lock; - struct lustre_handle lockh; - lock = list_entry(tmp, struct ldlm_lock, l_inode_link); - - if (!list_empty(&lock->l_inode_link)) { - list_del_init(&lock->l_inode_link); - LDLM_LOCK_PUT(lock); - } - ldlm_lock2handle(lock, &lockh); - rc = ldlm_cli_cancel(&lockh); - if (rc < 0) - CERROR("ldlm_cli_cancel: %d\n", rc); - } - //l_unlock(&obddev->obd_namespace->ns_lock); + //ldlm_cli_cancel_unused(); EXIT; @@ -321,13 +303,6 @@ int ll_lock_callback(struct ldlm_lock *lock, struct ldlm_lock_desc *new, up(&inode->i_sem); ldlm_lock2handle(lock, &lockh); - l_lock(&lock->l_resource->lr_namespace->ns_lock); - if (!list_empty(&lock->l_inode_link)) { - list_del_init(&lock->l_inode_link); - LDLM_LOCK_PUT(lock); - } - l_unlock(&lock->l_resource->lr_namespace->ns_lock); - rc = ldlm_cli_cancel(&lockh); if (rc != ELDLM_OK) CERROR("ldlm_cli_cancel failed: %d\n", rc); diff --git a/lustre/llite/super.c b/lustre/llite/super.c index 1d5dd71..01ec7c5 100644 --- a/lustre/llite/super.c +++ b/lustre/llite/super.c @@ -442,7 +442,6 @@ static void ll_read_inode2(struct inode *inode, void *opaque) ENTRY; sema_init(&ii->lli_open_sem, 1); - INIT_LIST_HEAD(&ii->lli_osc_locks); /* core attributes first */ if (body->valid & OBD_MD_FLID) @@ -467,8 +466,8 @@ static void ll_read_inode2(struct inode *inode, void *opaque) inode->i_generation = body->generation; if (body->valid & OBD_MD_FLRDEV) inode->i_rdev = body->extra; - //if (body->valid & OBD_MD_FLSIZE) - // inode->i_size = body->size; + if (body->valid & OBD_MD_FLSIZE) + inode->i_size = body->size; //if (body->valid & OBD_MD_FLEASIZE) diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 864d679..44dbec0 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -598,9 +598,6 @@ static int osc_enqueue(struct lustre_handle *connh, struct lov_stripe_md *md, __u64 res_id[RES_NAME_SIZE] = { md->lmd_object_id }; struct obd_device *obddev = class_conn2obd(connh); struct ldlm_extent *extent = extentp; - struct ldlm_lock *lock; - struct inode *inode = data; - struct ll_inode_info *lli = ll_i2info(inode); int rc; __u32 mode2; @@ -651,20 +648,6 @@ static int osc_enqueue(struct lustre_handle *connh, struct lov_stripe_md *md, parent_lock, res_id, type, extent, sizeof(extent), mode, flags, ldlm_completion_ast, callback, data, datalen, lockh); - if (rc) - return rc; - - /* This code must change if we ever stop passing an inode in as data */ - /* This is ldlm and llite code. It makes me sad that it's in - * osc_request.c --phil */ - lock = ldlm_handle2lock(lockh); - if (lock) { - /* Lock already has an extra ref from handle2lock */ - l_lock(&obddev->obd_namespace->ns_lock); - list_add(&lock->l_inode_link, &lli->lli_osc_locks); - l_unlock(&obddev->obd_namespace->ns_lock); - } - return rc; } -- 1.8.3.1