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) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* Global fscache object list maintainer and viewer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #define FSCACHE_DEBUG_LEVEL COOKIE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/proc_fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/key.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <keys/user-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) static struct rb_root fscache_object_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) static DEFINE_RWLOCK(fscache_object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) struct fscache_objlist_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	unsigned long	config;		/* display configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define FSCACHE_OBJLIST_CONFIG_KEY	0x00000001	/* show object keys */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define FSCACHE_OBJLIST_CONFIG_AUX	0x00000002	/* show object auxdata */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define FSCACHE_OBJLIST_CONFIG_COOKIE	0x00000004	/* show objects with cookies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define FSCACHE_OBJLIST_CONFIG_NOCOOKIE	0x00000008	/* show objects without cookies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define FSCACHE_OBJLIST_CONFIG_BUSY	0x00000010	/* show busy objects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define FSCACHE_OBJLIST_CONFIG_IDLE	0x00000020	/* show idle objects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define FSCACHE_OBJLIST_CONFIG_PENDWR	0x00000040	/* show objects with pending writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define FSCACHE_OBJLIST_CONFIG_NOPENDWR	0x00000080	/* show objects without pending writes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define FSCACHE_OBJLIST_CONFIG_READS	0x00000100	/* show objects with active reads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define FSCACHE_OBJLIST_CONFIG_NOREADS	0x00000200	/* show objects without active reads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define FSCACHE_OBJLIST_CONFIG_EVENTS	0x00000400	/* show objects with events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define FSCACHE_OBJLIST_CONFIG_NOEVENTS	0x00000800	/* show objects without no events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define FSCACHE_OBJLIST_CONFIG_WORK	0x00001000	/* show objects with work */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define FSCACHE_OBJLIST_CONFIG_NOWORK	0x00002000	/* show objects without work */
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39)  * Add an object to the object list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * - we use the address of the fscache_object structure as the key into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  *   tree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) void fscache_objlist_add(struct fscache_object *obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	struct fscache_object *xobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	struct rb_node **p = &fscache_object_list.rb_node, *parent = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	ASSERT(RB_EMPTY_NODE(&obj->objlist_link));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	write_lock(&fscache_object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	while (*p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		parent = *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		xobj = rb_entry(parent, struct fscache_object, objlist_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		if (obj < xobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 			p = &(*p)->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		else if (obj > xobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			p = &(*p)->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	rb_link_node(&obj->objlist_link, parent, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	rb_insert_color(&obj->objlist_link, &fscache_object_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	write_unlock(&fscache_object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  * Remove an object from the object list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) void fscache_objlist_remove(struct fscache_object *obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	if (RB_EMPTY_NODE(&obj->objlist_link))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	write_lock(&fscache_object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	BUG_ON(RB_EMPTY_ROOT(&fscache_object_list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	rb_erase(&obj->objlist_link, &fscache_object_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	write_unlock(&fscache_object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)  * find the object in the tree on or after the specified index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) static struct fscache_object *fscache_objlist_lookup(loff_t *_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	struct fscache_object *pobj, *obj = NULL, *minobj = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	struct rb_node *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	unsigned long pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (*_pos >= (unsigned long) ERR_PTR(-ENOENT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	pos = *_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	/* banners (can't represent line 0 by pos 0 as that would involve
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	 * returning a NULL pointer) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	if (pos == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		return (struct fscache_object *)(long)++(*_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (pos < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		return (struct fscache_object *)pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	pobj = (struct fscache_object *)pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	p = fscache_object_list.rb_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	while (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		obj = rb_entry(p, struct fscache_object, objlist_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		if (pobj < obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 			if (!minobj || minobj > obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 				minobj = obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 			p = p->rb_left;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		} else if (pobj > obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			p = p->rb_right;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 			minobj = obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		obj = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (!minobj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		*_pos = (unsigned long) ERR_PTR(-ENOENT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	else if (minobj != obj)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		*_pos = (unsigned long) minobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	return minobj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)  * set up the iterator to start reading from the first line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static void *fscache_objlist_start(struct seq_file *m, loff_t *_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	__acquires(&fscache_object_list_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	read_lock(&fscache_object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	return fscache_objlist_lookup(_pos);
^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)  * move to the next line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static void *fscache_objlist_next(struct seq_file *m, void *v, loff_t *_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	(*_pos)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	return fscache_objlist_lookup(_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  * clean up after reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) static void fscache_objlist_stop(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	__releases(&fscache_object_list_lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	read_unlock(&fscache_object_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)  * display an object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) static int fscache_objlist_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	struct fscache_objlist_data *data = m->private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	struct fscache_object *obj = v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	struct fscache_cookie *cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	unsigned long config = data->config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	char _type[3], *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	u8 *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	if ((unsigned long) v == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		seq_puts(m, "OBJECT   PARENT   STAT CHLDN OPS OOP IPR EX READS"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 			 " EM EV FL S"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			 " | NETFS_COOKIE_DEF TY FL NETFS_DATA");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		if (config & (FSCACHE_OBJLIST_CONFIG_KEY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 			      FSCACHE_OBJLIST_CONFIG_AUX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 			seq_puts(m, "       ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		if (config & FSCACHE_OBJLIST_CONFIG_KEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 			seq_puts(m, "OBJECT_KEY");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		if ((config & (FSCACHE_OBJLIST_CONFIG_KEY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 			       FSCACHE_OBJLIST_CONFIG_AUX)) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		    (FSCACHE_OBJLIST_CONFIG_KEY | FSCACHE_OBJLIST_CONFIG_AUX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 			seq_puts(m, ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		if (config & FSCACHE_OBJLIST_CONFIG_AUX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 			seq_puts(m, "AUX_DATA");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		seq_puts(m, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	if ((unsigned long) v == 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		seq_puts(m, "======== ======== ==== ===== === === === == ====="
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 			 " == == == ="
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 			 " | ================ == == ================");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 		if (config & (FSCACHE_OBJLIST_CONFIG_KEY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			      FSCACHE_OBJLIST_CONFIG_AUX))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			seq_puts(m, " ================");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		seq_puts(m, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	/* filter out any unwanted objects */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) #define FILTER(criterion, _yes, _no)					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	do {								\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		unsigned long yes = FSCACHE_OBJLIST_CONFIG_##_yes;	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		unsigned long no = FSCACHE_OBJLIST_CONFIG_##_no;	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		if (criterion) {					\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 			if (!(config & yes))				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 				return 0;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		} else {						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 			if (!(config & no))				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 				return 0;				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		}							\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	} while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	cookie = obj->cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	if (~config) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		FILTER(cookie->def,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		       COOKIE, NOCOOKIE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		FILTER(fscache_object_is_active(obj) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		       obj->n_ops != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		       obj->n_obj_ops != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		       obj->flags ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		       !list_empty(&obj->dependents),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		       BUSY, IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		FILTER(test_bit(FSCACHE_OBJECT_PENDING_WRITE, &obj->flags),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		       PENDWR, NOPENDWR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		FILTER(atomic_read(&obj->n_reads),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		       READS, NOREADS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		FILTER(obj->events & obj->event_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 		       EVENTS, NOEVENTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		FILTER(work_busy(&obj->work), WORK, NOWORK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 		   "%8x %8x %s %5u %3u %3u %3u %2u %5u %2lx %2lx %2lx %1x | ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		   obj->debug_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		   obj->parent ? obj->parent->debug_id : -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		   obj->state->short_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		   obj->n_children,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		   obj->n_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		   obj->n_obj_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		   obj->n_in_progress,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		   obj->n_exclusive,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		   atomic_read(&obj->n_reads),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		   obj->event_mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		   obj->events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 		   obj->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		   work_busy(&obj->work));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	if (fscache_use_cookie(obj)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		uint16_t keylen = 0, auxlen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		switch (cookie->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 			type = "IX";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 			type = "DT";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 			snprintf(_type, sizeof(_type), "%02u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 				 cookie->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 			type = _type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		seq_printf(m, "%-16s %s %2lx %16p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 			   cookie->def->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 			   type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			   cookie->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 			   cookie->netfs_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		if (config & FSCACHE_OBJLIST_CONFIG_KEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 			keylen = cookie->key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		if (config & FSCACHE_OBJLIST_CONFIG_AUX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 			auxlen = cookie->aux_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		if (keylen > 0 || auxlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			seq_puts(m, " ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			p = keylen <= sizeof(cookie->inline_key) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 				cookie->inline_key : cookie->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 			for (; keylen > 0; keylen--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 				seq_printf(m, "%02x", *p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			if (auxlen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 				if (config & FSCACHE_OBJLIST_CONFIG_KEY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 					seq_puts(m, ", ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 				p = auxlen <= sizeof(cookie->inline_aux) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 					cookie->inline_aux : cookie->aux;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 				for (; auxlen > 0; auxlen--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 					seq_printf(m, "%02x", *p++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		seq_puts(m, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		fscache_unuse_cookie(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		seq_puts(m, "<no_netfs>\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static const struct seq_operations fscache_objlist_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	.start		= fscache_objlist_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	.stop		= fscache_objlist_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	.next		= fscache_objlist_next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	.show		= fscache_objlist_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)  * get the configuration for filtering the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) static void fscache_objlist_config(struct fscache_objlist_data *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) #ifdef CONFIG_KEYS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	const struct user_key_payload *confkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	unsigned long config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	struct key *key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	const char *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	key = request_key(&key_type_user, "fscache:objlist", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	if (IS_ERR(key))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		goto no_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	config = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	confkey = user_key_payload_rcu(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	if (!confkey) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		/* key was revoked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		key_put(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		goto no_config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	buf = confkey->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	for (len = confkey->datalen - 1; len >= 0; len--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		switch (buf[len]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		case 'K': config |= FSCACHE_OBJLIST_CONFIG_KEY;		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 		case 'A': config |= FSCACHE_OBJLIST_CONFIG_AUX;		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		case 'C': config |= FSCACHE_OBJLIST_CONFIG_COOKIE;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		case 'c': config |= FSCACHE_OBJLIST_CONFIG_NOCOOKIE;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		case 'B': config |= FSCACHE_OBJLIST_CONFIG_BUSY;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		case 'b': config |= FSCACHE_OBJLIST_CONFIG_IDLE;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		case 'W': config |= FSCACHE_OBJLIST_CONFIG_PENDWR;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		case 'w': config |= FSCACHE_OBJLIST_CONFIG_NOPENDWR;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		case 'R': config |= FSCACHE_OBJLIST_CONFIG_READS;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		case 'r': config |= FSCACHE_OBJLIST_CONFIG_NOREADS;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		case 'S': config |= FSCACHE_OBJLIST_CONFIG_WORK;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		case 's': config |= FSCACHE_OBJLIST_CONFIG_NOWORK;	break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 	key_put(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	if (!(config & (FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	    config   |= FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (!(config & (FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	    config   |= FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	if (!(config & (FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	    config   |= FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	if (!(config & (FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	    config   |= FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	if (!(config & (FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	    config   |= FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	if (!(config & (FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	    config   |= FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	data->config = config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) no_config:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	data->config = ULONG_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)  * open "/proc/fs/fscache/objects" to provide a list of active objects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)  * - can be configured by a user-defined key added to the caller's keyrings
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static int fscache_objlist_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	struct fscache_objlist_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	data = __seq_open_private(file, &fscache_objlist_ops, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	/* get the configuration key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	fscache_objlist_config(data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)  * clean up on close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) static int fscache_objlist_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 	struct seq_file *m = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	kfree(m->private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	m->private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	return seq_release(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) const struct proc_ops fscache_objlist_proc_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	.proc_open	= fscache_objlist_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	.proc_read	= seq_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	.proc_lseek	= seq_lseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	.proc_release	= fscache_objlist_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) };