1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
5 * Written by David Howells (dhowells@redhat.com)
9 #include <linux/slab.h>
11 #include <trace/events/fscache.h>
14 * Allocate and set up a volume representation. We make sure all the fanout
15 * directories are created and pinned.
17 void cachefiles_acquire_volume(struct fscache_volume
*vcookie
)
19 struct cachefiles_volume
*volume
;
20 struct cachefiles_cache
*cache
= vcookie
->cache
->cache_priv
;
21 const struct cred
*saved_cred
;
22 struct dentry
*vdentry
, *fan
;
26 int ret
, n_accesses
, i
;
30 volume
= kzalloc(sizeof(struct cachefiles_volume
), GFP_KERNEL
);
33 volume
->vcookie
= vcookie
;
34 volume
->cache
= cache
;
35 INIT_LIST_HEAD(&volume
->cache_link
);
37 cachefiles_begin_secure(cache
, &saved_cred
);
39 len
= vcookie
->key
[0];
40 name
= kmalloc(len
+ 3, GFP_NOFS
);
44 memcpy(name
+ 1, vcookie
->key
+ 1, len
);
48 vdentry
= cachefiles_get_directory(cache
, cache
->store
, name
, &is_new
);
51 volume
->dentry
= vdentry
;
54 if (!cachefiles_set_volume_xattr(volume
))
57 ret
= cachefiles_check_volume_xattr(volume
);
61 inode_lock_nested(d_inode(cache
->store
), I_MUTEX_PARENT
);
62 cachefiles_bury_object(cache
, NULL
, cache
->store
, vdentry
,
63 FSCACHE_VOLUME_IS_WEIRD
);
64 cachefiles_put_directory(volume
->dentry
);
70 for (i
= 0; i
< 256; i
++) {
71 sprintf(name
, "@%02x", i
);
72 fan
= cachefiles_get_directory(cache
, vdentry
, name
, NULL
);
75 volume
->fanout
[i
] = fan
;
78 cachefiles_end_secure(cache
, saved_cred
);
80 vcookie
->cache_priv
= volume
;
81 n_accesses
= atomic_inc_return(&vcookie
->n_accesses
); /* Stop wakeups on dec-to-0 */
82 trace_fscache_access_volume(vcookie
->debug_id
, 0,
83 refcount_read(&vcookie
->ref
),
84 n_accesses
, fscache_access_cache_pin
);
86 spin_lock(&cache
->object_list_lock
);
87 list_add(&volume
->cache_link
, &volume
->cache
->volumes
);
88 spin_unlock(&cache
->object_list_lock
);
94 for (i
= 0; i
< 256; i
++)
95 cachefiles_put_directory(volume
->fanout
[i
]);
97 cachefiles_put_directory(volume
->dentry
);
102 cachefiles_end_secure(cache
, saved_cred
);
106 * Release a volume representation.
108 static void __cachefiles_free_volume(struct cachefiles_volume
*volume
)
114 volume
->vcookie
->cache_priv
= NULL
;
116 for (i
= 0; i
< 256; i
++)
117 cachefiles_put_directory(volume
->fanout
[i
]);
118 cachefiles_put_directory(volume
->dentry
);
122 void cachefiles_free_volume(struct fscache_volume
*vcookie
)
124 struct cachefiles_volume
*volume
= vcookie
->cache_priv
;
127 spin_lock(&volume
->cache
->object_list_lock
);
128 list_del_init(&volume
->cache_link
);
129 spin_unlock(&volume
->cache
->object_list_lock
);
130 __cachefiles_free_volume(volume
);
134 void cachefiles_withdraw_volume(struct cachefiles_volume
*volume
)
136 cachefiles_set_volume_xattr(volume
);
137 __cachefiles_free_volume(volume
);