lkml.org 
[lkml]   [2021]   [Dec]   [22]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[PATCH v4 02/68] cachefiles: Delete the cachefiles driver pending rewrite
    From
    Date
    Delete the code from the cachefiles driver to make it easier to rewrite and
    resubmit in a logical manner.

    Signed-off-by: David Howells <dhowells@redhat.com>
    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    cc: linux-cachefs@redhat.com
    Link: https://lore.kernel.org/r/163819577641.215744.12718114397770666596.stgit@warthog.procyon.org.uk/ # v1
    Link: https://lore.kernel.org/r/163906883770.143852.4149714614981373410.stgit@warthog.procyon.org.uk/ # v2
    Link: https://lore.kernel.org/r/163967076066.1823006.7175712134577687753.stgit@warthog.procyon.org.uk/ # v3
    ---

    fs/Kconfig | 1
    fs/Makefile | 1
    fs/cachefiles/Kconfig | 21 -
    fs/cachefiles/Makefile | 18 -
    fs/cachefiles/bind.c | 278 ----------
    fs/cachefiles/daemon.c | 748 ---------------------------
    fs/cachefiles/interface.c | 572 ---------------------
    fs/cachefiles/internal.h | 350 -------------
    fs/cachefiles/io.c | 420 ---------------
    fs/cachefiles/key.c | 155 ------
    fs/cachefiles/main.c | 95 ---
    fs/cachefiles/namei.c | 1018 -------------------------------------
    fs/cachefiles/rdwr.c | 972 -----------------------------------
    fs/cachefiles/security.c | 112 ----
    fs/cachefiles/xattr.c | 324 ------------
    include/trace/events/cachefiles.h | 321 ------------
    16 files changed, 5406 deletions(-)
    delete mode 100644 fs/cachefiles/Kconfig
    delete mode 100644 fs/cachefiles/Makefile
    delete mode 100644 fs/cachefiles/bind.c
    delete mode 100644 fs/cachefiles/daemon.c
    delete mode 100644 fs/cachefiles/interface.c
    delete mode 100644 fs/cachefiles/internal.h
    delete mode 100644 fs/cachefiles/io.c
    delete mode 100644 fs/cachefiles/key.c
    delete mode 100644 fs/cachefiles/main.c
    delete mode 100644 fs/cachefiles/namei.c
    delete mode 100644 fs/cachefiles/rdwr.c
    delete mode 100644 fs/cachefiles/security.c
    delete mode 100644 fs/cachefiles/xattr.c
    delete mode 100644 include/trace/events/cachefiles.h

    diff --git a/fs/Kconfig b/fs/Kconfig
    index a6313a969bc5..86e311377e6e 100644
    --- a/fs/Kconfig
    +++ b/fs/Kconfig
    @@ -132,7 +132,6 @@ menu "Caches"

    source "fs/netfs/Kconfig"
    source "fs/fscache/Kconfig"
    -source "fs/cachefiles/Kconfig"

    endmenu

    diff --git a/fs/Makefile b/fs/Makefile
    index 84c5e4cdfee5..290815f3fd31 100644
    --- a/fs/Makefile
    +++ b/fs/Makefile
    @@ -125,7 +125,6 @@ obj-$(CONFIG_AFS_FS) += afs/
    obj-$(CONFIG_NILFS2_FS) += nilfs2/
    obj-$(CONFIG_BEFS_FS) += befs/
    obj-$(CONFIG_HOSTFS) += hostfs/
    -obj-$(CONFIG_CACHEFILES) += cachefiles/
    obj-$(CONFIG_DEBUG_FS) += debugfs/
    obj-$(CONFIG_TRACING) += tracefs/
    obj-$(CONFIG_OCFS2_FS) += ocfs2/
    diff --git a/fs/cachefiles/Kconfig b/fs/cachefiles/Kconfig
    deleted file mode 100644
    index 6827b40f7ddc..000000000000
    --- a/fs/cachefiles/Kconfig
    +++ /dev/null
    @@ -1,21 +0,0 @@
    -# SPDX-License-Identifier: GPL-2.0-only
    -
    -config CACHEFILES
    - tristate "Filesystem caching on files"
    - depends on FSCACHE && BLOCK
    - help
    - This permits use of a mounted filesystem as a cache for other
    - filesystems - primarily networking filesystems - thus allowing fast
    - local disk to enhance the speed of slower devices.
    -
    - See Documentation/filesystems/caching/cachefiles.rst for more
    - information.
    -
    -config CACHEFILES_DEBUG
    - bool "Debug CacheFiles"
    - depends on CACHEFILES
    - help
    - This permits debugging to be dynamically enabled in the filesystem
    - caching on files module. If this is set, the debugging output may be
    - enabled by setting bits in /sys/modules/cachefiles/parameter/debug or
    - by including a debugging specifier in /etc/cachefilesd.conf.
    diff --git a/fs/cachefiles/Makefile b/fs/cachefiles/Makefile
    deleted file mode 100644
    index 02fd17731769..000000000000
    --- a/fs/cachefiles/Makefile
    +++ /dev/null
    @@ -1,18 +0,0 @@
    -# SPDX-License-Identifier: GPL-2.0
    -#
    -# Makefile for caching in a mounted filesystem
    -#
    -
    -cachefiles-y := \
    - bind.o \
    - daemon.o \
    - interface.o \
    - io.o \
    - key.o \
    - main.o \
    - namei.o \
    - rdwr.o \
    - security.o \
    - xattr.o
    -
    -obj-$(CONFIG_CACHEFILES) := cachefiles.o
    diff --git a/fs/cachefiles/bind.c b/fs/cachefiles/bind.c
    deleted file mode 100644
    index d463d89f5db8..000000000000
    --- a/fs/cachefiles/bind.c
    +++ /dev/null
    @@ -1,278 +0,0 @@
    -// SPDX-License-Identifier: GPL-2.0-or-later
    -/* Bind and unbind a cache from the filesystem backing it
    - *
    - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -
    -#include <linux/module.h>
    -#include <linux/init.h>
    -#include <linux/sched.h>
    -#include <linux/completion.h>
    -#include <linux/slab.h>
    -#include <linux/fs.h>
    -#include <linux/file.h>
    -#include <linux/namei.h>
    -#include <linux/mount.h>
    -#include <linux/statfs.h>
    -#include <linux/ctype.h>
    -#include <linux/xattr.h>
    -#include "internal.h"
    -
    -static int cachefiles_daemon_add_cache(struct cachefiles_cache *caches);
    -
    -/*
    - * bind a directory as a cache
    - */
    -int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args)
    -{
    - _enter("{%u,%u,%u,%u,%u,%u},%s",
    - cache->frun_percent,
    - cache->fcull_percent,
    - cache->fstop_percent,
    - cache->brun_percent,
    - cache->bcull_percent,
    - cache->bstop_percent,
    - args);
    -
    - /* start by checking things over */
    - ASSERT(cache->fstop_percent >= 0 &&
    - cache->fstop_percent < cache->fcull_percent &&
    - cache->fcull_percent < cache->frun_percent &&
    - cache->frun_percent < 100);
    -
    - ASSERT(cache->bstop_percent >= 0 &&
    - cache->bstop_percent < cache->bcull_percent &&
    - cache->bcull_percent < cache->brun_percent &&
    - cache->brun_percent < 100);
    -
    - if (*args) {
    - pr_err("'bind' command doesn't take an argument\n");
    - return -EINVAL;
    - }
    -
    - if (!cache->rootdirname) {
    - pr_err("No cache directory specified\n");
    - return -EINVAL;
    - }
    -
    - /* don't permit already bound caches to be re-bound */
    - if (test_bit(CACHEFILES_READY, &cache->flags)) {
    - pr_err("Cache already bound\n");
    - return -EBUSY;
    - }
    -
    - /* make sure we have copies of the tag and dirname strings */
    - if (!cache->tag) {
    - /* the tag string is released by the fops->release()
    - * function, so we don't release it on error here */
    - cache->tag = kstrdup("CacheFiles", GFP_KERNEL);
    - if (!cache->tag)
    - return -ENOMEM;
    - }
    -
    - /* add the cache */
    - return cachefiles_daemon_add_cache(cache);
    -}
    -
    -/*
    - * add a cache
    - */
    -static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
    -{
    - struct cachefiles_object *fsdef;
    - struct path path;
    - struct kstatfs stats;
    - struct dentry *graveyard, *cachedir, *root;
    - const struct cred *saved_cred;
    - int ret;
    -
    - _enter("");
    -
    - /* we want to work under the module's security ID */
    - ret = cachefiles_get_security_ID(cache);
    - if (ret < 0)
    - return ret;
    -
    - cachefiles_begin_secure(cache, &saved_cred);
    -
    - /* allocate the root index object */
    - ret = -ENOMEM;
    -
    - fsdef = kmem_cache_alloc(cachefiles_object_jar, GFP_KERNEL);
    - if (!fsdef)
    - goto error_root_object;
    -
    - ASSERTCMP(fsdef->backer, ==, NULL);
    -
    - atomic_set(&fsdef->usage, 1);
    - fsdef->type = FSCACHE_COOKIE_TYPE_INDEX;
    -
    - /* look up the directory at the root of the cache */
    - ret = kern_path(cache->rootdirname, LOOKUP_DIRECTORY, &path);
    - if (ret < 0)
    - goto error_open_root;
    -
    - cache->mnt = path.mnt;
    - root = path.dentry;
    -
    - ret = -EINVAL;
    - if (mnt_user_ns(path.mnt) != &init_user_ns) {
    - pr_warn("File cache on idmapped mounts not supported");
    - goto error_unsupported;
    - }
    -
    - /* check parameters */
    - ret = -EOPNOTSUPP;
    - if (d_is_negative(root) ||
    - !d_backing_inode(root)->i_op->lookup ||
    - !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)
    - goto error_unsupported;
    -
    - ret = -EROFS;
    - if (sb_rdonly(root->d_sb))
    - goto error_unsupported;
    -
    - /* determine the security of the on-disk cache as this governs
    - * security ID of files we create */
    - ret = cachefiles_determine_cache_security(cache, root, &saved_cred);
    - if (ret < 0)
    - goto error_unsupported;
    -
    - /* get the cache size and blocksize */
    - ret = vfs_statfs(&path, &stats);
    - if (ret < 0)
    - goto error_unsupported;
    -
    - ret = -ERANGE;
    - if (stats.f_bsize <= 0)
    - goto error_unsupported;
    -
    - ret = -EOPNOTSUPP;
    - if (stats.f_bsize > PAGE_SIZE)
    - goto error_unsupported;
    -
    - cache->bsize = stats.f_bsize;
    - cache->bshift = 0;
    - if (stats.f_bsize < PAGE_SIZE)
    - cache->bshift = PAGE_SHIFT - ilog2(stats.f_bsize);
    -
    - _debug("blksize %u (shift %u)",
    - cache->bsize, cache->bshift);
    -
    - _debug("size %llu, avail %llu",
    - (unsigned long long) stats.f_blocks,
    - (unsigned long long) stats.f_bavail);
    -
    - /* set up caching limits */
    - do_div(stats.f_files, 100);
    - cache->fstop = stats.f_files * cache->fstop_percent;
    - cache->fcull = stats.f_files * cache->fcull_percent;
    - cache->frun = stats.f_files * cache->frun_percent;
    -
    - _debug("limits {%llu,%llu,%llu} files",
    - (unsigned long long) cache->frun,
    - (unsigned long long) cache->fcull,
    - (unsigned long long) cache->fstop);
    -
    - stats.f_blocks >>= cache->bshift;
    - do_div(stats.f_blocks, 100);
    - cache->bstop = stats.f_blocks * cache->bstop_percent;
    - cache->bcull = stats.f_blocks * cache->bcull_percent;
    - cache->brun = stats.f_blocks * cache->brun_percent;
    -
    - _debug("limits {%llu,%llu,%llu} blocks",
    - (unsigned long long) cache->brun,
    - (unsigned long long) cache->bcull,
    - (unsigned long long) cache->bstop);
    -
    - /* get the cache directory and check its type */
    - cachedir = cachefiles_get_directory(cache, root, "cache");
    - if (IS_ERR(cachedir)) {
    - ret = PTR_ERR(cachedir);
    - goto error_unsupported;
    - }
    -
    - fsdef->dentry = cachedir;
    - fsdef->fscache.cookie = NULL;
    -
    - ret = cachefiles_check_object_type(fsdef);
    - if (ret < 0)
    - goto error_unsupported;
    -
    - /* get the graveyard directory */
    - graveyard = cachefiles_get_directory(cache, root, "graveyard");
    - if (IS_ERR(graveyard)) {
    - ret = PTR_ERR(graveyard);
    - goto error_unsupported;
    - }
    -
    - cache->graveyard = graveyard;
    -
    - /* publish the cache */
    - fscache_init_cache(&cache->cache,
    - &cachefiles_cache_ops,
    - "%s",
    - fsdef->dentry->d_sb->s_id);
    -
    - fscache_object_init(&fsdef->fscache, &fscache_fsdef_index,
    - &cache->cache);
    -
    - ret = fscache_add_cache(&cache->cache, &fsdef->fscache, cache->tag);
    - if (ret < 0)
    - goto error_add_cache;
    -
    - /* done */
    - set_bit(CACHEFILES_READY, &cache->flags);
    - dput(root);
    -
    - pr_info("File cache on %s registered\n", cache->cache.identifier);
    -
    - /* check how much space the cache has */
    - cachefiles_has_space(cache, 0, 0);
    - cachefiles_end_secure(cache, saved_cred);
    - return 0;
    -
    -error_add_cache:
    - dput(cache->graveyard);
    - cache->graveyard = NULL;
    -error_unsupported:
    - mntput(cache->mnt);
    - cache->mnt = NULL;
    - dput(fsdef->dentry);
    - fsdef->dentry = NULL;
    - dput(root);
    -error_open_root:
    - kmem_cache_free(cachefiles_object_jar, fsdef);
    -error_root_object:
    - cachefiles_end_secure(cache, saved_cred);
    - pr_err("Failed to register: %d\n", ret);
    - return ret;
    -}
    -
    -/*
    - * unbind a cache on fd release
    - */
    -void cachefiles_daemon_unbind(struct cachefiles_cache *cache)
    -{
    - _enter("");
    -
    - if (test_bit(CACHEFILES_READY, &cache->flags)) {
    - pr_info("File cache on %s unregistering\n",
    - cache->cache.identifier);
    -
    - fscache_withdraw_cache(&cache->cache);
    - }
    -
    - dput(cache->graveyard);
    - mntput(cache->mnt);
    -
    - kfree(cache->rootdirname);
    - kfree(cache->secctx);
    - kfree(cache->tag);
    -
    - _leave("");
    -}
    diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c
    deleted file mode 100644
    index 752c1e43416f..000000000000
    --- a/fs/cachefiles/daemon.c
    +++ /dev/null
    @@ -1,748 +0,0 @@
    -// SPDX-License-Identifier: GPL-2.0-or-later
    -/* Daemon interface
    - *
    - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -
    -#include <linux/module.h>
    -#include <linux/init.h>
    -#include <linux/sched.h>
    -#include <linux/completion.h>
    -#include <linux/slab.h>
    -#include <linux/fs.h>
    -#include <linux/file.h>
    -#include <linux/namei.h>
    -#include <linux/poll.h>
    -#include <linux/mount.h>
    -#include <linux/statfs.h>
    -#include <linux/ctype.h>
    -#include <linux/string.h>
    -#include <linux/fs_struct.h>
    -#include "internal.h"
    -
    -static int cachefiles_daemon_open(struct inode *, struct file *);
    -static int cachefiles_daemon_release(struct inode *, struct file *);
    -static ssize_t cachefiles_daemon_read(struct file *, char __user *, size_t,
    - loff_t *);
    -static ssize_t cachefiles_daemon_write(struct file *, const char __user *,
    - size_t, loff_t *);
    -static __poll_t cachefiles_daemon_poll(struct file *,
    - struct poll_table_struct *);
    -static int cachefiles_daemon_frun(struct cachefiles_cache *, char *);
    -static int cachefiles_daemon_fcull(struct cachefiles_cache *, char *);
    -static int cachefiles_daemon_fstop(struct cachefiles_cache *, char *);
    -static int cachefiles_daemon_brun(struct cachefiles_cache *, char *);
    -static int cachefiles_daemon_bcull(struct cachefiles_cache *, char *);
    -static int cachefiles_daemon_bstop(struct cachefiles_cache *, char *);
    -static int cachefiles_daemon_cull(struct cachefiles_cache *, char *);
    -static int cachefiles_daemon_debug(struct cachefiles_cache *, char *);
    -static int cachefiles_daemon_dir(struct cachefiles_cache *, char *);
    -static int cachefiles_daemon_inuse(struct cachefiles_cache *, char *);
    -static int cachefiles_daemon_secctx(struct cachefiles_cache *, char *);
    -static int cachefiles_daemon_tag(struct cachefiles_cache *, char *);
    -
    -static unsigned long cachefiles_open;
    -
    -const struct file_operations cachefiles_daemon_fops = {
    - .owner = THIS_MODULE,
    - .open = cachefiles_daemon_open,
    - .release = cachefiles_daemon_release,
    - .read = cachefiles_daemon_read,
    - .write = cachefiles_daemon_write,
    - .poll = cachefiles_daemon_poll,
    - .llseek = noop_llseek,
    -};
    -
    -struct cachefiles_daemon_cmd {
    - char name[8];
    - int (*handler)(struct cachefiles_cache *cache, char *args);
    -};
    -
    -static const struct cachefiles_daemon_cmd cachefiles_daemon_cmds[] = {
    - { "bind", cachefiles_daemon_bind },
    - { "brun", cachefiles_daemon_brun },
    - { "bcull", cachefiles_daemon_bcull },
    - { "bstop", cachefiles_daemon_bstop },
    - { "cull", cachefiles_daemon_cull },
    - { "debug", cachefiles_daemon_debug },
    - { "dir", cachefiles_daemon_dir },
    - { "frun", cachefiles_daemon_frun },
    - { "fcull", cachefiles_daemon_fcull },
    - { "fstop", cachefiles_daemon_fstop },
    - { "inuse", cachefiles_daemon_inuse },
    - { "secctx", cachefiles_daemon_secctx },
    - { "tag", cachefiles_daemon_tag },
    - { "", NULL }
    -};
    -
    -
    -/*
    - * do various checks
    - */
    -static int cachefiles_daemon_open(struct inode *inode, struct file *file)
    -{
    - struct cachefiles_cache *cache;
    -
    - _enter("");
    -
    - /* only the superuser may do this */
    - if (!capable(CAP_SYS_ADMIN))
    - return -EPERM;
    -
    - /* the cachefiles device may only be open once at a time */
    - if (xchg(&cachefiles_open, 1) == 1)
    - return -EBUSY;
    -
    - /* allocate a cache record */
    - cache = kzalloc(sizeof(struct cachefiles_cache), GFP_KERNEL);
    - if (!cache) {
    - cachefiles_open = 0;
    - return -ENOMEM;
    - }
    -
    - mutex_init(&cache->daemon_mutex);
    - cache->active_nodes = RB_ROOT;
    - rwlock_init(&cache->active_lock);
    - init_waitqueue_head(&cache->daemon_pollwq);
    -
    - /* set default caching limits
    - * - limit at 1% free space and/or free files
    - * - cull below 5% free space and/or free files
    - * - cease culling above 7% free space and/or free files
    - */
    - cache->frun_percent = 7;
    - cache->fcull_percent = 5;
    - cache->fstop_percent = 1;
    - cache->brun_percent = 7;
    - cache->bcull_percent = 5;
    - cache->bstop_percent = 1;
    -
    - file->private_data = cache;
    - cache->cachefilesd = file;
    - return 0;
    -}
    -
    -/*
    - * release a cache
    - */
    -static int cachefiles_daemon_release(struct inode *inode, struct file *file)
    -{
    - struct cachefiles_cache *cache = file->private_data;
    -
    - _enter("");
    -
    - ASSERT(cache);
    -
    - set_bit(CACHEFILES_DEAD, &cache->flags);
    -
    - cachefiles_daemon_unbind(cache);
    -
    - ASSERT(!cache->active_nodes.rb_node);
    -
    - /* clean up the control file interface */
    - cache->cachefilesd = NULL;
    - file->private_data = NULL;
    - cachefiles_open = 0;
    -
    - kfree(cache);
    -
    - _leave("");
    - return 0;
    -}
    -
    -/*
    - * read the cache state
    - */
    -static ssize_t cachefiles_daemon_read(struct file *file, char __user *_buffer,
    - size_t buflen, loff_t *pos)
    -{
    - struct cachefiles_cache *cache = file->private_data;
    - unsigned long long b_released;
    - unsigned f_released;
    - char buffer[256];
    - int n;
    -
    - //_enter(",,%zu,", buflen);
    -
    - if (!test_bit(CACHEFILES_READY, &cache->flags))
    - return 0;
    -
    - /* check how much space the cache has */
    - cachefiles_has_space(cache, 0, 0);
    -
    - /* summarise */
    - f_released = atomic_xchg(&cache->f_released, 0);
    - b_released = atomic_long_xchg(&cache->b_released, 0);
    - clear_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
    -
    - n = snprintf(buffer, sizeof(buffer),
    - "cull=%c"
    - " frun=%llx"
    - " fcull=%llx"
    - " fstop=%llx"
    - " brun=%llx"
    - " bcull=%llx"
    - " bstop=%llx"
    - " freleased=%x"
    - " breleased=%llx",
    - test_bit(CACHEFILES_CULLING, &cache->flags) ? '1' : '0',
    - (unsigned long long) cache->frun,
    - (unsigned long long) cache->fcull,
    - (unsigned long long) cache->fstop,
    - (unsigned long long) cache->brun,
    - (unsigned long long) cache->bcull,
    - (unsigned long long) cache->bstop,
    - f_released,
    - b_released);
    -
    - if (n > buflen)
    - return -EMSGSIZE;
    -
    - if (copy_to_user(_buffer, buffer, n) != 0)
    - return -EFAULT;
    -
    - return n;
    -}
    -
    -/*
    - * command the cache
    - */
    -static ssize_t cachefiles_daemon_write(struct file *file,
    - const char __user *_data,
    - size_t datalen,
    - loff_t *pos)
    -{
    - const struct cachefiles_daemon_cmd *cmd;
    - struct cachefiles_cache *cache = file->private_data;
    - ssize_t ret;
    - char *data, *args, *cp;
    -
    - //_enter(",,%zu,", datalen);
    -
    - ASSERT(cache);
    -
    - if (test_bit(CACHEFILES_DEAD, &cache->flags))
    - return -EIO;
    -
    - if (datalen < 0 || datalen > PAGE_SIZE - 1)
    - return -EOPNOTSUPP;
    -
    - /* drag the command string into the kernel so we can parse it */
    - data = memdup_user_nul(_data, datalen);
    - if (IS_ERR(data))
    - return PTR_ERR(data);
    -
    - ret = -EINVAL;
    - if (memchr(data, '\0', datalen))
    - goto error;
    -
    - /* strip any newline */
    - cp = memchr(data, '\n', datalen);
    - if (cp) {
    - if (cp == data)
    - goto error;
    -
    - *cp = '\0';
    - }
    -
    - /* parse the command */
    - ret = -EOPNOTSUPP;
    -
    - for (args = data; *args; args++)
    - if (isspace(*args))
    - break;
    - if (*args) {
    - if (args == data)
    - goto error;
    - *args = '\0';
    - args = skip_spaces(++args);
    - }
    -
    - /* run the appropriate command handler */
    - for (cmd = cachefiles_daemon_cmds; cmd->name[0]; cmd++)
    - if (strcmp(cmd->name, data) == 0)
    - goto found_command;
    -
    -error:
    - kfree(data);
    - //_leave(" = %zd", ret);
    - return ret;
    -
    -found_command:
    - mutex_lock(&cache->daemon_mutex);
    -
    - ret = -EIO;
    - if (!test_bit(CACHEFILES_DEAD, &cache->flags))
    - ret = cmd->handler(cache, args);
    -
    - mutex_unlock(&cache->daemon_mutex);
    -
    - if (ret == 0)
    - ret = datalen;
    - goto error;
    -}
    -
    -/*
    - * poll for culling state
    - * - use EPOLLOUT to indicate culling state
    - */
    -static __poll_t cachefiles_daemon_poll(struct file *file,
    - struct poll_table_struct *poll)
    -{
    - struct cachefiles_cache *cache = file->private_data;
    - __poll_t mask;
    -
    - poll_wait(file, &cache->daemon_pollwq, poll);
    - mask = 0;
    -
    - if (test_bit(CACHEFILES_STATE_CHANGED, &cache->flags))
    - mask |= EPOLLIN;
    -
    - if (test_bit(CACHEFILES_CULLING, &cache->flags))
    - mask |= EPOLLOUT;
    -
    - return mask;
    -}
    -
    -/*
    - * give a range error for cache space constraints
    - * - can be tail-called
    - */
    -static int cachefiles_daemon_range_error(struct cachefiles_cache *cache,
    - char *args)
    -{
    - pr_err("Free space limits must be in range 0%%<=stop<cull<run<100%%\n");
    -
    - return -EINVAL;
    -}
    -
    -/*
    - * set the percentage of files at which to stop culling
    - * - command: "frun <N>%"
    - */
    -static int cachefiles_daemon_frun(struct cachefiles_cache *cache, char *args)
    -{
    - unsigned long frun;
    -
    - _enter(",%s", args);
    -
    - if (!*args)
    - return -EINVAL;
    -
    - frun = simple_strtoul(args, &args, 10);
    - if (args[0] != '%' || args[1] != '\0')
    - return -EINVAL;
    -
    - if (frun <= cache->fcull_percent || frun >= 100)
    - return cachefiles_daemon_range_error(cache, args);
    -
    - cache->frun_percent = frun;
    - return 0;
    -}
    -
    -/*
    - * set the percentage of files at which to start culling
    - * - command: "fcull <N>%"
    - */
    -static int cachefiles_daemon_fcull(struct cachefiles_cache *cache, char *args)
    -{
    - unsigned long fcull;
    -
    - _enter(",%s", args);
    -
    - if (!*args)
    - return -EINVAL;
    -
    - fcull = simple_strtoul(args, &args, 10);
    - if (args[0] != '%' || args[1] != '\0')
    - return -EINVAL;
    -
    - if (fcull <= cache->fstop_percent || fcull >= cache->frun_percent)
    - return cachefiles_daemon_range_error(cache, args);
    -
    - cache->fcull_percent = fcull;
    - return 0;
    -}
    -
    -/*
    - * set the percentage of files at which to stop allocating
    - * - command: "fstop <N>%"
    - */
    -static int cachefiles_daemon_fstop(struct cachefiles_cache *cache, char *args)
    -{
    - unsigned long fstop;
    -
    - _enter(",%s", args);
    -
    - if (!*args)
    - return -EINVAL;
    -
    - fstop = simple_strtoul(args, &args, 10);
    - if (args[0] != '%' || args[1] != '\0')
    - return -EINVAL;
    -
    - if (fstop < 0 || fstop >= cache->fcull_percent)
    - return cachefiles_daemon_range_error(cache, args);
    -
    - cache->fstop_percent = fstop;
    - return 0;
    -}
    -
    -/*
    - * set the percentage of blocks at which to stop culling
    - * - command: "brun <N>%"
    - */
    -static int cachefiles_daemon_brun(struct cachefiles_cache *cache, char *args)
    -{
    - unsigned long brun;
    -
    - _enter(",%s", args);
    -
    - if (!*args)
    - return -EINVAL;
    -
    - brun = simple_strtoul(args, &args, 10);
    - if (args[0] != '%' || args[1] != '\0')
    - return -EINVAL;
    -
    - if (brun <= cache->bcull_percent || brun >= 100)
    - return cachefiles_daemon_range_error(cache, args);
    -
    - cache->brun_percent = brun;
    - return 0;
    -}
    -
    -/*
    - * set the percentage of blocks at which to start culling
    - * - command: "bcull <N>%"
    - */
    -static int cachefiles_daemon_bcull(struct cachefiles_cache *cache, char *args)
    -{
    - unsigned long bcull;
    -
    - _enter(",%s", args);
    -
    - if (!*args)
    - return -EINVAL;
    -
    - bcull = simple_strtoul(args, &args, 10);
    - if (args[0] != '%' || args[1] != '\0')
    - return -EINVAL;
    -
    - if (bcull <= cache->bstop_percent || bcull >= cache->brun_percent)
    - return cachefiles_daemon_range_error(cache, args);
    -
    - cache->bcull_percent = bcull;
    - return 0;
    -}
    -
    -/*
    - * set the percentage of blocks at which to stop allocating
    - * - command: "bstop <N>%"
    - */
    -static int cachefiles_daemon_bstop(struct cachefiles_cache *cache, char *args)
    -{
    - unsigned long bstop;
    -
    - _enter(",%s", args);
    -
    - if (!*args)
    - return -EINVAL;
    -
    - bstop = simple_strtoul(args, &args, 10);
    - if (args[0] != '%' || args[1] != '\0')
    - return -EINVAL;
    -
    - if (bstop < 0 || bstop >= cache->bcull_percent)
    - return cachefiles_daemon_range_error(cache, args);
    -
    - cache->bstop_percent = bstop;
    - return 0;
    -}
    -
    -/*
    - * set the cache directory
    - * - command: "dir <name>"
    - */
    -static int cachefiles_daemon_dir(struct cachefiles_cache *cache, char *args)
    -{
    - char *dir;
    -
    - _enter(",%s", args);
    -
    - if (!*args) {
    - pr_err("Empty directory specified\n");
    - return -EINVAL;
    - }
    -
    - if (cache->rootdirname) {
    - pr_err("Second cache directory specified\n");
    - return -EEXIST;
    - }
    -
    - dir = kstrdup(args, GFP_KERNEL);
    - if (!dir)
    - return -ENOMEM;
    -
    - cache->rootdirname = dir;
    - return 0;
    -}
    -
    -/*
    - * set the cache security context
    - * - command: "secctx <ctx>"
    - */
    -static int cachefiles_daemon_secctx(struct cachefiles_cache *cache, char *args)
    -{
    - char *secctx;
    -
    - _enter(",%s", args);
    -
    - if (!*args) {
    - pr_err("Empty security context specified\n");
    - return -EINVAL;
    - }
    -
    - if (cache->secctx) {
    - pr_err("Second security context specified\n");
    - return -EINVAL;
    - }
    -
    - secctx = kstrdup(args, GFP_KERNEL);
    - if (!secctx)
    - return -ENOMEM;
    -
    - cache->secctx = secctx;
    - return 0;
    -}
    -
    -/*
    - * set the cache tag
    - * - command: "tag <name>"
    - */
    -static int cachefiles_daemon_tag(struct cachefiles_cache *cache, char *args)
    -{
    - char *tag;
    -
    - _enter(",%s", args);
    -
    - if (!*args) {
    - pr_err("Empty tag specified\n");
    - return -EINVAL;
    - }
    -
    - if (cache->tag)
    - return -EEXIST;
    -
    - tag = kstrdup(args, GFP_KERNEL);
    - if (!tag)
    - return -ENOMEM;
    -
    - cache->tag = tag;
    - return 0;
    -}
    -
    -/*
    - * request a node in the cache be culled from the current working directory
    - * - command: "cull <name>"
    - */
    -static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
    -{
    - struct path path;
    - const struct cred *saved_cred;
    - int ret;
    -
    - _enter(",%s", args);
    -
    - if (strchr(args, '/'))
    - goto inval;
    -
    - if (!test_bit(CACHEFILES_READY, &cache->flags)) {
    - pr_err("cull applied to unready cache\n");
    - return -EIO;
    - }
    -
    - if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
    - pr_err("cull applied to dead cache\n");
    - return -EIO;
    - }
    -
    - /* extract the directory dentry from the cwd */
    - get_fs_pwd(current->fs, &path);
    -
    - if (!d_can_lookup(path.dentry))
    - goto notdir;
    -
    - cachefiles_begin_secure(cache, &saved_cred);
    - ret = cachefiles_cull(cache, path.dentry, args);
    - cachefiles_end_secure(cache, saved_cred);
    -
    - path_put(&path);
    - _leave(" = %d", ret);
    - return ret;
    -
    -notdir:
    - path_put(&path);
    - pr_err("cull command requires dirfd to be a directory\n");
    - return -ENOTDIR;
    -
    -inval:
    - pr_err("cull command requires dirfd and filename\n");
    - return -EINVAL;
    -}
    -
    -/*
    - * set debugging mode
    - * - command: "debug <mask>"
    - */
    -static int cachefiles_daemon_debug(struct cachefiles_cache *cache, char *args)
    -{
    - unsigned long mask;
    -
    - _enter(",%s", args);
    -
    - mask = simple_strtoul(args, &args, 0);
    - if (args[0] != '\0')
    - goto inval;
    -
    - cachefiles_debug = mask;
    - _leave(" = 0");
    - return 0;
    -
    -inval:
    - pr_err("debug command requires mask\n");
    - return -EINVAL;
    -}
    -
    -/*
    - * find out whether an object in the current working directory is in use or not
    - * - command: "inuse <name>"
    - */
    -static int cachefiles_daemon_inuse(struct cachefiles_cache *cache, char *args)
    -{
    - struct path path;
    - const struct cred *saved_cred;
    - int ret;
    -
    - //_enter(",%s", args);
    -
    - if (strchr(args, '/'))
    - goto inval;
    -
    - if (!test_bit(CACHEFILES_READY, &cache->flags)) {
    - pr_err("inuse applied to unready cache\n");
    - return -EIO;
    - }
    -
    - if (test_bit(CACHEFILES_DEAD, &cache->flags)) {
    - pr_err("inuse applied to dead cache\n");
    - return -EIO;
    - }
    -
    - /* extract the directory dentry from the cwd */
    - get_fs_pwd(current->fs, &path);
    -
    - if (!d_can_lookup(path.dentry))
    - goto notdir;
    -
    - cachefiles_begin_secure(cache, &saved_cred);
    - ret = cachefiles_check_in_use(cache, path.dentry, args);
    - cachefiles_end_secure(cache, saved_cred);
    -
    - path_put(&path);
    - //_leave(" = %d", ret);
    - return ret;
    -
    -notdir:
    - path_put(&path);
    - pr_err("inuse command requires dirfd to be a directory\n");
    - return -ENOTDIR;
    -
    -inval:
    - pr_err("inuse command requires dirfd and filename\n");
    - return -EINVAL;
    -}
    -
    -/*
    - * see if we have space for a number of pages and/or a number of files in the
    - * cache
    - */
    -int cachefiles_has_space(struct cachefiles_cache *cache,
    - unsigned fnr, unsigned bnr)
    -{
    - struct kstatfs stats;
    - struct path path = {
    - .mnt = cache->mnt,
    - .dentry = cache->mnt->mnt_root,
    - };
    - int ret;
    -
    - //_enter("{%llu,%llu,%llu,%llu,%llu,%llu},%u,%u",
    - // (unsigned long long) cache->frun,
    - // (unsigned long long) cache->fcull,
    - // (unsigned long long) cache->fstop,
    - // (unsigned long long) cache->brun,
    - // (unsigned long long) cache->bcull,
    - // (unsigned long long) cache->bstop,
    - // fnr, bnr);
    -
    - /* find out how many pages of blockdev are available */
    - memset(&stats, 0, sizeof(stats));
    -
    - ret = vfs_statfs(&path, &stats);
    - if (ret < 0) {
    - if (ret == -EIO)
    - cachefiles_io_error(cache, "statfs failed");
    - _leave(" = %d", ret);
    - return ret;
    - }
    -
    - stats.f_bavail >>= cache->bshift;
    -
    - //_debug("avail %llu,%llu",
    - // (unsigned long long) stats.f_ffree,
    - // (unsigned long long) stats.f_bavail);
    -
    - /* see if there is sufficient space */
    - if (stats.f_ffree > fnr)
    - stats.f_ffree -= fnr;
    - else
    - stats.f_ffree = 0;
    -
    - if (stats.f_bavail > bnr)
    - stats.f_bavail -= bnr;
    - else
    - stats.f_bavail = 0;
    -
    - ret = -ENOBUFS;
    - if (stats.f_ffree < cache->fstop ||
    - stats.f_bavail < cache->bstop)
    - goto begin_cull;
    -
    - ret = 0;
    - if (stats.f_ffree < cache->fcull ||
    - stats.f_bavail < cache->bcull)
    - goto begin_cull;
    -
    - if (test_bit(CACHEFILES_CULLING, &cache->flags) &&
    - stats.f_ffree >= cache->frun &&
    - stats.f_bavail >= cache->brun &&
    - test_and_clear_bit(CACHEFILES_CULLING, &cache->flags)
    - ) {
    - _debug("cease culling");
    - cachefiles_state_changed(cache);
    - }
    -
    - //_leave(" = 0");
    - return 0;
    -
    -begin_cull:
    - if (!test_and_set_bit(CACHEFILES_CULLING, &cache->flags)) {
    - _debug("### CULL CACHE ###");
    - cachefiles_state_changed(cache);
    - }
    -
    - _leave(" = %d", ret);
    - return ret;
    -}
    diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
    deleted file mode 100644
    index da28ac1fa225..000000000000
    --- a/fs/cachefiles/interface.c
    +++ /dev/null
    @@ -1,572 +0,0 @@
    -// SPDX-License-Identifier: GPL-2.0-or-later
    -/* FS-Cache interface to CacheFiles
    - *
    - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -
    -#include <linux/slab.h>
    -#include <linux/mount.h>
    -#include "internal.h"
    -
    -struct cachefiles_lookup_data {
    - struct cachefiles_xattr *auxdata; /* auxiliary data */
    - char *key; /* key path */
    -};
    -
    -static int cachefiles_attr_changed(struct fscache_object *_object);
    -
    -/*
    - * allocate an object record for a cookie lookup and prepare the lookup data
    - */
    -static struct fscache_object *cachefiles_alloc_object(
    - struct fscache_cache *_cache,
    - struct fscache_cookie *cookie)
    -{
    - struct cachefiles_lookup_data *lookup_data;
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - struct cachefiles_xattr *auxdata;
    - unsigned keylen, auxlen;
    - void *buffer, *p;
    - char *key;
    -
    - cache = container_of(_cache, struct cachefiles_cache, cache);
    -
    - _enter("{%s},%x,", cache->cache.identifier, cookie->debug_id);
    -
    - lookup_data = kmalloc(sizeof(*lookup_data), cachefiles_gfp);
    - if (!lookup_data)
    - goto nomem_lookup_data;
    -
    - /* create a new object record and a temporary leaf image */
    - object = kmem_cache_alloc(cachefiles_object_jar, cachefiles_gfp);
    - if (!object)
    - goto nomem_object;
    -
    - ASSERTCMP(object->backer, ==, NULL);
    -
    - BUG_ON(test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
    - atomic_set(&object->usage, 1);
    -
    - fscache_object_init(&object->fscache, cookie, &cache->cache);
    -
    - object->type = cookie->def->type;
    -
    - /* get hold of the raw key
    - * - stick the length on the front and leave space on the back for the
    - * encoder
    - */
    - buffer = kmalloc((2 + 512) + 3, cachefiles_gfp);
    - if (!buffer)
    - goto nomem_buffer;
    -
    - keylen = cookie->key_len;
    - if (keylen <= sizeof(cookie->inline_key))
    - p = cookie->inline_key;
    - else
    - p = cookie->key;
    - memcpy(buffer + 2, p, keylen);
    -
    - *(uint16_t *)buffer = keylen;
    - ((char *)buffer)[keylen + 2] = 0;
    - ((char *)buffer)[keylen + 3] = 0;
    - ((char *)buffer)[keylen + 4] = 0;
    -
    - /* turn the raw key into something that can work with as a filename */
    - key = cachefiles_cook_key(buffer, keylen + 2, object->type);
    - if (!key)
    - goto nomem_key;
    -
    - /* get hold of the auxiliary data and prepend the object type */
    - auxdata = buffer;
    - auxlen = cookie->aux_len;
    - if (auxlen) {
    - if (auxlen <= sizeof(cookie->inline_aux))
    - p = cookie->inline_aux;
    - else
    - p = cookie->aux;
    - memcpy(auxdata->data, p, auxlen);
    - }
    -
    - auxdata->len = auxlen + 1;
    - auxdata->type = cookie->type;
    -
    - lookup_data->auxdata = auxdata;
    - lookup_data->key = key;
    - object->lookup_data = lookup_data;
    -
    - _leave(" = %x [%p]", object->fscache.debug_id, lookup_data);
    - return &object->fscache;
    -
    -nomem_key:
    - kfree(buffer);
    -nomem_buffer:
    - BUG_ON(test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
    - kmem_cache_free(cachefiles_object_jar, object);
    - fscache_object_destroyed(&cache->cache);
    -nomem_object:
    - kfree(lookup_data);
    -nomem_lookup_data:
    - _leave(" = -ENOMEM");
    - return ERR_PTR(-ENOMEM);
    -}
    -
    -/*
    - * attempt to look up the nominated node in this cache
    - * - return -ETIMEDOUT to be scheduled again
    - */
    -static int cachefiles_lookup_object(struct fscache_object *_object)
    -{
    - struct cachefiles_lookup_data *lookup_data;
    - struct cachefiles_object *parent, *object;
    - struct cachefiles_cache *cache;
    - const struct cred *saved_cred;
    - int ret;
    -
    - _enter("{OBJ%x}", _object->debug_id);
    -
    - cache = container_of(_object->cache, struct cachefiles_cache, cache);
    - parent = container_of(_object->parent,
    - struct cachefiles_object, fscache);
    - object = container_of(_object, struct cachefiles_object, fscache);
    - lookup_data = object->lookup_data;
    -
    - ASSERTCMP(lookup_data, !=, NULL);
    -
    - /* look up the key, creating any missing bits */
    - cachefiles_begin_secure(cache, &saved_cred);
    - ret = cachefiles_walk_to_object(parent, object,
    - lookup_data->key,
    - lookup_data->auxdata);
    - cachefiles_end_secure(cache, saved_cred);
    -
    - /* polish off by setting the attributes of non-index files */
    - if (ret == 0 &&
    - object->fscache.cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX)
    - cachefiles_attr_changed(&object->fscache);
    -
    - if (ret < 0 && ret != -ETIMEDOUT) {
    - if (ret != -ENOBUFS)
    - pr_warn("Lookup failed error %d\n", ret);
    - fscache_object_lookup_error(&object->fscache);
    - }
    -
    - _leave(" [%d]", ret);
    - return ret;
    -}
    -
    -/*
    - * indication of lookup completion
    - */
    -static void cachefiles_lookup_complete(struct fscache_object *_object)
    -{
    - struct cachefiles_object *object;
    -
    - object = container_of(_object, struct cachefiles_object, fscache);
    -
    - _enter("{OBJ%x,%p}", object->fscache.debug_id, object->lookup_data);
    -
    - if (object->lookup_data) {
    - kfree(object->lookup_data->key);
    - kfree(object->lookup_data->auxdata);
    - kfree(object->lookup_data);
    - object->lookup_data = NULL;
    - }
    -}
    -
    -/*
    - * increment the usage count on an inode object (may fail if unmounting)
    - */
    -static
    -struct fscache_object *cachefiles_grab_object(struct fscache_object *_object,
    - enum fscache_obj_ref_trace why)
    -{
    - struct cachefiles_object *object =
    - container_of(_object, struct cachefiles_object, fscache);
    - int u;
    -
    - _enter("{OBJ%x,%d}", _object->debug_id, atomic_read(&object->usage));
    -
    -#ifdef CACHEFILES_DEBUG_SLAB
    - ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
    -#endif
    -
    - u = atomic_inc_return(&object->usage);
    - trace_cachefiles_ref(object, _object->cookie,
    - (enum cachefiles_obj_ref_trace)why, u);
    - return &object->fscache;
    -}
    -
    -/*
    - * update the auxiliary data for an object object on disk
    - */
    -static void cachefiles_update_object(struct fscache_object *_object)
    -{
    - struct cachefiles_object *object;
    - struct cachefiles_xattr *auxdata;
    - struct cachefiles_cache *cache;
    - struct fscache_cookie *cookie;
    - const struct cred *saved_cred;
    - const void *aux;
    - unsigned auxlen;
    -
    - _enter("{OBJ%x}", _object->debug_id);
    -
    - object = container_of(_object, struct cachefiles_object, fscache);
    - cache = container_of(object->fscache.cache, struct cachefiles_cache,
    - cache);
    -
    - if (!fscache_use_cookie(_object)) {
    - _leave(" [relinq]");
    - return;
    - }
    -
    - cookie = object->fscache.cookie;
    - auxlen = cookie->aux_len;
    -
    - if (!auxlen) {
    - fscache_unuse_cookie(_object);
    - _leave(" [no aux]");
    - return;
    - }
    -
    - auxdata = kmalloc(2 + auxlen + 3, cachefiles_gfp);
    - if (!auxdata) {
    - fscache_unuse_cookie(_object);
    - _leave(" [nomem]");
    - return;
    - }
    -
    - aux = (auxlen <= sizeof(cookie->inline_aux)) ?
    - cookie->inline_aux : cookie->aux;
    -
    - memcpy(auxdata->data, aux, auxlen);
    - fscache_unuse_cookie(_object);
    -
    - auxdata->len = auxlen + 1;
    - auxdata->type = cookie->type;
    -
    - cachefiles_begin_secure(cache, &saved_cred);
    - cachefiles_update_object_xattr(object, auxdata);
    - cachefiles_end_secure(cache, saved_cred);
    - kfree(auxdata);
    - _leave("");
    -}
    -
    -/*
    - * discard the resources pinned by an object and effect retirement if
    - * requested
    - */
    -static void cachefiles_drop_object(struct fscache_object *_object)
    -{
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - const struct cred *saved_cred;
    - struct inode *inode;
    - blkcnt_t i_blocks = 0;
    -
    - ASSERT(_object);
    -
    - object = container_of(_object, struct cachefiles_object, fscache);
    -
    - _enter("{OBJ%x,%d}",
    - object->fscache.debug_id, atomic_read(&object->usage));
    -
    - cache = container_of(object->fscache.cache,
    - struct cachefiles_cache, cache);
    -
    -#ifdef CACHEFILES_DEBUG_SLAB
    - ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
    -#endif
    -
    - /* We need to tidy the object up if we did in fact manage to open it.
    - * It's possible for us to get here before the object is fully
    - * initialised if the parent goes away or the object gets retired
    - * before we set it up.
    - */
    - if (object->dentry) {
    - /* delete retired objects */
    - if (test_bit(FSCACHE_OBJECT_RETIRED, &object->fscache.flags) &&
    - _object != cache->cache.fsdef
    - ) {
    - _debug("- retire object OBJ%x", object->fscache.debug_id);
    - inode = d_backing_inode(object->dentry);
    - if (inode)
    - i_blocks = inode->i_blocks;
    -
    - cachefiles_begin_secure(cache, &saved_cred);
    - cachefiles_delete_object(cache, object);
    - cachefiles_end_secure(cache, saved_cred);
    - }
    -
    - /* close the filesystem stuff attached to the object */
    - if (object->backer != object->dentry)
    - dput(object->backer);
    - object->backer = NULL;
    - }
    -
    - /* note that the object is now inactive */
    - if (test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags))
    - cachefiles_mark_object_inactive(cache, object, i_blocks);
    -
    - dput(object->dentry);
    - object->dentry = NULL;
    -
    - _leave("");
    -}
    -
    -/*
    - * dispose of a reference to an object
    - */
    -void cachefiles_put_object(struct fscache_object *_object,
    - enum fscache_obj_ref_trace why)
    -{
    - struct cachefiles_object *object;
    - struct fscache_cache *cache;
    - int u;
    -
    - ASSERT(_object);
    -
    - object = container_of(_object, struct cachefiles_object, fscache);
    -
    - _enter("{OBJ%x,%d}",
    - object->fscache.debug_id, atomic_read(&object->usage));
    -
    -#ifdef CACHEFILES_DEBUG_SLAB
    - ASSERT((atomic_read(&object->usage) & 0xffff0000) != 0x6b6b0000);
    -#endif
    -
    - ASSERTIFCMP(object->fscache.parent,
    - object->fscache.parent->n_children, >, 0);
    -
    - u = atomic_dec_return(&object->usage);
    - trace_cachefiles_ref(object, _object->cookie,
    - (enum cachefiles_obj_ref_trace)why, u);
    - ASSERTCMP(u, !=, -1);
    - if (u == 0) {
    - _debug("- kill object OBJ%x", object->fscache.debug_id);
    -
    - ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags));
    - ASSERTCMP(object->fscache.parent, ==, NULL);
    - ASSERTCMP(object->backer, ==, NULL);
    - ASSERTCMP(object->dentry, ==, NULL);
    - ASSERTCMP(object->fscache.n_ops, ==, 0);
    - ASSERTCMP(object->fscache.n_children, ==, 0);
    -
    - if (object->lookup_data) {
    - kfree(object->lookup_data->key);
    - kfree(object->lookup_data->auxdata);
    - kfree(object->lookup_data);
    - object->lookup_data = NULL;
    - }
    -
    - cache = object->fscache.cache;
    - fscache_object_destroy(&object->fscache);
    - kmem_cache_free(cachefiles_object_jar, object);
    - fscache_object_destroyed(cache);
    - }
    -
    - _leave("");
    -}
    -
    -/*
    - * sync a cache
    - */
    -static void cachefiles_sync_cache(struct fscache_cache *_cache)
    -{
    - struct cachefiles_cache *cache;
    - const struct cred *saved_cred;
    - int ret;
    -
    - _enter("%s", _cache->tag->name);
    -
    - cache = container_of(_cache, struct cachefiles_cache, cache);
    -
    - /* make sure all pages pinned by operations on behalf of the netfs are
    - * written to disc */
    - cachefiles_begin_secure(cache, &saved_cred);
    - down_read(&cache->mnt->mnt_sb->s_umount);
    - ret = sync_filesystem(cache->mnt->mnt_sb);
    - up_read(&cache->mnt->mnt_sb->s_umount);
    - cachefiles_end_secure(cache, saved_cred);
    -
    - if (ret == -EIO)
    - cachefiles_io_error(cache,
    - "Attempt to sync backing fs superblock"
    - " returned error %d",
    - ret);
    -}
    -
    -/*
    - * check if the backing cache is updated to FS-Cache
    - * - called by FS-Cache when evaluates if need to invalidate the cache
    - */
    -static int cachefiles_check_consistency(struct fscache_operation *op)
    -{
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - const struct cred *saved_cred;
    - int ret;
    -
    - _enter("{OBJ%x}", op->object->debug_id);
    -
    - object = container_of(op->object, struct cachefiles_object, fscache);
    - cache = container_of(object->fscache.cache,
    - struct cachefiles_cache, cache);
    -
    - cachefiles_begin_secure(cache, &saved_cred);
    - ret = cachefiles_check_auxdata(object);
    - cachefiles_end_secure(cache, saved_cred);
    -
    - _leave(" = %d", ret);
    - return ret;
    -}
    -
    -/*
    - * notification the attributes on an object have changed
    - * - called with reads/writes excluded by FS-Cache
    - */
    -static int cachefiles_attr_changed(struct fscache_object *_object)
    -{
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - const struct cred *saved_cred;
    - struct iattr newattrs;
    - uint64_t ni_size;
    - loff_t oi_size;
    - int ret;
    -
    - ni_size = _object->store_limit_l;
    -
    - _enter("{OBJ%x},[%llu]",
    - _object->debug_id, (unsigned long long) ni_size);
    -
    - object = container_of(_object, struct cachefiles_object, fscache);
    - cache = container_of(object->fscache.cache,
    - struct cachefiles_cache, cache);
    -
    - if (ni_size == object->i_size)
    - return 0;
    -
    - if (!object->backer)
    - return -ENOBUFS;
    -
    - ASSERT(d_is_reg(object->backer));
    -
    - fscache_set_store_limit(&object->fscache, ni_size);
    -
    - oi_size = i_size_read(d_backing_inode(object->backer));
    - if (oi_size == ni_size)
    - return 0;
    -
    - cachefiles_begin_secure(cache, &saved_cred);
    - inode_lock(d_inode(object->backer));
    -
    - /* if there's an extension to a partial page at the end of the backing
    - * file, we need to discard the partial page so that we pick up new
    - * data after it */
    - if (oi_size & ~PAGE_MASK && ni_size > oi_size) {
    - _debug("discard tail %llx", oi_size);
    - newattrs.ia_valid = ATTR_SIZE;
    - newattrs.ia_size = oi_size & PAGE_MASK;
    - ret = notify_change(&init_user_ns, object->backer, &newattrs, NULL);
    - if (ret < 0)
    - goto truncate_failed;
    - }
    -
    - newattrs.ia_valid = ATTR_SIZE;
    - newattrs.ia_size = ni_size;
    - ret = notify_change(&init_user_ns, object->backer, &newattrs, NULL);
    -
    -truncate_failed:
    - inode_unlock(d_inode(object->backer));
    - cachefiles_end_secure(cache, saved_cred);
    -
    - if (ret == -EIO) {
    - fscache_set_store_limit(&object->fscache, 0);
    - cachefiles_io_error_obj(object, "Size set failed");
    - ret = -ENOBUFS;
    - }
    -
    - _leave(" = %d", ret);
    - return ret;
    -}
    -
    -/*
    - * Invalidate an object
    - */
    -static void cachefiles_invalidate_object(struct fscache_operation *op)
    -{
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - const struct cred *saved_cred;
    - struct path path;
    - uint64_t ni_size;
    - int ret;
    -
    - object = container_of(op->object, struct cachefiles_object, fscache);
    - cache = container_of(object->fscache.cache,
    - struct cachefiles_cache, cache);
    -
    - ni_size = op->object->store_limit_l;
    -
    - _enter("{OBJ%x},[%llu]",
    - op->object->debug_id, (unsigned long long)ni_size);
    -
    - if (object->backer) {
    - ASSERT(d_is_reg(object->backer));
    -
    - fscache_set_store_limit(&object->fscache, ni_size);
    -
    - path.dentry = object->backer;
    - path.mnt = cache->mnt;
    -
    - cachefiles_begin_secure(cache, &saved_cred);
    - ret = vfs_truncate(&path, 0);
    - if (ret == 0)
    - ret = vfs_truncate(&path, ni_size);
    - cachefiles_end_secure(cache, saved_cred);
    -
    - if (ret != 0) {
    - fscache_set_store_limit(&object->fscache, 0);
    - if (ret == -EIO)
    - cachefiles_io_error_obj(object,
    - "Invalidate failed");
    - }
    - }
    -
    - fscache_op_complete(op, true);
    - _leave("");
    -}
    -
    -/*
    - * dissociate a cache from all the pages it was backing
    - */
    -static void cachefiles_dissociate_pages(struct fscache_cache *cache)
    -{
    - _enter("");
    -}
    -
    -const struct fscache_cache_ops cachefiles_cache_ops = {
    - .name = "cachefiles",
    - .alloc_object = cachefiles_alloc_object,
    - .lookup_object = cachefiles_lookup_object,
    - .lookup_complete = cachefiles_lookup_complete,
    - .grab_object = cachefiles_grab_object,
    - .update_object = cachefiles_update_object,
    - .invalidate_object = cachefiles_invalidate_object,
    - .drop_object = cachefiles_drop_object,
    - .put_object = cachefiles_put_object,
    - .sync_cache = cachefiles_sync_cache,
    - .attr_changed = cachefiles_attr_changed,
    - .read_or_alloc_page = cachefiles_read_or_alloc_page,
    - .read_or_alloc_pages = cachefiles_read_or_alloc_pages,
    - .allocate_page = cachefiles_allocate_page,
    - .allocate_pages = cachefiles_allocate_pages,
    - .write_page = cachefiles_write_page,
    - .uncache_page = cachefiles_uncache_page,
    - .dissociate_pages = cachefiles_dissociate_pages,
    - .check_consistency = cachefiles_check_consistency,
    - .begin_read_operation = cachefiles_begin_read_operation,
    -};
    diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
    deleted file mode 100644
    index 0a511c36dab8..000000000000
    --- a/fs/cachefiles/internal.h
    +++ /dev/null
    @@ -1,350 +0,0 @@
    -/* SPDX-License-Identifier: GPL-2.0-or-later */
    -/* General netfs cache on cache files internal defs
    - *
    - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -
    -#ifdef pr_fmt
    -#undef pr_fmt
    -#endif
    -
    -#define pr_fmt(fmt) "CacheFiles: " fmt
    -
    -
    -#include <linux/fscache-cache.h>
    -#include <linux/timer.h>
    -#include <linux/wait_bit.h>
    -#include <linux/cred.h>
    -#include <linux/workqueue.h>
    -#include <linux/security.h>
    -
    -struct cachefiles_cache;
    -struct cachefiles_object;
    -
    -extern unsigned cachefiles_debug;
    -#define CACHEFILES_DEBUG_KENTER 1
    -#define CACHEFILES_DEBUG_KLEAVE 2
    -#define CACHEFILES_DEBUG_KDEBUG 4
    -
    -#define cachefiles_gfp (__GFP_RECLAIM | __GFP_NORETRY | __GFP_NOMEMALLOC)
    -
    -/*
    - * node records
    - */
    -struct cachefiles_object {
    - struct fscache_object fscache; /* fscache handle */
    - struct cachefiles_lookup_data *lookup_data; /* cached lookup data */
    - struct dentry *dentry; /* the file/dir representing this object */
    - struct dentry *backer; /* backing file */
    - loff_t i_size; /* object size */
    - unsigned long flags;
    -#define CACHEFILES_OBJECT_ACTIVE 0 /* T if marked active */
    - atomic_t usage; /* object usage count */
    - uint8_t type; /* object type */
    - uint8_t new; /* T if object new */
    - spinlock_t work_lock;
    - struct rb_node active_node; /* link in active tree (dentry is key) */
    -};
    -
    -extern struct kmem_cache *cachefiles_object_jar;
    -
    -/*
    - * Cache files cache definition
    - */
    -struct cachefiles_cache {
    - struct fscache_cache cache; /* FS-Cache record */
    - struct vfsmount *mnt; /* mountpoint holding the cache */
    - struct dentry *graveyard; /* directory into which dead objects go */
    - struct file *cachefilesd; /* manager daemon handle */
    - const struct cred *cache_cred; /* security override for accessing cache */
    - struct mutex daemon_mutex; /* command serialisation mutex */
    - wait_queue_head_t daemon_pollwq; /* poll waitqueue for daemon */
    - struct rb_root active_nodes; /* active nodes (can't be culled) */
    - rwlock_t active_lock; /* lock for active_nodes */
    - atomic_t gravecounter; /* graveyard uniquifier */
    - atomic_t f_released; /* number of objects released lately */
    - atomic_long_t b_released; /* number of blocks released lately */
    - unsigned frun_percent; /* when to stop culling (% files) */
    - unsigned fcull_percent; /* when to start culling (% files) */
    - unsigned fstop_percent; /* when to stop allocating (% files) */
    - unsigned brun_percent; /* when to stop culling (% blocks) */
    - unsigned bcull_percent; /* when to start culling (% blocks) */
    - unsigned bstop_percent; /* when to stop allocating (% blocks) */
    - unsigned bsize; /* cache's block size */
    - unsigned bshift; /* min(ilog2(PAGE_SIZE / bsize), 0) */
    - uint64_t frun; /* when to stop culling */
    - uint64_t fcull; /* when to start culling */
    - uint64_t fstop; /* when to stop allocating */
    - sector_t brun; /* when to stop culling */
    - sector_t bcull; /* when to start culling */
    - sector_t bstop; /* when to stop allocating */
    - unsigned long flags;
    -#define CACHEFILES_READY 0 /* T if cache prepared */
    -#define CACHEFILES_DEAD 1 /* T if cache dead */
    -#define CACHEFILES_CULLING 2 /* T if cull engaged */
    -#define CACHEFILES_STATE_CHANGED 3 /* T if state changed (poll trigger) */
    - char *rootdirname; /* name of cache root directory */
    - char *secctx; /* LSM security context */
    - char *tag; /* cache binding tag */
    -};
    -
    -/*
    - * backing file read tracking
    - */
    -struct cachefiles_one_read {
    - wait_queue_entry_t monitor; /* link into monitored waitqueue */
    - struct page *back_page; /* backing file page we're waiting for */
    - struct page *netfs_page; /* netfs page we're going to fill */
    - struct fscache_retrieval *op; /* retrieval op covering this */
    - struct list_head op_link; /* link in op's todo list */
    -};
    -
    -/*
    - * backing file write tracking
    - */
    -struct cachefiles_one_write {
    - struct page *netfs_page; /* netfs page to copy */
    - struct cachefiles_object *object;
    - struct list_head obj_link; /* link in object's lists */
    - fscache_rw_complete_t end_io_func;
    - void *context;
    -};
    -
    -/*
    - * auxiliary data xattr buffer
    - */
    -struct cachefiles_xattr {
    - uint16_t len;
    - uint8_t type;
    - uint8_t data[];
    -};
    -
    -#include <trace/events/cachefiles.h>
    -
    -/*
    - * note change of state for daemon
    - */
    -static inline void cachefiles_state_changed(struct cachefiles_cache *cache)
    -{
    - set_bit(CACHEFILES_STATE_CHANGED, &cache->flags);
    - wake_up_all(&cache->daemon_pollwq);
    -}
    -
    -/*
    - * bind.c
    - */
    -extern int cachefiles_daemon_bind(struct cachefiles_cache *cache, char *args);
    -extern void cachefiles_daemon_unbind(struct cachefiles_cache *cache);
    -
    -/*
    - * daemon.c
    - */
    -extern const struct file_operations cachefiles_daemon_fops;
    -
    -extern int cachefiles_has_space(struct cachefiles_cache *cache,
    - unsigned fnr, unsigned bnr);
    -
    -/*
    - * interface.c
    - */
    -extern const struct fscache_cache_ops cachefiles_cache_ops;
    -
    -void cachefiles_put_object(struct fscache_object *_object,
    - enum fscache_obj_ref_trace why);
    -
    -/*
    - * key.c
    - */
    -extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
    -
    -/*
    - * namei.c
    - */
    -extern void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
    - struct cachefiles_object *object,
    - blkcnt_t i_blocks);
    -extern int cachefiles_delete_object(struct cachefiles_cache *cache,
    - struct cachefiles_object *object);
    -extern int cachefiles_walk_to_object(struct cachefiles_object *parent,
    - struct cachefiles_object *object,
    - const char *key,
    - struct cachefiles_xattr *auxdata);
    -extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
    - struct dentry *dir,
    - const char *name);
    -
    -extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
    - char *filename);
    -
    -extern int cachefiles_check_in_use(struct cachefiles_cache *cache,
    - struct dentry *dir, char *filename);
    -
    -/*
    - * rdwr.c
    - */
    -extern int cachefiles_read_or_alloc_page(struct fscache_retrieval *,
    - struct page *, gfp_t);
    -extern int cachefiles_read_or_alloc_pages(struct fscache_retrieval *,
    - struct list_head *, unsigned *,
    - gfp_t);
    -extern int cachefiles_allocate_page(struct fscache_retrieval *, struct page *,
    - gfp_t);
    -extern int cachefiles_allocate_pages(struct fscache_retrieval *,
    - struct list_head *, unsigned *, gfp_t);
    -extern int cachefiles_write_page(struct fscache_storage *, struct page *);
    -extern void cachefiles_uncache_page(struct fscache_object *, struct page *);
    -
    -/*
    - * rdwr2.c
    - */
    -extern int cachefiles_begin_read_operation(struct netfs_read_request *,
    - struct fscache_retrieval *);
    -
    -/*
    - * security.c
    - */
    -extern int cachefiles_get_security_ID(struct cachefiles_cache *cache);
    -extern int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
    - struct dentry *root,
    - const struct cred **_saved_cred);
    -
    -static inline void cachefiles_begin_secure(struct cachefiles_cache *cache,
    - const struct cred **_saved_cred)
    -{
    - *_saved_cred = override_creds(cache->cache_cred);
    -}
    -
    -static inline void cachefiles_end_secure(struct cachefiles_cache *cache,
    - const struct cred *saved_cred)
    -{
    - revert_creds(saved_cred);
    -}
    -
    -/*
    - * xattr.c
    - */
    -extern int cachefiles_check_object_type(struct cachefiles_object *object);
    -extern int cachefiles_set_object_xattr(struct cachefiles_object *object,
    - struct cachefiles_xattr *auxdata);
    -extern int cachefiles_update_object_xattr(struct cachefiles_object *object,
    - struct cachefiles_xattr *auxdata);
    -extern int cachefiles_check_auxdata(struct cachefiles_object *object);
    -extern int cachefiles_check_object_xattr(struct cachefiles_object *object,
    - struct cachefiles_xattr *auxdata);
    -extern int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
    - struct dentry *dentry);
    -
    -
    -/*
    - * error handling
    - */
    -
    -#define cachefiles_io_error(___cache, FMT, ...) \
    -do { \
    - pr_err("I/O Error: " FMT"\n", ##__VA_ARGS__); \
    - fscache_io_error(&(___cache)->cache); \
    - set_bit(CACHEFILES_DEAD, &(___cache)->flags); \
    -} while (0)
    -
    -#define cachefiles_io_error_obj(object, FMT, ...) \
    -do { \
    - struct cachefiles_cache *___cache; \
    - \
    - ___cache = container_of((object)->fscache.cache, \
    - struct cachefiles_cache, cache); \
    - cachefiles_io_error(___cache, FMT, ##__VA_ARGS__); \
    -} while (0)
    -
    -
    -/*
    - * debug tracing
    - */
    -#define dbgprintk(FMT, ...) \
    - printk(KERN_DEBUG "[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
    -
    -#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
    -#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
    -#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
    -
    -
    -#if defined(__KDEBUG)
    -#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
    -#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
    -#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
    -
    -#elif defined(CONFIG_CACHEFILES_DEBUG)
    -#define _enter(FMT, ...) \
    -do { \
    - if (cachefiles_debug & CACHEFILES_DEBUG_KENTER) \
    - kenter(FMT, ##__VA_ARGS__); \
    -} while (0)
    -
    -#define _leave(FMT, ...) \
    -do { \
    - if (cachefiles_debug & CACHEFILES_DEBUG_KLEAVE) \
    - kleave(FMT, ##__VA_ARGS__); \
    -} while (0)
    -
    -#define _debug(FMT, ...) \
    -do { \
    - if (cachefiles_debug & CACHEFILES_DEBUG_KDEBUG) \
    - kdebug(FMT, ##__VA_ARGS__); \
    -} while (0)
    -
    -#else
    -#define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__)
    -#define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
    -#define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
    -#endif
    -
    -#if 1 /* defined(__KDEBUGALL) */
    -
    -#define ASSERT(X) \
    -do { \
    - if (unlikely(!(X))) { \
    - pr_err("\n"); \
    - pr_err("Assertion failed\n"); \
    - BUG(); \
    - } \
    -} while (0)
    -
    -#define ASSERTCMP(X, OP, Y) \
    -do { \
    - if (unlikely(!((X) OP (Y)))) { \
    - pr_err("\n"); \
    - pr_err("Assertion failed\n"); \
    - pr_err("%lx " #OP " %lx is false\n", \
    - (unsigned long)(X), (unsigned long)(Y)); \
    - BUG(); \
    - } \
    -} while (0)
    -
    -#define ASSERTIF(C, X) \
    -do { \
    - if (unlikely((C) && !(X))) { \
    - pr_err("\n"); \
    - pr_err("Assertion failed\n"); \
    - BUG(); \
    - } \
    -} while (0)
    -
    -#define ASSERTIFCMP(C, X, OP, Y) \
    -do { \
    - if (unlikely((C) && !((X) OP (Y)))) { \
    - pr_err("\n"); \
    - pr_err("Assertion failed\n"); \
    - pr_err("%lx " #OP " %lx is false\n", \
    - (unsigned long)(X), (unsigned long)(Y)); \
    - BUG(); \
    - } \
    -} while (0)
    -
    -#else
    -
    -#define ASSERT(X) do {} while (0)
    -#define ASSERTCMP(X, OP, Y) do {} while (0)
    -#define ASSERTIF(C, X) do {} while (0)
    -#define ASSERTIFCMP(C, X, OP, Y) do {} while (0)
    -
    -#endif
    diff --git a/fs/cachefiles/io.c b/fs/cachefiles/io.c
    deleted file mode 100644
    index effe37ef8629..000000000000
    --- a/fs/cachefiles/io.c
    +++ /dev/null
    @@ -1,420 +0,0 @@
    -// SPDX-License-Identifier: GPL-2.0-or-later
    -/* kiocb-using read/write
    - *
    - * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -
    -#include <linux/mount.h>
    -#include <linux/slab.h>
    -#include <linux/file.h>
    -#include <linux/uio.h>
    -#include <linux/sched/mm.h>
    -#include <linux/netfs.h>
    -#include "internal.h"
    -
    -struct cachefiles_kiocb {
    - struct kiocb iocb;
    - refcount_t ki_refcnt;
    - loff_t start;
    - union {
    - size_t skipped;
    - size_t len;
    - };
    - netfs_io_terminated_t term_func;
    - void *term_func_priv;
    - bool was_async;
    -};
    -
    -static inline void cachefiles_put_kiocb(struct cachefiles_kiocb *ki)
    -{
    - if (refcount_dec_and_test(&ki->ki_refcnt)) {
    - fput(ki->iocb.ki_filp);
    - kfree(ki);
    - }
    -}
    -
    -/*
    - * Handle completion of a read from the cache.
    - */
    -static void cachefiles_read_complete(struct kiocb *iocb, long ret)
    -{
    - struct cachefiles_kiocb *ki = container_of(iocb, struct cachefiles_kiocb, iocb);
    -
    - _enter("%ld", ret);
    -
    - if (ki->term_func) {
    - if (ret >= 0)
    - ret += ki->skipped;
    - ki->term_func(ki->term_func_priv, ret, ki->was_async);
    - }
    -
    - cachefiles_put_kiocb(ki);
    -}
    -
    -/*
    - * Initiate a read from the cache.
    - */
    -static int cachefiles_read(struct netfs_cache_resources *cres,
    - loff_t start_pos,
    - struct iov_iter *iter,
    - bool seek_data,
    - netfs_io_terminated_t term_func,
    - void *term_func_priv)
    -{
    - struct cachefiles_kiocb *ki;
    - struct file *file = cres->cache_priv2;
    - unsigned int old_nofs;
    - ssize_t ret = -ENOBUFS;
    - size_t len = iov_iter_count(iter), skipped = 0;
    -
    - _enter("%pD,%li,%llx,%zx/%llx",
    - file, file_inode(file)->i_ino, start_pos, len,
    - i_size_read(file_inode(file)));
    -
    - /* If the caller asked us to seek for data before doing the read, then
    - * we should do that now. If we find a gap, we fill it with zeros.
    - */
    - if (seek_data) {
    - loff_t off = start_pos, off2;
    -
    - off2 = vfs_llseek(file, off, SEEK_DATA);
    - if (off2 < 0 && off2 >= (loff_t)-MAX_ERRNO && off2 != -ENXIO) {
    - skipped = 0;
    - ret = off2;
    - goto presubmission_error;
    - }
    -
    - if (off2 == -ENXIO || off2 >= start_pos + len) {
    - /* The region is beyond the EOF or there's no more data
    - * in the region, so clear the rest of the buffer and
    - * return success.
    - */
    - iov_iter_zero(len, iter);
    - skipped = len;
    - ret = 0;
    - goto presubmission_error;
    - }
    -
    - skipped = off2 - off;
    - iov_iter_zero(skipped, iter);
    - }
    -
    - ret = -ENOBUFS;
    - ki = kzalloc(sizeof(struct cachefiles_kiocb), GFP_KERNEL);
    - if (!ki)
    - goto presubmission_error;
    -
    - refcount_set(&ki->ki_refcnt, 2);
    - ki->iocb.ki_filp = file;
    - ki->iocb.ki_pos = start_pos + skipped;
    - ki->iocb.ki_flags = IOCB_DIRECT;
    - ki->iocb.ki_hint = ki_hint_validate(file_write_hint(file));
    - ki->iocb.ki_ioprio = get_current_ioprio();
    - ki->skipped = skipped;
    - ki->term_func = term_func;
    - ki->term_func_priv = term_func_priv;
    - ki->was_async = true;
    -
    - if (ki->term_func)
    - ki->iocb.ki_complete = cachefiles_read_complete;
    -
    - get_file(ki->iocb.ki_filp);
    -
    - old_nofs = memalloc_nofs_save();
    - ret = vfs_iocb_iter_read(file, &ki->iocb, iter);
    - memalloc_nofs_restore(old_nofs);
    - switch (ret) {
    - case -EIOCBQUEUED:
    - goto in_progress;
    -
    - case -ERESTARTSYS:
    - case -ERESTARTNOINTR:
    - case -ERESTARTNOHAND:
    - case -ERESTART_RESTARTBLOCK:
    - /* There's no easy way to restart the syscall since other AIO's
    - * may be already running. Just fail this IO with EINTR.
    - */
    - ret = -EINTR;
    - fallthrough;
    - default:
    - ki->was_async = false;
    - cachefiles_read_complete(&ki->iocb, ret);
    - if (ret > 0)
    - ret = 0;
    - break;
    - }
    -
    -in_progress:
    - cachefiles_put_kiocb(ki);
    - _leave(" = %zd", ret);
    - return ret;
    -
    -presubmission_error:
    - if (term_func)
    - term_func(term_func_priv, ret < 0 ? ret : skipped, false);
    - return ret;
    -}
    -
    -/*
    - * Handle completion of a write to the cache.
    - */
    -static void cachefiles_write_complete(struct kiocb *iocb, long ret)
    -{
    - struct cachefiles_kiocb *ki = container_of(iocb, struct cachefiles_kiocb, iocb);
    - struct inode *inode = file_inode(ki->iocb.ki_filp);
    -
    - _enter("%ld", ret);
    -
    - /* Tell lockdep we inherited freeze protection from submission thread */
    - __sb_writers_acquired(inode->i_sb, SB_FREEZE_WRITE);
    - __sb_end_write(inode->i_sb, SB_FREEZE_WRITE);
    -
    - if (ki->term_func)
    - ki->term_func(ki->term_func_priv, ret, ki->was_async);
    -
    - cachefiles_put_kiocb(ki);
    -}
    -
    -/*
    - * Initiate a write to the cache.
    - */
    -static int cachefiles_write(struct netfs_cache_resources *cres,
    - loff_t start_pos,
    - struct iov_iter *iter,
    - netfs_io_terminated_t term_func,
    - void *term_func_priv)
    -{
    - struct cachefiles_kiocb *ki;
    - struct inode *inode;
    - struct file *file = cres->cache_priv2;
    - unsigned int old_nofs;
    - ssize_t ret = -ENOBUFS;
    - size_t len = iov_iter_count(iter);
    -
    - _enter("%pD,%li,%llx,%zx/%llx",
    - file, file_inode(file)->i_ino, start_pos, len,
    - i_size_read(file_inode(file)));
    -
    - ki = kzalloc(sizeof(struct cachefiles_kiocb), GFP_KERNEL);
    - if (!ki)
    - goto presubmission_error;
    -
    - refcount_set(&ki->ki_refcnt, 2);
    - ki->iocb.ki_filp = file;
    - ki->iocb.ki_pos = start_pos;
    - ki->iocb.ki_flags = IOCB_DIRECT | IOCB_WRITE;
    - ki->iocb.ki_hint = ki_hint_validate(file_write_hint(file));
    - ki->iocb.ki_ioprio = get_current_ioprio();
    - ki->start = start_pos;
    - ki->len = len;
    - ki->term_func = term_func;
    - ki->term_func_priv = term_func_priv;
    - ki->was_async = true;
    -
    - if (ki->term_func)
    - ki->iocb.ki_complete = cachefiles_write_complete;
    -
    - /* Open-code file_start_write here to grab freeze protection, which
    - * will be released by another thread in aio_complete_rw(). Fool
    - * lockdep by telling it the lock got released so that it doesn't
    - * complain about the held lock when we return to userspace.
    - */
    - inode = file_inode(file);
    - __sb_start_write(inode->i_sb, SB_FREEZE_WRITE);
    - __sb_writers_release(inode->i_sb, SB_FREEZE_WRITE);
    -
    - get_file(ki->iocb.ki_filp);
    -
    - old_nofs = memalloc_nofs_save();
    - ret = vfs_iocb_iter_write(file, &ki->iocb, iter);
    - memalloc_nofs_restore(old_nofs);
    - switch (ret) {
    - case -EIOCBQUEUED:
    - goto in_progress;
    -
    - case -ERESTARTSYS:
    - case -ERESTARTNOINTR:
    - case -ERESTARTNOHAND:
    - case -ERESTART_RESTARTBLOCK:
    - /* There's no easy way to restart the syscall since other AIO's
    - * may be already running. Just fail this IO with EINTR.
    - */
    - ret = -EINTR;
    - fallthrough;
    - default:
    - ki->was_async = false;
    - cachefiles_write_complete(&ki->iocb, ret);
    - if (ret > 0)
    - ret = 0;
    - break;
    - }
    -
    -in_progress:
    - cachefiles_put_kiocb(ki);
    - _leave(" = %zd", ret);
    - return ret;
    -
    -presubmission_error:
    - if (term_func)
    - term_func(term_func_priv, -ENOMEM, false);
    - return -ENOMEM;
    -}
    -
    -/*
    - * Prepare a read operation, shortening it to a cached/uncached
    - * boundary as appropriate.
    - */
    -static enum netfs_read_source cachefiles_prepare_read(struct netfs_read_subrequest *subreq,
    - loff_t i_size)
    -{
    - struct fscache_retrieval *op = subreq->rreq->cache_resources.cache_priv;
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - const struct cred *saved_cred;
    - struct file *file = subreq->rreq->cache_resources.cache_priv2;
    - loff_t off, to;
    -
    - _enter("%zx @%llx/%llx", subreq->len, subreq->start, i_size);
    -
    - object = container_of(op->op.object,
    - struct cachefiles_object, fscache);
    - cache = container_of(object->fscache.cache,
    - struct cachefiles_cache, cache);
    -
    - if (!file)
    - goto cache_fail_nosec;
    -
    - if (subreq->start >= i_size)
    - return NETFS_FILL_WITH_ZEROES;
    -
    - cachefiles_begin_secure(cache, &saved_cred);
    -
    - off = vfs_llseek(file, subreq->start, SEEK_DATA);
    - if (off < 0 && off >= (loff_t)-MAX_ERRNO) {
    - if (off == (loff_t)-ENXIO)
    - goto download_and_store;
    - goto cache_fail;
    - }
    -
    - if (off >= subreq->start + subreq->len)
    - goto download_and_store;
    -
    - if (off > subreq->start) {
    - off = round_up(off, cache->bsize);
    - subreq->len = off - subreq->start;
    - goto download_and_store;
    - }
    -
    - to = vfs_llseek(file, subreq->start, SEEK_HOLE);
    - if (to < 0 && to >= (loff_t)-MAX_ERRNO)
    - goto cache_fail;
    -
    - if (to < subreq->start + subreq->len) {
    - if (subreq->start + subreq->len >= i_size)
    - to = round_up(to, cache->bsize);
    - else
    - to = round_down(to, cache->bsize);
    - subreq->len = to - subreq->start;
    - }
    -
    - cachefiles_end_secure(cache, saved_cred);
    - return NETFS_READ_FROM_CACHE;
    -
    -download_and_store:
    - if (cachefiles_has_space(cache, 0, (subreq->len + PAGE_SIZE - 1) / PAGE_SIZE) == 0)
    - __set_bit(NETFS_SREQ_WRITE_TO_CACHE, &subreq->flags);
    -cache_fail:
    - cachefiles_end_secure(cache, saved_cred);
    -cache_fail_nosec:
    - return NETFS_DOWNLOAD_FROM_SERVER;
    -}
    -
    -/*
    - * Prepare for a write to occur.
    - */
    -static int cachefiles_prepare_write(struct netfs_cache_resources *cres,
    - loff_t *_start, size_t *_len, loff_t i_size)
    -{
    - loff_t start = *_start;
    - size_t len = *_len, down;
    -
    - /* Round to DIO size */
    - down = start - round_down(start, PAGE_SIZE);
    - *_start = start - down;
    - *_len = round_up(down + len, PAGE_SIZE);
    - return 0;
    -}
    -
    -/*
    - * Clean up an operation.
    - */
    -static void cachefiles_end_operation(struct netfs_cache_resources *cres)
    -{
    - struct fscache_retrieval *op = cres->cache_priv;
    - struct file *file = cres->cache_priv2;
    -
    - _enter("");
    -
    - if (file)
    - fput(file);
    - if (op) {
    - fscache_op_complete(&op->op, false);
    - fscache_put_retrieval(op);
    - }
    -
    - _leave("");
    -}
    -
    -static const struct netfs_cache_ops cachefiles_netfs_cache_ops = {
    - .end_operation = cachefiles_end_operation,
    - .read = cachefiles_read,
    - .write = cachefiles_write,
    - .prepare_read = cachefiles_prepare_read,
    - .prepare_write = cachefiles_prepare_write,
    -};
    -
    -/*
    - * Open the cache file when beginning a cache operation.
    - */
    -int cachefiles_begin_read_operation(struct netfs_read_request *rreq,
    - struct fscache_retrieval *op)
    -{
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - struct path path;
    - struct file *file;
    -
    - _enter("");
    -
    - object = container_of(op->op.object,
    - struct cachefiles_object, fscache);
    - cache = container_of(object->fscache.cache,
    - struct cachefiles_cache, cache);
    -
    - path.mnt = cache->mnt;
    - path.dentry = object->backer;
    - file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE | O_DIRECT,
    - d_inode(object->backer), cache->cache_cred);
    - if (IS_ERR(file))
    - return PTR_ERR(file);
    - if (!S_ISREG(file_inode(file)->i_mode))
    - goto error_file;
    - if (unlikely(!file->f_op->read_iter) ||
    - unlikely(!file->f_op->write_iter)) {
    - pr_notice("Cache does not support read_iter and write_iter\n");
    - goto error_file;
    - }
    -
    - fscache_get_retrieval(op);
    - rreq->cache_resources.cache_priv = op;
    - rreq->cache_resources.cache_priv2 = file;
    - rreq->cache_resources.ops = &cachefiles_netfs_cache_ops;
    - rreq->cache_resources.debug_id = object->fscache.debug_id;
    - _leave("");
    - return 0;
    -
    -error_file:
    - fput(file);
    - return -EIO;
    -}
    diff --git a/fs/cachefiles/key.c b/fs/cachefiles/key.c
    deleted file mode 100644
    index 7f94efc97e23..000000000000
    --- a/fs/cachefiles/key.c
    +++ /dev/null
    @@ -1,155 +0,0 @@
    -// SPDX-License-Identifier: GPL-2.0-or-later
    -/* Key to pathname encoder
    - *
    - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -
    -#include <linux/slab.h>
    -#include "internal.h"
    -
    -static const char cachefiles_charmap[64] =
    - "0123456789" /* 0 - 9 */
    - "abcdefghijklmnopqrstuvwxyz" /* 10 - 35 */
    - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" /* 36 - 61 */
    - "_-" /* 62 - 63 */
    - ;
    -
    -static const char cachefiles_filecharmap[256] = {
    - /* we skip space and tab and control chars */
    - [33 ... 46] = 1, /* '!' -> '.' */
    - /* we skip '/' as it's significant to pathwalk */
    - [48 ... 127] = 1, /* '0' -> '~' */
    -};
    -
    -/*
    - * turn the raw key into something cooked
    - * - the raw key should include the length in the two bytes at the front
    - * - the key may be up to 514 bytes in length (including the length word)
    - * - "base64" encode the strange keys, mapping 3 bytes of raw to four of
    - * cooked
    - * - need to cut the cooked key into 252 char lengths (189 raw bytes)
    - */
    -char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type)
    -{
    - unsigned char csum, ch;
    - unsigned int acc;
    - char *key;
    - int loop, len, max, seg, mark, print;
    -
    - _enter(",%d", keylen);
    -
    - BUG_ON(keylen < 2 || keylen > 514);
    -
    - csum = raw[0] + raw[1];
    - print = 1;
    - for (loop = 2; loop < keylen; loop++) {
    - ch = raw[loop];
    - csum += ch;
    - print &= cachefiles_filecharmap[ch];
    - }
    -
    - if (print) {
    - /* if the path is usable ASCII, then we render it directly */
    - max = keylen - 2;
    - max += 2; /* two base64'd length chars on the front */
    - max += 5; /* @checksum/M */
    - max += 3 * 2; /* maximum number of segment dividers (".../M")
    - * is ((514 + 251) / 252) = 3
    - */
    - max += 1; /* NUL on end */
    - } else {
    - /* calculate the maximum length of the cooked key */
    - keylen = (keylen + 2) / 3;
    -
    - max = keylen * 4;
    - max += 5; /* @checksum/M */
    - max += 3 * 2; /* maximum number of segment dividers (".../M")
    - * is ((514 + 188) / 189) = 3
    - */
    - max += 1; /* NUL on end */
    - }
    -
    - max += 1; /* 2nd NUL on end */
    -
    - _debug("max: %d", max);
    -
    - key = kmalloc(max, cachefiles_gfp);
    - if (!key)
    - return NULL;
    -
    - len = 0;
    -
    - /* build the cooked key */
    - sprintf(key, "@%02x%c+", (unsigned) csum, 0);
    - len = 5;
    - mark = len - 1;
    -
    - if (print) {
    - acc = *(uint16_t *) raw;
    - raw += 2;
    -
    - key[len + 1] = cachefiles_charmap[acc & 63];
    - acc >>= 6;
    - key[len] = cachefiles_charmap[acc & 63];
    - len += 2;
    -
    - seg = 250;
    - for (loop = keylen; loop > 0; loop--) {
    - if (seg <= 0) {
    - key[len++] = '\0';
    - mark = len;
    - key[len++] = '+';
    - seg = 252;
    - }
    -
    - key[len++] = *raw++;
    - ASSERT(len < max);
    - }
    -
    - switch (type) {
    - case FSCACHE_COOKIE_TYPE_INDEX: type = 'I'; break;
    - case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'D'; break;
    - default: type = 'S'; break;
    - }
    - } else {
    - seg = 252;
    - for (loop = keylen; loop > 0; loop--) {
    - if (seg <= 0) {
    - key[len++] = '\0';
    - mark = len;
    - key[len++] = '+';
    - seg = 252;
    - }
    -
    - acc = *raw++;
    - acc |= *raw++ << 8;
    - acc |= *raw++ << 16;
    -
    - _debug("acc: %06x", acc);
    -
    - key[len++] = cachefiles_charmap[acc & 63];
    - acc >>= 6;
    - key[len++] = cachefiles_charmap[acc & 63];
    - acc >>= 6;
    - key[len++] = cachefiles_charmap[acc & 63];
    - acc >>= 6;
    - key[len++] = cachefiles_charmap[acc & 63];
    -
    - ASSERT(len < max);
    - }
    -
    - switch (type) {
    - case FSCACHE_COOKIE_TYPE_INDEX: type = 'J'; break;
    - case FSCACHE_COOKIE_TYPE_DATAFILE: type = 'E'; break;
    - default: type = 'T'; break;
    - }
    - }
    -
    - key[mark] = type;
    - key[len++] = 0;
    - key[len] = 0;
    -
    - _leave(" = %s %d", key, len);
    - return key;
    -}
    diff --git a/fs/cachefiles/main.c b/fs/cachefiles/main.c
    deleted file mode 100644
    index 9c8d34c49b12..000000000000
    --- a/fs/cachefiles/main.c
    +++ /dev/null
    @@ -1,95 +0,0 @@
    -// SPDX-License-Identifier: GPL-2.0-or-later
    -/* Network filesystem caching backend to use cache files on a premounted
    - * filesystem
    - *
    - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -
    -#include <linux/module.h>
    -#include <linux/init.h>
    -#include <linux/sched.h>
    -#include <linux/completion.h>
    -#include <linux/slab.h>
    -#include <linux/fs.h>
    -#include <linux/file.h>
    -#include <linux/namei.h>
    -#include <linux/mount.h>
    -#include <linux/statfs.h>
    -#include <linux/sysctl.h>
    -#include <linux/miscdevice.h>
    -#define CREATE_TRACE_POINTS
    -#include "internal.h"
    -
    -unsigned cachefiles_debug;
    -module_param_named(debug, cachefiles_debug, uint, S_IWUSR | S_IRUGO);
    -MODULE_PARM_DESC(cachefiles_debug, "CacheFiles debugging mask");
    -
    -MODULE_DESCRIPTION("Mounted-filesystem based cache");
    -MODULE_AUTHOR("Red Hat, Inc.");
    -MODULE_LICENSE("GPL");
    -
    -struct kmem_cache *cachefiles_object_jar;
    -
    -static struct miscdevice cachefiles_dev = {
    - .minor = MISC_DYNAMIC_MINOR,
    - .name = "cachefiles",
    - .fops = &cachefiles_daemon_fops,
    -};
    -
    -static void cachefiles_object_init_once(void *_object)
    -{
    - struct cachefiles_object *object = _object;
    -
    - memset(object, 0, sizeof(*object));
    - spin_lock_init(&object->work_lock);
    -}
    -
    -/*
    - * initialise the fs caching module
    - */
    -static int __init cachefiles_init(void)
    -{
    - int ret;
    -
    - ret = misc_register(&cachefiles_dev);
    - if (ret < 0)
    - goto error_dev;
    -
    - /* create an object jar */
    - ret = -ENOMEM;
    - cachefiles_object_jar =
    - kmem_cache_create("cachefiles_object_jar",
    - sizeof(struct cachefiles_object),
    - 0,
    - SLAB_HWCACHE_ALIGN,
    - cachefiles_object_init_once);
    - if (!cachefiles_object_jar) {
    - pr_notice("Failed to allocate an object jar\n");
    - goto error_object_jar;
    - }
    -
    - pr_info("Loaded\n");
    - return 0;
    -
    -error_object_jar:
    - misc_deregister(&cachefiles_dev);
    -error_dev:
    - pr_err("failed to register: %d\n", ret);
    - return ret;
    -}
    -
    -fs_initcall(cachefiles_init);
    -
    -/*
    - * clean up on module removal
    - */
    -static void __exit cachefiles_exit(void)
    -{
    - pr_info("Unloading\n");
    -
    - kmem_cache_destroy(cachefiles_object_jar);
    - misc_deregister(&cachefiles_dev);
    -}
    -
    -module_exit(cachefiles_exit);
    diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
    deleted file mode 100644
    index a9aca5ab5970..000000000000
    --- a/fs/cachefiles/namei.c
    +++ /dev/null
    @@ -1,1018 +0,0 @@
    -// SPDX-License-Identifier: GPL-2.0-or-later
    -/* CacheFiles path walking and related routines
    - *
    - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -
    -#include <linux/module.h>
    -#include <linux/sched.h>
    -#include <linux/file.h>
    -#include <linux/fs.h>
    -#include <linux/fsnotify.h>
    -#include <linux/quotaops.h>
    -#include <linux/xattr.h>
    -#include <linux/mount.h>
    -#include <linux/namei.h>
    -#include <linux/security.h>
    -#include <linux/slab.h>
    -#include "internal.h"
    -
    -#define CACHEFILES_KEYBUF_SIZE 512
    -
    -/*
    - * dump debugging info about an object
    - */
    -static noinline
    -void __cachefiles_printk_object(struct cachefiles_object *object,
    - const char *prefix)
    -{
    - struct fscache_cookie *cookie;
    - const u8 *k;
    - unsigned loop;
    -
    - pr_err("%sobject: OBJ%x\n", prefix, object->fscache.debug_id);
    - pr_err("%sobjstate=%s fl=%lx wbusy=%x ev=%lx[%lx]\n",
    - prefix, object->fscache.state->name,
    - object->fscache.flags, work_busy(&object->fscache.work),
    - object->fscache.events, object->fscache.event_mask);
    - pr_err("%sops=%u inp=%u exc=%u\n",
    - prefix, object->fscache.n_ops, object->fscache.n_in_progress,
    - object->fscache.n_exclusive);
    - pr_err("%sparent=%x\n",
    - prefix, object->fscache.parent ? object->fscache.parent->debug_id : 0);
    -
    - spin_lock(&object->fscache.lock);
    - cookie = object->fscache.cookie;
    - if (cookie) {
    - pr_err("%scookie=%x [pr=%x nd=%p fl=%lx]\n",
    - prefix,
    - cookie->debug_id,
    - cookie->parent ? cookie->parent->debug_id : 0,
    - cookie->netfs_data,
    - cookie->flags);
    - pr_err("%skey=[%u] '", prefix, cookie->key_len);
    - k = (cookie->key_len <= sizeof(cookie->inline_key)) ?
    - cookie->inline_key : cookie->key;
    - for (loop = 0; loop < cookie->key_len; loop++)
    - pr_cont("%02x", k[loop]);
    - pr_cont("'\n");
    - } else {
    - pr_err("%scookie=NULL\n", prefix);
    - }
    - spin_unlock(&object->fscache.lock);
    -}
    -
    -/*
    - * dump debugging info about a pair of objects
    - */
    -static noinline void cachefiles_printk_object(struct cachefiles_object *object,
    - struct cachefiles_object *xobject)
    -{
    - if (object)
    - __cachefiles_printk_object(object, "");
    - if (xobject)
    - __cachefiles_printk_object(xobject, "x");
    -}
    -
    -/*
    - * mark the owner of a dentry, if there is one, to indicate that that dentry
    - * has been preemptively deleted
    - * - the caller must hold the i_mutex on the dentry's parent as required to
    - * call vfs_unlink(), vfs_rmdir() or vfs_rename()
    - */
    -static void cachefiles_mark_object_buried(struct cachefiles_cache *cache,
    - struct dentry *dentry,
    - enum fscache_why_object_killed why)
    -{
    - struct cachefiles_object *object;
    - struct rb_node *p;
    -
    - _enter(",'%pd'", dentry);
    -
    - write_lock(&cache->active_lock);
    -
    - p = cache->active_nodes.rb_node;
    - while (p) {
    - object = rb_entry(p, struct cachefiles_object, active_node);
    - if (object->dentry > dentry)
    - p = p->rb_left;
    - else if (object->dentry < dentry)
    - p = p->rb_right;
    - else
    - goto found_dentry;
    - }
    -
    - write_unlock(&cache->active_lock);
    - trace_cachefiles_mark_buried(NULL, dentry, why);
    - _leave(" [no owner]");
    - return;
    -
    - /* found the dentry for */
    -found_dentry:
    - kdebug("preemptive burial: OBJ%x [%s] %pd",
    - object->fscache.debug_id,
    - object->fscache.state->name,
    - dentry);
    -
    - trace_cachefiles_mark_buried(object, dentry, why);
    -
    - if (fscache_object_is_live(&object->fscache)) {
    - pr_err("\n");
    - pr_err("Error: Can't preemptively bury live object\n");
    - cachefiles_printk_object(object, NULL);
    - } else {
    - if (why != FSCACHE_OBJECT_IS_STALE)
    - fscache_object_mark_killed(&object->fscache, why);
    - }
    -
    - write_unlock(&cache->active_lock);
    - _leave(" [owner marked]");
    -}
    -
    -/*
    - * record the fact that an object is now active
    - */
    -static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
    - struct cachefiles_object *object)
    -{
    - struct cachefiles_object *xobject;
    - struct rb_node **_p, *_parent = NULL;
    - struct dentry *dentry;
    -
    - _enter(",%x", object->fscache.debug_id);
    -
    -try_again:
    - write_lock(&cache->active_lock);
    -
    - dentry = object->dentry;
    - trace_cachefiles_mark_active(object, dentry);
    -
    - if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) {
    - pr_err("Error: Object already active\n");
    - cachefiles_printk_object(object, NULL);
    - BUG();
    - }
    -
    - _p = &cache->active_nodes.rb_node;
    - while (*_p) {
    - _parent = *_p;
    - xobject = rb_entry(_parent,
    - struct cachefiles_object, active_node);
    -
    - ASSERT(xobject != object);
    -
    - if (xobject->dentry > dentry)
    - _p = &(*_p)->rb_left;
    - else if (xobject->dentry < dentry)
    - _p = &(*_p)->rb_right;
    - else
    - goto wait_for_old_object;
    - }
    -
    - rb_link_node(&object->active_node, _parent, _p);
    - rb_insert_color(&object->active_node, &cache->active_nodes);
    -
    - write_unlock(&cache->active_lock);
    - _leave(" = 0");
    - return 0;
    -
    - /* an old object from a previous incarnation is hogging the slot - we
    - * need to wait for it to be destroyed */
    -wait_for_old_object:
    - trace_cachefiles_wait_active(object, dentry, xobject);
    - clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
    -
    - if (fscache_object_is_live(&xobject->fscache)) {
    - pr_err("\n");
    - pr_err("Error: Unexpected object collision\n");
    - cachefiles_printk_object(object, xobject);
    - }
    - atomic_inc(&xobject->usage);
    - write_unlock(&cache->active_lock);
    -
    - if (test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) {
    - wait_queue_head_t *wq;
    -
    - signed long timeout = 60 * HZ;
    - wait_queue_entry_t wait;
    - bool requeue;
    -
    - /* if the object we're waiting for is queued for processing,
    - * then just put ourselves on the queue behind it */
    - if (work_pending(&xobject->fscache.work)) {
    - _debug("queue OBJ%x behind OBJ%x immediately",
    - object->fscache.debug_id,
    - xobject->fscache.debug_id);
    - goto requeue;
    - }
    -
    - /* otherwise we sleep until either the object we're waiting for
    - * is done, or the fscache_object is congested */
    - wq = bit_waitqueue(&xobject->flags, CACHEFILES_OBJECT_ACTIVE);
    - init_wait(&wait);
    - requeue = false;
    - do {
    - prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
    - if (!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags))
    - break;
    -
    - requeue = fscache_object_sleep_till_congested(&timeout);
    - } while (timeout > 0 && !requeue);
    - finish_wait(wq, &wait);
    -
    - if (requeue &&
    - test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) {
    - _debug("queue OBJ%x behind OBJ%x after wait",
    - object->fscache.debug_id,
    - xobject->fscache.debug_id);
    - goto requeue;
    - }
    -
    - if (timeout <= 0) {
    - pr_err("\n");
    - pr_err("Error: Overlong wait for old active object to go away\n");
    - cachefiles_printk_object(object, xobject);
    - goto requeue;
    - }
    - }
    -
    - ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags));
    -
    - cache->cache.ops->put_object(&xobject->fscache,
    - (enum fscache_obj_ref_trace)cachefiles_obj_put_wait_retry);
    - goto try_again;
    -
    -requeue:
    - cache->cache.ops->put_object(&xobject->fscache,
    - (enum fscache_obj_ref_trace)cachefiles_obj_put_wait_timeo);
    - _leave(" = -ETIMEDOUT");
    - return -ETIMEDOUT;
    -}
    -
    -/*
    - * Mark an object as being inactive.
    - */
    -void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
    - struct cachefiles_object *object,
    - blkcnt_t i_blocks)
    -{
    - struct dentry *dentry = object->dentry;
    - struct inode *inode = d_backing_inode(dentry);
    -
    - trace_cachefiles_mark_inactive(object, dentry, inode);
    -
    - write_lock(&cache->active_lock);
    - rb_erase(&object->active_node, &cache->active_nodes);
    - clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
    - write_unlock(&cache->active_lock);
    -
    - wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE);
    -
    - /* This object can now be culled, so we need to let the daemon know
    - * that there is something it can remove if it needs to.
    - */
    - atomic_long_add(i_blocks, &cache->b_released);
    - if (atomic_inc_return(&cache->f_released))
    - cachefiles_state_changed(cache);
    -}
    -
    -/*
    - * delete an object representation from the cache
    - * - file backed objects are unlinked
    - * - directory backed objects are stuffed into the graveyard for userspace to
    - * delete
    - * - unlocks the directory mutex
    - */
    -static int cachefiles_bury_object(struct cachefiles_cache *cache,
    - struct cachefiles_object *object,
    - struct dentry *dir,
    - struct dentry *rep,
    - bool preemptive,
    - enum fscache_why_object_killed why)
    -{
    - struct dentry *grave, *trap;
    - struct path path, path_to_graveyard;
    - char nbuffer[8 + 8 + 1];
    - int ret;
    -
    - _enter(",'%pd','%pd'", dir, rep);
    -
    - /* non-directories can just be unlinked */
    - if (!d_is_dir(rep)) {
    - _debug("unlink stale object");
    -
    - path.mnt = cache->mnt;
    - path.dentry = dir;
    - ret = security_path_unlink(&path, rep);
    - if (ret < 0) {
    - cachefiles_io_error(cache, "Unlink security error");
    - } else {
    - trace_cachefiles_unlink(object, rep, why);
    - ret = vfs_unlink(&init_user_ns, d_inode(dir), rep,
    - NULL);
    -
    - if (preemptive)
    - cachefiles_mark_object_buried(cache, rep, why);
    - }
    -
    - inode_unlock(d_inode(dir));
    -
    - if (ret == -EIO)
    - cachefiles_io_error(cache, "Unlink failed");
    -
    - _leave(" = %d", ret);
    - return ret;
    - }
    -
    - /* directories have to be moved to the graveyard */
    - _debug("move stale object to graveyard");
    - inode_unlock(d_inode(dir));
    -
    -try_again:
    - /* first step is to make up a grave dentry in the graveyard */
    - sprintf(nbuffer, "%08x%08x",
    - (uint32_t) ktime_get_real_seconds(),
    - (uint32_t) atomic_inc_return(&cache->gravecounter));
    -
    - /* do the multiway lock magic */
    - trap = lock_rename(cache->graveyard, dir);
    -
    - /* do some checks before getting the grave dentry */
    - if (rep->d_parent != dir || IS_DEADDIR(d_inode(rep))) {
    - /* the entry was probably culled when we dropped the parent dir
    - * lock */
    - unlock_rename(cache->graveyard, dir);
    - _leave(" = 0 [culled?]");
    - return 0;
    - }
    -
    - if (!d_can_lookup(cache->graveyard)) {
    - unlock_rename(cache->graveyard, dir);
    - cachefiles_io_error(cache, "Graveyard no longer a directory");
    - return -EIO;
    - }
    -
    - if (trap == rep) {
    - unlock_rename(cache->graveyard, dir);
    - cachefiles_io_error(cache, "May not make directory loop");
    - return -EIO;
    - }
    -
    - if (d_mountpoint(rep)) {
    - unlock_rename(cache->graveyard, dir);
    - cachefiles_io_error(cache, "Mountpoint in cache");
    - return -EIO;
    - }
    -
    - grave = lookup_one_len(nbuffer, cache->graveyard, strlen(nbuffer));
    - if (IS_ERR(grave)) {
    - unlock_rename(cache->graveyard, dir);
    -
    - if (PTR_ERR(grave) == -ENOMEM) {
    - _leave(" = -ENOMEM");
    - return -ENOMEM;
    - }
    -
    - cachefiles_io_error(cache, "Lookup error %ld",
    - PTR_ERR(grave));
    - return -EIO;
    - }
    -
    - if (d_is_positive(grave)) {
    - unlock_rename(cache->graveyard, dir);
    - dput(grave);
    - grave = NULL;
    - cond_resched();
    - goto try_again;
    - }
    -
    - if (d_mountpoint(grave)) {
    - unlock_rename(cache->graveyard, dir);
    - dput(grave);
    - cachefiles_io_error(cache, "Mountpoint in graveyard");
    - return -EIO;
    - }
    -
    - /* target should not be an ancestor of source */
    - if (trap == grave) {
    - unlock_rename(cache->graveyard, dir);
    - dput(grave);
    - cachefiles_io_error(cache, "May not make directory loop");
    - return -EIO;
    - }
    -
    - /* attempt the rename */
    - path.mnt = cache->mnt;
    - path.dentry = dir;
    - path_to_graveyard.mnt = cache->mnt;
    - path_to_graveyard.dentry = cache->graveyard;
    - ret = security_path_rename(&path, rep, &path_to_graveyard, grave, 0);
    - if (ret < 0) {
    - cachefiles_io_error(cache, "Rename security error %d", ret);
    - } else {
    - struct renamedata rd = {
    - .old_mnt_userns = &init_user_ns,
    - .old_dir = d_inode(dir),
    - .old_dentry = rep,
    - .new_mnt_userns = &init_user_ns,
    - .new_dir = d_inode(cache->graveyard),
    - .new_dentry = grave,
    - };
    - trace_cachefiles_rename(object, rep, grave, why);
    - ret = vfs_rename(&rd);
    - if (ret != 0 && ret != -ENOMEM)
    - cachefiles_io_error(cache,
    - "Rename failed with error %d", ret);
    -
    - if (preemptive)
    - cachefiles_mark_object_buried(cache, rep, why);
    - }
    -
    - unlock_rename(cache->graveyard, dir);
    - dput(grave);
    - _leave(" = 0");
    - return 0;
    -}
    -
    -/*
    - * delete an object representation from the cache
    - */
    -int cachefiles_delete_object(struct cachefiles_cache *cache,
    - struct cachefiles_object *object)
    -{
    - struct dentry *dir;
    - int ret;
    -
    - _enter(",OBJ%x{%pd}", object->fscache.debug_id, object->dentry);
    -
    - ASSERT(object->dentry);
    - ASSERT(d_backing_inode(object->dentry));
    - ASSERT(object->dentry->d_parent);
    -
    - dir = dget_parent(object->dentry);
    -
    - inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
    -
    - if (test_bit(FSCACHE_OBJECT_KILLED_BY_CACHE, &object->fscache.flags)) {
    - /* object allocation for the same key preemptively deleted this
    - * object's file so that it could create its own file */
    - _debug("object preemptively buried");
    - inode_unlock(d_inode(dir));
    - ret = 0;
    - } else {
    - /* we need to check that our parent is _still_ our parent - it
    - * may have been renamed */
    - if (dir == object->dentry->d_parent) {
    - ret = cachefiles_bury_object(cache, object, dir,
    - object->dentry, false,
    - FSCACHE_OBJECT_WAS_RETIRED);
    - } else {
    - /* it got moved, presumably by cachefilesd culling it,
    - * so it's no longer in the key path and we can ignore
    - * it */
    - inode_unlock(d_inode(dir));
    - ret = 0;
    - }
    - }
    -
    - dput(dir);
    - _leave(" = %d", ret);
    - return ret;
    -}
    -
    -/*
    - * walk from the parent object to the child object through the backing
    - * filesystem, creating directories as we go
    - */
    -int cachefiles_walk_to_object(struct cachefiles_object *parent,
    - struct cachefiles_object *object,
    - const char *key,
    - struct cachefiles_xattr *auxdata)
    -{
    - struct cachefiles_cache *cache;
    - struct dentry *dir, *next = NULL;
    - struct inode *inode;
    - struct path path;
    - const char *name;
    - int ret, nlen;
    -
    - _enter("OBJ%x{%pd},OBJ%x,%s,",
    - parent->fscache.debug_id, parent->dentry,
    - object->fscache.debug_id, key);
    -
    - cache = container_of(parent->fscache.cache,
    - struct cachefiles_cache, cache);
    - path.mnt = cache->mnt;
    -
    - ASSERT(parent->dentry);
    - ASSERT(d_backing_inode(parent->dentry));
    -
    - if (!(d_is_dir(parent->dentry))) {
    - // TODO: convert file to dir
    - _leave("looking up in none directory");
    - return -ENOBUFS;
    - }
    -
    - dir = dget(parent->dentry);
    -
    -advance:
    - /* attempt to transit the first directory component */
    - name = key;
    - nlen = strlen(key);
    -
    - /* key ends in a double NUL */
    - key = key + nlen + 1;
    - if (!*key)
    - key = NULL;
    -
    -lookup_again:
    - /* search the current directory for the element name */
    - _debug("lookup '%s'", name);
    -
    - inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
    -
    - next = lookup_one_len(name, dir, nlen);
    - if (IS_ERR(next)) {
    - trace_cachefiles_lookup(object, next, NULL);
    - goto lookup_error;
    - }
    -
    - inode = d_backing_inode(next);
    - trace_cachefiles_lookup(object, next, inode);
    - _debug("next -> %pd %s", next, inode ? "positive" : "negative");
    -
    - if (!key)
    - object->new = !inode;
    -
    - /* if this element of the path doesn't exist, then the lookup phase
    - * failed, and we can release any readers in the certain knowledge that
    - * there's nothing for them to actually read */
    - if (d_is_negative(next))
    - fscache_object_lookup_negative(&object->fscache);
    -
    - /* we need to create the object if it's negative */
    - if (key || object->type == FSCACHE_COOKIE_TYPE_INDEX) {
    - /* index objects and intervening tree levels must be subdirs */
    - if (d_is_negative(next)) {
    - ret = cachefiles_has_space(cache, 1, 0);
    - if (ret < 0)
    - goto no_space_error;
    -
    - path.dentry = dir;
    - ret = security_path_mkdir(&path, next, 0);
    - if (ret < 0)
    - goto create_error;
    - ret = vfs_mkdir(&init_user_ns, d_inode(dir), next, 0);
    - if (!key)
    - trace_cachefiles_mkdir(object, next, ret);
    - if (ret < 0)
    - goto create_error;
    -
    - if (unlikely(d_unhashed(next))) {
    - dput(next);
    - inode_unlock(d_inode(dir));
    - goto lookup_again;
    - }
    - ASSERT(d_backing_inode(next));
    -
    - _debug("mkdir -> %pd{ino=%lu}",
    - next, d_backing_inode(next)->i_ino);
    -
    - } else if (!d_can_lookup(next)) {
    - pr_err("inode %lu is not a directory\n",
    - d_backing_inode(next)->i_ino);
    - ret = -ENOBUFS;
    - goto error;
    - }
    -
    - } else {
    - /* non-index objects start out life as files */
    - if (d_is_negative(next)) {
    - ret = cachefiles_has_space(cache, 1, 0);
    - if (ret < 0)
    - goto no_space_error;
    -
    - path.dentry = dir;
    - ret = security_path_mknod(&path, next, S_IFREG, 0);
    - if (ret < 0)
    - goto create_error;
    - ret = vfs_create(&init_user_ns, d_inode(dir), next,
    - S_IFREG, true);
    - trace_cachefiles_create(object, next, ret);
    - if (ret < 0)
    - goto create_error;
    -
    - ASSERT(d_backing_inode(next));
    -
    - _debug("create -> %pd{ino=%lu}",
    - next, d_backing_inode(next)->i_ino);
    -
    - } else if (!d_can_lookup(next) &&
    - !d_is_reg(next)
    - ) {
    - pr_err("inode %lu is not a file or directory\n",
    - d_backing_inode(next)->i_ino);
    - ret = -ENOBUFS;
    - goto error;
    - }
    - }
    -
    - /* process the next component */
    - if (key) {
    - _debug("advance");
    - inode_unlock(d_inode(dir));
    - dput(dir);
    - dir = next;
    - next = NULL;
    - goto advance;
    - }
    -
    - /* we've found the object we were looking for */
    - object->dentry = next;
    -
    - /* if we've found that the terminal object exists, then we need to
    - * check its attributes and delete it if it's out of date */
    - if (!object->new) {
    - _debug("validate '%pd'", next);
    -
    - ret = cachefiles_check_object_xattr(object, auxdata);
    - if (ret == -ESTALE) {
    - /* delete the object (the deleter drops the directory
    - * mutex) */
    - object->dentry = NULL;
    -
    - ret = cachefiles_bury_object(cache, object, dir, next,
    - true,
    - FSCACHE_OBJECT_IS_STALE);
    - dput(next);
    - next = NULL;
    -
    - if (ret < 0)
    - goto delete_error;
    -
    - _debug("redo lookup");
    - fscache_object_retrying_stale(&object->fscache);
    - goto lookup_again;
    - }
    - }
    -
    - /* note that we're now using this object */
    - ret = cachefiles_mark_object_active(cache, object);
    -
    - inode_unlock(d_inode(dir));
    - dput(dir);
    - dir = NULL;
    -
    - if (ret == -ETIMEDOUT)
    - goto mark_active_timed_out;
    -
    - _debug("=== OBTAINED_OBJECT ===");
    -
    - if (object->new) {
    - /* attach data to a newly constructed terminal object */
    - ret = cachefiles_set_object_xattr(object, auxdata);
    - if (ret < 0)
    - goto check_error;
    - } else {
    - /* always update the atime on an object we've just looked up
    - * (this is used to keep track of culling, and atimes are only
    - * updated by read, write and readdir but not lookup or
    - * open) */
    - path.dentry = next;
    - touch_atime(&path);
    - }
    -
    - /* open a file interface onto a data file */
    - if (object->type != FSCACHE_COOKIE_TYPE_INDEX) {
    - if (d_is_reg(object->dentry)) {
    - const struct address_space_operations *aops;
    -
    - ret = -EPERM;
    - aops = d_backing_inode(object->dentry)->i_mapping->a_ops;
    - if (!aops->bmap)
    - goto check_error;
    - if (object->dentry->d_sb->s_blocksize > PAGE_SIZE)
    - goto check_error;
    -
    - object->backer = object->dentry;
    - } else {
    - BUG(); // TODO: open file in data-class subdir
    - }
    - }
    -
    - object->new = 0;
    - fscache_obtained_object(&object->fscache);
    -
    - _leave(" = 0 [%lu]", d_backing_inode(object->dentry)->i_ino);
    - return 0;
    -
    -no_space_error:
    - fscache_object_mark_killed(&object->fscache, FSCACHE_OBJECT_NO_SPACE);
    -create_error:
    - _debug("create error %d", ret);
    - if (ret == -EIO)
    - cachefiles_io_error(cache, "Create/mkdir failed");
    - goto error;
    -
    -mark_active_timed_out:
    - _debug("mark active timed out");
    - goto release_dentry;
    -
    -check_error:
    - _debug("check error %d", ret);
    - cachefiles_mark_object_inactive(
    - cache, object, d_backing_inode(object->dentry)->i_blocks);
    -release_dentry:
    - dput(object->dentry);
    - object->dentry = NULL;
    - goto error_out;
    -
    -delete_error:
    - _debug("delete error %d", ret);
    - goto error_out2;
    -
    -lookup_error:
    - _debug("lookup error %ld", PTR_ERR(next));
    - ret = PTR_ERR(next);
    - if (ret == -EIO)
    - cachefiles_io_error(cache, "Lookup failed");
    - next = NULL;
    -error:
    - inode_unlock(d_inode(dir));
    - dput(next);
    -error_out2:
    - dput(dir);
    -error_out:
    - _leave(" = error %d", -ret);
    - return ret;
    -}
    -
    -/*
    - * get a subdirectory
    - */
    -struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
    - struct dentry *dir,
    - const char *dirname)
    -{
    - struct dentry *subdir;
    - struct path path;
    - int ret;
    -
    - _enter(",,%s", dirname);
    -
    - /* search the current directory for the element name */
    - inode_lock(d_inode(dir));
    -
    -retry:
    - subdir = lookup_one_len(dirname, dir, strlen(dirname));
    - if (IS_ERR(subdir)) {
    - if (PTR_ERR(subdir) == -ENOMEM)
    - goto nomem_d_alloc;
    - goto lookup_error;
    - }
    -
    - _debug("subdir -> %pd %s",
    - subdir, d_backing_inode(subdir) ? "positive" : "negative");
    -
    - /* we need to create the subdir if it doesn't exist yet */
    - if (d_is_negative(subdir)) {
    - ret = cachefiles_has_space(cache, 1, 0);
    - if (ret < 0)
    - goto mkdir_error;
    -
    - _debug("attempt mkdir");
    -
    - path.mnt = cache->mnt;
    - path.dentry = dir;
    - ret = security_path_mkdir(&path, subdir, 0700);
    - if (ret < 0)
    - goto mkdir_error;
    - ret = vfs_mkdir(&init_user_ns, d_inode(dir), subdir, 0700);
    - if (ret < 0)
    - goto mkdir_error;
    -
    - if (unlikely(d_unhashed(subdir))) {
    - dput(subdir);
    - goto retry;
    - }
    - ASSERT(d_backing_inode(subdir));
    -
    - _debug("mkdir -> %pd{ino=%lu}",
    - subdir, d_backing_inode(subdir)->i_ino);
    - }
    -
    - inode_unlock(d_inode(dir));
    -
    - /* we need to make sure the subdir is a directory */
    - ASSERT(d_backing_inode(subdir));
    -
    - if (!d_can_lookup(subdir)) {
    - pr_err("%s is not a directory\n", dirname);
    - ret = -EIO;
    - goto check_error;
    - }
    -
    - ret = -EPERM;
    - if (!(d_backing_inode(subdir)->i_opflags & IOP_XATTR) ||
    - !d_backing_inode(subdir)->i_op->lookup ||
    - !d_backing_inode(subdir)->i_op->mkdir ||
    - !d_backing_inode(subdir)->i_op->create ||
    - !d_backing_inode(subdir)->i_op->rename ||
    - !d_backing_inode(subdir)->i_op->rmdir ||
    - !d_backing_inode(subdir)->i_op->unlink)
    - goto check_error;
    -
    - _leave(" = [%lu]", d_backing_inode(subdir)->i_ino);
    - return subdir;
    -
    -check_error:
    - dput(subdir);
    - _leave(" = %d [check]", ret);
    - return ERR_PTR(ret);
    -
    -mkdir_error:
    - inode_unlock(d_inode(dir));
    - dput(subdir);
    - pr_err("mkdir %s failed with error %d\n", dirname, ret);
    - return ERR_PTR(ret);
    -
    -lookup_error:
    - inode_unlock(d_inode(dir));
    - ret = PTR_ERR(subdir);
    - pr_err("Lookup %s failed with error %d\n", dirname, ret);
    - return ERR_PTR(ret);
    -
    -nomem_d_alloc:
    - inode_unlock(d_inode(dir));
    - _leave(" = -ENOMEM");
    - return ERR_PTR(-ENOMEM);
    -}
    -
    -/*
    - * find out if an object is in use or not
    - * - if finds object and it's not in use:
    - * - returns a pointer to the object and a reference on it
    - * - returns with the directory locked
    - */
    -static struct dentry *cachefiles_check_active(struct cachefiles_cache *cache,
    - struct dentry *dir,
    - char *filename)
    -{
    - struct cachefiles_object *object;
    - struct rb_node *_n;
    - struct dentry *victim;
    - int ret;
    -
    - //_enter(",%pd/,%s",
    - // dir, filename);
    -
    - /* look up the victim */
    - inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
    -
    - victim = lookup_one_len(filename, dir, strlen(filename));
    - if (IS_ERR(victim))
    - goto lookup_error;
    -
    - //_debug("victim -> %pd %s",
    - // victim, d_backing_inode(victim) ? "positive" : "negative");
    -
    - /* if the object is no longer there then we probably retired the object
    - * at the netfs's request whilst the cull was in progress
    - */
    - if (d_is_negative(victim)) {
    - inode_unlock(d_inode(dir));
    - dput(victim);
    - _leave(" = -ENOENT [absent]");
    - return ERR_PTR(-ENOENT);
    - }
    -
    - /* check to see if we're using this object */
    - read_lock(&cache->active_lock);
    -
    - _n = cache->active_nodes.rb_node;
    -
    - while (_n) {
    - object = rb_entry(_n, struct cachefiles_object, active_node);
    -
    - if (object->dentry > victim)
    - _n = _n->rb_left;
    - else if (object->dentry < victim)
    - _n = _n->rb_right;
    - else
    - goto object_in_use;
    - }
    -
    - read_unlock(&cache->active_lock);
    -
    - //_leave(" = %pd", victim);
    - return victim;
    -
    -object_in_use:
    - read_unlock(&cache->active_lock);
    - inode_unlock(d_inode(dir));
    - dput(victim);
    - //_leave(" = -EBUSY [in use]");
    - return ERR_PTR(-EBUSY);
    -
    -lookup_error:
    - inode_unlock(d_inode(dir));
    - ret = PTR_ERR(victim);
    - if (ret == -ENOENT) {
    - /* file or dir now absent - probably retired by netfs */
    - _leave(" = -ESTALE [absent]");
    - return ERR_PTR(-ESTALE);
    - }
    -
    - if (ret == -EIO) {
    - cachefiles_io_error(cache, "Lookup failed");
    - } else if (ret != -ENOMEM) {
    - pr_err("Internal error: %d\n", ret);
    - ret = -EIO;
    - }
    -
    - _leave(" = %d", ret);
    - return ERR_PTR(ret);
    -}
    -
    -/*
    - * cull an object if it's not in use
    - * - called only by cache manager daemon
    - */
    -int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
    - char *filename)
    -{
    - struct dentry *victim;
    - int ret;
    -
    - _enter(",%pd/,%s", dir, filename);
    -
    - victim = cachefiles_check_active(cache, dir, filename);
    - if (IS_ERR(victim))
    - return PTR_ERR(victim);
    -
    - _debug("victim -> %pd %s",
    - victim, d_backing_inode(victim) ? "positive" : "negative");
    -
    - /* okay... the victim is not being used so we can cull it
    - * - start by marking it as stale
    - */
    - _debug("victim is cullable");
    -
    - ret = cachefiles_remove_object_xattr(cache, victim);
    - if (ret < 0)
    - goto error_unlock;
    -
    - /* actually remove the victim (drops the dir mutex) */
    - _debug("bury");
    -
    - ret = cachefiles_bury_object(cache, NULL, dir, victim, false,
    - FSCACHE_OBJECT_WAS_CULLED);
    - if (ret < 0)
    - goto error;
    -
    - dput(victim);
    - _leave(" = 0");
    - return 0;
    -
    -error_unlock:
    - inode_unlock(d_inode(dir));
    -error:
    - dput(victim);
    - if (ret == -ENOENT) {
    - /* file or dir now absent - probably retired by netfs */
    - _leave(" = -ESTALE [absent]");
    - return -ESTALE;
    - }
    -
    - if (ret != -ENOMEM) {
    - pr_err("Internal error: %d\n", ret);
    - ret = -EIO;
    - }
    -
    - _leave(" = %d", ret);
    - return ret;
    -}
    -
    -/*
    - * find out if an object is in use or not
    - * - called only by cache manager daemon
    - * - returns -EBUSY or 0 to indicate whether an object is in use or not
    - */
    -int cachefiles_check_in_use(struct cachefiles_cache *cache, struct dentry *dir,
    - char *filename)
    -{
    - struct dentry *victim;
    -
    - //_enter(",%pd/,%s",
    - // dir, filename);
    -
    - victim = cachefiles_check_active(cache, dir, filename);
    - if (IS_ERR(victim))
    - return PTR_ERR(victim);
    -
    - inode_unlock(d_inode(dir));
    - dput(victim);
    - //_leave(" = 0");
    - return 0;
    -}
    diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c
    deleted file mode 100644
    index fcf4f3b72923..000000000000
    --- a/fs/cachefiles/rdwr.c
    +++ /dev/null
    @@ -1,972 +0,0 @@
    -// SPDX-License-Identifier: GPL-2.0-or-later
    -/* Storage object read/write
    - *
    - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -
    -#include <linux/mount.h>
    -#include <linux/slab.h>
    -#include <linux/file.h>
    -#include <linux/swap.h>
    -#include "internal.h"
    -
    -/*
    - * detect wake up events generated by the unlocking of pages in which we're
    - * interested
    - * - we use this to detect read completion of backing pages
    - * - the caller holds the waitqueue lock
    - */
    -static int cachefiles_read_waiter(wait_queue_entry_t *wait, unsigned mode,
    - int sync, void *_key)
    -{
    - struct cachefiles_one_read *monitor =
    - container_of(wait, struct cachefiles_one_read, monitor);
    - struct cachefiles_object *object;
    - struct fscache_retrieval *op = monitor->op;
    - struct wait_page_key *key = _key;
    - struct folio *folio = wait->private;
    -
    - ASSERT(key);
    -
    - _enter("{%lu},%u,%d,{%p,%u}",
    - monitor->netfs_page->index, mode, sync,
    - key->folio, key->bit_nr);
    -
    - if (key->folio != folio || key->bit_nr != PG_locked)
    - return 0;
    -
    - _debug("--- monitor %p %lx ---", folio, folio->flags);
    -
    - if (!folio_test_uptodate(folio) && !folio_test_error(folio)) {
    - /* unlocked, not uptodate and not erronous? */
    - _debug("page probably truncated");
    - }
    -
    - /* remove from the waitqueue */
    - list_del(&wait->entry);
    -
    - /* move onto the action list and queue for FS-Cache thread pool */
    - ASSERT(op);
    -
    - /* We need to temporarily bump the usage count as we don't own a ref
    - * here otherwise cachefiles_read_copier() may free the op between the
    - * monitor being enqueued on the op->to_do list and the op getting
    - * enqueued on the work queue.
    - */
    - fscache_get_retrieval(op);
    -
    - object = container_of(op->op.object, struct cachefiles_object, fscache);
    - spin_lock(&object->work_lock);
    - list_add_tail(&monitor->op_link, &op->to_do);
    - fscache_enqueue_retrieval(op);
    - spin_unlock(&object->work_lock);
    -
    - fscache_put_retrieval(op);
    - return 0;
    -}
    -
    -/*
    - * handle a probably truncated page
    - * - check to see if the page is still relevant and reissue the read if
    - * possible
    - * - return -EIO on error, -ENODATA if the page is gone, -EINPROGRESS if we
    - * must wait again and 0 if successful
    - */
    -static int cachefiles_read_reissue(struct cachefiles_object *object,
    - struct cachefiles_one_read *monitor)
    -{
    - struct address_space *bmapping = d_backing_inode(object->backer)->i_mapping;
    - struct page *backpage = monitor->back_page, *backpage2;
    - int ret;
    -
    - _enter("{ino=%lx},{%lx,%lx}",
    - d_backing_inode(object->backer)->i_ino,
    - backpage->index, backpage->flags);
    -
    - /* skip if the page was truncated away completely */
    - if (backpage->mapping != bmapping) {
    - _leave(" = -ENODATA [mapping]");
    - return -ENODATA;
    - }
    -
    - backpage2 = find_get_page(bmapping, backpage->index);
    - if (!backpage2) {
    - _leave(" = -ENODATA [gone]");
    - return -ENODATA;
    - }
    -
    - if (backpage != backpage2) {
    - put_page(backpage2);
    - _leave(" = -ENODATA [different]");
    - return -ENODATA;
    - }
    -
    - /* the page is still there and we already have a ref on it, so we don't
    - * need a second */
    - put_page(backpage2);
    -
    - INIT_LIST_HEAD(&monitor->op_link);
    - folio_add_wait_queue(page_folio(backpage), &monitor->monitor);
    -
    - if (trylock_page(backpage)) {
    - ret = -EIO;
    - if (PageError(backpage))
    - goto unlock_discard;
    - ret = 0;
    - if (PageUptodate(backpage))
    - goto unlock_discard;
    -
    - _debug("reissue read");
    - ret = bmapping->a_ops->readpage(NULL, backpage);
    - if (ret < 0)
    - goto discard;
    - }
    -
    - /* but the page may have been read before the monitor was installed, so
    - * the monitor may miss the event - so we have to ensure that we do get
    - * one in such a case */
    - if (trylock_page(backpage)) {
    - _debug("jumpstart %p {%lx}", backpage, backpage->flags);
    - unlock_page(backpage);
    - }
    -
    - /* it'll reappear on the todo list */
    - _leave(" = -EINPROGRESS");
    - return -EINPROGRESS;
    -
    -unlock_discard:
    - unlock_page(backpage);
    -discard:
    - spin_lock_irq(&object->work_lock);
    - list_del(&monitor->op_link);
    - spin_unlock_irq(&object->work_lock);
    - _leave(" = %d", ret);
    - return ret;
    -}
    -
    -/*
    - * copy data from backing pages to netfs pages to complete a read operation
    - * - driven by FS-Cache's thread pool
    - */
    -static void cachefiles_read_copier(struct fscache_operation *_op)
    -{
    - struct cachefiles_one_read *monitor;
    - struct cachefiles_object *object;
    - struct fscache_retrieval *op;
    - int error, max;
    -
    - op = container_of(_op, struct fscache_retrieval, op);
    - object = container_of(op->op.object,
    - struct cachefiles_object, fscache);
    -
    - _enter("{ino=%lu}", d_backing_inode(object->backer)->i_ino);
    -
    - max = 8;
    - spin_lock_irq(&object->work_lock);
    -
    - while (!list_empty(&op->to_do)) {
    - monitor = list_entry(op->to_do.next,
    - struct cachefiles_one_read, op_link);
    - list_del(&monitor->op_link);
    -
    - spin_unlock_irq(&object->work_lock);
    -
    - _debug("- copy {%lu}", monitor->back_page->index);
    -
    - recheck:
    - if (test_bit(FSCACHE_COOKIE_INVALIDATING,
    - &object->fscache.cookie->flags)) {
    - error = -ESTALE;
    - } else if (PageUptodate(monitor->back_page)) {
    - copy_highpage(monitor->netfs_page, monitor->back_page);
    - fscache_mark_page_cached(monitor->op,
    - monitor->netfs_page);
    - error = 0;
    - } else if (!PageError(monitor->back_page)) {
    - /* the page has probably been truncated */
    - error = cachefiles_read_reissue(object, monitor);
    - if (error == -EINPROGRESS)
    - goto next;
    - goto recheck;
    - } else {
    - cachefiles_io_error_obj(
    - object,
    - "Readpage failed on backing file %lx",
    - (unsigned long) monitor->back_page->flags);
    - error = -EIO;
    - }
    -
    - put_page(monitor->back_page);
    -
    - fscache_end_io(op, monitor->netfs_page, error);
    - put_page(monitor->netfs_page);
    - fscache_retrieval_complete(op, 1);
    - fscache_put_retrieval(op);
    - kfree(monitor);
    -
    - next:
    - /* let the thread pool have some air occasionally */
    - max--;
    - if (max < 0 || need_resched()) {
    - if (!list_empty(&op->to_do))
    - fscache_enqueue_retrieval(op);
    - _leave(" [maxed out]");
    - return;
    - }
    -
    - spin_lock_irq(&object->work_lock);
    - }
    -
    - spin_unlock_irq(&object->work_lock);
    - _leave("");
    -}
    -
    -/*
    - * read the corresponding page to the given set from the backing file
    - * - an uncertain page is simply discarded, to be tried again another time
    - */
    -static int cachefiles_read_backing_file_one(struct cachefiles_object *object,
    - struct fscache_retrieval *op,
    - struct page *netpage)
    -{
    - struct cachefiles_one_read *monitor;
    - struct address_space *bmapping;
    - struct page *newpage, *backpage;
    - int ret;
    -
    - _enter("");
    -
    - _debug("read back %p{%lu,%d}",
    - netpage, netpage->index, page_count(netpage));
    -
    - monitor = kzalloc(sizeof(*monitor), cachefiles_gfp);
    - if (!monitor)
    - goto nomem;
    -
    - monitor->netfs_page = netpage;
    - monitor->op = fscache_get_retrieval(op);
    -
    - init_waitqueue_func_entry(&monitor->monitor, cachefiles_read_waiter);
    -
    - /* attempt to get hold of the backing page */
    - bmapping = d_backing_inode(object->backer)->i_mapping;
    - newpage = NULL;
    -
    - for (;;) {
    - backpage = find_get_page(bmapping, netpage->index);
    - if (backpage)
    - goto backing_page_already_present;
    -
    - if (!newpage) {
    - newpage = __page_cache_alloc(cachefiles_gfp);
    - if (!newpage)
    - goto nomem_monitor;
    - }
    -
    - ret = add_to_page_cache_lru(newpage, bmapping,
    - netpage->index, cachefiles_gfp);
    - if (ret == 0)
    - goto installed_new_backing_page;
    - if (ret != -EEXIST)
    - goto nomem_page;
    - }
    -
    - /* we've installed a new backing page, so now we need to start
    - * it reading */
    -installed_new_backing_page:
    - _debug("- new %p", newpage);
    -
    - backpage = newpage;
    - newpage = NULL;
    -
    -read_backing_page:
    - ret = bmapping->a_ops->readpage(NULL, backpage);
    - if (ret < 0)
    - goto read_error;
    -
    - /* set the monitor to transfer the data across */
    -monitor_backing_page:
    - _debug("- monitor add");
    -
    - /* install the monitor */
    - get_page(monitor->netfs_page);
    - get_page(backpage);
    - monitor->back_page = backpage;
    - monitor->monitor.private = backpage;
    - folio_add_wait_queue(page_folio(backpage), &monitor->monitor);
    - monitor = NULL;
    -
    - /* but the page may have been read before the monitor was installed, so
    - * the monitor may miss the event - so we have to ensure that we do get
    - * one in such a case */
    - if (trylock_page(backpage)) {
    - _debug("jumpstart %p {%lx}", backpage, backpage->flags);
    - unlock_page(backpage);
    - }
    - goto success;
    -
    - /* if the backing page is already present, it can be in one of
    - * three states: read in progress, read failed or read okay */
    -backing_page_already_present:
    - _debug("- present");
    -
    - if (newpage) {
    - put_page(newpage);
    - newpage = NULL;
    - }
    -
    - if (PageError(backpage))
    - goto io_error;
    -
    - if (PageUptodate(backpage))
    - goto backing_page_already_uptodate;
    -
    - if (!trylock_page(backpage))
    - goto monitor_backing_page;
    - _debug("read %p {%lx}", backpage, backpage->flags);
    - goto read_backing_page;
    -
    - /* the backing page is already up to date, attach the netfs
    - * page to the pagecache and LRU and copy the data across */
    -backing_page_already_uptodate:
    - _debug("- uptodate");
    -
    - fscache_mark_page_cached(op, netpage);
    -
    - copy_highpage(netpage, backpage);
    - fscache_end_io(op, netpage, 0);
    - fscache_retrieval_complete(op, 1);
    -
    -success:
    - _debug("success");
    - ret = 0;
    -
    -out:
    - if (backpage)
    - put_page(backpage);
    - if (monitor) {
    - fscache_put_retrieval(monitor->op);
    - kfree(monitor);
    - }
    - _leave(" = %d", ret);
    - return ret;
    -
    -read_error:
    - _debug("read error %d", ret);
    - if (ret == -ENOMEM) {
    - fscache_retrieval_complete(op, 1);
    - goto out;
    - }
    -io_error:
    - cachefiles_io_error_obj(object, "Page read error on backing file");
    - fscache_retrieval_complete(op, 1);
    - ret = -ENOBUFS;
    - goto out;
    -
    -nomem_page:
    - put_page(newpage);
    -nomem_monitor:
    - fscache_put_retrieval(monitor->op);
    - kfree(monitor);
    -nomem:
    - fscache_retrieval_complete(op, 1);
    - _leave(" = -ENOMEM");
    - return -ENOMEM;
    -}
    -
    -/*
    - * read a page from the cache or allocate a block in which to store it
    - * - cache withdrawal is prevented by the caller
    - * - returns -EINTR if interrupted
    - * - returns -ENOMEM if ran out of memory
    - * - returns -ENOBUFS if no buffers can be made available
    - * - returns -ENOBUFS if page is beyond EOF
    - * - if the page is backed by a block in the cache:
    - * - a read will be started which will call the callback on completion
    - * - 0 will be returned
    - * - else if the page is unbacked:
    - * - the metadata will be retained
    - * - -ENODATA will be returned
    - */
    -int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
    - struct page *page,
    - gfp_t gfp)
    -{
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - struct inode *inode;
    - sector_t block;
    - unsigned shift;
    - int ret, ret2;
    -
    - object = container_of(op->op.object,
    - struct cachefiles_object, fscache);
    - cache = container_of(object->fscache.cache,
    - struct cachefiles_cache, cache);
    -
    - _enter("{%p},{%lx},,,", object, page->index);
    -
    - if (!object->backer)
    - goto enobufs;
    -
    - inode = d_backing_inode(object->backer);
    - ASSERT(S_ISREG(inode->i_mode));
    -
    - /* calculate the shift required to use bmap */
    - shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
    -
    - op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
    - op->op.flags |= FSCACHE_OP_ASYNC;
    - op->op.processor = cachefiles_read_copier;
    -
    - /* we assume the absence or presence of the first block is a good
    - * enough indication for the page as a whole
    - * - TODO: don't use bmap() for this as it is _not_ actually good
    - * enough for this as it doesn't indicate errors, but it's all we've
    - * got for the moment
    - */
    - block = page->index;
    - block <<= shift;
    -
    - ret2 = bmap(inode, &block);
    - ASSERT(ret2 == 0);
    -
    - _debug("%llx -> %llx",
    - (unsigned long long) (page->index << shift),
    - (unsigned long long) block);
    -
    - if (block) {
    - /* submit the apparently valid page to the backing fs to be
    - * read from disk */
    - ret = cachefiles_read_backing_file_one(object, op, page);
    - } else if (cachefiles_has_space(cache, 0, 1) == 0) {
    - /* there's space in the cache we can use */
    - fscache_mark_page_cached(op, page);
    - fscache_retrieval_complete(op, 1);
    - ret = -ENODATA;
    - } else {
    - goto enobufs;
    - }
    -
    - _leave(" = %d", ret);
    - return ret;
    -
    -enobufs:
    - fscache_retrieval_complete(op, 1);
    - _leave(" = -ENOBUFS");
    - return -ENOBUFS;
    -}
    -
    -/*
    - * read the corresponding pages to the given set from the backing file
    - * - any uncertain pages are simply discarded, to be tried again another time
    - */
    -static int cachefiles_read_backing_file(struct cachefiles_object *object,
    - struct fscache_retrieval *op,
    - struct list_head *list)
    -{
    - struct cachefiles_one_read *monitor = NULL;
    - struct address_space *bmapping = d_backing_inode(object->backer)->i_mapping;
    - struct page *newpage = NULL, *netpage, *_n, *backpage = NULL;
    - int ret = 0;
    -
    - _enter("");
    -
    - list_for_each_entry_safe(netpage, _n, list, lru) {
    - list_del(&netpage->lru);
    -
    - _debug("read back %p{%lu,%d}",
    - netpage, netpage->index, page_count(netpage));
    -
    - if (!monitor) {
    - monitor = kzalloc(sizeof(*monitor), cachefiles_gfp);
    - if (!monitor)
    - goto nomem;
    -
    - monitor->op = fscache_get_retrieval(op);
    - init_waitqueue_func_entry(&monitor->monitor,
    - cachefiles_read_waiter);
    - }
    -
    - for (;;) {
    - backpage = find_get_page(bmapping, netpage->index);
    - if (backpage)
    - goto backing_page_already_present;
    -
    - if (!newpage) {
    - newpage = __page_cache_alloc(cachefiles_gfp);
    - if (!newpage)
    - goto nomem;
    - }
    -
    - ret = add_to_page_cache_lru(newpage, bmapping,
    - netpage->index,
    - cachefiles_gfp);
    - if (ret == 0)
    - goto installed_new_backing_page;
    - if (ret != -EEXIST)
    - goto nomem;
    - }
    -
    - /* we've installed a new backing page, so now we need
    - * to start it reading */
    - installed_new_backing_page:
    - _debug("- new %p", newpage);
    -
    - backpage = newpage;
    - newpage = NULL;
    -
    - reread_backing_page:
    - ret = bmapping->a_ops->readpage(NULL, backpage);
    - if (ret < 0)
    - goto read_error;
    -
    - /* add the netfs page to the pagecache and LRU, and set the
    - * monitor to transfer the data across */
    - monitor_backing_page:
    - _debug("- monitor add");
    -
    - ret = add_to_page_cache_lru(netpage, op->mapping,
    - netpage->index, cachefiles_gfp);
    - if (ret < 0) {
    - if (ret == -EEXIST) {
    - put_page(backpage);
    - backpage = NULL;
    - put_page(netpage);
    - netpage = NULL;
    - fscache_retrieval_complete(op, 1);
    - continue;
    - }
    - goto nomem;
    - }
    -
    - /* install a monitor */
    - get_page(netpage);
    - monitor->netfs_page = netpage;
    -
    - get_page(backpage);
    - monitor->back_page = backpage;
    - monitor->monitor.private = backpage;
    - folio_add_wait_queue(page_folio(backpage), &monitor->monitor);
    - monitor = NULL;
    -
    - /* but the page may have been read before the monitor was
    - * installed, so the monitor may miss the event - so we have to
    - * ensure that we do get one in such a case */
    - if (trylock_page(backpage)) {
    - _debug("2unlock %p {%lx}", backpage, backpage->flags);
    - unlock_page(backpage);
    - }
    -
    - put_page(backpage);
    - backpage = NULL;
    -
    - put_page(netpage);
    - netpage = NULL;
    - continue;
    -
    - /* if the backing page is already present, it can be in one of
    - * three states: read in progress, read failed or read okay */
    - backing_page_already_present:
    - _debug("- present %p", backpage);
    -
    - if (PageError(backpage))
    - goto io_error;
    -
    - if (PageUptodate(backpage))
    - goto backing_page_already_uptodate;
    -
    - _debug("- not ready %p{%lx}", backpage, backpage->flags);
    -
    - if (!trylock_page(backpage))
    - goto monitor_backing_page;
    -
    - if (PageError(backpage)) {
    - _debug("error %lx", backpage->flags);
    - unlock_page(backpage);
    - goto io_error;
    - }
    -
    - if (PageUptodate(backpage))
    - goto backing_page_already_uptodate_unlock;
    -
    - /* we've locked a page that's neither up to date nor erroneous,
    - * so we need to attempt to read it again */
    - goto reread_backing_page;
    -
    - /* the backing page is already up to date, attach the netfs
    - * page to the pagecache and LRU and copy the data across */
    - backing_page_already_uptodate_unlock:
    - _debug("uptodate %lx", backpage->flags);
    - unlock_page(backpage);
    - backing_page_already_uptodate:
    - _debug("- uptodate");
    -
    - ret = add_to_page_cache_lru(netpage, op->mapping,
    - netpage->index, cachefiles_gfp);
    - if (ret < 0) {
    - if (ret == -EEXIST) {
    - put_page(backpage);
    - backpage = NULL;
    - put_page(netpage);
    - netpage = NULL;
    - fscache_retrieval_complete(op, 1);
    - continue;
    - }
    - goto nomem;
    - }
    -
    - copy_highpage(netpage, backpage);
    -
    - put_page(backpage);
    - backpage = NULL;
    -
    - fscache_mark_page_cached(op, netpage);
    -
    - /* the netpage is unlocked and marked up to date here */
    - fscache_end_io(op, netpage, 0);
    - put_page(netpage);
    - netpage = NULL;
    - fscache_retrieval_complete(op, 1);
    - continue;
    - }
    -
    - netpage = NULL;
    -
    - _debug("out");
    -
    -out:
    - /* tidy up */
    - if (newpage)
    - put_page(newpage);
    - if (netpage)
    - put_page(netpage);
    - if (backpage)
    - put_page(backpage);
    - if (monitor) {
    - fscache_put_retrieval(op);
    - kfree(monitor);
    - }
    -
    - list_for_each_entry_safe(netpage, _n, list, lru) {
    - list_del(&netpage->lru);
    - put_page(netpage);
    - fscache_retrieval_complete(op, 1);
    - }
    -
    - _leave(" = %d", ret);
    - return ret;
    -
    -nomem:
    - _debug("nomem");
    - ret = -ENOMEM;
    - goto record_page_complete;
    -
    -read_error:
    - _debug("read error %d", ret);
    - if (ret == -ENOMEM)
    - goto record_page_complete;
    -io_error:
    - cachefiles_io_error_obj(object, "Page read error on backing file");
    - ret = -ENOBUFS;
    -record_page_complete:
    - fscache_retrieval_complete(op, 1);
    - goto out;
    -}
    -
    -/*
    - * read a list of pages from the cache or allocate blocks in which to store
    - * them
    - */
    -int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
    - struct list_head *pages,
    - unsigned *nr_pages,
    - gfp_t gfp)
    -{
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - struct list_head backpages;
    - struct pagevec pagevec;
    - struct inode *inode;
    - struct page *page, *_n;
    - unsigned shift, nrbackpages;
    - int ret, ret2, space;
    -
    - object = container_of(op->op.object,
    - struct cachefiles_object, fscache);
    - cache = container_of(object->fscache.cache,
    - struct cachefiles_cache, cache);
    -
    - _enter("{OBJ%x,%d},,%d,,",
    - object->fscache.debug_id, atomic_read(&op->op.usage),
    - *nr_pages);
    -
    - if (!object->backer)
    - goto all_enobufs;
    -
    - space = 1;
    - if (cachefiles_has_space(cache, 0, *nr_pages) < 0)
    - space = 0;
    -
    - inode = d_backing_inode(object->backer);
    - ASSERT(S_ISREG(inode->i_mode));
    -
    - /* calculate the shift required to use bmap */
    - shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits;
    -
    - pagevec_init(&pagevec);
    -
    - op->op.flags &= FSCACHE_OP_KEEP_FLAGS;
    - op->op.flags |= FSCACHE_OP_ASYNC;
    - op->op.processor = cachefiles_read_copier;
    -
    - INIT_LIST_HEAD(&backpages);
    - nrbackpages = 0;
    -
    - ret = space ? -ENODATA : -ENOBUFS;
    - list_for_each_entry_safe(page, _n, pages, lru) {
    - sector_t block;
    -
    - /* we assume the absence or presence of the first block is a
    - * good enough indication for the page as a whole
    - * - TODO: don't use bmap() for this as it is _not_ actually
    - * good enough for this as it doesn't indicate errors, but
    - * it's all we've got for the moment
    - */
    - block = page->index;
    - block <<= shift;
    -
    - ret2 = bmap(inode, &block);
    - ASSERT(ret2 == 0);
    -
    - _debug("%llx -> %llx",
    - (unsigned long long) (page->index << shift),
    - (unsigned long long) block);
    -
    - if (block) {
    - /* we have data - add it to the list to give to the
    - * backing fs */
    - list_move(&page->lru, &backpages);
    - (*nr_pages)--;
    - nrbackpages++;
    - } else if (space && pagevec_add(&pagevec, page) == 0) {
    - fscache_mark_pages_cached(op, &pagevec);
    - fscache_retrieval_complete(op, 1);
    - ret = -ENODATA;
    - } else {
    - fscache_retrieval_complete(op, 1);
    - }
    - }
    -
    - if (pagevec_count(&pagevec) > 0)
    - fscache_mark_pages_cached(op, &pagevec);
    -
    - if (list_empty(pages))
    - ret = 0;
    -
    - /* submit the apparently valid pages to the backing fs to be read from
    - * disk */
    - if (nrbackpages > 0) {
    - ret2 = cachefiles_read_backing_file(object, op, &backpages);
    - if (ret2 == -ENOMEM || ret2 == -EINTR)
    - ret = ret2;
    - }
    -
    - _leave(" = %d [nr=%u%s]",
    - ret, *nr_pages, list_empty(pages) ? " empty" : "");
    - return ret;
    -
    -all_enobufs:
    - fscache_retrieval_complete(op, *nr_pages);
    - return -ENOBUFS;
    -}
    -
    -/*
    - * allocate a block in the cache in which to store a page
    - * - cache withdrawal is prevented by the caller
    - * - returns -EINTR if interrupted
    - * - returns -ENOMEM if ran out of memory
    - * - returns -ENOBUFS if no buffers can be made available
    - * - returns -ENOBUFS if page is beyond EOF
    - * - otherwise:
    - * - the metadata will be retained
    - * - 0 will be returned
    - */
    -int cachefiles_allocate_page(struct fscache_retrieval *op,
    - struct page *page,
    - gfp_t gfp)
    -{
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - int ret;
    -
    - object = container_of(op->op.object,
    - struct cachefiles_object, fscache);
    - cache = container_of(object->fscache.cache,
    - struct cachefiles_cache, cache);
    -
    - _enter("%p,{%lx},", object, page->index);
    -
    - ret = cachefiles_has_space(cache, 0, 1);
    - if (ret == 0)
    - fscache_mark_page_cached(op, page);
    - else
    - ret = -ENOBUFS;
    -
    - fscache_retrieval_complete(op, 1);
    - _leave(" = %d", ret);
    - return ret;
    -}
    -
    -/*
    - * allocate blocks in the cache in which to store a set of pages
    - * - cache withdrawal is prevented by the caller
    - * - returns -EINTR if interrupted
    - * - returns -ENOMEM if ran out of memory
    - * - returns -ENOBUFS if some buffers couldn't be made available
    - * - returns -ENOBUFS if some pages are beyond EOF
    - * - otherwise:
    - * - -ENODATA will be returned
    - * - metadata will be retained for any page marked
    - */
    -int cachefiles_allocate_pages(struct fscache_retrieval *op,
    - struct list_head *pages,
    - unsigned *nr_pages,
    - gfp_t gfp)
    -{
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - struct pagevec pagevec;
    - struct page *page;
    - int ret;
    -
    - object = container_of(op->op.object,
    - struct cachefiles_object, fscache);
    - cache = container_of(object->fscache.cache,
    - struct cachefiles_cache, cache);
    -
    - _enter("%p,,,%d,", object, *nr_pages);
    -
    - ret = cachefiles_has_space(cache, 0, *nr_pages);
    - if (ret == 0) {
    - pagevec_init(&pagevec);
    -
    - list_for_each_entry(page, pages, lru) {
    - if (pagevec_add(&pagevec, page) == 0)
    - fscache_mark_pages_cached(op, &pagevec);
    - }
    -
    - if (pagevec_count(&pagevec) > 0)
    - fscache_mark_pages_cached(op, &pagevec);
    - ret = -ENODATA;
    - } else {
    - ret = -ENOBUFS;
    - }
    -
    - fscache_retrieval_complete(op, *nr_pages);
    - _leave(" = %d", ret);
    - return ret;
    -}
    -
    -/*
    - * request a page be stored in the cache
    - * - cache withdrawal is prevented by the caller
    - * - this request may be ignored if there's no cache block available, in which
    - * case -ENOBUFS will be returned
    - * - if the op is in progress, 0 will be returned
    - */
    -int cachefiles_write_page(struct fscache_storage *op, struct page *page)
    -{
    - struct cachefiles_object *object;
    - struct cachefiles_cache *cache;
    - struct file *file;
    - struct path path;
    - loff_t pos, eof;
    - size_t len;
    - void *data;
    - int ret = -ENOBUFS;
    -
    - ASSERT(op != NULL);
    - ASSERT(page != NULL);
    -
    - object = container_of(op->op.object,
    - struct cachefiles_object, fscache);
    -
    - _enter("%p,%p{%lx},,,", object, page, page->index);
    -
    - if (!object->backer) {
    - _leave(" = -ENOBUFS");
    - return -ENOBUFS;
    - }
    -
    - ASSERT(d_is_reg(object->backer));
    -
    - cache = container_of(object->fscache.cache,
    - struct cachefiles_cache, cache);
    -
    - pos = (loff_t)page->index << PAGE_SHIFT;
    -
    - /* We mustn't write more data than we have, so we have to beware of a
    - * partial page at EOF.
    - */
    - eof = object->fscache.store_limit_l;
    - if (pos >= eof)
    - goto error;
    -
    - /* write the page to the backing filesystem and let it store it in its
    - * own time */
    - path.mnt = cache->mnt;
    - path.dentry = object->backer;
    - file = dentry_open(&path, O_RDWR | O_LARGEFILE, cache->cache_cred);
    - if (IS_ERR(file)) {
    - ret = PTR_ERR(file);
    - goto error_2;
    - }
    -
    - len = PAGE_SIZE;
    - if (eof & ~PAGE_MASK) {
    - if (eof - pos < PAGE_SIZE) {
    - _debug("cut short %llx to %llx",
    - pos, eof);
    - len = eof - pos;
    - ASSERTCMP(pos + len, ==, eof);
    - }
    - }
    -
    - data = kmap(page);
    - ret = kernel_write(file, data, len, &pos);
    - kunmap(page);
    - fput(file);
    - if (ret != len)
    - goto error_eio;
    -
    - _leave(" = 0");
    - return 0;
    -
    -error_eio:
    - ret = -EIO;
    -error_2:
    - if (ret == -EIO)
    - cachefiles_io_error_obj(object,
    - "Write page to backing file failed");
    -error:
    - _leave(" = -ENOBUFS [%d]", ret);
    - return -ENOBUFS;
    -}
    -
    -/*
    - * detach a backing block from a page
    - * - cache withdrawal is prevented by the caller
    - */
    -void cachefiles_uncache_page(struct fscache_object *_object, struct page *page)
    - __releases(&object->fscache.cookie->lock)
    -{
    - struct cachefiles_object *object;
    -
    - object = container_of(_object, struct cachefiles_object, fscache);
    -
    - _enter("%p,{%lu}", object, page->index);
    -
    - spin_unlock(&object->fscache.cookie->lock);
    -}
    diff --git a/fs/cachefiles/security.c b/fs/cachefiles/security.c
    deleted file mode 100644
    index aec13fd94692..000000000000
    --- a/fs/cachefiles/security.c
    +++ /dev/null
    @@ -1,112 +0,0 @@
    -// SPDX-License-Identifier: GPL-2.0-or-later
    -/* CacheFiles security management
    - *
    - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -
    -#include <linux/fs.h>
    -#include <linux/cred.h>
    -#include "internal.h"
    -
    -/*
    - * determine the security context within which we access the cache from within
    - * the kernel
    - */
    -int cachefiles_get_security_ID(struct cachefiles_cache *cache)
    -{
    - struct cred *new;
    - int ret;
    -
    - _enter("{%s}", cache->secctx);
    -
    - new = prepare_kernel_cred(current);
    - if (!new) {
    - ret = -ENOMEM;
    - goto error;
    - }
    -
    - if (cache->secctx) {
    - ret = set_security_override_from_ctx(new, cache->secctx);
    - if (ret < 0) {
    - put_cred(new);
    - pr_err("Security denies permission to nominate security context: error %d\n",
    - ret);
    - goto error;
    - }
    - }
    -
    - cache->cache_cred = new;
    - ret = 0;
    -error:
    - _leave(" = %d", ret);
    - return ret;
    -}
    -
    -/*
    - * see if mkdir and create can be performed in the root directory
    - */
    -static int cachefiles_check_cache_dir(struct cachefiles_cache *cache,
    - struct dentry *root)
    -{
    - int ret;
    -
    - ret = security_inode_mkdir(d_backing_inode(root), root, 0);
    - if (ret < 0) {
    - pr_err("Security denies permission to make dirs: error %d",
    - ret);
    - return ret;
    - }
    -
    - ret = security_inode_create(d_backing_inode(root), root, 0);
    - if (ret < 0)
    - pr_err("Security denies permission to create files: error %d",
    - ret);
    -
    - return ret;
    -}
    -
    -/*
    - * check the security details of the on-disk cache
    - * - must be called with security override in force
    - * - must return with a security override in force - even in the case of an
    - * error
    - */
    -int cachefiles_determine_cache_security(struct cachefiles_cache *cache,
    - struct dentry *root,
    - const struct cred **_saved_cred)
    -{
    - struct cred *new;
    - int ret;
    -
    - _enter("");
    -
    - /* duplicate the cache creds for COW (the override is currently in
    - * force, so we can use prepare_creds() to do this) */
    - new = prepare_creds();
    - if (!new)
    - return -ENOMEM;
    -
    - cachefiles_end_secure(cache, *_saved_cred);
    -
    - /* use the cache root dir's security context as the basis with
    - * which create files */
    - ret = set_create_files_as(new, d_backing_inode(root));
    - if (ret < 0) {
    - abort_creds(new);
    - cachefiles_begin_secure(cache, _saved_cred);
    - _leave(" = %d [cfa]", ret);
    - return ret;
    - }
    -
    - put_cred(cache->cache_cred);
    - cache->cache_cred = new;
    -
    - cachefiles_begin_secure(cache, _saved_cred);
    - ret = cachefiles_check_cache_dir(cache, root);
    -
    - if (ret == -EOPNOTSUPP)
    - ret = 0;
    - _leave(" = %d", ret);
    - return ret;
    -}
    diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
    deleted file mode 100644
    index 9e82de668595..000000000000
    --- a/fs/cachefiles/xattr.c
    +++ /dev/null
    @@ -1,324 +0,0 @@
    -// SPDX-License-Identifier: GPL-2.0-or-later
    -/* CacheFiles extended attribute management
    - *
    - * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -
    -#include <linux/module.h>
    -#include <linux/sched.h>
    -#include <linux/file.h>
    -#include <linux/fs.h>
    -#include <linux/fsnotify.h>
    -#include <linux/quotaops.h>
    -#include <linux/xattr.h>
    -#include <linux/slab.h>
    -#include "internal.h"
    -
    -static const char cachefiles_xattr_cache[] =
    - XATTR_USER_PREFIX "CacheFiles.cache";
    -
    -/*
    - * check the type label on an object
    - * - done using xattrs
    - */
    -int cachefiles_check_object_type(struct cachefiles_object *object)
    -{
    - struct dentry *dentry = object->dentry;
    - char type[3], xtype[3];
    - int ret;
    -
    - ASSERT(dentry);
    - ASSERT(d_backing_inode(dentry));
    -
    - if (!object->fscache.cookie)
    - strcpy(type, "C3");
    - else
    - snprintf(type, 3, "%02x", object->fscache.cookie->def->type);
    -
    - _enter("%x{%s}", object->fscache.debug_id, type);
    -
    - /* attempt to install a type label directly */
    - ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache, type,
    - 2, XATTR_CREATE);
    - if (ret == 0) {
    - _debug("SET"); /* we succeeded */
    - goto error;
    - }
    -
    - if (ret != -EEXIST) {
    - pr_err("Can't set xattr on %pd [%lu] (err %d)\n",
    - dentry, d_backing_inode(dentry)->i_ino,
    - -ret);
    - goto error;
    - }
    -
    - /* read the current type label */
    - ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache, xtype,
    - 3);
    - if (ret < 0) {
    - if (ret == -ERANGE)
    - goto bad_type_length;
    -
    - pr_err("Can't read xattr on %pd [%lu] (err %d)\n",
    - dentry, d_backing_inode(dentry)->i_ino,
    - -ret);
    - goto error;
    - }
    -
    - /* check the type is what we're expecting */
    - if (ret != 2)
    - goto bad_type_length;
    -
    - if (xtype[0] != type[0] || xtype[1] != type[1])
    - goto bad_type;
    -
    - ret = 0;
    -
    -error:
    - _leave(" = %d", ret);
    - return ret;
    -
    -bad_type_length:
    - pr_err("Cache object %lu type xattr length incorrect\n",
    - d_backing_inode(dentry)->i_ino);
    - ret = -EIO;
    - goto error;
    -
    -bad_type:
    - xtype[2] = 0;
    - pr_err("Cache object %pd [%lu] type %s not %s\n",
    - dentry, d_backing_inode(dentry)->i_ino,
    - xtype, type);
    - ret = -EIO;
    - goto error;
    -}
    -
    -/*
    - * set the state xattr on a cache file
    - */
    -int cachefiles_set_object_xattr(struct cachefiles_object *object,
    - struct cachefiles_xattr *auxdata)
    -{
    - struct dentry *dentry = object->dentry;
    - int ret;
    -
    - ASSERT(dentry);
    -
    - _enter("%p,#%d", object, auxdata->len);
    -
    - /* attempt to install the cache metadata directly */
    - _debug("SET #%u", auxdata->len);
    -
    - clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
    - ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
    - &auxdata->type, auxdata->len, XATTR_CREATE);
    - if (ret < 0 && ret != -ENOMEM)
    - cachefiles_io_error_obj(
    - object,
    - "Failed to set xattr with error %d", ret);
    -
    - _leave(" = %d", ret);
    - return ret;
    -}
    -
    -/*
    - * update the state xattr on a cache file
    - */
    -int cachefiles_update_object_xattr(struct cachefiles_object *object,
    - struct cachefiles_xattr *auxdata)
    -{
    - struct dentry *dentry = object->dentry;
    - int ret;
    -
    - if (!dentry)
    - return -ESTALE;
    -
    - _enter("%x,#%d", object->fscache.debug_id, auxdata->len);
    -
    - /* attempt to install the cache metadata directly */
    - _debug("SET #%u", auxdata->len);
    -
    - clear_bit(FSCACHE_COOKIE_AUX_UPDATED, &object->fscache.cookie->flags);
    - ret = vfs_setxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
    - &auxdata->type, auxdata->len, XATTR_REPLACE);
    - if (ret < 0 && ret != -ENOMEM)
    - cachefiles_io_error_obj(
    - object,
    - "Failed to update xattr with error %d", ret);
    -
    - _leave(" = %d", ret);
    - return ret;
    -}
    -
    -/*
    - * check the consistency between the backing cache and the FS-Cache cookie
    - */
    -int cachefiles_check_auxdata(struct cachefiles_object *object)
    -{
    - struct cachefiles_xattr *auxbuf;
    - enum fscache_checkaux validity;
    - struct dentry *dentry = object->dentry;
    - ssize_t xlen;
    - int ret;
    -
    - ASSERT(dentry);
    - ASSERT(d_backing_inode(dentry));
    - ASSERT(object->fscache.cookie->def->check_aux);
    -
    - auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, GFP_KERNEL);
    - if (!auxbuf)
    - return -ENOMEM;
    -
    - xlen = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
    - &auxbuf->type, 512 + 1);
    - ret = -ESTALE;
    - if (xlen < 1 ||
    - auxbuf->type != object->fscache.cookie->def->type)
    - goto error;
    -
    - xlen--;
    - validity = fscache_check_aux(&object->fscache, &auxbuf->data, xlen,
    - i_size_read(d_backing_inode(dentry)));
    - if (validity != FSCACHE_CHECKAUX_OKAY)
    - goto error;
    -
    - ret = 0;
    -error:
    - kfree(auxbuf);
    - return ret;
    -}
    -
    -/*
    - * check the state xattr on a cache file
    - * - return -ESTALE if the object should be deleted
    - */
    -int cachefiles_check_object_xattr(struct cachefiles_object *object,
    - struct cachefiles_xattr *auxdata)
    -{
    - struct cachefiles_xattr *auxbuf;
    - struct dentry *dentry = object->dentry;
    - int ret;
    -
    - _enter("%p,#%d", object, auxdata->len);
    -
    - ASSERT(dentry);
    - ASSERT(d_backing_inode(dentry));
    -
    - auxbuf = kmalloc(sizeof(struct cachefiles_xattr) + 512, cachefiles_gfp);
    - if (!auxbuf) {
    - _leave(" = -ENOMEM");
    - return -ENOMEM;
    - }
    -
    - /* read the current type label */
    - ret = vfs_getxattr(&init_user_ns, dentry, cachefiles_xattr_cache,
    - &auxbuf->type, 512 + 1);
    - if (ret < 0) {
    - if (ret == -ENODATA)
    - goto stale; /* no attribute - power went off
    - * mid-cull? */
    -
    - if (ret == -ERANGE)
    - goto bad_type_length;
    -
    - cachefiles_io_error_obj(object,
    - "Can't read xattr on %lu (err %d)",
    - d_backing_inode(dentry)->i_ino, -ret);
    - goto error;
    - }
    -
    - /* check the on-disk object */
    - if (ret < 1)
    - goto bad_type_length;
    -
    - if (auxbuf->type != auxdata->type)
    - goto stale;
    -
    - auxbuf->len = ret;
    -
    - /* consult the netfs */
    - if (object->fscache.cookie->def->check_aux) {
    - enum fscache_checkaux result;
    - unsigned int dlen;
    -
    - dlen = auxbuf->len - 1;
    -
    - _debug("checkaux %s #%u",
    - object->fscache.cookie->def->name, dlen);
    -
    - result = fscache_check_aux(&object->fscache,
    - &auxbuf->data, dlen,
    - i_size_read(d_backing_inode(dentry)));
    -
    - switch (result) {
    - /* entry okay as is */
    - case FSCACHE_CHECKAUX_OKAY:
    - goto okay;
    -
    - /* entry requires update */
    - case FSCACHE_CHECKAUX_NEEDS_UPDATE:
    - break;
    -
    - /* entry requires deletion */
    - case FSCACHE_CHECKAUX_OBSOLETE:
    - goto stale;
    -
    - default:
    - BUG();
    - }
    -
    - /* update the current label */
    - ret = vfs_setxattr(&init_user_ns, dentry,
    - cachefiles_xattr_cache, &auxdata->type,
    - auxdata->len, XATTR_REPLACE);
    - if (ret < 0) {
    - cachefiles_io_error_obj(object,
    - "Can't update xattr on %lu"
    - " (error %d)",
    - d_backing_inode(dentry)->i_ino, -ret);
    - goto error;
    - }
    - }
    -
    -okay:
    - ret = 0;
    -
    -error:
    - kfree(auxbuf);
    - _leave(" = %d", ret);
    - return ret;
    -
    -bad_type_length:
    - pr_err("Cache object %lu xattr length incorrect\n",
    - d_backing_inode(dentry)->i_ino);
    - ret = -EIO;
    - goto error;
    -
    -stale:
    - ret = -ESTALE;
    - goto error;
    -}
    -
    -/*
    - * remove the object's xattr to mark it stale
    - */
    -int cachefiles_remove_object_xattr(struct cachefiles_cache *cache,
    - struct dentry *dentry)
    -{
    - int ret;
    -
    - ret = vfs_removexattr(&init_user_ns, dentry, cachefiles_xattr_cache);
    - if (ret < 0) {
    - if (ret == -ENOENT || ret == -ENODATA)
    - ret = 0;
    - else if (ret != -ENOMEM)
    - cachefiles_io_error(cache,
    - "Can't remove xattr from %lu"
    - " (error %d)",
    - d_backing_inode(dentry)->i_ino, -ret);
    - }
    -
    - _leave(" = %d", ret);
    - return ret;
    -}
    diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h
    deleted file mode 100644
    index 920b6a303d60..000000000000
    --- a/include/trace/events/cachefiles.h
    +++ /dev/null
    @@ -1,321 +0,0 @@
    -/* SPDX-License-Identifier: GPL-2.0-or-later */
    -/* CacheFiles tracepoints
    - *
    - * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
    - * Written by David Howells (dhowells@redhat.com)
    - */
    -#undef TRACE_SYSTEM
    -#define TRACE_SYSTEM cachefiles
    -
    -#if !defined(_TRACE_CACHEFILES_H) || defined(TRACE_HEADER_MULTI_READ)
    -#define _TRACE_CACHEFILES_H
    -
    -#include <linux/tracepoint.h>
    -
    -/*
    - * Define enums for tracing information.
    - */
    -#ifndef __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
    -#define __CACHEFILES_DECLARE_TRACE_ENUMS_ONCE_ONLY
    -
    -enum cachefiles_obj_ref_trace {
    - cachefiles_obj_put_wait_retry = fscache_obj_ref__nr_traces,
    - cachefiles_obj_put_wait_timeo,
    - cachefiles_obj_ref__nr_traces
    -};
    -
    -#endif
    -
    -/*
    - * Define enum -> string mappings for display.
    - */
    -#define cachefiles_obj_kill_traces \
    - EM(FSCACHE_OBJECT_IS_STALE, "stale") \
    - EM(FSCACHE_OBJECT_NO_SPACE, "no_space") \
    - EM(FSCACHE_OBJECT_WAS_RETIRED, "was_retired") \
    - E_(FSCACHE_OBJECT_WAS_CULLED, "was_culled")
    -
    -#define cachefiles_obj_ref_traces \
    - EM(fscache_obj_get_add_to_deps, "GET add_to_deps") \
    - EM(fscache_obj_get_queue, "GET queue") \
    - EM(fscache_obj_put_alloc_fail, "PUT alloc_fail") \
    - EM(fscache_obj_put_attach_fail, "PUT attach_fail") \
    - EM(fscache_obj_put_drop_obj, "PUT drop_obj") \
    - EM(fscache_obj_put_enq_dep, "PUT enq_dep") \
    - EM(fscache_obj_put_queue, "PUT queue") \
    - EM(fscache_obj_put_work, "PUT work") \
    - EM(cachefiles_obj_put_wait_retry, "PUT wait_retry") \
    - E_(cachefiles_obj_put_wait_timeo, "PUT wait_timeo")
    -
    -/*
    - * Export enum symbols via userspace.
    - */
    -#undef EM
    -#undef E_
    -#define EM(a, b) TRACE_DEFINE_ENUM(a);
    -#define E_(a, b) TRACE_DEFINE_ENUM(a);
    -
    -cachefiles_obj_kill_traces;
    -cachefiles_obj_ref_traces;
    -
    -/*
    - * Now redefine the EM() and E_() macros to map the enums to the strings that
    - * will be printed in the output.
    - */
    -#undef EM
    -#undef E_
    -#define EM(a, b) { a, b },
    -#define E_(a, b) { a, b }
    -
    -
    -TRACE_EVENT(cachefiles_ref,
    - TP_PROTO(struct cachefiles_object *obj,
    - struct fscache_cookie *cookie,
    - enum cachefiles_obj_ref_trace why,
    - int usage),
    -
    - TP_ARGS(obj, cookie, why, usage),
    -
    - /* Note that obj may be NULL */
    - TP_STRUCT__entry(
    - __field(unsigned int, obj )
    - __field(unsigned int, cookie )
    - __field(enum cachefiles_obj_ref_trace, why )
    - __field(int, usage )
    - ),
    -
    - TP_fast_assign(
    - __entry->obj = obj->fscache.debug_id;
    - __entry->cookie = cookie->debug_id;
    - __entry->usage = usage;
    - __entry->why = why;
    - ),
    -
    - TP_printk("c=%08x o=%08x u=%d %s",
    - __entry->cookie, __entry->obj, __entry->usage,
    - __print_symbolic(__entry->why, cachefiles_obj_ref_traces))
    - );
    -
    -TRACE_EVENT(cachefiles_lookup,
    - TP_PROTO(struct cachefiles_object *obj,
    - struct dentry *de,
    - struct inode *inode),
    -
    - TP_ARGS(obj, de, inode),
    -
    - TP_STRUCT__entry(
    - __field(unsigned int, obj )
    - __field(struct dentry *, de )
    - __field(struct inode *, inode )
    - ),
    -
    - TP_fast_assign(
    - __entry->obj = obj->fscache.debug_id;
    - __entry->de = de;
    - __entry->inode = inode;
    - ),
    -
    - TP_printk("o=%08x d=%p i=%p",
    - __entry->obj, __entry->de, __entry->inode)
    - );
    -
    -TRACE_EVENT(cachefiles_mkdir,
    - TP_PROTO(struct cachefiles_object *obj,
    - struct dentry *de, int ret),
    -
    - TP_ARGS(obj, de, ret),
    -
    - TP_STRUCT__entry(
    - __field(unsigned int, obj )
    - __field(struct dentry *, de )
    - __field(int, ret )
    - ),
    -
    - TP_fast_assign(
    - __entry->obj = obj->fscache.debug_id;
    - __entry->de = de;
    - __entry->ret = ret;
    - ),
    -
    - TP_printk("o=%08x d=%p r=%u",
    - __entry->obj, __entry->de, __entry->ret)
    - );
    -
    -TRACE_EVENT(cachefiles_create,
    - TP_PROTO(struct cachefiles_object *obj,
    - struct dentry *de, int ret),
    -
    - TP_ARGS(obj, de, ret),
    -
    - TP_STRUCT__entry(
    - __field(unsigned int, obj )
    - __field(struct dentry *, de )
    - __field(int, ret )
    - ),
    -
    - TP_fast_assign(
    - __entry->obj = obj->fscache.debug_id;
    - __entry->de = de;
    - __entry->ret = ret;
    - ),
    -
    - TP_printk("o=%08x d=%p r=%u",
    - __entry->obj, __entry->de, __entry->ret)
    - );
    -
    -TRACE_EVENT(cachefiles_unlink,
    - TP_PROTO(struct cachefiles_object *obj,
    - struct dentry *de,
    - enum fscache_why_object_killed why),
    -
    - TP_ARGS(obj, de, why),
    -
    - /* Note that obj may be NULL */
    - TP_STRUCT__entry(
    - __field(unsigned int, obj )
    - __field(struct dentry *, de )
    - __field(enum fscache_why_object_killed, why )
    - ),
    -
    - TP_fast_assign(
    - __entry->obj = obj ? obj->fscache.debug_id : UINT_MAX;
    - __entry->de = de;
    - __entry->why = why;
    - ),
    -
    - TP_printk("o=%08x d=%p w=%s",
    - __entry->obj, __entry->de,
    - __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
    - );
    -
    -TRACE_EVENT(cachefiles_rename,
    - TP_PROTO(struct cachefiles_object *obj,
    - struct dentry *de,
    - struct dentry *to,
    - enum fscache_why_object_killed why),
    -
    - TP_ARGS(obj, de, to, why),
    -
    - /* Note that obj may be NULL */
    - TP_STRUCT__entry(
    - __field(unsigned int, obj )
    - __field(struct dentry *, de )
    - __field(struct dentry *, to )
    - __field(enum fscache_why_object_killed, why )
    - ),
    -
    - TP_fast_assign(
    - __entry->obj = obj ? obj->fscache.debug_id : UINT_MAX;
    - __entry->de = de;
    - __entry->to = to;
    - __entry->why = why;
    - ),
    -
    - TP_printk("o=%08x d=%p t=%p w=%s",
    - __entry->obj, __entry->de, __entry->to,
    - __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
    - );
    -
    -TRACE_EVENT(cachefiles_mark_active,
    - TP_PROTO(struct cachefiles_object *obj,
    - struct dentry *de),
    -
    - TP_ARGS(obj, de),
    -
    - /* Note that obj may be NULL */
    - TP_STRUCT__entry(
    - __field(unsigned int, obj )
    - __field(struct dentry *, de )
    - ),
    -
    - TP_fast_assign(
    - __entry->obj = obj->fscache.debug_id;
    - __entry->de = de;
    - ),
    -
    - TP_printk("o=%08x d=%p",
    - __entry->obj, __entry->de)
    - );
    -
    -TRACE_EVENT(cachefiles_wait_active,
    - TP_PROTO(struct cachefiles_object *obj,
    - struct dentry *de,
    - struct cachefiles_object *xobj),
    -
    - TP_ARGS(obj, de, xobj),
    -
    - /* Note that obj may be NULL */
    - TP_STRUCT__entry(
    - __field(unsigned int, obj )
    - __field(unsigned int, xobj )
    - __field(struct dentry *, de )
    - __field(u16, flags )
    - __field(u16, fsc_flags )
    - ),
    -
    - TP_fast_assign(
    - __entry->obj = obj->fscache.debug_id;
    - __entry->de = de;
    - __entry->xobj = xobj->fscache.debug_id;
    - __entry->flags = xobj->flags;
    - __entry->fsc_flags = xobj->fscache.flags;
    - ),
    -
    - TP_printk("o=%08x d=%p wo=%08x wf=%x wff=%x",
    - __entry->obj, __entry->de, __entry->xobj,
    - __entry->flags, __entry->fsc_flags)
    - );
    -
    -TRACE_EVENT(cachefiles_mark_inactive,
    - TP_PROTO(struct cachefiles_object *obj,
    - struct dentry *de,
    - struct inode *inode),
    -
    - TP_ARGS(obj, de, inode),
    -
    - /* Note that obj may be NULL */
    - TP_STRUCT__entry(
    - __field(unsigned int, obj )
    - __field(struct dentry *, de )
    - __field(struct inode *, inode )
    - ),
    -
    - TP_fast_assign(
    - __entry->obj = obj->fscache.debug_id;
    - __entry->de = de;
    - __entry->inode = inode;
    - ),
    -
    - TP_printk("o=%08x d=%p i=%p",
    - __entry->obj, __entry->de, __entry->inode)
    - );
    -
    -TRACE_EVENT(cachefiles_mark_buried,
    - TP_PROTO(struct cachefiles_object *obj,
    - struct dentry *de,
    - enum fscache_why_object_killed why),
    -
    - TP_ARGS(obj, de, why),
    -
    - /* Note that obj may be NULL */
    - TP_STRUCT__entry(
    - __field(unsigned int, obj )
    - __field(struct dentry *, de )
    - __field(enum fscache_why_object_killed, why )
    - ),
    -
    - TP_fast_assign(
    - __entry->obj = obj ? obj->fscache.debug_id : UINT_MAX;
    - __entry->de = de;
    - __entry->why = why;
    - ),
    -
    - TP_printk("o=%08x d=%p w=%s",
    - __entry->obj, __entry->de,
    - __print_symbolic(__entry->why, cachefiles_obj_kill_traces))
    - );
    -
    -#endif /* _TRACE_CACHEFILES_H */
    -
    -/* This part must be outside protection */
    -#include <trace/define_trace.h>

    \
     
     \ /
      Last update: 2021-12-23 00:14    [W:6.520 / U:0.192 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site