diff options
| author | Yoshihisa Abe <yoshiabe@cs.cmu.edu> | 2010-10-25 02:03:46 -0400 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-10-25 08:02:40 -0700 | 
| commit | da47c19e5c746829042933c8f945a71e2b62d6fc (patch) | |
| tree | 54110db260f57c01745e1ace343ec72b7eec6c69 | |
| parent | f7cc02b8715618e179242ba9cc10bdc5146ae565 (diff) | |
| download | olio-linux-3.10-da47c19e5c746829042933c8f945a71e2b62d6fc.tar.xz olio-linux-3.10-da47c19e5c746829042933c8f945a71e2b62d6fc.zip  | |
Coda: replace BKL with mutex
Replace the BKL with a mutex to protect the venus_comm structure which
binds the mountpoint with the character device and holds the upcall
queues.
Signed-off-by: Yoshihisa Abe <yoshiabe@cs.cmu.edu>
Signed-off-by: Jan Harkes <jaharkes@cs.cmu.edu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
| -rw-r--r-- | fs/coda/inode.c | 19 | ||||
| -rw-r--r-- | fs/coda/psdev.c | 28 | ||||
| -rw-r--r-- | fs/coda/upcall.c | 71 | ||||
| -rw-r--r-- | include/linux/coda_psdev.h | 2 | 
4 files changed, 70 insertions, 50 deletions
diff --git a/fs/coda/inode.c b/fs/coda/inode.c index b7fa3e3d772..7993b96ca34 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -15,7 +15,7 @@  #include <linux/stat.h>  #include <linux/errno.h>  #include <linux/unistd.h> -#include <linux/smp_lock.h> +#include <linux/mutex.h>  #include <linux/spinlock.h>  #include <linux/file.h>  #include <linux/vfs.h> @@ -145,7 +145,7 @@ static int get_device_index(struct coda_mount_data *data)  static int coda_fill_super(struct super_block *sb, void *data, int silent)  {  	struct inode *root = NULL; -	struct venus_comm *vc = NULL; +	struct venus_comm *vc;  	struct CodaFid fid;  	int error;  	int idx; @@ -159,7 +159,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)  	printk(KERN_INFO "coda_read_super: device index: %i\n", idx);  	vc = &coda_comms[idx]; -	lock_kernel(); +	mutex_lock(&vc->vc_mutex);  	if (!vc->vc_inuse) {  		printk("coda_read_super: No pseudo device\n"); @@ -178,7 +178,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)  		goto unlock_out;  	vc->vc_sb = sb; -	unlock_kernel(); +	mutex_unlock(&vc->vc_mutex);  	sb->s_fs_info = vc;  	sb->s_flags |= MS_NOATIME; @@ -217,20 +217,23 @@ error:  	if (root)  		iput(root); -	lock_kernel(); +	mutex_lock(&vc->vc_mutex);  	bdi_destroy(&vc->bdi);  	vc->vc_sb = NULL;  	sb->s_fs_info = NULL;  unlock_out: -	unlock_kernel(); +	mutex_unlock(&vc->vc_mutex);  	return error;  }  static void coda_put_super(struct super_block *sb)  { -	bdi_destroy(&coda_vcp(sb)->bdi); -	coda_vcp(sb)->vc_sb = NULL; +	struct venus_comm *vcp = coda_vcp(sb); +	mutex_lock(&vcp->vc_mutex); +	bdi_destroy(&vcp->bdi); +	vcp->vc_sb = NULL;  	sb->s_fs_info = NULL; +	mutex_unlock(&vcp->vc_mutex);  	printk("Coda: Bye bye.\n");  } diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c index 9a9248e632c..62647a8595e 100644 --- a/fs/coda/psdev.c +++ b/fs/coda/psdev.c @@ -35,7 +35,7 @@  #include <linux/poll.h>  #include <linux/init.h>  #include <linux/list.h> -#include <linux/smp_lock.h> +#include <linux/mutex.h>  #include <linux/device.h>  #include <asm/io.h>  #include <asm/system.h> @@ -67,8 +67,10 @@ static unsigned int coda_psdev_poll(struct file *file, poll_table * wait)  	unsigned int mask = POLLOUT | POLLWRNORM;  	poll_wait(file, &vcp->vc_waitq, wait); +	mutex_lock(&vcp->vc_mutex);  	if (!list_empty(&vcp->vc_pending))                  mask |= POLLIN | POLLRDNORM; +	mutex_unlock(&vcp->vc_mutex);  	return mask;  } @@ -143,7 +145,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,  	}  	/* Look for the message on the processing queue. */ -	lock_kernel(); +	mutex_lock(&vcp->vc_mutex);  	list_for_each(lh, &vcp->vc_processing) {  		tmp = list_entry(lh, struct upc_req , uc_chain);  		if (tmp->uc_unique == hdr.unique) { @@ -152,7 +154,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,  			break;  		}  	} -	unlock_kernel(); +	mutex_unlock(&vcp->vc_mutex);  	if (!req) {  		printk("psdev_write: msg (%d, %d) not found\n",  @@ -207,7 +209,7 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf,  	if (nbytes == 0)  		return 0; -	lock_kernel(); +	mutex_lock(&vcp->vc_mutex);  	add_wait_queue(&vcp->vc_waitq, &wait);  	set_current_state(TASK_INTERRUPTIBLE); @@ -221,7 +223,9 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf,  			retval = -ERESTARTSYS;  			break;  		} +		mutex_unlock(&vcp->vc_mutex);  		schedule(); +		mutex_lock(&vcp->vc_mutex);  	}  	set_current_state(TASK_RUNNING); @@ -254,7 +258,7 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf,  	CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));  	kfree(req);  out: -	unlock_kernel(); +	mutex_unlock(&vcp->vc_mutex);  	return (count ? count : retval);  } @@ -267,10 +271,10 @@ static int coda_psdev_open(struct inode * inode, struct file * file)  	if (idx < 0 || idx >= MAX_CODADEVS)  		return -ENODEV; -	lock_kernel(); -  	err = -EBUSY;  	vcp = &coda_comms[idx]; +	mutex_lock(&vcp->vc_mutex); +  	if (!vcp->vc_inuse) {  		vcp->vc_inuse++; @@ -284,7 +288,7 @@ static int coda_psdev_open(struct inode * inode, struct file * file)  		err = 0;  	} -	unlock_kernel(); +	mutex_unlock(&vcp->vc_mutex);  	return err;  } @@ -299,7 +303,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file)  		return -1;  	} -	lock_kernel(); +	mutex_lock(&vcp->vc_mutex);  	/* Wakeup clients so they can return. */  	list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { @@ -324,7 +328,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file)  	file->private_data = NULL;  	vcp->vc_inuse--; -	unlock_kernel(); +	mutex_unlock(&vcp->vc_mutex);  	return 0;  } @@ -353,9 +357,11 @@ static int init_coda_psdev(void)  		err = PTR_ERR(coda_psdev_class);  		goto out_chrdev;  	}		 -	for (i = 0; i < MAX_CODADEVS; i++) +	for (i = 0; i < MAX_CODADEVS; i++) { +		mutex_init(&(&coda_comms[i])->vc_mutex);  		device_create(coda_psdev_class, NULL,  			      MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i); +	}  	coda_sysctl_init();  	goto out; diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index 4c258cb5266..c3563cab975 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c @@ -27,7 +27,7 @@  #include <linux/errno.h>  #include <linux/string.h>  #include <linux/slab.h> -#include <linux/smp_lock.h> +#include <linux/mutex.h>  #include <asm/uaccess.h>  #include <linux/vmalloc.h>  #include <linux/vfs.h> @@ -607,7 +607,8 @@ static void coda_unblock_signals(sigset_t *old)  				 (r)->uc_opcode != CODA_RELEASE) || \  				(r)->uc_flags & CODA_REQ_READ)) -static inline void coda_waitfor_upcall(struct upc_req *req) +static inline void coda_waitfor_upcall(struct venus_comm *vcp, +				       struct upc_req *req)  {  	DECLARE_WAITQUEUE(wait, current);  	unsigned long timeout = jiffies + coda_timeout * HZ; @@ -640,10 +641,12 @@ static inline void coda_waitfor_upcall(struct upc_req *req)  			break;  		} +		mutex_unlock(&vcp->vc_mutex);  		if (blocked)  			schedule_timeout(HZ);  		else  			schedule(); +		mutex_lock(&vcp->vc_mutex);  	}  	if (blocked)  		coda_unblock_signals(&old); @@ -671,7 +674,7 @@ static int coda_upcall(struct venus_comm *vcp,  	struct upc_req *req = NULL, *sig_req;  	int error; -	lock_kernel(); +	mutex_lock(&vcp->vc_mutex);  	if (!vcp->vc_inuse) {  		printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n"); @@ -711,7 +714,7 @@ static int coda_upcall(struct venus_comm *vcp,  	 * ENODEV.  */  	/* Go to sleep.  Wake up on signals only after the timeout. */ -	coda_waitfor_upcall(req); +	coda_waitfor_upcall(vcp, req);  	/* Op went through, interrupt or not... */  	if (req->uc_flags & CODA_REQ_WRITE) { @@ -765,7 +768,7 @@ static int coda_upcall(struct venus_comm *vcp,  exit:  	kfree(req); -	unlock_kernel(); +	mutex_unlock(&vcp->vc_mutex);  	return error;  } @@ -806,11 +809,11 @@ exit:  int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)  {  	struct inode *inode = NULL; -	struct CodaFid *fid, *newfid; +	struct CodaFid *fid = NULL, *newfid;  	struct super_block *sb;  	/* Handle invalidation requests. */ -	lock_kernel(); +	mutex_lock(&vcp->vc_mutex);  	sb = vcp->vc_sb;  	if (!sb || !sb->s_root)  		goto unlock_out; @@ -829,47 +832,53 @@ int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)  	case CODA_ZAPDIR:  		fid = &out->coda_zapdir.CodaFid; -		inode = coda_fid_to_inode(fid, sb); -		if (inode) { -			coda_flag_inode_children(inode, C_PURGE); -			coda_flag_inode(inode, C_VATTR); -		}  		break;  	case CODA_ZAPFILE:  		fid = &out->coda_zapfile.CodaFid; -		inode = coda_fid_to_inode(fid, sb); -		if (inode) -			coda_flag_inode(inode, C_VATTR);  		break;  	case CODA_PURGEFID:  		fid = &out->coda_purgefid.CodaFid; -		inode = coda_fid_to_inode(fid, sb); -		if (inode) { -			coda_flag_inode_children(inode, C_PURGE); - -			/* catch the dentries later if some are still busy */ -			coda_flag_inode(inode, C_PURGE); -			d_prune_aliases(inode); - -		}  		break;  	case CODA_REPLACE:  		fid = &out->coda_replace.OldFid; -		newfid = &out->coda_replace.NewFid; -		inode = coda_fid_to_inode(fid, sb); -		if (inode) -			coda_replace_fid(inode, fid, newfid);  		break;  	} +	if (fid) +		inode = coda_fid_to_inode(fid, sb);  unlock_out: -	unlock_kernel(); +	mutex_unlock(&vcp->vc_mutex); + +	if (!inode) +		return 0; + +	switch (opcode) { +	case CODA_ZAPDIR: +		coda_flag_inode_children(inode, C_PURGE); +		coda_flag_inode(inode, C_VATTR); +		break; + +	case CODA_ZAPFILE: +		coda_flag_inode(inode, C_VATTR); +		break; + +	case CODA_PURGEFID: +		coda_flag_inode_children(inode, C_PURGE); -	if (inode) -		iput(inode); +		/* catch the dentries later if some are still busy */ +		coda_flag_inode(inode, C_PURGE); +		d_prune_aliases(inode); +		break; + +	case CODA_REPLACE: +		newfid = &out->coda_replace.NewFid; +		coda_replace_fid(inode, fid, newfid); +		break; +	} +	iput(inode);  	return 0;  } diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h index 1e60c5a41a5..72f2d2f0af9 100644 --- a/include/linux/coda_psdev.h +++ b/include/linux/coda_psdev.h @@ -8,6 +8,7 @@  #ifdef __KERNEL__  #include <linux/backing-dev.h> +#include <linux/mutex.h>  struct kstatfs; @@ -20,6 +21,7 @@ struct venus_comm {  	int                 vc_inuse;  	struct super_block *vc_sb;  	struct backing_dev_info bdi; +	struct mutex	    vc_mutex;  };  |