[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220802030342.46302-3-jefflexu@linux.alibaba.com>
Date: Tue, 2 Aug 2022 11:03:35 +0800
From: Jingbo Xu <jefflexu@...ux.alibaba.com>
To: dhowells@...hat.com, linux-cachefs@...hat.com
Cc: linux-kernel@...r.kernel.org, xiang@...nel.org
Subject: [PATCH RFC 2/9] cachefiles: add content map file helpers
Besides the mapping mechanism provided by the backing fs, a self
maintained bitmap can be used to track if the corresponding file range
is cached by the backing file or not. In this case, a content map file
is used to permanentize the bitmap.
As the first step, add the helper functions for looking up and freeing
these content map files.
Signed-off-by: Jingbo Xu <jefflexu@...ux.alibaba.com>
---
fs/cachefiles/internal.h | 4 ++
fs/cachefiles/namei.c | 88 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+)
diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
index 6cba2c6de2f9..4c3ee6935811 100644
--- a/fs/cachefiles/internal.h
+++ b/fs/cachefiles/internal.h
@@ -270,6 +270,10 @@ extern struct dentry *cachefiles_get_directory(struct cachefiles_cache *cache,
bool *_is_new);
extern void cachefiles_put_directory(struct dentry *dir);
+int cachefiles_look_up_map(struct cachefiles_cache *cache,
+ struct dentry *dir, struct file **pfile);
+void cachefiles_put_map(struct file *file);
+
extern int cachefiles_cull(struct cachefiles_cache *cache, struct dentry *dir,
char *filename);
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index facf2ebe464b..2948eea18ca2 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -231,6 +231,94 @@ void cachefiles_put_directory(struct dentry *dir)
}
}
+/*
+ * Look up a content map file.
+ */
+int cachefiles_look_up_map(struct cachefiles_cache *cache,
+ struct dentry *dir, struct file **pfile)
+{
+ struct dentry *dentry;
+ struct file *file;
+ struct path path;
+ char *name = "Map";
+ int ret;
+
+ inode_lock_nested(d_inode(dir), I_MUTEX_PARENT);
+retry:
+ ret = cachefiles_inject_read_error();
+ if (ret)
+ goto err_unlock_dir;
+
+ dentry = lookup_one_len(name, dir, strlen(name));
+ if (IS_ERR(dentry)) {
+ ret = PTR_ERR(dentry);
+ goto err_unlock_dir;
+ }
+
+ if (d_is_negative(dentry)) {
+ ret = cachefiles_has_space(cache, 1, 0,
+ cachefiles_has_space_for_create);
+ if (ret)
+ goto err_dput;
+
+ ret = vfs_create(&init_user_ns, d_inode(dir), dentry, S_IFREG, true);
+ if (ret)
+ goto err_dput;
+
+ if (unlikely(d_unhashed(dentry))) {
+ cachefiles_put_directory(dentry);
+ goto retry;
+ }
+ ASSERT(d_backing_inode(dentry));
+ }
+
+ inode_lock(d_inode(dentry));
+ inode_unlock(d_inode(dir));
+
+ if (!__cachefiles_mark_inode_in_use(NULL, dentry)) {
+ inode_unlock(d_inode(dentry));
+ dput(dentry);
+ return -EBUSY;
+ }
+
+ inode_unlock(d_inode(dentry));
+ ASSERT(d_backing_inode(dentry));
+
+ if (!d_is_reg(dentry)) {
+ pr_err("%pd is not a file\n", dentry);
+ cachefiles_put_directory(dentry);
+ return -EIO;
+ }
+
+ path.mnt = cache->mnt;
+ path.dentry = dentry;
+ file = open_with_fake_path(&path, O_RDWR | O_LARGEFILE,
+ d_backing_inode(dentry), cache->cache_cred);
+ if (IS_ERR(file))
+ cachefiles_put_directory(dentry);
+
+ *pfile = file;
+ dput(dentry);
+ return 0;
+
+err_dput:
+ dput(dentry);
+err_unlock_dir:
+ inode_unlock(d_inode(dir));
+ return ret;
+}
+
+/*
+ * Put a content map file.
+ */
+void cachefiles_put_map(struct file *file)
+{
+ if (file) {
+ cachefiles_do_unmark_inode_in_use(NULL, file->f_path.dentry);
+ fput(file);
+ }
+}
+
/*
* Remove a regular file from the cache.
*/
--
2.27.0
Powered by blists - more mailing lists