xref: /openbmc/linux/fs/ext2/namei.c (revision 1b69c6d0ae90b7f1a4f61d5c8209d5cb7a55f849)
1  /*
2   * linux/fs/ext2/namei.c
3   *
4   * Rewrite to pagecache. Almost all code had been changed, so blame me
5   * if the things go wrong. Please, send bug reports to
6   * viro@parcelfarce.linux.theplanet.co.uk
7   *
8   * Stuff here is basically a glue between the VFS and generic UNIXish
9   * filesystem that keeps everything in pagecache. All knowledge of the
10   * directory layout is in fs/ext2/dir.c - it turned out to be easily separatable
11   * and it's easier to debug that way. In principle we might want to
12   * generalize that a bit and turn it into a library. Or not.
13   *
14   * The only non-static object here is ext2_dir_inode_operations.
15   *
16   * TODO: get rid of kmap() use, add readahead.
17   *
18   * Copyright (C) 1992, 1993, 1994, 1995
19   * Remy Card (card@masi.ibp.fr)
20   * Laboratoire MASI - Institut Blaise Pascal
21   * Universite Pierre et Marie Curie (Paris VI)
22   *
23   *  from
24   *
25   *  linux/fs/minix/namei.c
26   *
27   *  Copyright (C) 1991, 1992  Linus Torvalds
28   *
29   *  Big-endian to little-endian byte-swapping/bitmaps by
30   *        David S. Miller (davem@caip.rutgers.edu), 1995
31   */
32  
33  #include <linux/pagemap.h>
34  #include <linux/quotaops.h>
35  #include "ext2.h"
36  #include "xattr.h"
37  #include "acl.h"
38  
39  static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
40  {
41  	int err = ext2_add_link(dentry, inode);
42  	if (!err) {
43  		unlock_new_inode(inode);
44  		d_instantiate(dentry, inode);
45  		return 0;
46  	}
47  	inode_dec_link_count(inode);
48  	unlock_new_inode(inode);
49  	iput(inode);
50  	return err;
51  }
52  
53  /*
54   * Methods themselves.
55   */
56  
57  static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, unsigned int flags)
58  {
59  	struct inode * inode;
60  	ino_t ino;
61  
62  	if (dentry->d_name.len > EXT2_NAME_LEN)
63  		return ERR_PTR(-ENAMETOOLONG);
64  
65  	ino = ext2_inode_by_name(dir, &dentry->d_name);
66  	inode = NULL;
67  	if (ino) {
68  		inode = ext2_iget(dir->i_sb, ino);
69  		if (inode == ERR_PTR(-ESTALE)) {
70  			ext2_error(dir->i_sb, __func__,
71  					"deleted inode referenced: %lu",
72  					(unsigned long) ino);
73  			return ERR_PTR(-EIO);
74  		}
75  	}
76  	return d_splice_alias(inode, dentry);
77  }
78  
79  struct dentry *ext2_get_parent(struct dentry *child)
80  {
81  	struct qstr dotdot = QSTR_INIT("..", 2);
82  	unsigned long ino = ext2_inode_by_name(d_inode(child), &dotdot);
83  	if (!ino)
84  		return ERR_PTR(-ENOENT);
85  	return d_obtain_alias(ext2_iget(d_inode(child)->i_sb, ino));
86  }
87  
88  /*
89   * By the time this is called, we already have created
90   * the directory cache entry for the new file, but it
91   * is so far negative - it has no inode.
92   *
93   * If the create succeeds, we fill in the inode information
94   * with d_instantiate().
95   */
96  static int ext2_create (struct inode * dir, struct dentry * dentry, umode_t mode, bool excl)
97  {
98  	struct inode *inode;
99  	int err;
100  
101  	err = dquot_initialize(dir);
102  	if (err)
103  		return err;
104  
105  	inode = ext2_new_inode(dir, mode, &dentry->d_name);
106  	if (IS_ERR(inode))
107  		return PTR_ERR(inode);
108  
109  	inode->i_op = &ext2_file_inode_operations;
110  	if (test_opt(inode->i_sb, NOBH)) {
111  		inode->i_mapping->a_ops = &ext2_nobh_aops;
112  		inode->i_fop = &ext2_file_operations;
113  	} else {
114  		inode->i_mapping->a_ops = &ext2_aops;
115  		inode->i_fop = &ext2_file_operations;
116  	}
117  	mark_inode_dirty(inode);
118  	return ext2_add_nondir(dentry, inode);
119  }
120  
121  static int ext2_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
122  {
123  	struct inode *inode = ext2_new_inode(dir, mode, NULL);
124  	if (IS_ERR(inode))
125  		return PTR_ERR(inode);
126  
127  	inode->i_op = &ext2_file_inode_operations;
128  	if (test_opt(inode->i_sb, NOBH)) {
129  		inode->i_mapping->a_ops = &ext2_nobh_aops;
130  		inode->i_fop = &ext2_file_operations;
131  	} else {
132  		inode->i_mapping->a_ops = &ext2_aops;
133  		inode->i_fop = &ext2_file_operations;
134  	}
135  	mark_inode_dirty(inode);
136  	d_tmpfile(dentry, inode);
137  	unlock_new_inode(inode);
138  	return 0;
139  }
140  
141  static int ext2_mknod (struct inode * dir, struct dentry *dentry, umode_t mode, dev_t rdev)
142  {
143  	struct inode * inode;
144  	int err;
145  
146  	if (!new_valid_dev(rdev))
147  		return -EINVAL;
148  
149  	err = dquot_initialize(dir);
150  	if (err)
151  		return err;
152  
153  	inode = ext2_new_inode (dir, mode, &dentry->d_name);
154  	err = PTR_ERR(inode);
155  	if (!IS_ERR(inode)) {
156  		init_special_inode(inode, inode->i_mode, rdev);
157  #ifdef CONFIG_EXT2_FS_XATTR
158  		inode->i_op = &ext2_special_inode_operations;
159  #endif
160  		mark_inode_dirty(inode);
161  		err = ext2_add_nondir(dentry, inode);
162  	}
163  	return err;
164  }
165  
166  static int ext2_symlink (struct inode * dir, struct dentry * dentry,
167  	const char * symname)
168  {
169  	struct super_block * sb = dir->i_sb;
170  	int err = -ENAMETOOLONG;
171  	unsigned l = strlen(symname)+1;
172  	struct inode * inode;
173  
174  	if (l > sb->s_blocksize)
175  		goto out;
176  
177  	err = dquot_initialize(dir);
178  	if (err)
179  		goto out;
180  
181  	inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO, &dentry->d_name);
182  	err = PTR_ERR(inode);
183  	if (IS_ERR(inode))
184  		goto out;
185  
186  	if (l > sizeof (EXT2_I(inode)->i_data)) {
187  		/* slow symlink */
188  		inode->i_op = &ext2_symlink_inode_operations;
189  		if (test_opt(inode->i_sb, NOBH))
190  			inode->i_mapping->a_ops = &ext2_nobh_aops;
191  		else
192  			inode->i_mapping->a_ops = &ext2_aops;
193  		err = page_symlink(inode, symname, l);
194  		if (err)
195  			goto out_fail;
196  	} else {
197  		/* fast symlink */
198  		inode->i_op = &ext2_fast_symlink_inode_operations;
199  		inode->i_link = (char*)EXT2_I(inode)->i_data;
200  		memcpy(inode->i_link, symname, l);
201  		inode->i_size = l-1;
202  	}
203  	mark_inode_dirty(inode);
204  
205  	err = ext2_add_nondir(dentry, inode);
206  out:
207  	return err;
208  
209  out_fail:
210  	inode_dec_link_count(inode);
211  	unlock_new_inode(inode);
212  	iput (inode);
213  	goto out;
214  }
215  
216  static int ext2_link (struct dentry * old_dentry, struct inode * dir,
217  	struct dentry *dentry)
218  {
219  	struct inode *inode = d_inode(old_dentry);
220  	int err;
221  
222  	err = dquot_initialize(dir);
223  	if (err)
224  		return err;
225  
226  	inode->i_ctime = CURRENT_TIME_SEC;
227  	inode_inc_link_count(inode);
228  	ihold(inode);
229  
230  	err = ext2_add_link(dentry, inode);
231  	if (!err) {
232  		d_instantiate(dentry, inode);
233  		return 0;
234  	}
235  	inode_dec_link_count(inode);
236  	iput(inode);
237  	return err;
238  }
239  
240  static int ext2_mkdir(struct inode * dir, struct dentry * dentry, umode_t mode)
241  {
242  	struct inode * inode;
243  	int err;
244  
245  	err = dquot_initialize(dir);
246  	if (err)
247  		return err;
248  
249  	inode_inc_link_count(dir);
250  
251  	inode = ext2_new_inode(dir, S_IFDIR | mode, &dentry->d_name);
252  	err = PTR_ERR(inode);
253  	if (IS_ERR(inode))
254  		goto out_dir;
255  
256  	inode->i_op = &ext2_dir_inode_operations;
257  	inode->i_fop = &ext2_dir_operations;
258  	if (test_opt(inode->i_sb, NOBH))
259  		inode->i_mapping->a_ops = &ext2_nobh_aops;
260  	else
261  		inode->i_mapping->a_ops = &ext2_aops;
262  
263  	inode_inc_link_count(inode);
264  
265  	err = ext2_make_empty(inode, dir);
266  	if (err)
267  		goto out_fail;
268  
269  	err = ext2_add_link(dentry, inode);
270  	if (err)
271  		goto out_fail;
272  
273  	unlock_new_inode(inode);
274  	d_instantiate(dentry, inode);
275  out:
276  	return err;
277  
278  out_fail:
279  	inode_dec_link_count(inode);
280  	inode_dec_link_count(inode);
281  	unlock_new_inode(inode);
282  	iput(inode);
283  out_dir:
284  	inode_dec_link_count(dir);
285  	goto out;
286  }
287  
288  static int ext2_unlink(struct inode * dir, struct dentry *dentry)
289  {
290  	struct inode * inode = d_inode(dentry);
291  	struct ext2_dir_entry_2 * de;
292  	struct page * page;
293  	int err;
294  
295  	err = dquot_initialize(dir);
296  	if (err)
297  		goto out;
298  
299  	de = ext2_find_entry (dir, &dentry->d_name, &page);
300  	if (!de) {
301  		err = -ENOENT;
302  		goto out;
303  	}
304  
305  	err = ext2_delete_entry (de, page);
306  	if (err)
307  		goto out;
308  
309  	inode->i_ctime = dir->i_ctime;
310  	inode_dec_link_count(inode);
311  	err = 0;
312  out:
313  	return err;
314  }
315  
316  static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
317  {
318  	struct inode * inode = d_inode(dentry);
319  	int err = -ENOTEMPTY;
320  
321  	if (ext2_empty_dir(inode)) {
322  		err = ext2_unlink(dir, dentry);
323  		if (!err) {
324  			inode->i_size = 0;
325  			inode_dec_link_count(inode);
326  			inode_dec_link_count(dir);
327  		}
328  	}
329  	return err;
330  }
331  
332  static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
333  	struct inode * new_dir,	struct dentry * new_dentry )
334  {
335  	struct inode * old_inode = d_inode(old_dentry);
336  	struct inode * new_inode = d_inode(new_dentry);
337  	struct page * dir_page = NULL;
338  	struct ext2_dir_entry_2 * dir_de = NULL;
339  	struct page * old_page;
340  	struct ext2_dir_entry_2 * old_de;
341  	int err;
342  
343  	err = dquot_initialize(old_dir);
344  	if (err)
345  		goto out;
346  
347  	err = dquot_initialize(new_dir);
348  	if (err)
349  		goto out;
350  
351  	old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page);
352  	if (!old_de) {
353  		err = -ENOENT;
354  		goto out;
355  	}
356  
357  	if (S_ISDIR(old_inode->i_mode)) {
358  		err = -EIO;
359  		dir_de = ext2_dotdot(old_inode, &dir_page);
360  		if (!dir_de)
361  			goto out_old;
362  	}
363  
364  	if (new_inode) {
365  		struct page *new_page;
366  		struct ext2_dir_entry_2 *new_de;
367  
368  		err = -ENOTEMPTY;
369  		if (dir_de && !ext2_empty_dir (new_inode))
370  			goto out_dir;
371  
372  		err = -ENOENT;
373  		new_de = ext2_find_entry (new_dir, &new_dentry->d_name, &new_page);
374  		if (!new_de)
375  			goto out_dir;
376  		ext2_set_link(new_dir, new_de, new_page, old_inode, 1);
377  		new_inode->i_ctime = CURRENT_TIME_SEC;
378  		if (dir_de)
379  			drop_nlink(new_inode);
380  		inode_dec_link_count(new_inode);
381  	} else {
382  		err = ext2_add_link(new_dentry, old_inode);
383  		if (err)
384  			goto out_dir;
385  		if (dir_de)
386  			inode_inc_link_count(new_dir);
387  	}
388  
389  	/*
390  	 * Like most other Unix systems, set the ctime for inodes on a
391   	 * rename.
392  	 */
393  	old_inode->i_ctime = CURRENT_TIME_SEC;
394  	mark_inode_dirty(old_inode);
395  
396  	ext2_delete_entry (old_de, old_page);
397  
398  	if (dir_de) {
399  		if (old_dir != new_dir)
400  			ext2_set_link(old_inode, dir_de, dir_page, new_dir, 0);
401  		else {
402  			kunmap(dir_page);
403  			page_cache_release(dir_page);
404  		}
405  		inode_dec_link_count(old_dir);
406  	}
407  	return 0;
408  
409  
410  out_dir:
411  	if (dir_de) {
412  		kunmap(dir_page);
413  		page_cache_release(dir_page);
414  	}
415  out_old:
416  	kunmap(old_page);
417  	page_cache_release(old_page);
418  out:
419  	return err;
420  }
421  
422  const struct inode_operations ext2_dir_inode_operations = {
423  	.create		= ext2_create,
424  	.lookup		= ext2_lookup,
425  	.link		= ext2_link,
426  	.unlink		= ext2_unlink,
427  	.symlink	= ext2_symlink,
428  	.mkdir		= ext2_mkdir,
429  	.rmdir		= ext2_rmdir,
430  	.mknod		= ext2_mknod,
431  	.rename		= ext2_rename,
432  #ifdef CONFIG_EXT2_FS_XATTR
433  	.setxattr	= generic_setxattr,
434  	.getxattr	= generic_getxattr,
435  	.listxattr	= ext2_listxattr,
436  	.removexattr	= generic_removexattr,
437  #endif
438  	.setattr	= ext2_setattr,
439  	.get_acl	= ext2_get_acl,
440  	.set_acl	= ext2_set_acl,
441  	.tmpfile	= ext2_tmpfile,
442  };
443  
444  const struct inode_operations ext2_special_inode_operations = {
445  #ifdef CONFIG_EXT2_FS_XATTR
446  	.setxattr	= generic_setxattr,
447  	.getxattr	= generic_getxattr,
448  	.listxattr	= ext2_listxattr,
449  	.removexattr	= generic_removexattr,
450  #endif
451  	.setattr	= ext2_setattr,
452  	.get_acl	= ext2_get_acl,
453  	.set_acl	= ext2_set_acl,
454  };
455