Round the size of a cachefile up to DIO block size so that we can always read back the last partial page of a file using direct I/O. Signed-off-by: David Howells <dhowells@xxxxxxxxxx> --- fs/cachefiles/bind.c | 3 ++- fs/cachefiles/interface.c | 2 ++ fs/cachefiles/internal.h | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c index af7386ad14af..4ea8c93e14d8 100644 --- a/fs/cachefiles/bind.c +++ b/fs/cachefiles/bind.c @@ -126,7 +126,8 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache) !d_backing_inode(root)->i_op->mkdir || !(d_backing_inode(root)->i_opflags & IOP_XATTR) || !root->d_sb->s_op->statfs || - !root->d_sb->s_op->sync_fs) + !root->d_sb->s_op->sync_fs || + root->d_sb->s_blocksize > PAGE_SIZE) goto error_unsupported; ret = -EROFS; diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 8f98e5c27d66..3e678ab14c85 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c @@ -268,6 +268,7 @@ static int cachefiles_attr_changed(struct cachefiles_object *object) int ret; ni_size = object->cookie->object_size; + ni_size = round_up(ni_size, CACHEFILES_DIO_BLOCK_SIZE); _enter("{OBJ%x},[%llu]", object->debug_id, (unsigned long long) ni_size); @@ -346,6 +347,7 @@ static void cachefiles_invalidate_object(struct cachefiles_object *object) cachefiles_trunc_invalidate); ret = vfs_truncate(&file->f_path, 0); if (ret == 0) { + ni_size = round_up(ni_size, CACHEFILES_DIO_BLOCK_SIZE); trace_cachefiles_trunc(object, file_inode(file), 0, ni_size, cachefiles_trunc_set_size); diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 4705f968e661..ff00c5249f4f 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -19,6 +19,8 @@ #include <linux/workqueue.h> #include <linux/security.h> +#define CACHEFILES_DIO_BLOCK_SIZE 4096 + struct cachefiles_cache; struct cachefiles_object;