Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 87065519 authored by Jan Harkes's avatar Jan Harkes Committed by Linus Torvalds
Browse files

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: default avatarJan Harkes <jaharkes@cs.cmu.edu>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent ed31a7dd
Loading
Loading
Loading
Loading
+30 −31
Original line number Original line Diff line number Diff line
@@ -273,33 +273,31 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf,
static int coda_psdev_open(struct inode * inode, struct file * file)
static int coda_psdev_open(struct inode * inode, struct file * file)
{
{
	struct venus_comm *vcp;
	struct venus_comm *vcp;
	int idx;
	int idx, err;


	lock_kernel();
	idx = iminor(inode);
	idx = iminor(inode);
	if(idx >= MAX_CODADEVS) {
	if (idx < 0 || idx >= MAX_CODADEVS)
		unlock_kernel();
		return -ENODEV;
		return -ENODEV;
	}


	lock_kernel();

	err = -EBUSY;
	vcp = &coda_comms[idx];
	vcp = &coda_comms[idx];
	if(vcp->vc_inuse) {
	if (!vcp->vc_inuse) {
		unlock_kernel();
		vcp->vc_inuse++;
		return -EBUSY;
	}


	if (!vcp->vc_inuse++) {
		INIT_LIST_HEAD(&vcp->vc_pending);
		INIT_LIST_HEAD(&vcp->vc_pending);
		INIT_LIST_HEAD(&vcp->vc_processing);
		INIT_LIST_HEAD(&vcp->vc_processing);
		init_waitqueue_head(&vcp->vc_waitq);
		init_waitqueue_head(&vcp->vc_waitq);
		vcp->vc_sb = NULL;
		vcp->vc_sb = NULL;
		vcp->vc_seq = 0;
		vcp->vc_seq = 0;
	}


		file->private_data = vcp;
		file->private_data = vcp;
		err = 0;
	}


	unlock_kernel();
	unlock_kernel();
        return 0;
	return err;
}
}




@@ -308,20 +306,17 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
	struct venus_comm *vcp = (struct venus_comm *) file->private_data;
	struct venus_comm *vcp = (struct venus_comm *) file->private_data;
	struct upc_req *req, *tmp;
	struct upc_req *req, *tmp;


	lock_kernel();
	if (!vcp || !vcp->vc_inuse ) {
	if ( !vcp->vc_inuse ) {
		unlock_kernel();
		printk("psdev_release: Not open.\n");
		printk("psdev_release: Not open.\n");
		return -1;
		return -1;
	}
	}


	if (--vcp->vc_inuse) {
	lock_kernel();
		unlock_kernel();
		return 0;
	}


	/* Wakeup clients so they can return. */
	/* Wakeup clients so they can return. */
	list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) {
	list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) {
		list_del(&req->uc_chain);

		/* Async requests need to be freed here */
		/* Async requests need to be freed here */
		if (req->uc_flags & REQ_ASYNC) {
		if (req->uc_flags & REQ_ASYNC) {
			CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
			CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
@@ -332,11 +327,15 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
		wake_up(&req->uc_sleep);
		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;
		req->uc_flags |= REQ_ABORT;
		wake_up(&req->uc_sleep);
		wake_up(&req->uc_sleep);
	}
	}


	file->private_data = NULL;
	vcp->vc_inuse--;
	unlock_kernel();
	unlock_kernel();
	return 0;
	return 0;
}
}
+2 −7
Original line number Original line Diff line number Diff line
@@ -641,8 +641,7 @@ int venus_statfs(struct dentry *dentry, struct kstatfs *sfs)
 * 
 * 
 */
 */


static inline void coda_waitfor_upcall(struct upc_req *vmp,
static inline void coda_waitfor_upcall(struct upc_req *vmp)
				       struct venus_comm *vcommp)
{
{
	DECLARE_WAITQUEUE(wait, current);
	DECLARE_WAITQUEUE(wait, current);


@@ -655,10 +654,6 @@ static inline void coda_waitfor_upcall(struct upc_req *vmp,
		else
		else
			set_current_state(TASK_UNINTERRUPTIBLE);
			set_current_state(TASK_UNINTERRUPTIBLE);


                /* venus died */
                if ( !vcommp->vc_inuse )
                        break;

		/* got a reply */
		/* got a reply */
		if ( vmp->uc_flags & ( REQ_WRITE | REQ_ABORT ) )
		if ( vmp->uc_flags & ( REQ_WRITE | REQ_ABORT ) )
			break;
			break;
@@ -738,7 +733,7 @@ static int coda_upcall(struct coda_sb_info *sbi,
	 * ENODEV.  */
	 * ENODEV.  */


	/* Go to sleep.  Wake up on signals only after the timeout. */
	/* 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 */
	if (vcommp->vc_inuse) {      /* i.e. Venus is still alive */
	    /* Op went through, interrupt or not... */
	    /* Op went through, interrupt or not... */