17063fbf2SJoel Becker /* -*- mode: c; c-basic-offset: 8; -*- 27063fbf2SJoel Becker * vim: noexpandtab sw=8 ts=8 sts=0: 37063fbf2SJoel Becker * 47063fbf2SJoel Becker * inode.c - basic inode and dentry operations. 57063fbf2SJoel Becker * 67063fbf2SJoel Becker * This program is free software; you can redistribute it and/or 77063fbf2SJoel Becker * modify it under the terms of the GNU General Public 87063fbf2SJoel Becker * License as published by the Free Software Foundation; either 97063fbf2SJoel Becker * version 2 of the License, or (at your option) any later version. 107063fbf2SJoel Becker * 117063fbf2SJoel Becker * This program is distributed in the hope that it will be useful, 127063fbf2SJoel Becker * but WITHOUT ANY WARRANTY; without even the implied warranty of 137063fbf2SJoel Becker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 147063fbf2SJoel Becker * General Public License for more details. 157063fbf2SJoel Becker * 167063fbf2SJoel Becker * You should have received a copy of the GNU General Public 177063fbf2SJoel Becker * License along with this program; if not, write to the 187063fbf2SJoel Becker * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 197063fbf2SJoel Becker * Boston, MA 021110-1307, USA. 207063fbf2SJoel Becker * 217063fbf2SJoel Becker * Based on sysfs: 227063fbf2SJoel Becker * sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel 237063fbf2SJoel Becker * 247063fbf2SJoel Becker * configfs Copyright (C) 2005 Oracle. All rights reserved. 257063fbf2SJoel Becker * 26395cf969SPaul Bolle * Please see Documentation/filesystems/configfs/configfs.txt for more 27395cf969SPaul Bolle * information. 287063fbf2SJoel Becker */ 297063fbf2SJoel Becker 307063fbf2SJoel Becker #undef DEBUG 317063fbf2SJoel Becker 327063fbf2SJoel Becker #include <linux/pagemap.h> 337063fbf2SJoel Becker #include <linux/namei.h> 347063fbf2SJoel Becker #include <linux/backing-dev.h> 353d0f89bbSJoel Becker #include <linux/capability.h> 36e8edc6e0SAlexey Dobriyan #include <linux/sched.h> 37e74cc06dSLouis Rilling #include <linux/lockdep.h> 385a0e3ad6STejun Heo #include <linux/slab.h> 397063fbf2SJoel Becker 407063fbf2SJoel Becker #include <linux/configfs.h> 417063fbf2SJoel Becker #include "configfs_internal.h" 427063fbf2SJoel Becker 43e74cc06dSLouis Rilling #ifdef CONFIG_LOCKDEP 44e74cc06dSLouis Rilling static struct lock_class_key default_group_class[MAX_LOCK_DEPTH]; 45e74cc06dSLouis Rilling #endif 46e74cc06dSLouis Rilling 47f5e54d6eSChristoph Hellwig static const struct address_space_operations configfs_aops = { 487063fbf2SJoel Becker .readpage = simple_readpage, 49800d15a5SNick Piggin .write_begin = simple_write_begin, 50800d15a5SNick Piggin .write_end = simple_write_end, 517063fbf2SJoel Becker }; 527063fbf2SJoel Becker 53754661f1SArjan van de Ven static const struct inode_operations configfs_inode_operations ={ 543d0f89bbSJoel Becker .setattr = configfs_setattr, 553d0f89bbSJoel Becker }; 563d0f89bbSJoel Becker 573d0f89bbSJoel Becker int configfs_setattr(struct dentry * dentry, struct iattr * iattr) 587063fbf2SJoel Becker { 592b0143b5SDavid Howells struct inode * inode = d_inode(dentry); 603d0f89bbSJoel Becker struct configfs_dirent * sd = dentry->d_fsdata; 613d0f89bbSJoel Becker struct iattr * sd_iattr; 623d0f89bbSJoel Becker unsigned int ia_valid = iattr->ia_valid; 633d0f89bbSJoel Becker int error; 643d0f89bbSJoel Becker 653d0f89bbSJoel Becker if (!sd) 663d0f89bbSJoel Becker return -EINVAL; 673d0f89bbSJoel Becker 683d0f89bbSJoel Becker sd_iattr = sd->s_iattr; 693d0f89bbSJoel Becker if (!sd_iattr) { 703d0f89bbSJoel Becker /* setting attributes for the first time, allocate now */ 71f8314dc6SPanagiotis Issaris sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL); 723d0f89bbSJoel Becker if (!sd_iattr) 733d0f89bbSJoel Becker return -ENOMEM; 743d0f89bbSJoel Becker /* assign default attributes */ 753d0f89bbSJoel Becker sd_iattr->ia_mode = sd->s_mode; 7669552c0cSEric W. Biederman sd_iattr->ia_uid = GLOBAL_ROOT_UID; 7769552c0cSEric W. Biederman sd_iattr->ia_gid = GLOBAL_ROOT_GID; 783d0f89bbSJoel Becker sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; 793d0f89bbSJoel Becker sd->s_iattr = sd_iattr; 803d0f89bbSJoel Becker } 813d0f89bbSJoel Becker /* attributes were changed atleast once in past */ 823d0f89bbSJoel Becker 8375de46b9SNick Piggin error = simple_setattr(dentry, iattr); 8475de46b9SNick Piggin if (error) 8575de46b9SNick Piggin return error; 8675de46b9SNick Piggin 873d0f89bbSJoel Becker if (ia_valid & ATTR_UID) 883d0f89bbSJoel Becker sd_iattr->ia_uid = iattr->ia_uid; 893d0f89bbSJoel Becker if (ia_valid & ATTR_GID) 903d0f89bbSJoel Becker sd_iattr->ia_gid = iattr->ia_gid; 913d0f89bbSJoel Becker if (ia_valid & ATTR_ATIME) 923d0f89bbSJoel Becker sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime, 933d0f89bbSJoel Becker inode->i_sb->s_time_gran); 943d0f89bbSJoel Becker if (ia_valid & ATTR_MTIME) 953d0f89bbSJoel Becker sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime, 963d0f89bbSJoel Becker inode->i_sb->s_time_gran); 973d0f89bbSJoel Becker if (ia_valid & ATTR_CTIME) 983d0f89bbSJoel Becker sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime, 993d0f89bbSJoel Becker inode->i_sb->s_time_gran); 1003d0f89bbSJoel Becker if (ia_valid & ATTR_MODE) { 1013d0f89bbSJoel Becker umode_t mode = iattr->ia_mode; 1023d0f89bbSJoel Becker 1033d0f89bbSJoel Becker if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) 1043d0f89bbSJoel Becker mode &= ~S_ISGID; 1053d0f89bbSJoel Becker sd_iattr->ia_mode = sd->s_mode = mode; 1063d0f89bbSJoel Becker } 1073d0f89bbSJoel Becker 1083d0f89bbSJoel Becker return error; 1093d0f89bbSJoel Becker } 1103d0f89bbSJoel Becker 11143947514SAl Viro static inline void set_default_inode_attr(struct inode * inode, umode_t mode) 1123d0f89bbSJoel Becker { 1137063fbf2SJoel Becker inode->i_mode = mode; 1143d0f89bbSJoel Becker inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 1153d0f89bbSJoel Becker } 1163d0f89bbSJoel Becker 1173d0f89bbSJoel Becker static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) 1183d0f89bbSJoel Becker { 1193d0f89bbSJoel Becker inode->i_mode = iattr->ia_mode; 1203d0f89bbSJoel Becker inode->i_uid = iattr->ia_uid; 1213d0f89bbSJoel Becker inode->i_gid = iattr->ia_gid; 1223d0f89bbSJoel Becker inode->i_atime = iattr->ia_atime; 1233d0f89bbSJoel Becker inode->i_mtime = iattr->ia_mtime; 1243d0f89bbSJoel Becker inode->i_ctime = iattr->ia_ctime; 1253d0f89bbSJoel Becker } 1263d0f89bbSJoel Becker 127b7c177fcSAl Viro struct inode *configfs_new_inode(umode_t mode, struct configfs_dirent *sd, 128b7c177fcSAl Viro struct super_block *s) 1293d0f89bbSJoel Becker { 130b7c177fcSAl Viro struct inode * inode = new_inode(s); 1313d0f89bbSJoel Becker if (inode) { 13285fe4025SChristoph Hellwig inode->i_ino = get_next_ino(); 1337063fbf2SJoel Becker inode->i_mapping->a_ops = &configfs_aops; 1343d0f89bbSJoel Becker inode->i_op = &configfs_inode_operations; 1353d0f89bbSJoel Becker 1363d0f89bbSJoel Becker if (sd->s_iattr) { 1373d0f89bbSJoel Becker /* sysfs_dirent has non-default attributes 1383d0f89bbSJoel Becker * get them for the new inode from persistent copy 1393d0f89bbSJoel Becker * in sysfs_dirent 1403d0f89bbSJoel Becker */ 1413d0f89bbSJoel Becker set_inode_attr(inode, sd->s_iattr); 1423d0f89bbSJoel Becker } else 1433d0f89bbSJoel Becker set_default_inode_attr(inode, mode); 1447063fbf2SJoel Becker } 1457063fbf2SJoel Becker return inode; 1467063fbf2SJoel Becker } 1477063fbf2SJoel Becker 148e74cc06dSLouis Rilling #ifdef CONFIG_LOCKDEP 149e74cc06dSLouis Rilling 150e74cc06dSLouis Rilling static void configfs_set_inode_lock_class(struct configfs_dirent *sd, 151e74cc06dSLouis Rilling struct inode *inode) 152e74cc06dSLouis Rilling { 153e74cc06dSLouis Rilling int depth = sd->s_depth; 154e74cc06dSLouis Rilling 155e74cc06dSLouis Rilling if (depth > 0) { 156e74cc06dSLouis Rilling if (depth <= ARRAY_SIZE(default_group_class)) { 157e74cc06dSLouis Rilling lockdep_set_class(&inode->i_mutex, 158e74cc06dSLouis Rilling &default_group_class[depth - 1]); 159e74cc06dSLouis Rilling } else { 160e74cc06dSLouis Rilling /* 161e74cc06dSLouis Rilling * In practice the maximum level of locking depth is 162e74cc06dSLouis Rilling * already reached. Just inform about possible reasons. 163e74cc06dSLouis Rilling */ 1641d88aa44SFabian Frederick pr_info("Too many levels of inodes for the locking correctness validator.\n"); 165c6686931SFabian Frederick pr_info("Spurious warnings may appear.\n"); 166e74cc06dSLouis Rilling } 167e74cc06dSLouis Rilling } 168e74cc06dSLouis Rilling } 169e74cc06dSLouis Rilling 170e74cc06dSLouis Rilling #else /* CONFIG_LOCKDEP */ 171e74cc06dSLouis Rilling 172e74cc06dSLouis Rilling static void configfs_set_inode_lock_class(struct configfs_dirent *sd, 173e74cc06dSLouis Rilling struct inode *inode) 174e74cc06dSLouis Rilling { 175e74cc06dSLouis Rilling } 176e74cc06dSLouis Rilling 177e74cc06dSLouis Rilling #endif /* CONFIG_LOCKDEP */ 178e74cc06dSLouis Rilling 179c88b1e70SAl Viro int configfs_create(struct dentry * dentry, umode_t mode, void (*init)(struct inode *)) 1807063fbf2SJoel Becker { 1817063fbf2SJoel Becker int error = 0; 1827063fbf2SJoel Becker struct inode *inode = NULL; 18316d13b59SAl Viro struct configfs_dirent *sd; 18416d13b59SAl Viro struct inode *p_inode; 1857063fbf2SJoel Becker 18616d13b59SAl Viro if (!dentry) 18716d13b59SAl Viro return -ENOENT; 18816d13b59SAl Viro 1892b0143b5SDavid Howells if (d_really_is_positive(dentry)) 19016d13b59SAl Viro return -EEXIST; 19116d13b59SAl Viro 19216d13b59SAl Viro sd = dentry->d_fsdata; 19316d13b59SAl Viro inode = configfs_new_inode(mode, sd, dentry->d_sb); 19416d13b59SAl Viro if (!inode) 19516d13b59SAl Viro return -ENOMEM; 19616d13b59SAl Viro 1972b0143b5SDavid Howells p_inode = d_inode(dentry->d_parent); 19816d13b59SAl Viro p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME; 19916d13b59SAl Viro configfs_set_inode_lock_class(sd, inode); 20016d13b59SAl Viro 201c88b1e70SAl Viro init(inode); 2027063fbf2SJoel Becker d_instantiate(dentry, inode); 2037063fbf2SJoel Becker if (S_ISDIR(mode) || S_ISLNK(mode)) 2047063fbf2SJoel Becker dget(dentry); /* pin link and directory dentries in core */ 2057063fbf2SJoel Becker return error; 2067063fbf2SJoel Becker } 2077063fbf2SJoel Becker 2087063fbf2SJoel Becker /* 2097063fbf2SJoel Becker * Get the name for corresponding element represented by the given configfs_dirent 2107063fbf2SJoel Becker */ 2117063fbf2SJoel Becker const unsigned char * configfs_get_name(struct configfs_dirent *sd) 2127063fbf2SJoel Becker { 2133d0f89bbSJoel Becker struct configfs_attribute *attr; 2147063fbf2SJoel Becker 2151a1974fdSEric Sesterhenn / snakebyte BUG_ON(!sd || !sd->s_element); 2167063fbf2SJoel Becker 2177063fbf2SJoel Becker /* These always have a dentry, so use that */ 2187063fbf2SJoel Becker if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK)) 2197063fbf2SJoel Becker return sd->s_dentry->d_name.name; 2207063fbf2SJoel Becker 22103607aceSPantelis Antoniou if (sd->s_type & (CONFIGFS_ITEM_ATTR | CONFIGFS_ITEM_BIN_ATTR)) { 2227063fbf2SJoel Becker attr = sd->s_element; 2233d0f89bbSJoel Becker return attr->ca_name; 2247063fbf2SJoel Becker } 2257063fbf2SJoel Becker return NULL; 2267063fbf2SJoel Becker } 2277063fbf2SJoel Becker 2287063fbf2SJoel Becker 2297063fbf2SJoel Becker /* 2307063fbf2SJoel Becker * Unhashes the dentry corresponding to given configfs_dirent 2311b1dcc1bSJes Sorensen * Called with parent inode's i_mutex held. 2327063fbf2SJoel Becker */ 2337063fbf2SJoel Becker void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent) 2347063fbf2SJoel Becker { 2357063fbf2SJoel Becker struct dentry * dentry = sd->s_dentry; 2367063fbf2SJoel Becker 2377063fbf2SJoel Becker if (dentry) { 2383d0f89bbSJoel Becker spin_lock(&dentry->d_lock); 239dc3f4198SAl Viro if (simple_positive(dentry)) { 240dc0474beSNick Piggin dget_dlock(dentry); 2417063fbf2SJoel Becker __d_drop(dentry); 2423d0f89bbSJoel Becker spin_unlock(&dentry->d_lock); 2432b0143b5SDavid Howells simple_unlink(d_inode(parent), dentry); 244b5c84bf6SNick Piggin } else 2453d0f89bbSJoel Becker spin_unlock(&dentry->d_lock); 2467063fbf2SJoel Becker } 2473d0f89bbSJoel Becker } 2487063fbf2SJoel Becker 2497063fbf2SJoel Becker void configfs_hash_and_remove(struct dentry * dir, const char * name) 2507063fbf2SJoel Becker { 2517063fbf2SJoel Becker struct configfs_dirent * sd; 2527063fbf2SJoel Becker struct configfs_dirent * parent_sd = dir->d_fsdata; 2537063fbf2SJoel Becker 2542b0143b5SDavid Howells if (d_really_is_negative(dir)) 2553d0f89bbSJoel Becker /* no inode means this hasn't been made visible yet */ 2563d0f89bbSJoel Becker return; 2573d0f89bbSJoel Becker 2585955102cSAl Viro inode_lock(d_inode(dir)); 2597063fbf2SJoel Becker list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { 2607063fbf2SJoel Becker if (!sd->s_element) 2617063fbf2SJoel Becker continue; 2627063fbf2SJoel Becker if (!strcmp(configfs_get_name(sd), name)) { 2636f610764SLouis Rilling spin_lock(&configfs_dirent_lock); 2647063fbf2SJoel Becker list_del_init(&sd->s_sibling); 2656f610764SLouis Rilling spin_unlock(&configfs_dirent_lock); 2667063fbf2SJoel Becker configfs_drop_dentry(sd, dir); 2677063fbf2SJoel Becker configfs_put(sd); 2687063fbf2SJoel Becker break; 2697063fbf2SJoel Becker } 2707063fbf2SJoel Becker } 2715955102cSAl Viro inode_unlock(d_inode(dir)); 2727063fbf2SJoel Becker } 273