xref: /OK3568_Linux_fs/kernel/fs/configfs/inode.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /* -*- mode: c; c-basic-offset: 8; -*-
3*4882a593Smuzhiyun  * vim: noexpandtab sw=8 ts=8 sts=0:
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * inode.c - basic inode and dentry operations.
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Based on sysfs:
8*4882a593Smuzhiyun  * 	sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * configfs Copyright (C) 2005 Oracle.  All rights reserved.
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * Please see Documentation/filesystems/configfs.rst for more
13*4882a593Smuzhiyun  * information.
14*4882a593Smuzhiyun  */
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #undef DEBUG
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include <linux/pagemap.h>
19*4882a593Smuzhiyun #include <linux/namei.h>
20*4882a593Smuzhiyun #include <linux/backing-dev.h>
21*4882a593Smuzhiyun #include <linux/capability.h>
22*4882a593Smuzhiyun #include <linux/sched.h>
23*4882a593Smuzhiyun #include <linux/lockdep.h>
24*4882a593Smuzhiyun #include <linux/slab.h>
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #include <linux/configfs.h>
27*4882a593Smuzhiyun #include "configfs_internal.h"
28*4882a593Smuzhiyun 
29*4882a593Smuzhiyun #ifdef CONFIG_LOCKDEP
30*4882a593Smuzhiyun static struct lock_class_key default_group_class[MAX_LOCK_DEPTH];
31*4882a593Smuzhiyun #endif
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun static const struct address_space_operations configfs_aops = {
34*4882a593Smuzhiyun 	.readpage	= simple_readpage,
35*4882a593Smuzhiyun 	.write_begin	= simple_write_begin,
36*4882a593Smuzhiyun 	.write_end	= simple_write_end,
37*4882a593Smuzhiyun };
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun static const struct inode_operations configfs_inode_operations ={
40*4882a593Smuzhiyun 	.setattr	= configfs_setattr,
41*4882a593Smuzhiyun };
42*4882a593Smuzhiyun 
configfs_setattr(struct dentry * dentry,struct iattr * iattr)43*4882a593Smuzhiyun int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun 	struct inode * inode = d_inode(dentry);
46*4882a593Smuzhiyun 	struct configfs_dirent * sd = dentry->d_fsdata;
47*4882a593Smuzhiyun 	struct iattr * sd_iattr;
48*4882a593Smuzhiyun 	unsigned int ia_valid = iattr->ia_valid;
49*4882a593Smuzhiyun 	int error;
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 	if (!sd)
52*4882a593Smuzhiyun 		return -EINVAL;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun 	sd_iattr = sd->s_iattr;
55*4882a593Smuzhiyun 	if (!sd_iattr) {
56*4882a593Smuzhiyun 		/* setting attributes for the first time, allocate now */
57*4882a593Smuzhiyun 		sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
58*4882a593Smuzhiyun 		if (!sd_iattr)
59*4882a593Smuzhiyun 			return -ENOMEM;
60*4882a593Smuzhiyun 		/* assign default attributes */
61*4882a593Smuzhiyun 		sd_iattr->ia_mode = sd->s_mode;
62*4882a593Smuzhiyun 		sd_iattr->ia_uid = GLOBAL_ROOT_UID;
63*4882a593Smuzhiyun 		sd_iattr->ia_gid = GLOBAL_ROOT_GID;
64*4882a593Smuzhiyun 		sd_iattr->ia_atime = sd_iattr->ia_mtime =
65*4882a593Smuzhiyun 			sd_iattr->ia_ctime = current_time(inode);
66*4882a593Smuzhiyun 		sd->s_iattr = sd_iattr;
67*4882a593Smuzhiyun 	}
68*4882a593Smuzhiyun 	/* attributes were changed atleast once in past */
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun 	error = simple_setattr(dentry, iattr);
71*4882a593Smuzhiyun 	if (error)
72*4882a593Smuzhiyun 		return error;
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	if (ia_valid & ATTR_UID)
75*4882a593Smuzhiyun 		sd_iattr->ia_uid = iattr->ia_uid;
76*4882a593Smuzhiyun 	if (ia_valid & ATTR_GID)
77*4882a593Smuzhiyun 		sd_iattr->ia_gid = iattr->ia_gid;
78*4882a593Smuzhiyun 	if (ia_valid & ATTR_ATIME)
79*4882a593Smuzhiyun 		sd_iattr->ia_atime = iattr->ia_atime;
80*4882a593Smuzhiyun 	if (ia_valid & ATTR_MTIME)
81*4882a593Smuzhiyun 		sd_iattr->ia_mtime = iattr->ia_mtime;
82*4882a593Smuzhiyun 	if (ia_valid & ATTR_CTIME)
83*4882a593Smuzhiyun 		sd_iattr->ia_ctime = iattr->ia_ctime;
84*4882a593Smuzhiyun 	if (ia_valid & ATTR_MODE) {
85*4882a593Smuzhiyun 		umode_t mode = iattr->ia_mode;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun 		if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
88*4882a593Smuzhiyun 			mode &= ~S_ISGID;
89*4882a593Smuzhiyun 		sd_iattr->ia_mode = sd->s_mode = mode;
90*4882a593Smuzhiyun 	}
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	return error;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun 
set_default_inode_attr(struct inode * inode,umode_t mode)95*4882a593Smuzhiyun static inline void set_default_inode_attr(struct inode * inode, umode_t mode)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun 	inode->i_mode = mode;
98*4882a593Smuzhiyun 	inode->i_atime = inode->i_mtime =
99*4882a593Smuzhiyun 		inode->i_ctime = current_time(inode);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun 
set_inode_attr(struct inode * inode,struct iattr * iattr)102*4882a593Smuzhiyun static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
103*4882a593Smuzhiyun {
104*4882a593Smuzhiyun 	inode->i_mode = iattr->ia_mode;
105*4882a593Smuzhiyun 	inode->i_uid = iattr->ia_uid;
106*4882a593Smuzhiyun 	inode->i_gid = iattr->ia_gid;
107*4882a593Smuzhiyun 	inode->i_atime = iattr->ia_atime;
108*4882a593Smuzhiyun 	inode->i_mtime = iattr->ia_mtime;
109*4882a593Smuzhiyun 	inode->i_ctime = iattr->ia_ctime;
110*4882a593Smuzhiyun }
111*4882a593Smuzhiyun 
configfs_new_inode(umode_t mode,struct configfs_dirent * sd,struct super_block * s)112*4882a593Smuzhiyun struct inode *configfs_new_inode(umode_t mode, struct configfs_dirent *sd,
113*4882a593Smuzhiyun 				 struct super_block *s)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun 	struct inode * inode = new_inode(s);
116*4882a593Smuzhiyun 	if (inode) {
117*4882a593Smuzhiyun 		inode->i_ino = get_next_ino();
118*4882a593Smuzhiyun 		inode->i_mapping->a_ops = &configfs_aops;
119*4882a593Smuzhiyun 		inode->i_op = &configfs_inode_operations;
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 		if (sd->s_iattr) {
122*4882a593Smuzhiyun 			/* sysfs_dirent has non-default attributes
123*4882a593Smuzhiyun 			 * get them for the new inode from persistent copy
124*4882a593Smuzhiyun 			 * in sysfs_dirent
125*4882a593Smuzhiyun 			 */
126*4882a593Smuzhiyun 			set_inode_attr(inode, sd->s_iattr);
127*4882a593Smuzhiyun 		} else
128*4882a593Smuzhiyun 			set_default_inode_attr(inode, mode);
129*4882a593Smuzhiyun 	}
130*4882a593Smuzhiyun 	return inode;
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun #ifdef CONFIG_LOCKDEP
134*4882a593Smuzhiyun 
configfs_set_inode_lock_class(struct configfs_dirent * sd,struct inode * inode)135*4882a593Smuzhiyun static void configfs_set_inode_lock_class(struct configfs_dirent *sd,
136*4882a593Smuzhiyun 					  struct inode *inode)
137*4882a593Smuzhiyun {
138*4882a593Smuzhiyun 	int depth = sd->s_depth;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	if (depth > 0) {
141*4882a593Smuzhiyun 		if (depth <= ARRAY_SIZE(default_group_class)) {
142*4882a593Smuzhiyun 			lockdep_set_class(&inode->i_rwsem,
143*4882a593Smuzhiyun 					  &default_group_class[depth - 1]);
144*4882a593Smuzhiyun 		} else {
145*4882a593Smuzhiyun 			/*
146*4882a593Smuzhiyun 			 * In practice the maximum level of locking depth is
147*4882a593Smuzhiyun 			 * already reached. Just inform about possible reasons.
148*4882a593Smuzhiyun 			 */
149*4882a593Smuzhiyun 			pr_info("Too many levels of inodes for the locking correctness validator.\n");
150*4882a593Smuzhiyun 			pr_info("Spurious warnings may appear.\n");
151*4882a593Smuzhiyun 		}
152*4882a593Smuzhiyun 	}
153*4882a593Smuzhiyun }
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun #else /* CONFIG_LOCKDEP */
156*4882a593Smuzhiyun 
configfs_set_inode_lock_class(struct configfs_dirent * sd,struct inode * inode)157*4882a593Smuzhiyun static void configfs_set_inode_lock_class(struct configfs_dirent *sd,
158*4882a593Smuzhiyun 					  struct inode *inode)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun }
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun #endif /* CONFIG_LOCKDEP */
163*4882a593Smuzhiyun 
configfs_create(struct dentry * dentry,umode_t mode)164*4882a593Smuzhiyun struct inode *configfs_create(struct dentry *dentry, umode_t mode)
165*4882a593Smuzhiyun {
166*4882a593Smuzhiyun 	struct inode *inode = NULL;
167*4882a593Smuzhiyun 	struct configfs_dirent *sd;
168*4882a593Smuzhiyun 	struct inode *p_inode;
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	if (!dentry)
171*4882a593Smuzhiyun 		return ERR_PTR(-ENOENT);
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	if (d_really_is_positive(dentry))
174*4882a593Smuzhiyun 		return ERR_PTR(-EEXIST);
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	sd = dentry->d_fsdata;
177*4882a593Smuzhiyun 	inode = configfs_new_inode(mode, sd, dentry->d_sb);
178*4882a593Smuzhiyun 	if (!inode)
179*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
180*4882a593Smuzhiyun 
181*4882a593Smuzhiyun 	p_inode = d_inode(dentry->d_parent);
182*4882a593Smuzhiyun 	p_inode->i_mtime = p_inode->i_ctime = current_time(p_inode);
183*4882a593Smuzhiyun 	configfs_set_inode_lock_class(sd, inode);
184*4882a593Smuzhiyun 	return inode;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun /*
188*4882a593Smuzhiyun  * Get the name for corresponding element represented by the given configfs_dirent
189*4882a593Smuzhiyun  */
configfs_get_name(struct configfs_dirent * sd)190*4882a593Smuzhiyun const unsigned char * configfs_get_name(struct configfs_dirent *sd)
191*4882a593Smuzhiyun {
192*4882a593Smuzhiyun 	struct configfs_attribute *attr;
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	BUG_ON(!sd || !sd->s_element);
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	/* These always have a dentry, so use that */
197*4882a593Smuzhiyun 	if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK))
198*4882a593Smuzhiyun 		return sd->s_dentry->d_name.name;
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	if (sd->s_type & (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR)) {
201*4882a593Smuzhiyun 		attr = sd->s_element;
202*4882a593Smuzhiyun 		return attr->ca_name;
203*4882a593Smuzhiyun 	}
204*4882a593Smuzhiyun 	return NULL;
205*4882a593Smuzhiyun }
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun /*
209*4882a593Smuzhiyun  * Unhashes the dentry corresponding to given configfs_dirent
210*4882a593Smuzhiyun  * Called with parent inode's i_mutex held.
211*4882a593Smuzhiyun  */
configfs_drop_dentry(struct configfs_dirent * sd,struct dentry * parent)212*4882a593Smuzhiyun void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
213*4882a593Smuzhiyun {
214*4882a593Smuzhiyun 	struct dentry * dentry = sd->s_dentry;
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	if (dentry) {
217*4882a593Smuzhiyun 		spin_lock(&dentry->d_lock);
218*4882a593Smuzhiyun 		if (simple_positive(dentry)) {
219*4882a593Smuzhiyun 			dget_dlock(dentry);
220*4882a593Smuzhiyun 			__d_drop(dentry);
221*4882a593Smuzhiyun 			spin_unlock(&dentry->d_lock);
222*4882a593Smuzhiyun 			simple_unlink(d_inode(parent), dentry);
223*4882a593Smuzhiyun 		} else
224*4882a593Smuzhiyun 			spin_unlock(&dentry->d_lock);
225*4882a593Smuzhiyun 	}
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun 
configfs_hash_and_remove(struct dentry * dir,const char * name)228*4882a593Smuzhiyun void configfs_hash_and_remove(struct dentry * dir, const char * name)
229*4882a593Smuzhiyun {
230*4882a593Smuzhiyun 	struct configfs_dirent * sd;
231*4882a593Smuzhiyun 	struct configfs_dirent * parent_sd = dir->d_fsdata;
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	if (d_really_is_negative(dir))
234*4882a593Smuzhiyun 		/* no inode means this hasn't been made visible yet */
235*4882a593Smuzhiyun 		return;
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	inode_lock(d_inode(dir));
238*4882a593Smuzhiyun 	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
239*4882a593Smuzhiyun 		if (!sd->s_element)
240*4882a593Smuzhiyun 			continue;
241*4882a593Smuzhiyun 		if (!strcmp(configfs_get_name(sd), name)) {
242*4882a593Smuzhiyun 			spin_lock(&configfs_dirent_lock);
243*4882a593Smuzhiyun 			list_del_init(&sd->s_sibling);
244*4882a593Smuzhiyun 			spin_unlock(&configfs_dirent_lock);
245*4882a593Smuzhiyun 			configfs_drop_dentry(sd, dir);
246*4882a593Smuzhiyun 			configfs_put(sd);
247*4882a593Smuzhiyun 			break;
248*4882a593Smuzhiyun 		}
249*4882a593Smuzhiyun 	}
250*4882a593Smuzhiyun 	inode_unlock(d_inode(dir));
251*4882a593Smuzhiyun }
252