Commit 6ed499a9 authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] Make sure sunrpc/cache doesn't confuse writers with readers.

When a sunrpc/cache channel is not open for reading, the
cache doesn't bother making and waiting for up-calls.

However it doesn't currently distingish between open-for-read/write
and open-for-write, so an op-for-write will look like a reader
and will cause inappropriate waiting.

This patch checks if a file is open-for-read and will only register
a file as a reader if it really is one.
parent 1f494fc0
...@@ -738,7 +738,9 @@ cache_ioctl(struct inode *ino, struct file *filp, ...@@ -738,7 +738,9 @@ cache_ioctl(struct inode *ino, struct file *filp,
static int static int
cache_open(struct inode *inode, struct file *filp) cache_open(struct inode *inode, struct file *filp)
{ {
struct cache_reader *rp; struct cache_reader *rp = NULL;
if (filp->f_mode & FMODE_READ) {
struct cache_detail *cd = PDE(inode)->data; struct cache_detail *cd = PDE(inode)->data;
rp = kmalloc(sizeof(*rp), GFP_KERNEL); rp = kmalloc(sizeof(*rp), GFP_KERNEL);
...@@ -751,6 +753,7 @@ cache_open(struct inode *inode, struct file *filp) ...@@ -751,6 +753,7 @@ cache_open(struct inode *inode, struct file *filp)
spin_lock(&queue_lock); spin_lock(&queue_lock);
list_add(&rp->q.list, &cd->queue); list_add(&rp->q.list, &cd->queue);
spin_unlock(&queue_lock); spin_unlock(&queue_lock);
}
filp->private_data = rp; filp->private_data = rp;
return 0; return 0;
} }
...@@ -761,6 +764,7 @@ cache_release(struct inode *inode, struct file *filp) ...@@ -761,6 +764,7 @@ cache_release(struct inode *inode, struct file *filp)
struct cache_reader *rp = filp->private_data; struct cache_reader *rp = filp->private_data;
struct cache_detail *cd = PDE(inode)->data; struct cache_detail *cd = PDE(inode)->data;
if (rp) {
spin_lock(&queue_lock); spin_lock(&queue_lock);
if (rp->offset) { if (rp->offset) {
struct cache_queue *cq; struct cache_queue *cq;
...@@ -784,6 +788,7 @@ cache_release(struct inode *inode, struct file *filp) ...@@ -784,6 +788,7 @@ cache_release(struct inode *inode, struct file *filp)
cd->last_close = get_seconds(); cd->last_close = get_seconds();
atomic_dec(&cd->readers); atomic_dec(&cd->readers);
}
return 0; return 0;
} }
......
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