Merge branch 'linus' into x86/urgent
[linux-2.6] / fs / configfs / inode.c
1 /* -*- mode: c; c-basic-offset: 8; -*-
2  * vim: noexpandtab sw=8 ts=8 sts=0:
3  *
4  * inode.c - basic inode and dentry operations.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 021110-1307, USA.
20  *
21  * Based on sysfs:
22  *      sysfs is Copyright (C) 2001, 2002, 2003 Patrick Mochel
23  *
24  * configfs Copyright (C) 2005 Oracle.  All rights reserved.
25  *
26  * Please see Documentation/filesystems/configfs.txt for more information.
27  */
28
29 #undef DEBUG
30
31 #include <linux/pagemap.h>
32 #include <linux/namei.h>
33 #include <linux/backing-dev.h>
34 #include <linux/capability.h>
35 #include <linux/sched.h>
36 #include <linux/lockdep.h>
37
38 #include <linux/configfs.h>
39 #include "configfs_internal.h"
40
41 #ifdef CONFIG_LOCKDEP
42 static struct lock_class_key default_group_class[MAX_LOCK_DEPTH];
43 #endif
44
45 extern struct super_block * configfs_sb;
46
47 static const struct address_space_operations configfs_aops = {
48         .readpage       = simple_readpage,
49         .write_begin    = simple_write_begin,
50         .write_end      = simple_write_end,
51 };
52
53 static struct backing_dev_info configfs_backing_dev_info = {
54         .ra_pages       = 0,    /* No readahead */
55         .capabilities   = BDI_CAP_NO_ACCT_AND_WRITEBACK,
56 };
57
58 static const struct inode_operations configfs_inode_operations ={
59         .setattr        = configfs_setattr,
60 };
61
62 int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
63 {
64         struct inode * inode = dentry->d_inode;
65         struct configfs_dirent * sd = dentry->d_fsdata;
66         struct iattr * sd_iattr;
67         unsigned int ia_valid = iattr->ia_valid;
68         int error;
69
70         if (!sd)
71                 return -EINVAL;
72
73         sd_iattr = sd->s_iattr;
74
75         error = inode_change_ok(inode, iattr);
76         if (error)
77                 return error;
78
79         error = inode_setattr(inode, iattr);
80         if (error)
81                 return error;
82
83         if (!sd_iattr) {
84                 /* setting attributes for the first time, allocate now */
85                 sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL);
86                 if (!sd_iattr)
87                         return -ENOMEM;
88                 /* assign default attributes */
89                 sd_iattr->ia_mode = sd->s_mode;
90                 sd_iattr->ia_uid = 0;
91                 sd_iattr->ia_gid = 0;
92                 sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME;
93                 sd->s_iattr = sd_iattr;
94         }
95
96         /* attributes were changed atleast once in past */
97
98         if (ia_valid & ATTR_UID)
99                 sd_iattr->ia_uid = iattr->ia_uid;
100         if (ia_valid & ATTR_GID)
101                 sd_iattr->ia_gid = iattr->ia_gid;
102         if (ia_valid & ATTR_ATIME)
103                 sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime,
104                                                 inode->i_sb->s_time_gran);
105         if (ia_valid & ATTR_MTIME)
106                 sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime,
107                                                 inode->i_sb->s_time_gran);
108         if (ia_valid & ATTR_CTIME)
109                 sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime,
110                                                 inode->i_sb->s_time_gran);
111         if (ia_valid & ATTR_MODE) {
112                 umode_t mode = iattr->ia_mode;
113
114                 if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID))
115                         mode &= ~S_ISGID;
116                 sd_iattr->ia_mode = sd->s_mode = mode;
117         }
118
119         return error;
120 }
121
122 static inline void set_default_inode_attr(struct inode * inode, mode_t mode)
123 {
124         inode->i_mode = mode;
125         inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
126 }
127
128 static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
129 {
130         inode->i_mode = iattr->ia_mode;
131         inode->i_uid = iattr->ia_uid;
132         inode->i_gid = iattr->ia_gid;
133         inode->i_atime = iattr->ia_atime;
134         inode->i_mtime = iattr->ia_mtime;
135         inode->i_ctime = iattr->ia_ctime;
136 }
137
138 struct inode * configfs_new_inode(mode_t mode, struct configfs_dirent * sd)
139 {
140         struct inode * inode = new_inode(configfs_sb);
141         if (inode) {
142                 inode->i_mapping->a_ops = &configfs_aops;
143                 inode->i_mapping->backing_dev_info = &configfs_backing_dev_info;
144                 inode->i_op = &configfs_inode_operations;
145
146                 if (sd->s_iattr) {
147                         /* sysfs_dirent has non-default attributes
148                          * get them for the new inode from persistent copy
149                          * in sysfs_dirent
150                          */
151                         set_inode_attr(inode, sd->s_iattr);
152                 } else
153                         set_default_inode_attr(inode, mode);
154         }
155         return inode;
156 }
157
158 #ifdef CONFIG_LOCKDEP
159
160 static void configfs_set_inode_lock_class(struct configfs_dirent *sd,
161                                           struct inode *inode)
162 {
163         int depth = sd->s_depth;
164
165         if (depth > 0) {
166                 if (depth <= ARRAY_SIZE(default_group_class)) {
167                         lockdep_set_class(&inode->i_mutex,
168                                           &default_group_class[depth - 1]);
169                 } else {
170                         /*
171                          * In practice the maximum level of locking depth is
172                          * already reached. Just inform about possible reasons.
173                          */
174                         printk(KERN_INFO "configfs: Too many levels of inodes"
175                                " for the locking correctness validator.\n");
176                         printk(KERN_INFO "Spurious warnings may appear.\n");
177                 }
178         }
179 }
180
181 #else /* CONFIG_LOCKDEP */
182
183 static void configfs_set_inode_lock_class(struct configfs_dirent *sd,
184                                           struct inode *inode)
185 {
186 }
187
188 #endif /* CONFIG_LOCKDEP */
189
190 int configfs_create(struct dentry * dentry, int mode, int (*init)(struct inode *))
191 {
192         int error = 0;
193         struct inode * inode = NULL;
194         if (dentry) {
195                 if (!dentry->d_inode) {
196                         struct configfs_dirent *sd = dentry->d_fsdata;
197                         if ((inode = configfs_new_inode(mode, sd))) {
198                                 if (dentry->d_parent && dentry->d_parent->d_inode) {
199                                         struct inode *p_inode = dentry->d_parent->d_inode;
200                                         p_inode->i_mtime = p_inode->i_ctime = CURRENT_TIME;
201                                 }
202                                 configfs_set_inode_lock_class(sd, inode);
203                                 goto Proceed;
204                         }
205                         else
206                                 error = -ENOMEM;
207                 } else
208                         error = -EEXIST;
209         } else
210                 error = -ENOENT;
211         goto Done;
212
213  Proceed:
214         if (init)
215                 error = init(inode);
216         if (!error) {
217                 d_instantiate(dentry, inode);
218                 if (S_ISDIR(mode) || S_ISLNK(mode))
219                         dget(dentry);  /* pin link and directory dentries in core */
220         } else
221                 iput(inode);
222  Done:
223         return error;
224 }
225
226 /*
227  * Get the name for corresponding element represented by the given configfs_dirent
228  */
229 const unsigned char * configfs_get_name(struct configfs_dirent *sd)
230 {
231         struct configfs_attribute *attr;
232
233         BUG_ON(!sd || !sd->s_element);
234
235         /* These always have a dentry, so use that */
236         if (sd->s_type & (CONFIGFS_DIR | CONFIGFS_ITEM_LINK))
237                 return sd->s_dentry->d_name.name;
238
239         if (sd->s_type & CONFIGFS_ITEM_ATTR) {
240                 attr = sd->s_element;
241                 return attr->ca_name;
242         }
243         return NULL;
244 }
245
246
247 /*
248  * Unhashes the dentry corresponding to given configfs_dirent
249  * Called with parent inode's i_mutex held.
250  */
251 void configfs_drop_dentry(struct configfs_dirent * sd, struct dentry * parent)
252 {
253         struct dentry * dentry = sd->s_dentry;
254
255         if (dentry) {
256                 spin_lock(&dcache_lock);
257                 spin_lock(&dentry->d_lock);
258                 if (!(d_unhashed(dentry) && dentry->d_inode)) {
259                         dget_locked(dentry);
260                         __d_drop(dentry);
261                         spin_unlock(&dentry->d_lock);
262                         spin_unlock(&dcache_lock);
263                         simple_unlink(parent->d_inode, dentry);
264                 } else {
265                         spin_unlock(&dentry->d_lock);
266                         spin_unlock(&dcache_lock);
267                 }
268         }
269 }
270
271 void configfs_hash_and_remove(struct dentry * dir, const char * name)
272 {
273         struct configfs_dirent * sd;
274         struct configfs_dirent * parent_sd = dir->d_fsdata;
275
276         if (dir->d_inode == NULL)
277                 /* no inode means this hasn't been made visible yet */
278                 return;
279
280         mutex_lock(&dir->d_inode->i_mutex);
281         list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
282                 if (!sd->s_element)
283                         continue;
284                 if (!strcmp(configfs_get_name(sd), name)) {
285                         spin_lock(&configfs_dirent_lock);
286                         list_del_init(&sd->s_sibling);
287                         spin_unlock(&configfs_dirent_lock);
288                         configfs_drop_dentry(sd, dir);
289                         configfs_put(sd);
290                         break;
291                 }
292         }
293         mutex_unlock(&dir->d_inode->i_mutex);
294 }
295
296 int __init configfs_inode_init(void)
297 {
298         return bdi_init(&configfs_backing_dev_info);
299 }
300
301 void __exit configfs_inode_exit(void)
302 {
303         bdi_destroy(&configfs_backing_dev_info);
304 }