Whamcloud - gitweb
- removed lock list from inode info
authorpschwan <pschwan>
Thu, 22 Aug 2002 20:46:29 +0000 (20:46 +0000)
committerpschwan <pschwan>
Thu, 22 Aug 2002 20:46:29 +0000 (20:46 +0000)
- added a function to cleanup unused locks on a resource
- fixed readdir

lustre/include/linux/lustre_dlm.h
lustre/include/linux/lustre_lite.h
lustre/ldlm/ldlm_lock.c
lustre/ldlm/ldlm_request.c
lustre/llite/file.c
lustre/llite/super.c
lustre/osc/osc_request.c

index d43c366..7db70b2 100644 (file)
@@ -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. */
index d48f32e..6ebd91b 100644 (file)
@@ -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
index d1edbdb..0f44c99 100644 (file)
@@ -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
index c50bb47..cbf3aeb 100644 (file)
@@ -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);
+}
index 23724c6..f5d8ee6 100644 (file)
@@ -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);
index 1d5dd71..01ec7c5 100644 (file)
@@ -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)
index 864d679..44dbec0 100644 (file)
@@ -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;
 }