Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=87065519633af79e0577e32a58dcd9cf3c45a8a0
Commit:     87065519633af79e0577e32a58dcd9cf3c45a8a0
Parent:     ed31a7dd636b296746c131b7386023aa1ef84309
Author:     Jan Harkes <[EMAIL PROTECTED]>
AuthorDate: Thu Jul 19 01:48:45 2007 -0700
Committer:  Linus Torvalds <[EMAIL PROTECTED]>
CommitDate: Thu Jul 19 10:04:48 2007 -0700

    coda: cleanup /dev/cfs open and close handling
    
    - Make sure device index is not a negative number.
    - Unlink queued requests when the device is closed to avoid passing them
      to the next opener.
    
    Signed-off-by: Jan Harkes <[EMAIL PROTECTED]>
    Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
    Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
---
 fs/coda/psdev.c  |   61 ++++++++++++++++++++++++++---------------------------
 fs/coda/upcall.c |    9 +------
 2 files changed, 32 insertions(+), 38 deletions(-)

diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 09382d4..6818c20 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -272,56 +272,51 @@ out:
 
 static int coda_psdev_open(struct inode * inode, struct file * file)
 {
-        struct venus_comm *vcp;
-       int idx;
+       struct venus_comm *vcp;
+       int idx, err;
 
-       lock_kernel();
        idx = iminor(inode);
-       if(idx >= MAX_CODADEVS) {
-               unlock_kernel();
+       if (idx < 0 || idx >= MAX_CODADEVS)
                return -ENODEV;
-       }
 
+       lock_kernel();
+
+       err = -EBUSY;
        vcp = &coda_comms[idx];
-       if(vcp->vc_inuse) {
-               unlock_kernel();
-               return -EBUSY;
-       }
-       
-       if (!vcp->vc_inuse++) {
+       if (!vcp->vc_inuse) {
+               vcp->vc_inuse++;
+
                INIT_LIST_HEAD(&vcp->vc_pending);
                INIT_LIST_HEAD(&vcp->vc_processing);
                init_waitqueue_head(&vcp->vc_waitq);
                vcp->vc_sb = NULL;
                vcp->vc_seq = 0;
+
+               file->private_data = vcp;
+               err = 0;
        }
-       
-       file->private_data = vcp;
 
        unlock_kernel();
-        return 0;
+       return err;
 }
 
 
 static int coda_psdev_release(struct inode * inode, struct file * file)
 {
-        struct venus_comm *vcp = (struct venus_comm *) file->private_data;
-        struct upc_req *req, *tmp;
+       struct venus_comm *vcp = (struct venus_comm *) file->private_data;
+       struct upc_req *req, *tmp;
 
-       lock_kernel();
-       if ( !vcp->vc_inuse ) {
-               unlock_kernel();
+       if (!vcp || !vcp->vc_inuse ) {
                printk("psdev_release: Not open.\n");
                return -1;
        }
 
-       if (--vcp->vc_inuse) {
-               unlock_kernel();
-               return 0;
-       }
-        
-        /* Wakeup clients so they can return. */
+       lock_kernel();
+
+       /* Wakeup clients so they can return. */
        list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) {
+               list_del(&req->uc_chain);
+
                /* Async requests need to be freed here */
                if (req->uc_flags & REQ_ASYNC) {
                        CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
@@ -330,13 +325,17 @@ static int coda_psdev_release(struct inode * inode, 
struct file * file)
                }
                req->uc_flags |= REQ_ABORT;
                wake_up(&req->uc_sleep);
-        }
-        
-       list_for_each_entry(req, &vcp->vc_processing, uc_chain) {
+       }
+
+       list_for_each_entry_safe(req, tmp, &vcp->vc_processing, uc_chain) {
+               list_del(&req->uc_chain);
+
                req->uc_flags |= REQ_ABORT;
-               wake_up(&req->uc_sleep);
-        }
+               wake_up(&req->uc_sleep);
+       }
 
+       file->private_data = NULL;
+       vcp->vc_inuse--;
        unlock_kernel();
        return 0;
 }
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c
index 1651b91..a44ca41 100644
--- a/fs/coda/upcall.c
+++ b/fs/coda/upcall.c
@@ -641,8 +641,7 @@ int venus_statfs(struct dentry *dentry, struct kstatfs *sfs)
  * 
  */
 
-static inline void coda_waitfor_upcall(struct upc_req *vmp,
-                                      struct venus_comm *vcommp)
+static inline void coda_waitfor_upcall(struct upc_req *vmp)
 {
        DECLARE_WAITQUEUE(wait, current);
 
@@ -655,10 +654,6 @@ static inline void coda_waitfor_upcall(struct upc_req *vmp,
                else
                        set_current_state(TASK_UNINTERRUPTIBLE);
 
-                /* venus died */
-                if ( !vcommp->vc_inuse )
-                        break;
-
                /* got a reply */
                if ( vmp->uc_flags & ( REQ_WRITE | REQ_ABORT ) )
                        break;
@@ -738,7 +733,7 @@ static int coda_upcall(struct coda_sb_info *sbi,
         * ENODEV.  */
 
        /* Go to sleep.  Wake up on signals only after the timeout. */
-       coda_waitfor_upcall(req, vcommp);
+       coda_waitfor_upcall(req);
 
        if (vcommp->vc_inuse) {      /* i.e. Venus is still alive */
            /* Op went through, interrupt or not... */
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to