linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / fs / nfs / read.c
index a0042fb..05eb43f 100644 (file)
@@ -42,9 +42,8 @@ mempool_t *nfs_rdata_mempool;
 
 #define MIN_POOL_READ  (32)
 
-void nfs_readdata_release(struct rpc_task *task)
+void nfs_readdata_release(void *data)
 {
-        struct nfs_read_data   *data = (struct nfs_read_data *)task->tk_calldata;
         nfs_readdata_free(data);
 }
 
@@ -84,7 +83,7 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode,
        int             result;
        struct nfs_read_data *rdata;
 
-       rdata = nfs_readdata_alloc();
+       rdata = nfs_readdata_alloc(1);
        if (!rdata)
                return -ENOMEM;
 
@@ -140,7 +139,9 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode,
                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);
@@ -173,7 +174,6 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
        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;
@@ -183,15 +183,13 @@ static void nfs_readpage_release(struct nfs_page *req)
 {
        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);
 }
 
 /*
@@ -216,13 +214,11 @@ static void nfs_read_rpcsetup(struct nfs_page *req, struct nfs_read_data *data,
        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,
@@ -287,7 +283,7 @@ static int nfs_pagein_multi(struct list_head *head, struct inode *inode)
 
        nbytes = req->wb_bytes;
        for(;;) {
-               data = nfs_readdata_alloc();
+               data = nfs_readdata_alloc(1);
                if (!data)
                        goto out_bad;
                INIT_LIST_HEAD(&data->pages);
@@ -343,7 +339,7 @@ static int nfs_pagein_one(struct list_head *head, struct inode *inode)
        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;
 
@@ -452,9 +448,9 @@ static void nfs_readpage_result_full(struct nfs_read_data *data, int status)
  * 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;
@@ -475,7 +471,9 @@ void nfs_readpage_result(struct rpc_task *task)
                }
                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);
 }
 
@@ -505,7 +503,7 @@ int nfs_readpage(struct file *file, struct page *page)
                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
@@ -553,7 +551,6 @@ readpage_async_filler(void *data, struct page *page)
        }
        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;
 }
@@ -575,7 +572,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
                        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