Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 158575
b: refs/heads/master
c: da77005
h: refs/heads/master
i:
  158573: ce3d22c
  158571: ee4b016
  158567: fb306ed
  158559: d19f222
v: v3
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Aug 9, 2009
1 parent af16b35 commit da1820f
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5b7a1b9f9214cb89dd164b43ca3fab7af4058e06
refs/heads/master: da77005f0d64486cd760f43d9b7cc2379262a363
95 changes: 70 additions & 25 deletions trunk/net/sunrpc/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/net.h>
#include <linux/workqueue.h>
#include <linux/mutex.h>
#include <linux/pagemap.h>
#include <asm/ioctls.h>
#include <linux/sunrpc/types.h>
#include <linux/sunrpc/cache.h>
Expand Down Expand Up @@ -702,13 +703,14 @@ cache_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
struct cache_reader *rp = filp->private_data;
struct cache_request *rq;
struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
struct inode *inode = filp->f_path.dentry->d_inode;
struct cache_detail *cd = PDE(inode)->data;
int err;

if (count == 0)
return 0;

mutex_lock(&queue_io_mutex); /* protect against multiple concurrent
mutex_lock(&inode->i_mutex); /* protect against multiple concurrent
* readers on this file */
again:
spin_lock(&queue_lock);
Expand All @@ -721,7 +723,7 @@ cache_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
}
if (rp->q.list.next == &cd->queue) {
spin_unlock(&queue_lock);
mutex_unlock(&queue_io_mutex);
mutex_unlock(&inode->i_mutex);
BUG_ON(rp->offset);
return 0;
}
Expand Down Expand Up @@ -768,38 +770,81 @@ cache_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
}
if (err == -EAGAIN)
goto again;
mutex_unlock(&queue_io_mutex);
mutex_unlock(&inode->i_mutex);
return err ? err : count;
}

static char write_buf[8192]; /* protected by queue_io_mutex */
static ssize_t cache_do_downcall(char *kaddr, const char __user *buf,
size_t count, struct cache_detail *cd)
{
ssize_t ret;

static ssize_t
cache_write(struct file *filp, const char __user *buf, size_t count,
loff_t *ppos)
if (copy_from_user(kaddr, buf, count))
return -EFAULT;
kaddr[count] = '\0';
ret = cd->cache_parse(cd, kaddr, count);
if (!ret)
ret = count;
return ret;
}

static ssize_t cache_slow_downcall(const char __user *buf,
size_t count, struct cache_detail *cd)
{
int err;
struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
static char write_buf[8192]; /* protected by queue_io_mutex */
ssize_t ret = -EINVAL;

if (count == 0)
return 0;
if (count >= sizeof(write_buf))
return -EINVAL;

goto out;
mutex_lock(&queue_io_mutex);
ret = cache_do_downcall(write_buf, buf, count, cd);
mutex_unlock(&queue_io_mutex);
out:
return ret;
}

if (copy_from_user(write_buf, buf, count)) {
mutex_unlock(&queue_io_mutex);
return -EFAULT;
}
write_buf[count] = '\0';
if (cd->cache_parse)
err = cd->cache_parse(cd, write_buf, count);
else
err = -EINVAL;
static ssize_t cache_downcall(struct address_space *mapping,
const char __user *buf,
size_t count, struct cache_detail *cd)
{
struct page *page;
char *kaddr;
ssize_t ret = -ENOMEM;

if (count >= PAGE_CACHE_SIZE)
goto out_slow;

page = find_or_create_page(mapping, 0, GFP_KERNEL);
if (!page)
goto out_slow;

kaddr = kmap(page);
ret = cache_do_downcall(kaddr, buf, count, cd);
kunmap(page);
unlock_page(page);
page_cache_release(page);
return ret;
out_slow:
return cache_slow_downcall(buf, count, cd);
}

mutex_unlock(&queue_io_mutex);
return err ? err : count;
static ssize_t
cache_write(struct file *filp, const char __user *buf, size_t count,
loff_t *ppos)
{
struct address_space *mapping = filp->f_mapping;
struct inode *inode = filp->f_path.dentry->d_inode;
struct cache_detail *cd = PDE(inode)->data;
ssize_t ret = -EINVAL;

if (!cd->cache_parse)
goto out;

mutex_lock(&inode->i_mutex);
ret = cache_downcall(mapping, buf, count, cd);
mutex_unlock(&inode->i_mutex);
out:
return ret;
}

static DECLARE_WAIT_QUEUE_HEAD(queue_wait);
Expand Down

0 comments on commit da1820f

Please sign in to comment.