Commit 87065519633af79e0577e32a58dcd9cf3c45a8a0

Authored by Jan Harkes
Committed by Linus Torvalds
1 parent ed31a7dd63

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 <jaharkes@cs.cmu.edu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 2 changed files with 32 additions and 38 deletions Side-by-side Diff

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