diff options
| -rw-r--r-- | fs/coda/psdev.c | 61 | ||||
| -rw-r--r-- | 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 09382d47a4e1..6818c20372ca 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c | |||
| @@ -272,56 +272,51 @@ out: | |||
| 272 | 272 | ||
| 273 | static int coda_psdev_open(struct inode * inode, struct file * file) | 273 | static int coda_psdev_open(struct inode * inode, struct file * file) |
| 274 | { | 274 | { |
| 275 | struct venus_comm *vcp; | 275 | struct venus_comm *vcp; |
| 276 | int idx; | 276 | int idx, err; |
| 277 | 277 | ||
| 278 | lock_kernel(); | ||
| 279 | idx = iminor(inode); | 278 | idx = iminor(inode); |
| 280 | if(idx >= MAX_CODADEVS) { | 279 | if (idx < 0 || idx >= MAX_CODADEVS) |
| 281 | unlock_kernel(); | ||
| 282 | return -ENODEV; | 280 | return -ENODEV; |
| 283 | } | ||
| 284 | 281 | ||
| 282 | lock_kernel(); | ||
| 283 | |||
| 284 | err = -EBUSY; | ||
| 285 | vcp = &coda_comms[idx]; | 285 | vcp = &coda_comms[idx]; |
| 286 | if(vcp->vc_inuse) { | 286 | if (!vcp->vc_inuse) { |
| 287 | unlock_kernel(); | 287 | vcp->vc_inuse++; |
| 288 | return -EBUSY; | 288 | |
| 289 | } | ||
| 290 | |||
| 291 | if (!vcp->vc_inuse++) { | ||
| 292 | INIT_LIST_HEAD(&vcp->vc_pending); | 289 | INIT_LIST_HEAD(&vcp->vc_pending); |
| 293 | INIT_LIST_HEAD(&vcp->vc_processing); | 290 | INIT_LIST_HEAD(&vcp->vc_processing); |
| 294 | init_waitqueue_head(&vcp->vc_waitq); | 291 | init_waitqueue_head(&vcp->vc_waitq); |
| 295 | vcp->vc_sb = NULL; | 292 | vcp->vc_sb = NULL; |
| 296 | vcp->vc_seq = 0; | 293 | vcp->vc_seq = 0; |
| 294 | |||
| 295 | file->private_data = vcp; | ||
| 296 | err = 0; | ||
| 297 | } | 297 | } |
| 298 | |||
| 299 | file->private_data = vcp; | ||
| 300 | 298 | ||
| 301 | unlock_kernel(); | 299 | unlock_kernel(); |
| 302 | return 0; | 300 | return err; |
| 303 | } | 301 | } |
| 304 | 302 | ||
| 305 | 303 | ||
| 306 | static int coda_psdev_release(struct inode * inode, struct file * file) | 304 | static int coda_psdev_release(struct inode * inode, struct file * file) |
| 307 | { | 305 | { |
| 308 | struct venus_comm *vcp = (struct venus_comm *) file->private_data; | 306 | struct venus_comm *vcp = (struct venus_comm *) file->private_data; |
| 309 | struct upc_req *req, *tmp; | 307 | struct upc_req *req, *tmp; |
| 310 | 308 | ||
| 311 | lock_kernel(); | 309 | if (!vcp || !vcp->vc_inuse ) { |
| 312 | if ( !vcp->vc_inuse ) { | ||
| 313 | unlock_kernel(); | ||
| 314 | printk("psdev_release: Not open.\n"); | 310 | printk("psdev_release: Not open.\n"); |
| 315 | return -1; | 311 | return -1; |
| 316 | } | 312 | } |
| 317 | 313 | ||
| 318 | if (--vcp->vc_inuse) { | 314 | lock_kernel(); |
| 319 | unlock_kernel(); | 315 | |
| 320 | return 0; | 316 | /* Wakeup clients so they can return. */ |
| 321 | } | ||
| 322 | |||
| 323 | /* Wakeup clients so they can return. */ | ||
| 324 | list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { | 317 | list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { |
| 318 | list_del(&req->uc_chain); | ||
| 319 | |||
| 325 | /* Async requests need to be freed here */ | 320 | /* Async requests need to be freed here */ |
| 326 | if (req->uc_flags & REQ_ASYNC) { | 321 | if (req->uc_flags & REQ_ASYNC) { |
| 327 | CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr)); | 322 | 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) | |||
| 330 | } | 325 | } |
| 331 | req->uc_flags |= REQ_ABORT; | 326 | req->uc_flags |= REQ_ABORT; |
| 332 | wake_up(&req->uc_sleep); | 327 | wake_up(&req->uc_sleep); |
| 333 | } | 328 | } |
| 334 | 329 | ||
| 335 | list_for_each_entry(req, &vcp->vc_processing, uc_chain) { | 330 | list_for_each_entry_safe(req, tmp, &vcp->vc_processing, uc_chain) { |
| 331 | list_del(&req->uc_chain); | ||
| 332 | |||
| 336 | req->uc_flags |= REQ_ABORT; | 333 | req->uc_flags |= REQ_ABORT; |
| 337 | wake_up(&req->uc_sleep); | 334 | wake_up(&req->uc_sleep); |
| 338 | } | 335 | } |
| 339 | 336 | ||
| 337 | file->private_data = NULL; | ||
| 338 | vcp->vc_inuse--; | ||
| 340 | unlock_kernel(); | 339 | unlock_kernel(); |
| 341 | return 0; | 340 | return 0; |
| 342 | } | 341 | } |
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index 1651b918219a..a44ca4155fd5 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c | |||
| @@ -641,8 +641,7 @@ int venus_statfs(struct dentry *dentry, struct kstatfs *sfs) | |||
| 641 | * | 641 | * |
| 642 | */ | 642 | */ |
| 643 | 643 | ||
| 644 | static inline void coda_waitfor_upcall(struct upc_req *vmp, | 644 | static inline void coda_waitfor_upcall(struct upc_req *vmp) |
| 645 | struct venus_comm *vcommp) | ||
| 646 | { | 645 | { |
| 647 | DECLARE_WAITQUEUE(wait, current); | 646 | DECLARE_WAITQUEUE(wait, current); |
| 648 | 647 | ||
| @@ -655,10 +654,6 @@ static inline void coda_waitfor_upcall(struct upc_req *vmp, | |||
| 655 | else | 654 | else |
| 656 | set_current_state(TASK_UNINTERRUPTIBLE); | 655 | set_current_state(TASK_UNINTERRUPTIBLE); |
| 657 | 656 | ||
| 658 | /* venus died */ | ||
| 659 | if ( !vcommp->vc_inuse ) | ||
| 660 | break; | ||
| 661 | |||
| 662 | /* got a reply */ | 657 | /* got a reply */ |
| 663 | if ( vmp->uc_flags & ( REQ_WRITE | REQ_ABORT ) ) | 658 | if ( vmp->uc_flags & ( REQ_WRITE | REQ_ABORT ) ) |
| 664 | break; | 659 | break; |
| @@ -738,7 +733,7 @@ static int coda_upcall(struct coda_sb_info *sbi, | |||
| 738 | * ENODEV. */ | 733 | * ENODEV. */ |
| 739 | 734 | ||
| 740 | /* Go to sleep. Wake up on signals only after the timeout. */ | 735 | /* Go to sleep. Wake up on signals only after the timeout. */ |
| 741 | coda_waitfor_upcall(req, vcommp); | 736 | coda_waitfor_upcall(req); |
| 742 | 737 | ||
| 743 | if (vcommp->vc_inuse) { /* i.e. Venus is still alive */ | 738 | if (vcommp->vc_inuse) { /* i.e. Venus is still alive */ |
| 744 | /* Op went through, interrupt or not... */ | 739 | /* Op went through, interrupt or not... */ |
