Skip to content

Commit 523d27c

Browse files
committed
afs: Convert afs to use the new fscache API
Change the afs filesystem to support the new afs driver. The following changes have been made: (1) The fscache_netfs struct is no more, and there's no need to register the filesystem as a whole. There's also no longer a cell cookie. (2) The volume cookie is now an fscache_volume cookie, allocated with fscache_acquire_volume(). This function takes three parameters: a string representing the "volume" in the index, a string naming the cache to use (or NULL) and a u64 that conveys coherency metadata for the volume. For afs, I've made it render the volume name string as: "afs,<cell>,<volume_id>" and the coherency data is currently 0. (3) The fscache_cookie_def is no more and needed information is passed directly to fscache_acquire_cookie(). The cache no longer calls back into the filesystem, but rather metadata changes are indicated at other times. fscache_acquire_cookie() is passed the same keying and coherency information as before, except that these are now stored in big endian form instead of cpu endian. This makes the cache more copyable. (4) fscache_use_cookie() and fscache_unuse_cookie() are called when a file is opened or closed to prevent a cache file from being culled and to keep resources to hand that are needed to do I/O. fscache_use_cookie() is given an indication if the cache is likely to be modified locally (e.g. the file is open for writing). fscache_unuse_cookie() is given a coherency update if we had the file open for writing and will update that. (5) fscache_invalidate() is now given uptodate auxiliary data and a file size. It can also take a flag to indicate if this was due to a DIO write. This is wrapped into afs_fscache_invalidate() now for convenience. (6) fscache_resize() now gets called from the finalisation of afs_setattr(), and afs_setattr() does use/unuse of the cookie around the call to support this. (7) fscache_note_page_release() is called from afs_release_page(). (8) Use a killable wait in nfs_vm_page_mkwrite() when waiting for PG_fscache to be cleared. Render the parts of the cookie key for an afs inode cookie as big endian. Changes ======= ver #2: - Use gfpflags_allow_blocking() rather than using flag directly. - fscache_acquire_volume() now returns errors. Signed-off-by: David Howells <[email protected]> Acked-by: Jeff Layton <[email protected]> Tested-by: [email protected] cc: Marc Dionne <[email protected]> cc: [email protected] cc: [email protected] Link: https://lore.kernel.org/r/163819661382.215744.1485608824741611837.stgit@warthog.procyon.org.uk/ # v1 Link: https://lore.kernel.org/r/163906970002.143852.17678518584089878259.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/163967174665.1823006.1301789965454084220.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/164021568841.640689.6684240152253400380.stgit@warthog.procyon.org.uk/ # v4
1 parent 9f08ebc commit 523d27c

File tree

10 files changed

+89
-151
lines changed

10 files changed

+89
-151
lines changed

fs/afs/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ config AFS_DEBUG
2525

2626
config AFS_FSCACHE
2727
bool "Provide AFS client caching support"
28-
depends on AFS_FS=m && FSCACHE_OLD_API || AFS_FS=y && FSCACHE_OLD_API=y
28+
depends on AFS_FS=m && FSCACHE || AFS_FS=y && FSCACHE=y
2929
help
3030
Say Y here if you want AFS data to be cached locally on disk through
3131
the generic filesystem cache manager

fs/afs/Makefile

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
# Makefile for Red Hat Linux AFS client.
44
#
55

6-
afs-cache-$(CONFIG_AFS_FSCACHE) := cache.o
7-
86
kafs-y := \
9-
$(afs-cache-y) \
107
addr_list.o \
118
callback.o \
129
cell.o \

fs/afs/cache.c

Lines changed: 0 additions & 68 deletions
This file was deleted.

fs/afs/cell.c

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -680,13 +680,6 @@ static int afs_activate_cell(struct afs_net *net, struct afs_cell *cell)
680680
return ret;
681681
}
682682

683-
#ifdef CONFIG_AFS_FSCACHE
684-
cell->cache = fscache_acquire_cookie(afs_cache_netfs.primary_index,
685-
&afs_cell_cache_index_def,
686-
cell->name, strlen(cell->name),
687-
NULL, 0,
688-
cell, 0, true);
689-
#endif
690683
ret = afs_proc_cell_setup(cell);
691684
if (ret < 0)
692685
return ret;
@@ -723,11 +716,6 @@ static void afs_deactivate_cell(struct afs_net *net, struct afs_cell *cell)
723716
afs_dynroot_rmdir(net, cell);
724717
mutex_unlock(&net->proc_cells_lock);
725718

726-
#ifdef CONFIG_AFS_FSCACHE
727-
fscache_relinquish_cookie(cell->cache, NULL, false);
728-
cell->cache = NULL;
729-
#endif
730-
731719
_leave("");
732720
}
733721

fs/afs/file.c

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,9 @@ int afs_open(struct inode *inode, struct file *file)
158158

159159
if (file->f_flags & O_TRUNC)
160160
set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
161-
161+
162+
fscache_use_cookie(afs_vnode_cache(vnode), file->f_mode & FMODE_WRITE);
163+
162164
file->private_data = af;
163165
_leave(" = 0");
164166
return 0;
@@ -177,8 +179,10 @@ int afs_open(struct inode *inode, struct file *file)
177179
*/
178180
int afs_release(struct inode *inode, struct file *file)
179181
{
182+
struct afs_vnode_cache_aux aux;
180183
struct afs_vnode *vnode = AFS_FS_I(inode);
181184
struct afs_file *af = file->private_data;
185+
loff_t i_size;
182186
int ret = 0;
183187

184188
_enter("{%llx:%llu},", vnode->fid.vid, vnode->fid.vnode);
@@ -189,6 +193,15 @@ int afs_release(struct inode *inode, struct file *file)
189193
file->private_data = NULL;
190194
if (af->wb)
191195
afs_put_wb_key(af->wb);
196+
197+
if ((file->f_mode & FMODE_WRITE)) {
198+
i_size = i_size_read(&vnode->vfs_inode);
199+
afs_set_cache_aux(vnode, &aux);
200+
fscache_unuse_cookie(afs_vnode_cache(vnode), &aux, &i_size);
201+
} else {
202+
fscache_unuse_cookie(afs_vnode_cache(vnode), NULL, NULL);
203+
}
204+
192205
key_put(af->key);
193206
kfree(af);
194207
afs_prune_wb_keys(vnode);
@@ -352,15 +365,18 @@ static void afs_init_rreq(struct netfs_read_request *rreq, struct file *file)
352365

353366
static bool afs_is_cache_enabled(struct inode *inode)
354367
{
355-
return fscache_cookie_enabled(afs_vnode_cache(AFS_FS_I(inode)));
368+
struct fscache_cookie *cookie = afs_vnode_cache(AFS_FS_I(inode));
369+
370+
return fscache_cookie_enabled(cookie) && cookie->cache_priv;
356371
}
357372

358373
static int afs_begin_cache_operation(struct netfs_read_request *rreq)
359374
{
360375
#ifdef CONFIG_AFS_FSCACHE
361376
struct afs_vnode *vnode = AFS_FS_I(rreq->inode);
362377

363-
return fscache_begin_read_operation(rreq, afs_vnode_cache(vnode));
378+
return fscache_begin_read_operation(&rreq->cache_resources,
379+
afs_vnode_cache(vnode));
364380
#else
365381
return -ENOBUFS;
366382
#endif
@@ -482,23 +498,24 @@ static void afs_invalidatepage(struct page *page, unsigned int offset,
482498
* release a page and clean up its private state if it's not busy
483499
* - return true if the page can now be released, false if not
484500
*/
485-
static int afs_releasepage(struct page *page, gfp_t gfp_flags)
501+
static int afs_releasepage(struct page *page, gfp_t gfp)
486502
{
487503
struct folio *folio = page_folio(page);
488504
struct afs_vnode *vnode = AFS_FS_I(folio_inode(folio));
489505

490506
_enter("{{%llx:%llu}[%lu],%lx},%x",
491507
vnode->fid.vid, vnode->fid.vnode, folio_index(folio), folio->flags,
492-
gfp_flags);
508+
gfp);
493509

494510
/* deny if page is being written to the cache and the caller hasn't
495511
* elected to wait */
496512
#ifdef CONFIG_AFS_FSCACHE
497513
if (folio_test_fscache(folio)) {
498-
if (!(gfp_flags & __GFP_DIRECT_RECLAIM) || !(gfp_flags & __GFP_FS))
514+
if (!gfpflags_allow_blocking(gfp) || !(gfp & __GFP_FS))
499515
return false;
500516
folio_wait_fscache(folio);
501517
}
518+
fscache_note_page_release(afs_vnode_cache(vnode));
502519
#endif
503520

504521
if (folio_test_private(folio)) {

fs/afs/inode.c

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -413,9 +413,9 @@ static void afs_get_inode_cache(struct afs_vnode *vnode)
413413
{
414414
#ifdef CONFIG_AFS_FSCACHE
415415
struct {
416-
u32 vnode_id;
417-
u32 unique;
418-
u32 vnode_id_ext[2]; /* Allow for a 96-bit key */
416+
__be32 vnode_id;
417+
__be32 unique;
418+
__be32 vnode_id_ext[2]; /* Allow for a 96-bit key */
419419
} __packed key;
420420
struct afs_vnode_cache_aux aux;
421421

@@ -424,17 +424,18 @@ static void afs_get_inode_cache(struct afs_vnode *vnode)
424424
return;
425425
}
426426

427-
key.vnode_id = vnode->fid.vnode;
428-
key.unique = vnode->fid.unique;
429-
key.vnode_id_ext[0] = vnode->fid.vnode >> 32;
430-
key.vnode_id_ext[1] = vnode->fid.vnode_hi;
431-
aux.data_version = vnode->status.data_version;
432-
433-
vnode->cache = fscache_acquire_cookie(vnode->volume->cache,
434-
&afs_vnode_cache_index_def,
435-
&key, sizeof(key),
436-
&aux, sizeof(aux),
437-
vnode, vnode->status.size, true);
427+
key.vnode_id = htonl(vnode->fid.vnode);
428+
key.unique = htonl(vnode->fid.unique);
429+
key.vnode_id_ext[0] = htonl(vnode->fid.vnode >> 32);
430+
key.vnode_id_ext[1] = htonl(vnode->fid.vnode_hi);
431+
afs_set_cache_aux(vnode, &aux);
432+
433+
vnode->cache = fscache_acquire_cookie(
434+
vnode->volume->cache,
435+
vnode->status.type == AFS_FTYPE_FILE ? 0 : FSCACHE_ADV_SINGLE_CHUNK,
436+
&key, sizeof(key),
437+
&aux, sizeof(aux),
438+
vnode->status.size);
438439
#endif
439440
}
440441

@@ -563,9 +564,7 @@ static void afs_zap_data(struct afs_vnode *vnode)
563564
{
564565
_enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
565566

566-
#ifdef CONFIG_AFS_FSCACHE
567-
fscache_invalidate(vnode->cache);
568-
#endif
567+
afs_invalidate_cache(vnode, 0);
569568

570569
/* nuke all the non-dirty pages that aren't locked, mapped or being
571570
* written back in a regular file and completely discard the pages in a
@@ -786,14 +785,9 @@ void afs_evict_inode(struct inode *inode)
786785
}
787786

788787
#ifdef CONFIG_AFS_FSCACHE
789-
{
790-
struct afs_vnode_cache_aux aux;
791-
792-
aux.data_version = vnode->status.data_version;
793-
fscache_relinquish_cookie(vnode->cache, &aux,
794-
test_bit(AFS_VNODE_DELETED, &vnode->flags));
795-
vnode->cache = NULL;
796-
}
788+
fscache_relinquish_cookie(vnode->cache,
789+
test_bit(AFS_VNODE_DELETED, &vnode->flags));
790+
vnode->cache = NULL;
797791
#endif
798792

799793
afs_prune_wb_keys(vnode);
@@ -833,6 +827,9 @@ static void afs_setattr_edit_file(struct afs_operation *op)
833827

834828
if (size < i_size)
835829
truncate_pagecache(inode, size);
830+
if (size != i_size)
831+
fscache_resize_cookie(afs_vnode_cache(vp->vnode),
832+
vp->scb.status.size);
836833
}
837834
}
838835

@@ -876,6 +873,8 @@ int afs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
876873
attr->ia_valid &= ~ATTR_SIZE;
877874
}
878875

876+
fscache_use_cookie(afs_vnode_cache(vnode), true);
877+
879878
/* flush any dirty data outstanding on a regular file */
880879
if (S_ISREG(vnode->vfs_inode.i_mode))
881880
filemap_write_and_wait(vnode->vfs_inode.i_mapping);
@@ -907,6 +906,7 @@ int afs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
907906

908907
out_unlock:
909908
up_write(&vnode->validate_lock);
909+
fscache_unuse_cookie(afs_vnode_cache(vnode), NULL, NULL);
910910
_leave(" = %d", ret);
911911
return ret;
912912
}

fs/afs/internal.h

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <linux/key.h>
1515
#include <linux/workqueue.h>
1616
#include <linux/sched.h>
17-
#define FSCACHE_USE_NEW_IO_API
1817
#include <linux/fscache.h>
1918
#include <linux/backing-dev.h>
2019
#include <linux/uuid.h>
@@ -364,9 +363,6 @@ struct afs_cell {
364363
struct key *anonymous_key; /* anonymous user key for this cell */
365364
struct work_struct manager; /* Manager for init/deinit/dns */
366365
struct hlist_node proc_link; /* /proc cell list link */
367-
#ifdef CONFIG_AFS_FSCACHE
368-
struct fscache_cookie *cache; /* caching cookie */
369-
#endif
370366
time64_t dns_expiry; /* Time AFSDB/SRV record expires */
371367
time64_t last_inactive; /* Time of last drop of usage count */
372368
atomic_t ref; /* Struct refcount */
@@ -590,7 +586,7 @@ struct afs_volume {
590586
#define AFS_VOLUME_BUSY 5 /* - T if volume busy notice given */
591587
#define AFS_VOLUME_MAYBE_NO_IBULK 6 /* - T if some servers don't have InlineBulkStatus */
592588
#ifdef CONFIG_AFS_FSCACHE
593-
struct fscache_cookie *cache; /* caching cookie */
589+
struct fscache_volume *cache; /* Caching cookie */
594590
#endif
595591
struct afs_server_list __rcu *servers; /* List of servers on which volume resides */
596592
rwlock_t servers_lock; /* Lock for ->servers */
@@ -872,9 +868,24 @@ struct afs_operation {
872868
* Cache auxiliary data.
873869
*/
874870
struct afs_vnode_cache_aux {
875-
u64 data_version;
871+
__be64 data_version;
876872
} __packed;
877873

874+
static inline void afs_set_cache_aux(struct afs_vnode *vnode,
875+
struct afs_vnode_cache_aux *aux)
876+
{
877+
aux->data_version = cpu_to_be64(vnode->status.data_version);
878+
}
879+
880+
static inline void afs_invalidate_cache(struct afs_vnode *vnode, unsigned int flags)
881+
{
882+
struct afs_vnode_cache_aux aux;
883+
884+
afs_set_cache_aux(vnode, &aux);
885+
fscache_invalidate(afs_vnode_cache(vnode), &aux,
886+
i_size_read(&vnode->vfs_inode), flags);
887+
}
888+
878889
/*
879890
* We use folio->private to hold the amount of the folio that we've written to,
880891
* splitting the field into two parts. However, we need to represent a range
@@ -962,13 +973,6 @@ extern void afs_merge_fs_addr6(struct afs_addr_list *, __be32 *, u16);
962973
*/
963974
#ifdef CONFIG_AFS_FSCACHE
964975
extern struct fscache_netfs afs_cache_netfs;
965-
extern struct fscache_cookie_def afs_cell_cache_index_def;
966-
extern struct fscache_cookie_def afs_volume_cache_index_def;
967-
extern struct fscache_cookie_def afs_vnode_cache_index_def;
968-
#else
969-
#define afs_cell_cache_index_def (*(struct fscache_cookie_def *) NULL)
970-
#define afs_volume_cache_index_def (*(struct fscache_cookie_def *) NULL)
971-
#define afs_vnode_cache_index_def (*(struct fscache_cookie_def *) NULL)
972976
#endif
973977

974978
/*
@@ -1506,7 +1510,7 @@ extern struct afs_vlserver_list *afs_extract_vlserver_list(struct afs_cell *,
15061510
* volume.c
15071511
*/
15081512
extern struct afs_volume *afs_create_volume(struct afs_fs_context *);
1509-
extern void afs_activate_volume(struct afs_volume *);
1513+
extern int afs_activate_volume(struct afs_volume *);
15101514
extern void afs_deactivate_volume(struct afs_volume *);
15111515
extern struct afs_volume *afs_get_volume(struct afs_volume *, enum afs_volume_trace);
15121516
extern void afs_put_volume(struct afs_net *, struct afs_volume *, enum afs_volume_trace);

0 commit comments

Comments
 (0)