diff options
Diffstat (limited to 'fs/afs/file.c')
-rw-r--r-- | fs/afs/file.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/fs/afs/file.c b/fs/afs/file.c index e8d6619890a9..11e69c5fb7ab 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c @@ -170,11 +170,12 @@ int afs_release(struct inode *inode, struct file *file) { struct afs_vnode *vnode = AFS_FS_I(inode); struct afs_file *af = file->private_data; + int ret = 0; _enter("{%llx:%llu},", vnode->fid.vid, vnode->fid.vnode); if ((file->f_mode & FMODE_WRITE)) - return vfs_fsync(file, 0); + ret = vfs_fsync(file, 0); file->private_data = NULL; if (af->wb) @@ -182,8 +183,8 @@ int afs_release(struct inode *inode, struct file *file) key_put(af->key); kfree(af); afs_prune_wb_keys(vnode); - _leave(" = 0"); - return 0; + _leave(" = %d", ret); + return ret; } /* @@ -227,6 +228,7 @@ static void afs_file_readpage_read_complete(struct page *page, int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *desc) { struct afs_fs_cursor fc; + struct afs_status_cb *scb; int ret; _enter("%s{%llx:%llu.%u},%x,,,", @@ -236,15 +238,22 @@ int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *de vnode->fid.unique, key_serial(key)); + scb = kzalloc(sizeof(struct afs_status_cb), GFP_KERNEL); + if (!scb) + return -ENOMEM; + ret = -ERESTARTSYS; - if (afs_begin_vnode_operation(&fc, vnode, key)) { + if (afs_begin_vnode_operation(&fc, vnode, key, true)) { + afs_dataversion_t data_version = vnode->status.data_version; + while (afs_select_fileserver(&fc)) { fc.cb_break = afs_calc_vnode_cb_break(vnode); - afs_fs_fetch_data(&fc, desc); + afs_fs_fetch_data(&fc, scb, desc); } - afs_check_for_remote_deletion(&fc, fc.vnode); - afs_vnode_commit_status(&fc, vnode, fc.cb_break); + afs_check_for_remote_deletion(&fc, vnode); + afs_vnode_commit_status(&fc, vnode, fc.cb_break, + &data_version, scb); ret = afs_end_vnode_operation(&fc); } @@ -254,6 +263,7 @@ int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *de &afs_v2net(vnode)->n_fetch_bytes); } + kfree(scb); _leave(" = %d", ret); return ret; } @@ -404,10 +414,10 @@ static int afs_readpage(struct file *file, struct page *page) /* * Make pages available as they're filled. */ -static void afs_readpages_page_done(struct afs_call *call, struct afs_read *req) +static void afs_readpages_page_done(struct afs_read *req) { #ifdef CONFIG_AFS_FSCACHE - struct afs_vnode *vnode = call->reply[0]; + struct afs_vnode *vnode = req->vnode; #endif struct page *page = req->pages[req->index]; @@ -461,6 +471,7 @@ static int afs_readpages_one(struct file *file, struct address_space *mapping, return -ENOMEM; refcount_set(&req->usage, 1); + req->vnode = vnode; req->page_done = afs_readpages_page_done; req->pos = first->index; req->pos <<= PAGE_SHIFT; |