Commit 621cbeb2 authored by Zizhi Wo's avatar Zizhi Wo Committed by Baokun Li
Browse files

cachefiles: Add restrictions to cachefiles_daemon_cull()

hulk inclusion
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IB5UKT



--------------------------------

When an erofs file system is mounted with ondemand mode, if the cache
root directory bound to cachefiles named rootdir, the resulting directory
structure is seen as follows, where different directories corresponded to
the objects of different levels:

		rootdir
	       ____|____
	      |	        |
	  cache(obj0) graveyard
	      |
        domain_dir(obj1)
	      |
	   hash_dir
	      |
      back_data.img(obj2)

In the current logic, if cull is executed on the cache directory, it first
determines whether the object corresponding to the directory is the active
node of cache. If yes, it cannot be executed. If the fscache_object lookup
successfully, it is set to avtive node; and if the lookup fails or the
object state machine goes into drop, it is set to inactive.

Currently cachefiles_daemon_cull() can execute on any directory or file
which have not been called cachefiles_mark_object_active(), and we want to
reduce the scope of this function. On the one hand, the user state needs
to add relevant constraints; on the other hand, kernel mode also needs
modified. This patch adds the restriction of filesystem-level isolation.

In addition, the top-level cache dir can be culled directly because obj0
is not added as active_node. This causes the entire cache directory to be
renamed graveyard, even though the underlying objects are inuse state, and
cannot be resolved by mounting it again. Fix it by marking it as active in
cachefiles_daemon_add_cache().

Signed-off-by: default avatarZizhi Wo <wozizhi@huawei.com>
Signed-off-by: default avatarBaokun Li <libaokun1@huawei.com>
parent 54ebd401
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -232,6 +232,12 @@ static int cachefiles_daemon_add_cache(struct cachefiles_cache *cache)
	if (ret < 0)
		goto error_add_cache;

	/*
	 * As the cache->daemon_mutex lock hold and the cache is set to
	 * CACHEFILES_READY, this function must not return an error.
	 */
	cachefiles_mark_object_active(cache, fsdef);

	/* done */
	set_bit(CACHEFILES_READY, &cache->flags);
	dput(root);
+6 −0
Original line number Diff line number Diff line
@@ -662,6 +662,12 @@ static int cachefiles_daemon_cull(struct cachefiles_cache *cache, char *args)
	if (!d_can_lookup(path.dentry))
		goto notdir;

	/* limit the scope of cull */
	if (cache->mnt != path.mnt) {
		path_put(&path);
		return -EOPNOTSUPP;
	}

	cachefiles_begin_secure(cache, &saved_cred);
	ret = cachefiles_cull(cache, path.dentry, args);
	cachefiles_end_secure(cache, saved_cred);
+2 −0
Original line number Diff line number Diff line
@@ -210,6 +210,8 @@ extern char *cachefiles_cook_key(struct cachefiles_object *object,
extern void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
					    struct cachefiles_object *object,
					    blkcnt_t i_blocks);
extern int cachefiles_mark_object_active(struct cachefiles_cache *cache,
					 struct cachefiles_object *object);
extern int cachefiles_delete_object(struct cachefiles_cache *cache,
				    struct cachefiles_object *object);
extern int cachefiles_walk_to_object(struct cachefiles_object *parent,
+2 −2
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ static void cachefiles_mark_object_buried(struct cachefiles_cache *cache,
/*
 * record the fact that an object is now active
 */
static int cachefiles_mark_object_active(struct cachefiles_cache *cache,
int cachefiles_mark_object_active(struct cachefiles_cache *cache,
				  struct cachefiles_object *object)
{
	struct cachefiles_object *xobject;