Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2)  * Copyright (c) 2002, 2007 Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * This software may be freely redistributed under the terms of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * GNU General Public License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * You should have received a copy of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * along with this program; if not, write to the Free Software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Authors: David Woodhouse <dwmw2@infradead.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  *          David Howells <dhowells@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/circ_buf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * Allow the fileserver to request callback state (re-)initialisation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * Unfortunately, UUIDs are not guaranteed unique.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) void afs_init_callback_state(struct afs_server *server)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		server->cb_s_break++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		server = rcu_dereference(server->uuid_next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	} while (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38)  * actually break a callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) void __afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	clear_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (test_and_clear_bit(AFS_VNODE_CB_PROMISED, &vnode->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		vnode->cb_break++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		afs_clear_permits(vnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		if (vnode->lock_state == AFS_VNODE_LOCK_WAITING_FOR_CB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 			afs_lock_may_be_available(vnode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		trace_afs_cb_break(&vnode->fid, vnode->cb_break, reason, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) void afs_break_callback(struct afs_vnode *vnode, enum afs_cb_break_reason reason)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	write_seqlock(&vnode->cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	__afs_break_callback(vnode, reason);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	write_sequnlock(&vnode->cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * Look up a volume by volume ID under RCU conditions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) static struct afs_volume *afs_lookup_volume_rcu(struct afs_cell *cell,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 						afs_volid_t vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	struct afs_volume *volume = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	struct rb_node *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	int seq = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		/* Unfortunately, rbtree walking doesn't give reliable results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		 * under just the RCU read lock, so we have to check for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		 * changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		read_seqbegin_or_lock(&cell->volume_lock, &seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		p = rcu_dereference_raw(cell->volumes.rb_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		while (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 			volume = rb_entry(p, struct afs_volume, cell_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			if (volume->vid < vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 				p = rcu_dereference_raw(p->rb_left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			else if (volume->vid > vid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 				p = rcu_dereference_raw(p->rb_right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			volume = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	} while (need_seqretry(&cell->volume_lock, seq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	done_seqretry(&cell->volume_lock, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	return volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  * allow the fileserver to explicitly break one callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  * - happens when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  *   - the backing file is changed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  *   - a lock is released
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void afs_break_one_callback(struct afs_volume *volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 				   struct afs_fid *fid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	struct super_block *sb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	struct afs_vnode *vnode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	struct inode *inode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (fid->vnode == 0 && fid->unique == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		/* The callback break applies to an entire volume. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		write_lock(&volume->cb_v_break_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		volume->cb_v_break++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		trace_afs_cb_break(fid, volume->cb_v_break,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 				   afs_cb_break_for_volume_callback, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		write_unlock(&volume->cb_v_break_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	/* See if we can find a matching inode - even an I_NEW inode needs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	 * be marked as it can have its callback broken before we finish
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	 * setting up the local inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	sb = rcu_dereference(volume->sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	if (!sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	inode = find_inode_rcu(sb, fid->vnode, afs_ilookup5_test_by_fid, fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	if (inode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		vnode = AFS_FS_I(inode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		afs_break_callback(vnode, afs_cb_break_for_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		trace_afs_cb_miss(fid, afs_cb_break_for_callback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static void afs_break_some_callbacks(struct afs_server *server,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 				     struct afs_callback_break *cbb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 				     size_t *_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	struct afs_callback_break *residue = cbb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	struct afs_volume *volume;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	afs_volid_t vid = cbb->fid.vid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	volume = afs_lookup_volume_rcu(server->cell, vid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	/* TODO: Find all matching volumes if we couldn't match the server and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	 * break them anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	for (i = *_count; i > 0; cbb++, i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		if (cbb->fid.vid == vid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			_debug("- Fid { vl=%08llx n=%llu u=%u }",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 			       cbb->fid.vid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			       cbb->fid.vnode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			       cbb->fid.unique);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			--*_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 			if (volume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 				afs_break_one_callback(volume, &cbb->fid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 			*residue++ = *cbb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)  * allow the fileserver to break callback promises
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) void afs_break_callbacks(struct afs_server *server, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			 struct afs_callback_break *callbacks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	_enter("%p,%zu,", server, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	ASSERT(server != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	while (count > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		afs_break_some_callbacks(server, callbacks, &count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }