File: /usr/src/linux/fs/ext2/namei.c

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 viro@math.psu.edu
6      *
7      * Stuff here is basically a glue between the VFS and generic UNIXish
8      * filesystem that keeps everything in pagecache. All knowledge of the
9      * directory layout is in fs/ext2/dir.c - it turned out to be easily separatable
10      * and it's easier to debug that way. In principle we might want to
11      * generalize that a bit and turn it into a library. Or not.
12      *
13      * The only non-static object here is ext2_dir_inode_operations.
14      *
15      * TODO: get rid of kmap() use, add readahead.
16      *
17      * Copyright (C) 1992, 1993, 1994, 1995
18      * Remy Card (card@masi.ibp.fr)
19      * Laboratoire MASI - Institut Blaise Pascal
20      * Universite Pierre et Marie Curie (Paris VI)
21      *
22      *  from
23      *
24      *  linux/fs/minix/namei.c
25      *
26      *  Copyright (C) 1991, 1992  Linus Torvalds
27      *
28      *  Big-endian to little-endian byte-swapping/bitmaps by
29      *        David S. Miller (davem@caip.rutgers.edu), 1995
30      */
31     
32     #include <linux/fs.h>
33     #include <linux/ext2_fs.h>
34     #include <linux/pagemap.h>
35     
36     /*
37      * Couple of helper functions - make the code slightly cleaner.
38      */
39     
40     static inline void ext2_inc_count(struct inode *inode)
41     {
42     	inode->i_nlink++;
43     	mark_inode_dirty(inode);
44     }
45     
46     static inline void ext2_dec_count(struct inode *inode)
47     {
48     	inode->i_nlink--;
49     	mark_inode_dirty(inode);
50     }
51     
52     static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
53     {
54     	int err = ext2_add_link(dentry, inode);
55     	if (!err) {
56     		d_instantiate(dentry, inode);
57     		return 0;
58     	}
59     	ext2_dec_count(inode);
60     	iput(inode);
61     	return err;
62     }
63     
64     /*
65      * Methods themselves.
66      */
67     
68     static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry)
69     {
70     	struct inode * inode;
71     	ino_t ino;
72     	
73     	if (dentry->d_name.len > EXT2_NAME_LEN)
74     		return ERR_PTR(-ENAMETOOLONG);
75     
76     	ino = ext2_inode_by_name(dir, dentry);
77     	inode = NULL;
78     	if (ino) {
79     		inode = iget(dir->i_sb, ino);
80     		if (!inode) 
81     			return ERR_PTR(-EACCES);
82     	}
83     	d_add(dentry, inode);
84     	return NULL;
85     }
86     
87     /*
88      * By the time this is called, we already have created
89      * the directory cache entry for the new file, but it
90      * is so far negative - it has no inode.
91      *
92      * If the create succeeds, we fill in the inode information
93      * with d_instantiate(). 
94      */
95     static int ext2_create (struct inode * dir, struct dentry * dentry, int mode)
96     {
97     	struct inode * inode = ext2_new_inode (dir, mode);
98     	int err = PTR_ERR(inode);
99     	if (!IS_ERR(inode)) {
100     		inode->i_op = &ext2_file_inode_operations;
101     		inode->i_fop = &ext2_file_operations;
102     		inode->i_mapping->a_ops = &ext2_aops;
103     		mark_inode_dirty(inode);
104     		err = ext2_add_nondir(dentry, inode);
105     	}
106     	return err;
107     }
108     
109     static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
110     {
111     	struct inode * inode = ext2_new_inode (dir, mode);
112     	int err = PTR_ERR(inode);
113     	if (!IS_ERR(inode)) {
114     		init_special_inode(inode, mode, rdev);
115     		mark_inode_dirty(inode);
116     		err = ext2_add_nondir(dentry, inode);
117     	}
118     	return err;
119     }
120     
121     static int ext2_symlink (struct inode * dir, struct dentry * dentry,
122     	const char * symname)
123     {
124     	struct super_block * sb = dir->i_sb;
125     	int err = -ENAMETOOLONG;
126     	unsigned l = strlen(symname)+1;
127     	struct inode * inode;
128     
129     	if (l > sb->s_blocksize)
130     		goto out;
131     
132     	inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO);
133     	err = PTR_ERR(inode);
134     	if (IS_ERR(inode))
135     		goto out;
136     
137     	if (l > sizeof (inode->u.ext2_i.i_data)) {
138     		/* slow symlink */
139     		inode->i_op = &page_symlink_inode_operations;
140     		inode->i_mapping->a_ops = &ext2_aops;
141     		err = block_symlink(inode, symname, l);
142     		if (err)
143     			goto out_fail;
144     	} else {
145     		/* fast symlink */
146     		inode->i_op = &ext2_fast_symlink_inode_operations;
147     		memcpy((char*)&inode->u.ext2_i.i_data,symname,l);
148     		inode->i_size = l-1;
149     	}
150     	mark_inode_dirty(inode);
151     
152     	err = ext2_add_nondir(dentry, inode);
153     out:
154     	return err;
155     
156     out_fail:
157     	ext2_dec_count(inode);
158     	iput (inode);
159     	goto out;
160     }
161     
162     static int ext2_link (struct dentry * old_dentry, struct inode * dir,
163     	struct dentry *dentry)
164     {
165     	struct inode *inode = old_dentry->d_inode;
166     
167     	if (S_ISDIR(inode->i_mode))
168     		return -EPERM;
169     
170     	if (inode->i_nlink >= EXT2_LINK_MAX)
171     		return -EMLINK;
172     
173     	inode->i_ctime = CURRENT_TIME;
174     	ext2_inc_count(inode);
175     	atomic_inc(&inode->i_count);
176     
177     	return ext2_add_nondir(dentry, inode);
178     }
179     
180     static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
181     {
182     	struct inode * inode;
183     	int err = -EMLINK;
184     
185     	if (dir->i_nlink >= EXT2_LINK_MAX)
186     		goto out;
187     
188     	ext2_inc_count(dir);
189     
190     	inode = ext2_new_inode (dir, S_IFDIR | mode);
191     	err = PTR_ERR(inode);
192     	if (IS_ERR(inode))
193     		goto out_dir;
194     
195     	inode->i_op = &ext2_dir_inode_operations;
196     	inode->i_fop = &ext2_dir_operations;
197     	inode->i_mapping->a_ops = &ext2_aops;
198     
199     	ext2_inc_count(inode);
200     
201     	err = ext2_make_empty(inode, dir);
202     	if (err)
203     		goto out_fail;
204     
205     	err = ext2_add_link(dentry, inode);
206     	if (err)
207     		goto out_fail;
208     
209     	d_instantiate(dentry, inode);
210     out:
211     	return err;
212     
213     out_fail:
214     	ext2_dec_count(inode);
215     	ext2_dec_count(inode);
216     	iput(inode);
217     out_dir:
218     	ext2_dec_count(dir);
219     	goto out;
220     }
221     
222     static int ext2_unlink(struct inode * dir, struct dentry *dentry)
223     {
224     	struct inode * inode = dentry->d_inode;
225     	struct ext2_dir_entry_2 * de;
226     	struct page * page;
227     	int err = -ENOENT;
228     
229     	de = ext2_find_entry (dir, dentry, &page);
230     	if (!de)
231     		goto out;
232     
233     	err = ext2_delete_entry (de, page);
234     	if (err)
235     		goto out;
236     
237     	inode->i_ctime = dir->i_ctime;
238     	ext2_dec_count(inode);
239     	err = 0;
240     out:
241     	return err;
242     }
243     
244     static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
245     {
246     	struct inode * inode = dentry->d_inode;
247     	int err = -ENOTEMPTY;
248     
249     	if (ext2_empty_dir(inode)) {
250     		err = ext2_unlink(dir, dentry);
251     		if (!err) {
252     			inode->i_size = 0;
253     			ext2_dec_count(inode);
254     			ext2_dec_count(dir);
255     		}
256     	}
257     	return err;
258     }
259     
260     static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
261     	struct inode * new_dir,	struct dentry * new_dentry )
262     {
263     	struct inode * old_inode = old_dentry->d_inode;
264     	struct inode * new_inode = new_dentry->d_inode;
265     	struct page * dir_page = NULL;
266     	struct ext2_dir_entry_2 * dir_de = NULL;
267     	struct page * old_page;
268     	struct ext2_dir_entry_2 * old_de;
269     	int err = -ENOENT;
270     
271     	old_de = ext2_find_entry (old_dir, old_dentry, &old_page);
272     	if (!old_de)
273     		goto out;
274     
275     	if (S_ISDIR(old_inode->i_mode)) {
276     		err = -EIO;
277     		dir_de = ext2_dotdot(old_inode, &dir_page);
278     		if (!dir_de)
279     			goto out_old;
280     	}
281     
282     	if (new_inode) {
283     		struct page *new_page;
284     		struct ext2_dir_entry_2 *new_de;
285     
286     		err = -ENOTEMPTY;
287     		if (dir_de && !ext2_empty_dir (new_inode))
288     			goto out_dir;
289     
290     		err = -ENOENT;
291     		new_de = ext2_find_entry (new_dir, new_dentry, &new_page);
292     		if (!new_de)
293     			goto out_dir;
294     		ext2_inc_count(old_inode);
295     		ext2_set_link(new_dir, new_de, new_page, old_inode);
296     		new_inode->i_ctime = CURRENT_TIME;
297     		if (dir_de)
298     			new_inode->i_nlink--;
299     		ext2_dec_count(new_inode);
300     	} else {
301     		if (dir_de) {
302     			err = -EMLINK;
303     			if (new_dir->i_nlink >= EXT2_LINK_MAX)
304     				goto out_dir;
305     		}
306     		ext2_inc_count(old_inode);
307     		err = ext2_add_link(new_dentry, old_inode);
308     		if (err) {
309     			ext2_dec_count(old_inode);
310     			goto out_dir;
311     		}
312     		if (dir_de)
313     			ext2_inc_count(new_dir);
314     	}
315     
316     	ext2_delete_entry (old_de, old_page);
317     	ext2_dec_count(old_inode);
318     
319     	if (dir_de) {
320     		ext2_set_link(old_inode, dir_de, dir_page, new_dir);
321     		ext2_dec_count(old_dir);
322     	}
323     	return 0;
324     
325     
326     out_dir:
327     	if (dir_de) {
328     		kunmap(dir_page);
329     		page_cache_release(dir_page);
330     	}
331     out_old:
332     	kunmap(old_page);
333     	page_cache_release(old_page);
334     out:
335     	return err;
336     }
337     
338     struct inode_operations ext2_dir_inode_operations = {
339     	create:		ext2_create,
340     	lookup:		ext2_lookup,
341     	link:		ext2_link,
342     	unlink:		ext2_unlink,
343     	symlink:	ext2_symlink,
344     	mkdir:		ext2_mkdir,
345     	rmdir:		ext2_rmdir,
346     	mknod:		ext2_mknod,
347     	rename:		ext2_rename,
348     };
349