lkml.org 
[lkml]   [2021]   [Dec]   [9]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH v2 50/67] cachefiles: Implement cookie resize for truncate
    From
    Date
    Implement resizing an object, using truncate and/or fallocate to adjust the
    object.

    Signed-off-by: David Howells <dhowells@redhat.com>
    cc: linux-cachefs@redhat.com
    Link: https://lore.kernel.org/r/163819646631.215744.13819016478175576761.stgit@warthog.procyon.org.uk/ # v1
    ---

    fs/cachefiles/interface.c | 78 +++++++++++++++++++++++++++++++++++++++++++++
    1 file changed, 78 insertions(+)

    diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
    index ad9d311413ff..51c968cd00a6 100644
    --- a/fs/cachefiles/interface.c
    +++ b/fs/cachefiles/interface.c
    @@ -220,6 +220,83 @@ static bool cachefiles_lookup_cookie(struct fscache_cookie *cookie)
    return false;
    }

    +/*
    + * Shorten the backing object to discard any dirty data and free up
    + * any unused granules.
    + */
    +static bool cachefiles_shorten_object(struct cachefiles_object *object,
    + struct file *file, loff_t new_size)
    +{
    + struct cachefiles_cache *cache = object->volume->cache;
    + struct inode *inode = file_inode(file);
    + loff_t i_size, dio_size;
    + int ret;
    +
    + dio_size = round_up(new_size, CACHEFILES_DIO_BLOCK_SIZE);
    + i_size = i_size_read(inode);
    +
    + trace_cachefiles_trunc(object, inode, i_size, dio_size,
    + cachefiles_trunc_shrink);
    + ret = cachefiles_inject_remove_error();
    + if (ret == 0)
    + ret = vfs_truncate(&file->f_path, dio_size);
    + if (ret < 0) {
    + trace_cachefiles_io_error(object, file_inode(file), ret,
    + cachefiles_trace_trunc_error);
    + cachefiles_io_error_obj(object, "Trunc-to-size failed %d", ret);
    + cachefiles_remove_object_xattr(cache, object, file->f_path.dentry);
    + return false;
    + }
    +
    + if (new_size < dio_size) {
    + trace_cachefiles_trunc(object, inode, dio_size, new_size,
    + cachefiles_trunc_dio_adjust);
    + ret = cachefiles_inject_write_error();
    + if (ret == 0)
    + ret = vfs_fallocate(file, FALLOC_FL_ZERO_RANGE,
    + new_size, dio_size);
    + if (ret < 0) {
    + trace_cachefiles_io_error(object, file_inode(file), ret,
    + cachefiles_trace_fallocate_error);
    + cachefiles_io_error_obj(object, "Trunc-to-dio-size failed %d", ret);
    + cachefiles_remove_object_xattr(cache, object, file->f_path.dentry);
    + return false;
    + }
    + }
    +
    + return true;
    +}
    +
    +/*
    + * Resize the backing object.
    + */
    +static void cachefiles_resize_cookie(struct netfs_cache_resources *cres,
    + loff_t new_size)
    +{
    + struct cachefiles_object *object = cachefiles_cres_object(cres);
    + struct cachefiles_cache *cache = object->volume->cache;
    + struct fscache_cookie *cookie = object->cookie;
    + const struct cred *saved_cred;
    + struct file *file = cachefiles_cres_file(cres);
    + loff_t old_size = cookie->object_size;
    +
    + _enter("%llu->%llu", old_size, new_size);
    +
    + if (new_size < old_size) {
    + cachefiles_begin_secure(cache, &saved_cred);
    + cachefiles_shorten_object(object, file, new_size);
    + cachefiles_end_secure(cache, saved_cred);
    + object->cookie->object_size = new_size;
    + return;
    + }
    +
    + /* The file is being expanded. We don't need to do anything
    + * particularly. cookie->initial_size doesn't change and so the point
    + * at which we have to download before doesn't change.
    + */
    + cookie->object_size = new_size;
    +}
    +
    /*
    * Commit changes to the object as we drop it.
    */
    @@ -363,5 +440,6 @@ const struct fscache_cache_ops cachefiles_cache_ops = {
    .withdraw_cookie = cachefiles_withdraw_cookie,
    .invalidate_cookie = cachefiles_invalidate_cookie,
    .begin_operation = cachefiles_begin_operation,
    + .resize_cookie = cachefiles_resize_cookie,
    .prepare_to_write = cachefiles_prepare_to_write,
    };

    \
     
     \ /
      Last update: 2021-12-09 18:07    [W:7.433 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site