Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

afs: split afs_pagecache_valid() out of afs_validate()

For the map_pages() method, we need a test that does not sleep. The page
fault handler will continue to call the fault() method where we can sleep
and do the full revalidation there.

Link: https://lkml.kernel.org/r/20230327174515.1811532-3-willy@infradead.org
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Acked-by: David Howells <dhowells@redhat.com>
Tested-by: David Howells <dhowells@redhat.com>
Cc: Darrick J. Wong <djwong@kernel.org>
Cc: Dave Chinner <david@fromorbit.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Matthew Wilcox (Oracle) and committed by
Andrew Morton
0050d7f5 945ea457

+22 -20
+2 -12
fs/afs/file.c
··· 569 569 static vm_fault_t afs_vm_map_pages(struct vm_fault *vmf, pgoff_t start_pgoff, pgoff_t end_pgoff) 570 570 { 571 571 struct afs_vnode *vnode = AFS_FS_I(file_inode(vmf->vma->vm_file)); 572 - struct afs_file *af = vmf->vma->vm_file->private_data; 573 572 574 - switch (afs_validate(vnode, af->key)) { 575 - case 0: 573 + if (afs_pagecache_valid(vnode)) 576 574 return filemap_map_pages(vmf, start_pgoff, end_pgoff); 577 - case -ENOMEM: 578 - return VM_FAULT_OOM; 579 - case -EINTR: 580 - case -ERESTARTSYS: 581 - return VM_FAULT_RETRY; 582 - case -ESTALE: 583 - default: 584 - return VM_FAULT_SIGBUS; 585 - } 575 + return 0; 586 576 } 587 577 588 578 static ssize_t afs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter)
+19 -8
fs/afs/inode.c
··· 668 668 } 669 669 670 670 /* 671 + * Returns true if the pagecache is still valid. Does not sleep. 672 + */ 673 + bool afs_pagecache_valid(struct afs_vnode *vnode) 674 + { 675 + if (unlikely(test_bit(AFS_VNODE_DELETED, &vnode->flags))) { 676 + if (vnode->netfs.inode.i_nlink) 677 + clear_nlink(&vnode->netfs.inode); 678 + return true; 679 + } 680 + 681 + if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags) && 682 + afs_check_validity(vnode)) 683 + return true; 684 + 685 + return false; 686 + } 687 + 688 + /* 671 689 * validate a vnode/inode 672 690 * - there are several things we need to check 673 691 * - parent dir data changes (rm, rmdir, rename, mkdir, create, link, ··· 702 684 vnode->fid.vid, vnode->fid.vnode, vnode->flags, 703 685 key_serial(key)); 704 686 705 - if (unlikely(test_bit(AFS_VNODE_DELETED, &vnode->flags))) { 706 - if (vnode->netfs.inode.i_nlink) 707 - clear_nlink(&vnode->netfs.inode); 708 - goto valid; 709 - } 710 - 711 - if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags) && 712 - afs_check_validity(vnode)) 687 + if (afs_pagecache_valid(vnode)) 713 688 goto valid; 714 689 715 690 down_write(&vnode->validate_lock);
+1
fs/afs/internal.h
··· 1171 1171 extern struct inode *afs_root_iget(struct super_block *, struct key *); 1172 1172 extern bool afs_check_validity(struct afs_vnode *); 1173 1173 extern int afs_validate(struct afs_vnode *, struct key *); 1174 + bool afs_pagecache_valid(struct afs_vnode *); 1174 1175 extern int afs_getattr(struct mnt_idmap *idmap, const struct path *, 1175 1176 struct kstat *, u32, unsigned int); 1176 1177 extern int afs_setattr(struct mnt_idmap *idmap, struct dentry *, struct iattr *);