Commit da47c19e authored by Yoshihisa Abe's avatar Yoshihisa Abe Committed by Linus Torvalds

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: default avatarYoshihisa Abe <yoshiabe@cs.cmu.edu>
Signed-off-by: default avatarJan Harkes <jaharkes@cs.cmu.edu>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f7cc02b8
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <linux/smp_lock.h> #include <linux/mutex.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/vfs.h> #include <linux/vfs.h>
...@@ -145,7 +145,7 @@ static int get_device_index(struct coda_mount_data *data) ...@@ -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) static int coda_fill_super(struct super_block *sb, void *data, int silent)
{ {
struct inode *root = NULL; struct inode *root = NULL;
struct venus_comm *vc = NULL; struct venus_comm *vc;
struct CodaFid fid; struct CodaFid fid;
int error; int error;
int idx; int idx;
...@@ -159,7 +159,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) ...@@ -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); printk(KERN_INFO "coda_read_super: device index: %i\n", idx);
vc = &coda_comms[idx]; vc = &coda_comms[idx];
lock_kernel(); mutex_lock(&vc->vc_mutex);
if (!vc->vc_inuse) { if (!vc->vc_inuse) {
printk("coda_read_super: No pseudo device\n"); 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) ...@@ -178,7 +178,7 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
goto unlock_out; goto unlock_out;
vc->vc_sb = sb; vc->vc_sb = sb;
unlock_kernel(); mutex_unlock(&vc->vc_mutex);
sb->s_fs_info = vc; sb->s_fs_info = vc;
sb->s_flags |= MS_NOATIME; sb->s_flags |= MS_NOATIME;
...@@ -217,20 +217,23 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent) ...@@ -217,20 +217,23 @@ static int coda_fill_super(struct super_block *sb, void *data, int silent)
if (root) if (root)
iput(root); iput(root);
lock_kernel(); mutex_lock(&vc->vc_mutex);
bdi_destroy(&vc->bdi); bdi_destroy(&vc->bdi);
vc->vc_sb = NULL; vc->vc_sb = NULL;
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
unlock_out: unlock_out:
unlock_kernel(); mutex_unlock(&vc->vc_mutex);
return error; return error;
} }
static void coda_put_super(struct super_block *sb) static void coda_put_super(struct super_block *sb)
{ {
bdi_destroy(&coda_vcp(sb)->bdi); struct venus_comm *vcp = coda_vcp(sb);
coda_vcp(sb)->vc_sb = NULL; mutex_lock(&vcp->vc_mutex);
bdi_destroy(&vcp->bdi);
vcp->vc_sb = NULL;
sb->s_fs_info = NULL; sb->s_fs_info = NULL;
mutex_unlock(&vcp->vc_mutex);
printk("Coda: Bye bye.\n"); printk("Coda: Bye bye.\n");
} }
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include <linux/poll.h> #include <linux/poll.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/smp_lock.h> #include <linux/mutex.h>
#include <linux/device.h> #include <linux/device.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/system.h> #include <asm/system.h>
...@@ -67,8 +67,10 @@ static unsigned int coda_psdev_poll(struct file *file, poll_table * wait) ...@@ -67,8 +67,10 @@ static unsigned int coda_psdev_poll(struct file *file, poll_table * wait)
unsigned int mask = POLLOUT | POLLWRNORM; unsigned int mask = POLLOUT | POLLWRNORM;
poll_wait(file, &vcp->vc_waitq, wait); poll_wait(file, &vcp->vc_waitq, wait);
mutex_lock(&vcp->vc_mutex);
if (!list_empty(&vcp->vc_pending)) if (!list_empty(&vcp->vc_pending))
mask |= POLLIN | POLLRDNORM; mask |= POLLIN | POLLRDNORM;
mutex_unlock(&vcp->vc_mutex);
return mask; return mask;
} }
...@@ -143,7 +145,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, ...@@ -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. */ /* Look for the message on the processing queue. */
lock_kernel(); mutex_lock(&vcp->vc_mutex);
list_for_each(lh, &vcp->vc_processing) { list_for_each(lh, &vcp->vc_processing) {
tmp = list_entry(lh, struct upc_req , uc_chain); tmp = list_entry(lh, struct upc_req , uc_chain);
if (tmp->uc_unique == hdr.unique) { if (tmp->uc_unique == hdr.unique) {
...@@ -152,7 +154,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf, ...@@ -152,7 +154,7 @@ static ssize_t coda_psdev_write(struct file *file, const char __user *buf,
break; break;
} }
} }
unlock_kernel(); mutex_unlock(&vcp->vc_mutex);
if (!req) { if (!req) {
printk("psdev_write: msg (%d, %d) not found\n", 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, ...@@ -207,7 +209,7 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf,
if (nbytes == 0) if (nbytes == 0)
return 0; return 0;
lock_kernel(); mutex_lock(&vcp->vc_mutex);
add_wait_queue(&vcp->vc_waitq, &wait); add_wait_queue(&vcp->vc_waitq, &wait);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
...@@ -221,7 +223,9 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf, ...@@ -221,7 +223,9 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf,
retval = -ERESTARTSYS; retval = -ERESTARTSYS;
break; break;
} }
mutex_unlock(&vcp->vc_mutex);
schedule(); schedule();
mutex_lock(&vcp->vc_mutex);
} }
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
...@@ -254,7 +258,7 @@ static ssize_t coda_psdev_read(struct file * file, char __user * buf, ...@@ -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)); CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
kfree(req); kfree(req);
out: out:
unlock_kernel(); mutex_unlock(&vcp->vc_mutex);
return (count ? count : retval); return (count ? count : retval);
} }
...@@ -267,10 +271,10 @@ static int coda_psdev_open(struct inode * inode, struct file * file) ...@@ -267,10 +271,10 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
if (idx < 0 || idx >= MAX_CODADEVS) if (idx < 0 || idx >= MAX_CODADEVS)
return -ENODEV; return -ENODEV;
lock_kernel();
err = -EBUSY; err = -EBUSY;
vcp = &coda_comms[idx]; vcp = &coda_comms[idx];
mutex_lock(&vcp->vc_mutex);
if (!vcp->vc_inuse) { if (!vcp->vc_inuse) {
vcp->vc_inuse++; vcp->vc_inuse++;
...@@ -284,7 +288,7 @@ static int coda_psdev_open(struct inode * inode, struct file * file) ...@@ -284,7 +288,7 @@ static int coda_psdev_open(struct inode * inode, struct file * file)
err = 0; err = 0;
} }
unlock_kernel(); mutex_unlock(&vcp->vc_mutex);
return err; return err;
} }
...@@ -299,7 +303,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file) ...@@ -299,7 +303,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
return -1; return -1;
} }
lock_kernel(); mutex_lock(&vcp->vc_mutex);
/* 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) {
...@@ -324,7 +328,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file) ...@@ -324,7 +328,7 @@ static int coda_psdev_release(struct inode * inode, struct file * file)
file->private_data = NULL; file->private_data = NULL;
vcp->vc_inuse--; vcp->vc_inuse--;
unlock_kernel(); mutex_unlock(&vcp->vc_mutex);
return 0; return 0;
} }
...@@ -353,9 +357,11 @@ static int init_coda_psdev(void) ...@@ -353,9 +357,11 @@ static int init_coda_psdev(void)
err = PTR_ERR(coda_psdev_class); err = PTR_ERR(coda_psdev_class);
goto out_chrdev; 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, device_create(coda_psdev_class, NULL,
MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i); MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i);
}
coda_sysctl_init(); coda_sysctl_init();
goto out; goto out;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/smp_lock.h> #include <linux/mutex.h>
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/vfs.h> #include <linux/vfs.h>
...@@ -607,7 +607,8 @@ static void coda_unblock_signals(sigset_t *old) ...@@ -607,7 +607,8 @@ static void coda_unblock_signals(sigset_t *old)
(r)->uc_opcode != CODA_RELEASE) || \ (r)->uc_opcode != CODA_RELEASE) || \
(r)->uc_flags & CODA_REQ_READ)) (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); DECLARE_WAITQUEUE(wait, current);
unsigned long timeout = jiffies + coda_timeout * HZ; unsigned long timeout = jiffies + coda_timeout * HZ;
...@@ -640,10 +641,12 @@ static inline void coda_waitfor_upcall(struct upc_req *req) ...@@ -640,10 +641,12 @@ static inline void coda_waitfor_upcall(struct upc_req *req)
break; break;
} }
mutex_unlock(&vcp->vc_mutex);
if (blocked) if (blocked)
schedule_timeout(HZ); schedule_timeout(HZ);
else else
schedule(); schedule();
mutex_lock(&vcp->vc_mutex);
} }
if (blocked) if (blocked)
coda_unblock_signals(&old); coda_unblock_signals(&old);
...@@ -671,7 +674,7 @@ static int coda_upcall(struct venus_comm *vcp, ...@@ -671,7 +674,7 @@ static int coda_upcall(struct venus_comm *vcp,
struct upc_req *req = NULL, *sig_req; struct upc_req *req = NULL, *sig_req;
int error; int error;
lock_kernel(); mutex_lock(&vcp->vc_mutex);
if (!vcp->vc_inuse) { if (!vcp->vc_inuse) {
printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n"); printk(KERN_NOTICE "coda: Venus dead, not sending upcall\n");
...@@ -711,7 +714,7 @@ static int coda_upcall(struct venus_comm *vcp, ...@@ -711,7 +714,7 @@ static int coda_upcall(struct venus_comm *vcp,
* 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); coda_waitfor_upcall(vcp, req);
/* Op went through, interrupt or not... */ /* Op went through, interrupt or not... */
if (req->uc_flags & CODA_REQ_WRITE) { if (req->uc_flags & CODA_REQ_WRITE) {
...@@ -765,7 +768,7 @@ static int coda_upcall(struct venus_comm *vcp, ...@@ -765,7 +768,7 @@ static int coda_upcall(struct venus_comm *vcp,
exit: exit:
kfree(req); kfree(req);
unlock_kernel(); mutex_unlock(&vcp->vc_mutex);
return error; return error;
} }
...@@ -806,11 +809,11 @@ static int coda_upcall(struct venus_comm *vcp, ...@@ -806,11 +809,11 @@ static int coda_upcall(struct venus_comm *vcp,
int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out) int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
{ {
struct inode *inode = NULL; struct inode *inode = NULL;
struct CodaFid *fid, *newfid; struct CodaFid *fid = NULL, *newfid;
struct super_block *sb; struct super_block *sb;
/* Handle invalidation requests. */ /* Handle invalidation requests. */
lock_kernel(); mutex_lock(&vcp->vc_mutex);
sb = vcp->vc_sb; sb = vcp->vc_sb;
if (!sb || !sb->s_root) if (!sb || !sb->s_root)
goto unlock_out; goto unlock_out;
...@@ -829,46 +832,52 @@ int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out) ...@@ -829,46 +832,52 @@ int coda_downcall(struct venus_comm *vcp, int opcode, union outputArgs *out)
case CODA_ZAPDIR: case CODA_ZAPDIR:
fid = &out->coda_zapdir.CodaFid; fid = &out->coda_zapdir.CodaFid;
break;
case CODA_ZAPFILE:
fid = &out->coda_zapfile.CodaFid;
break;
case CODA_PURGEFID:
fid = &out->coda_purgefid.CodaFid;
break;
case CODA_REPLACE:
fid = &out->coda_replace.OldFid;
break;
}
if (fid)
inode = coda_fid_to_inode(fid, sb); inode = coda_fid_to_inode(fid, sb);
if (inode) {
unlock_out:
mutex_unlock(&vcp->vc_mutex);
if (!inode)
return 0;
switch (opcode) {
case CODA_ZAPDIR:
coda_flag_inode_children(inode, C_PURGE); coda_flag_inode_children(inode, C_PURGE);
coda_flag_inode(inode, C_VATTR); coda_flag_inode(inode, C_VATTR);
}
break; break;
case CODA_ZAPFILE: case CODA_ZAPFILE:
fid = &out->coda_zapfile.CodaFid;
inode = coda_fid_to_inode(fid, sb);
if (inode)
coda_flag_inode(inode, C_VATTR); coda_flag_inode(inode, C_VATTR);
break; break;
case CODA_PURGEFID: case CODA_PURGEFID:
fid = &out->coda_purgefid.CodaFid;
inode = coda_fid_to_inode(fid, sb);
if (inode) {
coda_flag_inode_children(inode, C_PURGE); coda_flag_inode_children(inode, C_PURGE);
/* catch the dentries later if some are still busy */ /* catch the dentries later if some are still busy */
coda_flag_inode(inode, C_PURGE); coda_flag_inode(inode, C_PURGE);
d_prune_aliases(inode); d_prune_aliases(inode);
}
break; break;
case CODA_REPLACE: case CODA_REPLACE:
fid = &out->coda_replace.OldFid;
newfid = &out->coda_replace.NewFid; newfid = &out->coda_replace.NewFid;
inode = coda_fid_to_inode(fid, sb);
if (inode)
coda_replace_fid(inode, fid, newfid); coda_replace_fid(inode, fid, newfid);
break; break;
} }
unlock_out:
unlock_kernel();
if (inode)
iput(inode); iput(inode);
return 0; return 0;
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
#include <linux/mutex.h>
struct kstatfs; struct kstatfs;
...@@ -20,6 +21,7 @@ struct venus_comm { ...@@ -20,6 +21,7 @@ struct venus_comm {
int vc_inuse; int vc_inuse;
struct super_block *vc_sb; struct super_block *vc_sb;
struct backing_dev_info bdi; struct backing_dev_info bdi;
struct mutex vc_mutex;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment