forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cachefiles: Implement volume support
Implement support for creating the directory layout for a volume on disk and setting up and withdrawing volume caching. Each volume has a directory named for the volume key under the root of the cache (prefixed with an 'I' to indicate to cachefilesd that it's an index) and then creates a bunch of hash bucket subdirectories under that (named as '@' plus a hex number) in which cookie files will be created. 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/163819635314.215744.13081522301564537723.stgit@warthog.procyon.org.uk/ # v1 Link: https://lore.kernel.org/r/163906936397.143852.17788457778396467161.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/163967143860.1823006.7185205806080225038.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/164021545212.640689.5064821392307582927.stgit@warthog.procyon.org.uk/ # v4
- Loading branch information
Showing
6 changed files
with
171 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
/* Volume handling. | ||
* | ||
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved. | ||
* Written by David Howells (dhowells@redhat.com) | ||
*/ | ||
|
||
#include <linux/fs.h> | ||
#include <linux/slab.h> | ||
#include "internal.h" | ||
#include <trace/events/fscache.h> | ||
|
||
/* | ||
* Allocate and set up a volume representation. We make sure all the fanout | ||
* directories are created and pinned. | ||
*/ | ||
void cachefiles_acquire_volume(struct fscache_volume *vcookie) | ||
{ | ||
struct cachefiles_volume *volume; | ||
struct cachefiles_cache *cache = vcookie->cache->cache_priv; | ||
const struct cred *saved_cred; | ||
struct dentry *vdentry, *fan; | ||
size_t len; | ||
char *name; | ||
int n_accesses, i; | ||
|
||
_enter(""); | ||
|
||
volume = kzalloc(sizeof(struct cachefiles_volume), GFP_KERNEL); | ||
if (!volume) | ||
return; | ||
volume->vcookie = vcookie; | ||
volume->cache = cache; | ||
INIT_LIST_HEAD(&volume->cache_link); | ||
|
||
cachefiles_begin_secure(cache, &saved_cred); | ||
|
||
len = vcookie->key[0]; | ||
name = kmalloc(len + 3, GFP_NOFS); | ||
if (!name) | ||
goto error_vol; | ||
name[0] = 'I'; | ||
memcpy(name + 1, vcookie->key + 1, len); | ||
name[len + 1] = 0; | ||
|
||
vdentry = cachefiles_get_directory(cache, cache->store, name, NULL); | ||
if (IS_ERR(vdentry)) | ||
goto error_name; | ||
volume->dentry = vdentry; | ||
|
||
for (i = 0; i < 256; i++) { | ||
sprintf(name, "@%02x", i); | ||
fan = cachefiles_get_directory(cache, vdentry, name, NULL); | ||
if (IS_ERR(fan)) | ||
goto error_fan; | ||
volume->fanout[i] = fan; | ||
} | ||
|
||
cachefiles_end_secure(cache, saved_cred); | ||
|
||
vcookie->cache_priv = volume; | ||
n_accesses = atomic_inc_return(&vcookie->n_accesses); /* Stop wakeups on dec-to-0 */ | ||
trace_fscache_access_volume(vcookie->debug_id, 0, | ||
refcount_read(&vcookie->ref), | ||
n_accesses, fscache_access_cache_pin); | ||
|
||
spin_lock(&cache->object_list_lock); | ||
list_add(&volume->cache_link, &volume->cache->volumes); | ||
spin_unlock(&cache->object_list_lock); | ||
|
||
kfree(name); | ||
return; | ||
|
||
error_fan: | ||
for (i = 0; i < 256; i++) | ||
cachefiles_put_directory(volume->fanout[i]); | ||
cachefiles_put_directory(volume->dentry); | ||
error_name: | ||
kfree(name); | ||
error_vol: | ||
kfree(volume); | ||
cachefiles_end_secure(cache, saved_cred); | ||
} | ||
|
||
/* | ||
* Release a volume representation. | ||
*/ | ||
static void __cachefiles_free_volume(struct cachefiles_volume *volume) | ||
{ | ||
int i; | ||
|
||
_enter(""); | ||
|
||
volume->vcookie->cache_priv = NULL; | ||
|
||
for (i = 0; i < 256; i++) | ||
cachefiles_put_directory(volume->fanout[i]); | ||
cachefiles_put_directory(volume->dentry); | ||
kfree(volume); | ||
} | ||
|
||
void cachefiles_free_volume(struct fscache_volume *vcookie) | ||
{ | ||
struct cachefiles_volume *volume = vcookie->cache_priv; | ||
|
||
if (volume) { | ||
spin_lock(&volume->cache->object_list_lock); | ||
list_del_init(&volume->cache_link); | ||
spin_unlock(&volume->cache->object_list_lock); | ||
__cachefiles_free_volume(volume); | ||
} | ||
} | ||
|
||
void cachefiles_withdraw_volume(struct cachefiles_volume *volume) | ||
{ | ||
fscache_withdraw_volume(volume->vcookie); | ||
__cachefiles_free_volume(volume); | ||
} |