VisionFive2 Linux kernel

StarFive Tech Linux Kernel for VisionFive (JH7110) boards (mirror)

More than 9999 Commits   32 Branches   54 Tags
2874c5fd28426 (Thomas Gleixner   2019-05-27 08:55:01 +0200   1) // SPDX-License-Identifier: GPL-2.0-or-later
08e0e7c82eead (David Howells     2007-04-26 15:55:03 -0700   2) /* AFS filesystem file handling
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   3)  *
08e0e7c82eead (David Howells     2007-04-26 15:55:03 -0700   4)  * Copyright (C) 2002, 2007 Red Hat, Inc. All Rights Reserved.
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   5)  * Written by David Howells (dhowells@redhat.com)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   6)  */
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   7) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   8) #include <linux/kernel.h>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700   9) #include <linux/module.h>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  10) #include <linux/init.h>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  11) #include <linux/fs.h>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  12) #include <linux/pagemap.h>
31143d5d515ec (David Howells     2007-05-09 02:33:46 -0700  13) #include <linux/writeback.h>
5a0e3ad6af866 (Tejun Heo         2010-03-24 17:04:11 +0900  14) #include <linux/gfp.h>
91b467e0a3f5f (David Howells     2017-01-05 10:38:35 +0000  15) #include <linux/task_io_accounting_ops.h>
f86196ea8737c (Nikolay Borisov   2019-01-03 15:29:02 -0800  16) #include <linux/mm.h>
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000  17) #include <linux/netfs.h>
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  18) #include "internal.h"
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  19) 
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000  20) static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
416351f28d2b3 (David Howells     2007-05-09 02:33:45 -0700  21) static int afs_readpage(struct file *file, struct page *page);
d47992f86b307 (Lukas Czerner     2013-05-21 23:17:23 -0400  22) static void afs_invalidatepage(struct page *page, unsigned int offset,
d47992f86b307 (Lukas Czerner     2013-05-21 23:17:23 -0400  23) 			       unsigned int length);
416351f28d2b3 (David Howells     2007-05-09 02:33:45 -0700  24) static int afs_releasepage(struct page *page, gfp_t gfp_flags);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  25) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000  26) static void afs_readahead(struct readahead_control *ractl);
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100  27) 
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700  28) const struct file_operations afs_file_operations = {
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700  29) 	.open		= afs_open,
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700  30) 	.release	= afs_release,
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700  31) 	.llseek		= generic_file_llseek,
aad4f8bb42af0 (Al Viro           2014-04-02 14:33:16 -0400  32) 	.read_iter	= generic_file_read_iter,
50b5551d1719c (Al Viro           2014-04-03 14:13:46 -0400  33) 	.write_iter	= afs_file_write,
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000  34) 	.mmap		= afs_file_mmap,
5ffc4ef45b3b0 (Jens Axboe        2007-06-01 11:49:19 +0200  35) 	.splice_read	= generic_file_splice_read,
06a17bbe1d47f (David Howells     2020-10-27 09:39:04 +0000  36) 	.splice_write	= iter_file_splice_write,
31143d5d515ec (David Howells     2007-05-09 02:33:46 -0700  37) 	.fsync		= afs_fsync,
e8d6c554126b8 (David Howells     2007-07-15 23:40:12 -0700  38) 	.lock		= afs_lock,
e8d6c554126b8 (David Howells     2007-07-15 23:40:12 -0700  39) 	.flock		= afs_flock,
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700  40) };
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700  41) 
754661f143e70 (Arjan van de Ven  2007-02-12 00:55:38 -0800  42) const struct inode_operations afs_file_inode_operations = {
416351f28d2b3 (David Howells     2007-05-09 02:33:45 -0700  43) 	.getattr	= afs_getattr,
31143d5d515ec (David Howells     2007-05-09 02:33:46 -0700  44) 	.setattr	= afs_setattr,
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700  45) 	.permission	= afs_permission,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  46) };
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  47) 
f5e54d6e53a20 (Christoph Hellwig 2006-06-28 04:26:44 -0700  48) const struct address_space_operations afs_fs_aops = {
416351f28d2b3 (David Howells     2007-05-09 02:33:45 -0700  49) 	.readpage	= afs_readpage,
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000  50) 	.readahead	= afs_readahead,
31143d5d515ec (David Howells     2007-05-09 02:33:46 -0700  51) 	.set_page_dirty	= afs_set_page_dirty,
31143d5d515ec (David Howells     2007-05-09 02:33:46 -0700  52) 	.launder_page	= afs_launder_page,
416351f28d2b3 (David Howells     2007-05-09 02:33:45 -0700  53) 	.releasepage	= afs_releasepage,
416351f28d2b3 (David Howells     2007-05-09 02:33:45 -0700  54) 	.invalidatepage	= afs_invalidatepage,
15b4650e55e06 (Nicholas Piggin   2008-10-15 22:04:32 -0700  55) 	.write_begin	= afs_write_begin,
15b4650e55e06 (Nicholas Piggin   2008-10-15 22:04:32 -0700  56) 	.write_end	= afs_write_end,
31143d5d515ec (David Howells     2007-05-09 02:33:46 -0700  57) 	.writepage	= afs_writepage,
31143d5d515ec (David Howells     2007-05-09 02:33:46 -0700  58) 	.writepages	= afs_writepages,
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  59) };
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700  60) 
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000  61) static const struct vm_operations_struct afs_vm_ops = {
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000  62) 	.fault		= filemap_fault,
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000  63) 	.map_pages	= filemap_map_pages,
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000  64) 	.page_mkwrite	= afs_page_mkwrite,
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000  65) };
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000  66) 
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  67) /*
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  68)  * Discard a pin on a writeback key.
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  69)  */
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  70) void afs_put_wb_key(struct afs_wb_key *wbk)
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  71) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100  72) 	if (wbk && refcount_dec_and_test(&wbk->usage)) {
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  73) 		key_put(wbk->key);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  74) 		kfree(wbk);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  75) 	}
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  76) }
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  77) 
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  78) /*
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  79)  * Cache key for writeback.
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  80)  */
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  81) int afs_cache_wb_key(struct afs_vnode *vnode, struct afs_file *af)
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  82) {
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  83) 	struct afs_wb_key *wbk, *p;
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  84) 
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  85) 	wbk = kzalloc(sizeof(struct afs_wb_key), GFP_KERNEL);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  86) 	if (!wbk)
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  87) 		return -ENOMEM;
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  88) 	refcount_set(&wbk->usage, 2);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  89) 	wbk->key = af->key;
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  90) 
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  91) 	spin_lock(&vnode->wb_lock);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  92) 	list_for_each_entry(p, &vnode->wb_keys, vnode_link) {
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  93) 		if (p->key == wbk->key)
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  94) 			goto found;
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  95) 	}
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  96) 
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  97) 	key_get(wbk->key);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  98) 	list_add_tail(&wbk->vnode_link, &vnode->wb_keys);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000  99) 	spin_unlock(&vnode->wb_lock);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 100) 	af->wb = wbk;
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 101) 	return 0;
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 102) 
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 103) found:
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 104) 	refcount_inc(&p->usage);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 105) 	spin_unlock(&vnode->wb_lock);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 106) 	af->wb = p;
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 107) 	kfree(wbk);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 108) 	return 0;
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 109) }
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 110) 
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 111) /*
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 112)  * open an AFS file or directory and attach a key to it
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 113)  */
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 114) int afs_open(struct inode *inode, struct file *file)
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 115) {
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 116) 	struct afs_vnode *vnode = AFS_FS_I(inode);
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 117) 	struct afs_file *af;
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 118) 	struct key *key;
260a980317dac (David Howells     2007-04-26 15:59:35 -0700 119) 	int ret;
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 120) 
3b6492df4153b (David Howells     2018-10-20 00:57:57 +0100 121) 	_enter("{%llx:%llu},", vnode->fid.vid, vnode->fid.vnode);
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 122) 
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 123) 	key = afs_request_key(vnode->volume->cell);
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 124) 	if (IS_ERR(key)) {
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 125) 		ret = PTR_ERR(key);
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 126) 		goto error;
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 127) 	}
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 128) 
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 129) 	af = kzalloc(sizeof(*af), GFP_KERNEL);
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 130) 	if (!af) {
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 131) 		ret = -ENOMEM;
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 132) 		goto error_key;
260a980317dac (David Howells     2007-04-26 15:59:35 -0700 133) 	}
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 134) 	af->key = key;
260a980317dac (David Howells     2007-04-26 15:59:35 -0700 135) 
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 136) 	ret = afs_validate(vnode, key);
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 137) 	if (ret < 0)
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 138) 		goto error_af;
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 139) 
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 140) 	if (file->f_mode & FMODE_WRITE) {
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 141) 		ret = afs_cache_wb_key(vnode, af);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 142) 		if (ret < 0)
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 143) 			goto error_af;
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 144) 	}
5a8132761609b (David Howells     2018-04-06 14:17:26 +0100 145) 
5a8132761609b (David Howells     2018-04-06 14:17:26 +0100 146) 	if (file->f_flags & O_TRUNC)
5a8132761609b (David Howells     2018-04-06 14:17:26 +0100 147) 		set_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 148) 	
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 149) 	file->private_data = af;
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 150) 	_leave(" = 0");
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 151) 	return 0;
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 152) 
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 153) error_af:
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 154) 	kfree(af);
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 155) error_key:
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 156) 	key_put(key);
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 157) error:
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 158) 	_leave(" = %d", ret);
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 159) 	return ret;
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 160) }
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 161) 
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 162) /*
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 163)  * release an AFS file or directory and discard its key
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 164)  */
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 165) int afs_release(struct inode *inode, struct file *file)
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 166) {
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 167) 	struct afs_vnode *vnode = AFS_FS_I(inode);
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 168) 	struct afs_file *af = file->private_data;
a1b879eefc2b3 (David Howells     2019-05-15 12:09:17 +0100 169) 	int ret = 0;
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 170) 
3b6492df4153b (David Howells     2018-10-20 00:57:57 +0100 171) 	_enter("{%llx:%llu},", vnode->fid.vid, vnode->fid.vnode);
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 172) 
5a8132761609b (David Howells     2018-04-06 14:17:26 +0100 173) 	if ((file->f_mode & FMODE_WRITE))
a1b879eefc2b3 (David Howells     2019-05-15 12:09:17 +0100 174) 		ret = vfs_fsync(file, 0);
5a8132761609b (David Howells     2018-04-06 14:17:26 +0100 175) 
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 176) 	file->private_data = NULL;
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 177) 	if (af->wb)
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 178) 		afs_put_wb_key(af->wb);
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 179) 	key_put(af->key);
215804a99283c (David Howells     2017-11-02 15:27:52 +0000 180) 	kfree(af);
4343d00872e1d (David Howells     2017-11-02 15:27:52 +0000 181) 	afs_prune_wb_keys(vnode);
a1b879eefc2b3 (David Howells     2019-05-15 12:09:17 +0100 182) 	_leave(" = %d", ret);
a1b879eefc2b3 (David Howells     2019-05-15 12:09:17 +0100 183) 	return ret;
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 184) }
00d3b7a4533e3 (David Howells     2007-04-26 15:57:07 -0700 185) 
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 186) /*
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 187)  * Allocate a new read record.
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 188)  */
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 189) struct afs_read *afs_alloc_read(gfp_t gfp)
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 190) {
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 191) 	struct afs_read *req;
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 192) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 193) 	req = kzalloc(sizeof(struct afs_read), gfp);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 194) 	if (req)
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 195) 		refcount_set(&req->usage, 1);
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 196) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 197) 	return req;
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 198) }
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 199) 
196ee9cd2d047 (David Howells     2017-01-05 10:38:34 +0000 200) /*
196ee9cd2d047 (David Howells     2017-01-05 10:38:34 +0000 201)  * Dispose of a ref to a read record.
196ee9cd2d047 (David Howells     2017-01-05 10:38:34 +0000 202)  */
196ee9cd2d047 (David Howells     2017-01-05 10:38:34 +0000 203) void afs_put_read(struct afs_read *req)
196ee9cd2d047 (David Howells     2017-01-05 10:38:34 +0000 204) {
f3ddee8dc4e2c (David Howells     2018-04-06 14:17:25 +0100 205) 	if (refcount_dec_and_test(&req->usage)) {
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 206) 		if (req->cleanup)
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 207) 			req->cleanup(req);
c69bf479baa61 (David Howells     2020-02-06 14:22:27 +0000 208) 		key_put(req->key);
196ee9cd2d047 (David Howells     2017-01-05 10:38:34 +0000 209) 		kfree(req);
196ee9cd2d047 (David Howells     2017-01-05 10:38:34 +0000 210) 	}
196ee9cd2d047 (David Howells     2017-01-05 10:38:34 +0000 211) }
196ee9cd2d047 (David Howells     2017-01-05 10:38:34 +0000 212) 
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 213) static void afs_fetch_data_notify(struct afs_operation *op)
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 214) {
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 215) 	struct afs_read *req = op->fetch.req;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 216) 	struct netfs_read_subrequest *subreq = req->subreq;
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 217) 	int error = op->error;
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 218) 
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 219) 	if (error == -ECONNABORTED)
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 220) 		error = afs_abort_to_error(op->ac.abort_code);
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 221) 	req->error = error;
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 222) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 223) 	if (subreq) {
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 224) 		__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 225) 		netfs_subreq_terminated(subreq, error ?: req->actual_len, false);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 226) 		req->subreq = NULL;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 227) 	} else if (req->done) {
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 228) 		req->done(req);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 229) 	}
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 230) }
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 231) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 232) static void afs_fetch_data_success(struct afs_operation *op)
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 233) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 234) 	struct afs_vnode *vnode = op->file[0].vnode;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 235) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 236) 	_enter("op=%08x", op->debug_id);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 237) 	afs_vnode_commit_status(op, &op->file[0]);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 238) 	afs_stat_v(vnode, n_fetches);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 239) 	atomic_long_add(op->fetch.req->actual_len, &op->net->n_fetch_bytes);
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 240) 	afs_fetch_data_notify(op);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 241) }
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 242) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 243) static void afs_fetch_data_put(struct afs_operation *op)
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 244) {
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 245) 	op->fetch.req->error = op->error;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 246) 	afs_put_read(op->fetch.req);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 247) }
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 248) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 249) static const struct afs_operation_ops afs_fetch_data_operation = {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 250) 	.issue_afs_rpc	= afs_fs_fetch_data,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 251) 	.issue_yfs_rpc	= yfs_fs_fetch_data,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 252) 	.success	= afs_fetch_data_success,
728279a5a1fd9 (David Howells     2020-06-16 00:34:09 +0100 253) 	.aborted	= afs_check_for_remote_deletion,
dc4191841d099 (David Howells     2020-09-18 09:11:15 +0100 254) 	.failed		= afs_fetch_data_notify,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 255) 	.put		= afs_fetch_data_put,
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 256) };
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 257) 
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 258) /*
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 259)  * Fetch file data from the volume.
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 260)  */
c69bf479baa61 (David Howells     2020-02-06 14:22:27 +0000 261) int afs_fetch_data(struct afs_vnode *vnode, struct afs_read *req)
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 262) {
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 263) 	struct afs_operation *op;
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 264) 
3b6492df4153b (David Howells     2018-10-20 00:57:57 +0100 265) 	_enter("%s{%llx:%llu.%u},%x,,,",
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 266) 	       vnode->volume->name,
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 267) 	       vnode->fid.vid,
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 268) 	       vnode->fid.vnode,
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 269) 	       vnode->fid.unique,
c69bf479baa61 (David Howells     2020-02-06 14:22:27 +0000 270) 	       key_serial(req->key));
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 271) 
c69bf479baa61 (David Howells     2020-02-06 14:22:27 +0000 272) 	op = afs_alloc_operation(req->key, vnode->volume);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 273) 	if (IS_ERR(op)) {
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 274) 		if (req->subreq)
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 275) 			netfs_subreq_terminated(req->subreq, PTR_ERR(op), false);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 276) 		return PTR_ERR(op);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 277) 	}
a58823ac45896 (David Howells     2019-05-09 15:16:10 +0100 278) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 279) 	afs_op_set_vnode(op, 0, vnode);
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 280) 
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 281) 	op->fetch.req	= afs_get_read(req);
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 282) 	op->ops		= &afs_fetch_data_operation;
e49c7b2f6de7f (David Howells     2020-04-10 20:51:51 +0100 283) 	return afs_do_sync_operation(op);
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 284) }
d2ddc776a4581 (David Howells     2017-11-02 15:27:50 +0000 285) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 286) static void afs_req_issue_op(struct netfs_read_subrequest *subreq)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 287) {
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 288) 	struct afs_vnode *vnode = AFS_FS_I(subreq->rreq->inode);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 289) 	struct afs_read *fsreq;
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 290) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 291) 	fsreq = afs_alloc_read(GFP_NOFS);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 292) 	if (!fsreq)
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 293) 		return netfs_subreq_terminated(subreq, -ENOMEM, false);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 294) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 295) 	fsreq->subreq	= subreq;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 296) 	fsreq->pos	= subreq->start + subreq->transferred;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 297) 	fsreq->len	= subreq->len   - subreq->transferred;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 298) 	fsreq->key	= subreq->rreq->netfs_priv;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 299) 	fsreq->vnode	= vnode;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 300) 	fsreq->iter	= &fsreq->def_iter;
03ffae909278b (David Howells     2020-02-10 10:00:22 +0000 301) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 302) 	iov_iter_xarray(&fsreq->def_iter, READ,
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 303) 			&fsreq->vnode->vfs_inode.i_mapping->i_pages,
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 304) 			fsreq->pos, fsreq->len);
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 305) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 306) 	afs_fetch_data(fsreq->vnode, fsreq);
ec26815ad847d (David Howells     2007-04-26 15:49:28 -0700 307) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 308) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 309) static int afs_symlink_readpage(struct page *page)
f6d335c08df48 (Al Viro           2010-05-21 15:27:09 +0100 310) {
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 311) 	struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 312) 	struct afs_read *fsreq;
f6d335c08df48 (Al Viro           2010-05-21 15:27:09 +0100 313) 	int ret;
f6d335c08df48 (Al Viro           2010-05-21 15:27:09 +0100 314) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 315) 	fsreq = afs_alloc_read(GFP_NOFS);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 316) 	if (!fsreq)
91b467e0a3f5f (David Howells     2017-01-05 10:38:35 +0000 317) 		return -ENOMEM;
91b467e0a3f5f (David Howells     2017-01-05 10:38:35 +0000 318) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 319) 	fsreq->pos	= page->index * PAGE_SIZE;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 320) 	fsreq->len	= PAGE_SIZE;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 321) 	fsreq->vnode	= vnode;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 322) 	fsreq->iter	= &fsreq->def_iter;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 323) 	iov_iter_xarray(&fsreq->def_iter, READ, &page->mapping->i_pages,
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 324) 			fsreq->pos, fsreq->len);
c450846461f88 (David Howells     2020-02-06 14:22:28 +0000 325) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 326) 	ret = afs_fetch_data(fsreq->vnode, fsreq);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 327) 	page_endio(page, false, ret);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 328) 	return ret;
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 329) }
91b467e0a3f5f (David Howells     2017-01-05 10:38:35 +0000 330) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 331) static void afs_init_rreq(struct netfs_read_request *rreq, struct file *file)
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 332) {
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 333) 	rreq->netfs_priv = key_get(afs_file_key(file));
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 334) }
91b467e0a3f5f (David Howells     2017-01-05 10:38:35 +0000 335) 
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 336) static bool afs_is_cache_enabled(struct inode *inode)
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 337) {
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 338) 	struct fscache_cookie *cookie = afs_vnode_cache(AFS_FS_I(inode));
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 339) 
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 340) 	return fscache_cookie_enabled(cookie) && !hlist_empty(&cookie->backing_objects);
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 341) }
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 342) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 343) static int afs_begin_cache_operation(struct netfs_read_request *rreq)
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 344) {
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 345) 	struct afs_vnode *vnode = AFS_FS_I(rreq->inode);
91b467e0a3f5f (David Howells     2017-01-05 10:38:35 +0000 346) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 347) 	return fscache_begin_read_operation(rreq, afs_vnode_cache(vnode));
91b467e0a3f5f (David Howells     2017-01-05 10:38:35 +0000 348) }
91b467e0a3f5f (David Howells     2017-01-05 10:38:35 +0000 349) 
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 350) static int afs_check_write_begin(struct file *file, loff_t pos, unsigned len,
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 351) 				 struct page *page, void **_fsdata)
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 352) {
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 353) 	struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 354) 
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 355) 	return test_bit(AFS_VNODE_DELETED, &vnode->flags) ? -ESTALE : 0;
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 356) }
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 357) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 358) static void afs_priv_cleanup(struct address_space *mapping, void *netfs_priv)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 359) {
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 360) 	key_put(netfs_priv);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 361) }
f6d335c08df48 (Al Viro           2010-05-21 15:27:09 +0100 362) 
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 363) const struct netfs_read_request_ops afs_req_ops = {
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 364) 	.init_rreq		= afs_init_rreq,
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 365) 	.is_cache_enabled	= afs_is_cache_enabled,
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 366) 	.begin_cache_operation	= afs_begin_cache_operation,
3003bbd0697b6 (David Howells     2020-02-06 14:22:29 +0000 367) 	.check_write_begin	= afs_check_write_begin,
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 368) 	.issue_op		= afs_req_issue_op,
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 369) 	.cleanup		= afs_priv_cleanup,
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 370) };
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 371) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 372) static int afs_readpage(struct file *file, struct page *page)
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 373) {
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 374) 	if (!file)
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 375) 		return afs_symlink_readpage(page);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 376) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 377) 	return netfs_readpage(file, page, &afs_req_ops, NULL);
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 378) }
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 379) 
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 380) static void afs_readahead(struct readahead_control *ractl)
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 381) {
5cbf03985c67c (David Howells     2020-02-06 14:22:29 +0000 382) 	netfs_readahead(ractl, &afs_req_ops, NULL);
ec26815ad847d (David Howells     2007-04-26 15:49:28 -0700 383) }
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 384) 
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 385) /*
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 386)  * Adjust the dirty region of the page on truncation or full invalidation,
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 387)  * getting rid of the markers altogether if the region is entirely invalidated.
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 388)  */
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 389) static void afs_invalidate_dirty(struct page *page, unsigned int offset,
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 390) 				 unsigned int length)
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 391) {
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 392) 	struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 393) 	unsigned long priv;
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 394) 	unsigned int f, t, end = offset + length;
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 395) 
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 396) 	priv = page_private(page);
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 397) 
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 398) 	/* we clean up only if the entire page is being invalidated */
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 399) 	if (offset == 0 && length == thp_size(page))
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 400) 		goto full_invalidate;
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 401) 
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 402) 	 /* If the page was dirtied by page_mkwrite(), the PTE stays writable
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 403) 	  * and we don't get another notification to tell us to expand it
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 404) 	  * again.
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 405) 	  */
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 406) 	if (afs_is_page_dirty_mmapped(priv))
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 407) 		return;
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 408) 
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 409) 	/* We may need to shorten the dirty region */
67d78a6f6e7b3 (David Howells     2020-10-28 14:23:46 +0000 410) 	f = afs_page_dirty_from(page, priv);
67d78a6f6e7b3 (David Howells     2020-10-28 14:23:46 +0000 411) 	t = afs_page_dirty_to(page, priv);
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 412) 
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 413) 	if (t <= offset || f >= end)
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 414) 		return; /* Doesn't overlap */
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 415) 
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 416) 	if (f < offset && t > end)
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 417) 		return; /* Splits the dirty region - just absorb it */
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 418) 
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 419) 	if (f >= offset && t <= end)
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 420) 		goto undirty;
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 421) 
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 422) 	if (f < offset)
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 423) 		t = offset;
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 424) 	else
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 425) 		f = end;
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 426) 	if (f == t)
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 427) 		goto undirty;
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 428) 
67d78a6f6e7b3 (David Howells     2020-10-28 14:23:46 +0000 429) 	priv = afs_page_dirty(page, f, t);
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 430) 	set_page_private(page, priv);
67d78a6f6e7b3 (David Howells     2020-10-28 14:23:46 +0000 431) 	trace_afs_page_dirty(vnode, tracepoint_string("trunc"), page);
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 432) 	return;
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 433) 
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 434) undirty:
67d78a6f6e7b3 (David Howells     2020-10-28 14:23:46 +0000 435) 	trace_afs_page_dirty(vnode, tracepoint_string("undirty"), page);
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 436) 	clear_page_dirty_for_io(page);
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 437) full_invalidate:
67d78a6f6e7b3 (David Howells     2020-10-28 14:23:46 +0000 438) 	trace_afs_page_dirty(vnode, tracepoint_string("inval"), page);
e87b03f5830ec (David Howells     2020-10-20 09:33:45 +0100 439) 	detach_page_private(page);
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 440) }
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 441) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 442) /*
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 443)  * invalidate part or all of a page
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 444)  * - release a page and clean up its private data if offset is 0 (indicating
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 445)  *   the entire page)
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 446)  */
d47992f86b307 (Lukas Czerner     2013-05-21 23:17:23 -0400 447) static void afs_invalidatepage(struct page *page, unsigned int offset,
d47992f86b307 (Lukas Czerner     2013-05-21 23:17:23 -0400 448) 			       unsigned int length)
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 449) {
d47992f86b307 (Lukas Czerner     2013-05-21 23:17:23 -0400 450) 	_enter("{%lu},%u,%u", page->index, offset, length);
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 451) 
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 452) 	BUG_ON(!PageLocked(page));
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 453) 
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 454) 	if (PagePrivate(page))
f86726a69dec5 (David Howells     2020-10-22 14:08:23 +0100 455) 		afs_invalidate_dirty(page, offset, length);
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 456) 
630f5dda8442c (David Howells     2020-02-06 14:22:28 +0000 457) 	wait_on_page_fscache(page);
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 458) 	_leave("");
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 459) }
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 460) 
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 461) /*
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 462)  * release a page and clean up its private state if it's not busy
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 463)  * - return true if the page can now be released, false if not
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 464)  */
416351f28d2b3 (David Howells     2007-05-09 02:33:45 -0700 465) static int afs_releasepage(struct page *page, gfp_t gfp_flags)
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 466) {
416351f28d2b3 (David Howells     2007-05-09 02:33:45 -0700 467) 	struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 468) 
3b6492df4153b (David Howells     2018-10-20 00:57:57 +0100 469) 	_enter("{{%llx:%llu}[%lu],%lx},%x",
416351f28d2b3 (David Howells     2007-05-09 02:33:45 -0700 470) 	       vnode->fid.vid, vnode->fid.vnode, page->index, page->flags,
416351f28d2b3 (David Howells     2007-05-09 02:33:45 -0700 471) 	       gfp_flags);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 472) 
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 473) 	/* deny if page is being written to the cache and the caller hasn't
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 474) 	 * elected to wait */
630f5dda8442c (David Howells     2020-02-06 14:22:28 +0000 475) #ifdef CONFIG_AFS_FSCACHE
630f5dda8442c (David Howells     2020-02-06 14:22:28 +0000 476) 	if (PageFsCache(page)) {
630f5dda8442c (David Howells     2020-02-06 14:22:28 +0000 477) 		if (!(gfp_flags & __GFP_DIRECT_RECLAIM) || !(gfp_flags & __GFP_FS))
630f5dda8442c (David Howells     2020-02-06 14:22:28 +0000 478) 			return false;
630f5dda8442c (David Howells     2020-02-06 14:22:28 +0000 479) 		wait_on_page_fscache(page);
630f5dda8442c (David Howells     2020-02-06 14:22:28 +0000 480) 	}
630f5dda8442c (David Howells     2020-02-06 14:22:28 +0000 481) #endif
630f5dda8442c (David Howells     2020-02-06 14:22:28 +0000 482) 
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 483) 	if (PagePrivate(page)) {
67d78a6f6e7b3 (David Howells     2020-10-28 14:23:46 +0000 484) 		trace_afs_page_dirty(vnode, tracepoint_string("rel"), page);
e87b03f5830ec (David Howells     2020-10-20 09:33:45 +0100 485) 		detach_page_private(page);
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 486) 	}
^1da177e4c3f4 (Linus Torvalds    2005-04-16 15:20:36 -0700 487) 
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 488) 	/* indicate that the page can be released */
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 489) 	_leave(" = T");
9b3f26c9110dc (David Howells     2009-04-03 16:42:41 +0100 490) 	return 1;
ec26815ad847d (David Howells     2007-04-26 15:49:28 -0700 491) }
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 492) 
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 493) /*
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 494)  * Handle setting up a memory mapping on an AFS file.
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 495)  */
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 496) static int afs_file_mmap(struct file *file, struct vm_area_struct *vma)
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 497) {
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 498) 	int ret;
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 499) 
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 500) 	ret = generic_file_mmap(file, vma);
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 501) 	if (ret == 0)
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 502) 		vma->vm_ops = &afs_vm_ops;
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 503) 	return ret;
1cf7a1518aefa (David Howells     2017-11-02 15:27:52 +0000 504) }