#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
-#include <linux/mempool.h>
#include <linux/sunrpc/clnt.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_page.h>
static void nfs_readpage_result_full(struct nfs_read_data *, int);
static kmem_cache_t *nfs_rdata_cachep;
-static mempool_t *nfs_rdata_mempool;
+mempool_t *nfs_rdata_mempool;
#define MIN_POOL_READ (32)
-static struct nfs_read_data *nfs_readdata_alloc(void)
+void nfs_readdata_release(void *data)
{
- struct nfs_read_data *p;
- p = (struct nfs_read_data *)mempool_alloc(nfs_rdata_mempool, SLAB_NOFS);
- if (p)
- memset(p, 0, sizeof(*p));
- return p;
-}
-
-static __inline__ void nfs_readdata_free(struct nfs_read_data *p)
-{
- mempool_free(p, nfs_rdata_mempool);
-}
-
-static void nfs_readdata_release(struct rpc_task *task)
-{
- struct nfs_read_data *data = (struct nfs_read_data *)task->tk_calldata;
nfs_readdata_free(data);
}
int result;
struct nfs_read_data *rdata;
- rdata = nfs_readdata_alloc();
+ rdata = nfs_readdata_alloc(1);
if (!rdata)
return -ENOMEM;
if (rdata->res.eof != 0 || result == 0)
break;
} while (count);
- NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME;
+ spin_lock(&inode->i_lock);
+ NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
+ spin_unlock(&inode->i_lock);
if (count)
memclear_highpage_flush(page, rdata->args.pgbase, count);
if (len < PAGE_CACHE_SIZE)
memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);
- nfs_lock_request(new);
nfs_list_add_request(new, &one_request);
nfs_pagein_one(&one_request, inode);
return 0;
{
unlock_page(req->wb_page);
- nfs_clear_request(req);
- nfs_release_request(req);
- nfs_unlock_request(req);
-
dprintk("NFS: read done (%s/%Ld %d@%Ld)\n",
req->wb_context->dentry->d_inode->i_sb->s_id,
(long long)NFS_FILEID(req->wb_context->dentry->d_inode),
req->wb_bytes,
(long long)req_offset(req));
+ nfs_clear_request(req);
+ nfs_release_request(req);
}
/*
data->res.fattr = &data->fattr;
data->res.count = count;
data->res.eof = 0;
+ nfs_fattr_init(&data->fattr);
NFS_PROTO(inode)->read_setup(data);
data->task.tk_cookie = (unsigned long)inode;
- data->task.tk_calldata = data;
- /* Release requests */
- data->task.tk_release = nfs_readdata_release;
dprintk("NFS: %4d initiated read call (req %s/%Ld, %u bytes @ offset %Lu)\n",
data->task.tk_pid,
nbytes = req->wb_bytes;
for(;;) {
- data = nfs_readdata_alloc();
+ data = nfs_readdata_alloc(1);
if (!data)
goto out_bad;
INIT_LIST_HEAD(&data->pages);
if (NFS_SERVER(inode)->rsize < PAGE_CACHE_SIZE)
return nfs_pagein_multi(head, inode);
- data = nfs_readdata_alloc();
+ data = nfs_readdata_alloc(NFS_SERVER(inode)->rpages);
if (!data)
goto out_bad;
return -ENOMEM;
}
-int
+static int
nfs_pagein_list(struct list_head *head, int rpages)
{
LIST_HEAD(one_request);
* This is the callback from RPC telling us whether a reply was
* received or some error occurred (timeout or socket shutdown).
*/
-void nfs_readpage_result(struct rpc_task *task)
+void nfs_readpage_result(struct rpc_task *task, void *calldata)
{
- struct nfs_read_data *data = (struct nfs_read_data *)task->tk_calldata;
+ struct nfs_read_data *data = calldata;
struct nfs_readargs *argp = &data->args;
struct nfs_readres *resp = &data->res;
int status = task->tk_status;
}
task->tk_status = -EIO;
}
- NFS_FLAGS(data->inode) |= NFS_INO_INVALID_ATIME;
+ spin_lock(&data->inode->i_lock);
+ NFS_I(data->inode)->cache_validity |= NFS_INO_INVALID_ATIME;
+ spin_unlock(&data->inode->i_lock);
data->complete(data, status);
}
goto out_error;
if (file == NULL) {
- ctx = nfs_find_open_context(inode, FMODE_READ);
+ ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
if (ctx == NULL)
return -EBADF;
} else
}
if (len < PAGE_CACHE_SIZE)
memclear_highpage_flush(page, len, PAGE_CACHE_SIZE - len);
- nfs_lock_request(new);
nfs_list_add_request(new, desc->head);
return 0;
}
nr_pages);
if (filp == NULL) {
- desc.ctx = nfs_find_open_context(inode, FMODE_READ);
+ desc.ctx = nfs_find_open_context(inode, NULL, FMODE_READ);
if (desc.ctx == NULL)
return -EBADF;
} else