summaryrefslogtreecommitdiff
path: root/fs/afs/file.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-04-06 14:17:26 +0100
committerDavid Howells <dhowells@redhat.com>2018-04-09 21:54:48 +0100
commit5a8132761609bd7e42db642d6f157140d5bf2ae8 (patch)
tree70230e95b522728ccf37c67bc69b70abc62df003 /fs/afs/file.c
parent76a5cb6fc1e22a2a316fb690fc4cdd5121d1c0ff (diff)
afs: Do better accretion of small writes on newly created content
Processes like ld that do lots of small writes that aren't necessarily contiguous result in a lot of small StoreData operations to the server, the idea being that if someone else changes the data on the server, we only write our changes over that and not the space between. Further, we don't want to write back empty space if we can avoid it to make it easier for the server to do sparse files. However, making lots of tiny RPC ops is a lot less efficient for the server than one big one because each op requires allocation of resources and the taking of locks, so we want to compromise a bit. Reduce the load by the following: (1) If a file is just created locally or has just been truncated with O_TRUNC locally, allow subsequent writes to the file to be merged with intervening space if that space doesn't cross an entire intervening page. (2) Don't flush the file on ->flush() but rather on ->release() if the file was open for writing. Just linking vmlinux.o, without this patch, looking in /proc/fs/afs/stats: file-wr : n=441 nb=513581204 and after the patch: file-wr : n=62 nb=513668555 there were 379 fewer StoreData RPC operations at the expense of an extra 87K being written. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/file.c')
-rw-r--r--fs/afs/file.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/afs/file.c b/fs/afs/file.c
index e5cac1bc3cf0..c24c08016dd9 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);