Line data Source code
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 "ext2.h"
35 : #include "xattr.h"
36 : #include "acl.h"
37 : #include "xip.h"
38 :
39 : static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
40 : {
41 72 : int err = ext2_add_link(dentry, inode);
42 36 : if (!err) {
43 12 : d_instantiate(dentry, inode);
44 12 : unlock_new_inode(inode);
45 12 : return 0;
46 : }
47 24 : inode_dec_link_count(inode);
48 12 : unlock_new_inode(inode);
49 12 : iput(inode);
50 12 : return err;
51 : }
52 :
53 : /*
54 : * Methods themselves.
55 : */
56 :
57 : static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
58 : {
59 4 : struct inode * inode;
60 4 : ino_t ino;
61 4 :
62 12 : if (dentry->d_name.len > EXT2_NAME_LEN)
63 16 : return ERR_PTR(-ENAMETOOLONG);
64 4 :
65 16 : ino = ext2_inode_by_name(dir, &dentry->d_name);
66 8 : inode = NULL;
67 12 : if (ino) {
68 20 : inode = ext2_iget(dir->i_sb, ino);
69 24 : if (unlikely(IS_ERR(inode))) {
70 16 : if (PTR_ERR(inode) == -ESTALE) {
71 12 : ext2_error(dir->i_sb, __func__,
72 : "deleted inode referenced: %lu",
73 : (unsigned long) ino);
74 12 : return ERR_PTR(-EIO);
75 : } else {
76 12 : return ERR_CAST(inode);
77 : }
78 : }
79 : }
80 16 : return d_splice_alias(inode, dentry);
81 : }
82 :
83 : struct dentry *ext2_get_parent(struct dentry *child)
84 : {
85 4 : struct qstr dotdot = {.name = "..", .len = 2};
86 5 : unsigned long ino = ext2_inode_by_name(child->d_inode, &dotdot);
87 3 : if (!ino)
88 4 : return ERR_PTR(-ENOENT);
89 8 : return d_obtain_alias(ext2_iget(child->d_inode->i_sb, ino));
90 1 : }
91 :
92 : /*
93 : * By the time this is called, we already have created
94 : * the directory cache entry for the new file, but it
95 : * is so far negative - it has no inode.
96 : *
97 : * If the create succeeds, we fill in the inode information
98 : * with d_instantiate().
99 : */
100 : static int ext2_create (struct inode * dir, struct dentry * dentry, int mode, struct nameidata *nd)
101 : {
102 28 : struct inode * inode = ext2_new_inode (dir, mode);
103 16 : int err = PTR_ERR(inode);
104 20 : if (!IS_ERR(inode)) {
105 8 : inode->i_op = &ext2_file_inode_operations;
106 4 : if (ext2_use_xip(inode->i_sb)) {
107 4 : inode->i_mapping->a_ops = &ext2_aops_xip;
108 : inode->i_fop = &ext2_xip_file_operations;
109 16 : } else if (test_opt(inode->i_sb, NOBH)) {
110 4 : inode->i_mapping->a_ops = &ext2_nobh_aops;
111 4 : inode->i_fop = &ext2_file_operations;
112 : } else {
113 4 : inode->i_mapping->a_ops = &ext2_aops;
114 4 : inode->i_fop = &ext2_file_operations;
115 : }
116 8 : mark_inode_dirty(inode);
117 12 : err = ext2_add_nondir(dentry, inode);
118 : }
119 8 : return err;
120 : }
121 :
122 : static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
123 : {
124 4 : struct inode * inode;
125 4 : int err;
126 4 :
127 20 : if (!new_valid_dev(rdev))
128 8 : return -EINVAL;
129 :
130 20 : inode = ext2_new_inode (dir, mode);
131 12 : err = PTR_ERR(inode);
132 16 : if (!IS_ERR(inode)) {
133 8 : init_special_inode(inode, inode->i_mode, rdev);
134 : #ifdef CONFIG_EXT2_FS_XATTR
135 4 : inode->i_op = &ext2_special_inode_operations;
136 : #endif
137 8 : mark_inode_dirty(inode);
138 12 : err = ext2_add_nondir(dentry, inode);
139 : }
140 8 : return err;
141 : }
142 :
143 : static int ext2_symlink (struct inode * dir, struct dentry * dentry,
144 : const char * symname)
145 4 : {
146 8 : struct super_block * sb = dir->i_sb;
147 8 : int err = -ENAMETOOLONG;
148 12 : unsigned l = strlen(symname)+1;
149 4 : struct inode * inode;
150 4 :
151 12 : if (l > sb->s_blocksize)
152 8 : goto out;
153 4 :
154 20 : inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO);
155 12 : err = PTR_ERR(inode);
156 16 : if (IS_ERR(inode))
157 4 : goto out;
158 :
159 8 : if (l > sizeof (EXT2_I(inode)->i_data)) {
160 : /* slow symlink */
161 4 : inode->i_op = &ext2_symlink_inode_operations;
162 16 : if (test_opt(inode->i_sb, NOBH))
163 4 : inode->i_mapping->a_ops = &ext2_nobh_aops;
164 : else
165 4 : inode->i_mapping->a_ops = &ext2_aops;
166 4 : err = page_symlink(inode, symname, l);
167 8 : if (err)
168 4 : goto out_fail;
169 : } else {
170 : /* fast symlink */
171 4 : inode->i_op = &ext2_fast_symlink_inode_operations;
172 12 : memcpy((char*)(EXT2_I(inode)->i_data),symname,l);
173 4 : inode->i_size = l-1;
174 : }
175 16 : mark_inode_dirty(inode);
176 :
177 12 : err = ext2_add_nondir(dentry, inode);
178 : out:
179 20 : return err;
180 4 :
181 : out_fail:
182 8 : inode_dec_link_count(inode);
183 4 : unlock_new_inode(inode);
184 4 : iput (inode);
185 4 : goto out;
186 : }
187 :
188 : static int ext2_link (struct dentry * old_dentry, struct inode * dir,
189 : struct dentry *dentry)
190 4 : {
191 8 : struct inode *inode = old_dentry->d_inode;
192 4 : int err;
193 4 :
194 8 : if (inode->i_nlink >= EXT2_LINK_MAX)
195 4 : return -EMLINK;
196 :
197 16 : inode->i_ctime = CURRENT_TIME_SEC;
198 8 : inode_inc_link_count(inode);
199 8 : atomic_inc(&inode->i_count);
200 :
201 16 : err = ext2_add_link(dentry, inode);
202 8 : if (!err) {
203 4 : d_instantiate(dentry, inode);
204 4 : return 0;
205 : }
206 8 : inode_dec_link_count(inode);
207 4 : iput(inode);
208 4 : return err;
209 : }
210 :
211 : static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
212 : {
213 4 : struct inode * inode;
214 8 : int err = -EMLINK;
215 4 :
216 12 : if (dir->i_nlink >= EXT2_LINK_MAX)
217 8 : goto out;
218 :
219 8 : inode_inc_link_count(dir);
220 :
221 20 : inode = ext2_new_inode (dir, S_IFDIR | mode);
222 12 : err = PTR_ERR(inode);
223 16 : if (IS_ERR(inode))
224 4 : goto out_dir;
225 :
226 4 : inode->i_op = &ext2_dir_inode_operations;
227 4 : inode->i_fop = &ext2_dir_operations;
228 16 : if (test_opt(inode->i_sb, NOBH))
229 4 : inode->i_mapping->a_ops = &ext2_nobh_aops;
230 : else
231 4 : inode->i_mapping->a_ops = &ext2_aops;
232 :
233 8 : inode_inc_link_count(inode);
234 :
235 16 : err = ext2_make_empty(inode, dir);
236 8 : if (err)
237 4 : goto out_fail;
238 :
239 16 : err = ext2_add_link(dentry, inode);
240 8 : if (err)
241 4 : goto out_fail;
242 :
243 4 : d_instantiate(dentry, inode);
244 4 : unlock_new_inode(inode);
245 : out:
246 16 : return err;
247 8 :
248 : out_fail:
249 16 : inode_dec_link_count(inode);
250 8 : inode_dec_link_count(inode);
251 4 : unlock_new_inode(inode);
252 4 : iput(inode);
253 : out_dir:
254 20 : inode_dec_link_count(dir);
255 4 : goto out;
256 : }
257 :
258 : static int ext2_unlink(struct inode * dir, struct dentry *dentry)
259 : {
260 16 : struct inode * inode = dentry->d_inode;
261 8 : struct ext2_dir_entry_2 * de;
262 8 : struct page * page;
263 16 : int err = -ENOENT;
264 :
265 48 : de = ext2_find_entry (dir, &dentry->d_name, &page);
266 16 : if (!de)
267 8 : goto out;
268 :
269 16 : err = ext2_delete_entry (de, page);
270 16 : if (err)
271 8 : goto out;
272 :
273 8 : inode->i_ctime = dir->i_ctime;
274 16 : inode_dec_link_count(inode);
275 8 : err = 0;
276 : out:
277 32 : return err;
278 : }
279 :
280 : static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
281 : {
282 8 : struct inode * inode = dentry->d_inode;
283 8 : int err = -ENOTEMPTY;
284 4 :
285 20 : if (ext2_empty_dir(inode)) {
286 16 : err = ext2_unlink(dir, dentry);
287 8 : if (!err) {
288 4 : inode->i_size = 0;
289 8 : inode_dec_link_count(inode);
290 8 : inode_dec_link_count(dir);
291 : }
292 : }
293 12 : return err;
294 : }
295 :
296 : static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
297 : struct inode * new_dir, struct dentry * new_dentry )
298 : {
299 8 : struct inode * old_inode = old_dentry->d_inode;
300 8 : struct inode * new_inode = new_dentry->d_inode;
301 8 : struct page * dir_page = NULL;
302 8 : struct ext2_dir_entry_2 * dir_de = NULL;
303 4 : struct page * old_page;
304 4 : struct ext2_dir_entry_2 * old_de;
305 8 : int err = -ENOENT;
306 4 :
307 28 : old_de = ext2_find_entry (old_dir, &old_dentry->d_name, &old_page);
308 12 : if (!old_de)
309 8 : goto out;
310 4 :
311 16 : if (S_ISDIR(old_inode->i_mode)) {
312 8 : err = -EIO;
313 12 : dir_de = ext2_dotdot(old_inode, &dir_page);
314 8 : if (!dir_de)
315 4 : goto out_old;
316 : }
317 :
318 16 : if (new_inode) {
319 : struct page *new_page;
320 : struct ext2_dir_entry_2 *new_de;
321 :
322 8 : err = -ENOTEMPTY;
323 48 : if (dir_de && !ext2_empty_dir (new_inode))
324 4 : goto out_dir;
325 :
326 12 : err = -ENOENT;
327 72 : new_de = ext2_find_entry (new_dir, &new_dentry->d_name, &new_page);
328 8 : if (!new_de)
329 4 : goto out_dir;
330 8 : ext2_set_link(new_dir, new_de, new_page, old_inode, 1);
331 16 : new_inode->i_ctime = CURRENT_TIME_SEC;
332 8 : if (dir_de)
333 8 : drop_nlink(new_inode);
334 16 : inode_dec_link_count(new_inode);
335 : } else {
336 16 : if (dir_de) {
337 8 : err = -EMLINK;
338 16 : if (new_dir->i_nlink >= EXT2_LINK_MAX)
339 8 : goto out_dir;
340 : }
341 32 : err = ext2_add_link(new_dentry, old_inode);
342 8 : if (err)
343 4 : goto out_dir;
344 8 : if (dir_de)
345 8 : inode_inc_link_count(new_dir);
346 : }
347 :
348 : /*
349 : * Like most other Unix systems, set the ctime for inodes on a
350 : * rename.
351 : */
352 48 : old_inode->i_ctime = CURRENT_TIME_SEC;
353 24 : mark_inode_dirty(old_inode);
354 :
355 8 : ext2_delete_entry (old_de, old_page);
356 :
357 8 : if (dir_de) {
358 8 : if (old_dir != new_dir)
359 8 : ext2_set_link(old_inode, dir_de, dir_page, new_dir, 0);
360 : else {
361 8 : kunmap(dir_page);
362 4 : page_cache_release(dir_page);
363 : }
364 16 : inode_dec_link_count(old_dir);
365 : }
366 8 : return 0;
367 20 :
368 :
369 : out_dir:
370 40 : if (dir_de) {
371 40 : kunmap(dir_page);
372 4 : page_cache_release(dir_page);
373 : }
374 : out_old:
375 48 : kunmap(old_page);
376 4 : page_cache_release(old_page);
377 24 : out:
378 12 : return err;
379 : }
380 :
381 1 : const struct inode_operations ext2_dir_inode_operations = {
382 : .create = ext2_create,
383 : .lookup = ext2_lookup,
384 : .link = ext2_link,
385 : .unlink = ext2_unlink,
386 : .symlink = ext2_symlink,
387 : .mkdir = ext2_mkdir,
388 : .rmdir = ext2_rmdir,
389 : .mknod = ext2_mknod,
390 : .rename = ext2_rename,
391 : #ifdef CONFIG_EXT2_FS_XATTR
392 : .setxattr = generic_setxattr,
393 : .getxattr = generic_getxattr,
394 : .listxattr = ext2_listxattr,
395 : .removexattr = generic_removexattr,
396 : #endif
397 : .setattr = ext2_setattr,
398 : .check_acl = ext2_check_acl,
399 : };
400 :
401 1 : const struct inode_operations ext2_special_inode_operations = {
402 : #ifdef CONFIG_EXT2_FS_XATTR
403 : .setxattr = generic_setxattr,
404 : .getxattr = generic_getxattr,
405 : .listxattr = ext2_listxattr,
406 : .removexattr = generic_removexattr,
407 : #endif
408 : .setattr = ext2_setattr,
409 : .check_acl = ext2_check_acl,
410 : };
|