aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/afs/file.c')
-rw-r--r--fs/afs/file.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/fs/afs/file.c b/fs/afs/file.c
index a39192ced99e..7d4f26198573 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -30,7 +30,6 @@ static int afs_readpages(struct file *filp, struct address_space *mapping,
const struct file_operations afs_file_operations = {
.open = afs_open,
- .flush = afs_flush,
.release = afs_release,
.llseek = generic_file_llseek,
.read_iter = generic_file_read_iter,
@@ -146,6 +145,9 @@ int afs_open(struct inode *inode, struct file *file)
if (ret < 0)
goto error_af;
}
+
+ if (file->f_flags & O_TRUNC)
+ set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
file->private_data = af;
_leave(" = 0");
@@ -170,6 +172,9 @@ int afs_release(struct inode *inode, struct file *file)
_enter("{%x:%u},", vnode->fid.vid, vnode->fid.vnode);
+ if ((file->f_mode & FMODE_WRITE))
+ return vfs_fsync(file, 0);
+
file->private_data = NULL;
if (af->wb)
afs_put_wb_key(af->wb);
@@ -187,10 +192,12 @@ void afs_put_read(struct afs_read *req)
{
int i;
- if (atomic_dec_and_test(&req->usage)) {
+ if (refcount_dec_and_test(&req->usage)) {
for (i = 0; i < req->nr_pages; i++)
if (req->pages[i])
put_page(req->pages[i]);
+ if (req->pages != req->array)
+ kfree(req->pages);
kfree(req);
}
}
@@ -231,7 +238,7 @@ int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *de
ret = -ERESTARTSYS;
if (afs_begin_vnode_operation(&fc, vnode, key)) {
while (afs_select_fileserver(&fc)) {
- fc.cb_break = vnode->cb_break + vnode->cb_s_break;
+ fc.cb_break = afs_calc_vnode_cb_break(vnode);
afs_fs_fetch_data(&fc, desc);
}
@@ -240,6 +247,12 @@ int afs_fetch_data(struct afs_vnode *vnode, struct key *key, struct afs_read *de
ret = afs_end_vnode_operation(&fc);
}
+ if (ret == 0) {
+ afs_stat_v(vnode, n_fetches);
+ atomic_long_add(desc->actual_len,
+ &afs_v2net(vnode)->n_fetch_bytes);
+ }
+
_leave(" = %d", ret);
return ret;
}
@@ -297,10 +310,11 @@ int afs_page_filler(void *data, struct page *page)
* end of the file, the server will return a short read and the
* unmarshalling code will clear the unfilled space.
*/
- atomic_set(&req->usage, 1);
+ refcount_set(&req->usage, 1);
req->pos = (loff_t)page->index << PAGE_SHIFT;
req->len = PAGE_SIZE;
req->nr_pages = 1;
+ req->pages = req->array;
req->pages[0] = page;
get_page(page);
@@ -309,10 +323,6 @@ int afs_page_filler(void *data, struct page *page)
ret = afs_fetch_data(vnode, key, req);
afs_put_read(req);
- if (ret >= 0 && S_ISDIR(inode->i_mode) &&
- !afs_dir_check_page(inode, page))
- ret = -EIO;
-
if (ret < 0) {
if (ret == -ENOENT) {
_debug("got NOENT from server"
@@ -339,7 +349,8 @@ int afs_page_filler(void *data, struct page *page)
/* send the page to the cache */
#ifdef CONFIG_AFS_FSCACHE
if (PageFsCache(page) &&
- fscache_write_page(vnode->cache, page, GFP_KERNEL) != 0) {
+ fscache_write_page(vnode->cache, page, vnode->status.size,
+ GFP_KERNEL) != 0) {
fscache_uncache_page(vnode->cache, page);
BUG_ON(PageFsCache(page));
}
@@ -403,7 +414,8 @@ static void afs_readpages_page_done(struct afs_call *call, struct afs_read *req)
/* send the page to the cache */
#ifdef CONFIG_AFS_FSCACHE
if (PageFsCache(page) &&
- fscache_write_page(vnode->cache, page, GFP_KERNEL) != 0) {
+ fscache_write_page(vnode->cache, page, vnode->status.size,
+ GFP_KERNEL) != 0) {
fscache_uncache_page(vnode->cache, page);
BUG_ON(PageFsCache(page));
}
@@ -445,10 +457,11 @@ static int afs_readpages_one(struct file *file, struct address_space *mapping,
if (!req)
return -ENOMEM;
- atomic_set(&req->usage, 1);
+ refcount_set(&req->usage, 1);
req->page_done = afs_readpages_page_done;
req->pos = first->index;
req->pos <<= PAGE_SHIFT;
+ req->pages = req->array;
/* Transfer the pages to the request. We add them in until one fails
* to add to the LRU and then we stop (as that'll make a hole in the