[PATCH] x86-64 - new memory map handling
[linux-2.6/history.git] / fs / ext2 / namei.c
blob50eadb13e9a882f3d2fcc76da286ccbe9c269db0
1 /*
2 * linux/fs/ext2/namei.c
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
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.
13 * The only non-static object here is ext2_dir_inode_operations.
15 * TODO: get rid of kmap() use, add readahead.
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)
22 * from
24 * linux/fs/minix/namei.c
26 * Copyright (C) 1991, 1992 Linus Torvalds
28 * Big-endian to little-endian byte-swapping/bitmaps by
29 * David S. Miller (davem@caip.rutgers.edu), 1995
32 #include "ext2.h"
33 #include <linux/pagemap.h>
36 * Couple of helper functions - make the code slightly cleaner.
39 static inline void ext2_inc_count(struct inode *inode)
41 inode->i_nlink++;
42 mark_inode_dirty(inode);
45 static inline void ext2_dec_count(struct inode *inode)
47 inode->i_nlink--;
48 mark_inode_dirty(inode);
51 static inline int ext2_add_nondir(struct dentry *dentry, struct inode *inode)
53 int err = ext2_add_link(dentry, inode);
54 if (!err) {
55 d_instantiate(dentry, inode);
56 return 0;
58 ext2_dec_count(inode);
59 iput(inode);
60 return err;
64 * Methods themselves.
67 static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry)
69 struct inode * inode;
70 ino_t ino;
72 if (dentry->d_name.len > EXT2_NAME_LEN)
73 return ERR_PTR(-ENAMETOOLONG);
75 ino = ext2_inode_by_name(dir, dentry);
76 inode = NULL;
77 if (ino) {
78 inode = iget(dir->i_sb, ino);
79 if (!inode)
80 return ERR_PTR(-EACCES);
82 if (inode)
83 return d_splice_alias(inode, dentry);
84 d_add(dentry, inode);
85 return NULL;
88 struct dentry *ext2_get_parent(struct dentry *child)
90 unsigned long ino;
91 struct dentry *parent;
92 struct inode *inode;
93 struct dentry dotdot;
95 dotdot.d_name.name = "..";
96 dotdot.d_name.len = 2;
98 ino = ext2_inode_by_name(child->d_inode, &dotdot);
99 if (!ino)
100 return ERR_PTR(-ENOENT);
101 inode = iget(child->d_inode->i_sb, ino);
103 if (!inode)
104 return ERR_PTR(-EACCES);
105 parent = d_alloc_anon(inode);
106 if (!parent) {
107 iput(inode);
108 parent = ERR_PTR(-ENOMEM);
110 return parent;
114 * By the time this is called, we already have created
115 * the directory cache entry for the new file, but it
116 * is so far negative - it has no inode.
118 * If the create succeeds, we fill in the inode information
119 * with d_instantiate().
121 static int ext2_create (struct inode * dir, struct dentry * dentry, int mode)
123 struct inode * inode = ext2_new_inode (dir, mode);
124 int err = PTR_ERR(inode);
125 if (!IS_ERR(inode)) {
126 inode->i_op = &ext2_file_inode_operations;
127 inode->i_fop = &ext2_file_operations;
128 inode->i_mapping->a_ops = &ext2_aops;
129 mark_inode_dirty(inode);
130 err = ext2_add_nondir(dentry, inode);
132 return err;
135 static int ext2_mknod (struct inode * dir, struct dentry *dentry, int mode, int rdev)
137 struct inode * inode = ext2_new_inode (dir, mode);
138 int err = PTR_ERR(inode);
139 if (!IS_ERR(inode)) {
140 init_special_inode(inode, mode, rdev);
141 mark_inode_dirty(inode);
142 err = ext2_add_nondir(dentry, inode);
144 return err;
147 static int ext2_symlink (struct inode * dir, struct dentry * dentry,
148 const char * symname)
150 struct super_block * sb = dir->i_sb;
151 int err = -ENAMETOOLONG;
152 unsigned l = strlen(symname)+1;
153 struct inode * inode;
155 if (l > sb->s_blocksize)
156 goto out;
158 inode = ext2_new_inode (dir, S_IFLNK | S_IRWXUGO);
159 err = PTR_ERR(inode);
160 if (IS_ERR(inode))
161 goto out;
163 if (l > sizeof (EXT2_I(inode)->i_data)) {
164 /* slow symlink */
165 inode->i_op = &page_symlink_inode_operations;
166 inode->i_mapping->a_ops = &ext2_aops;
167 err = page_symlink(inode, symname, l);
168 if (err)
169 goto out_fail;
170 } else {
171 /* fast symlink */
172 inode->i_op = &ext2_fast_symlink_inode_operations;
173 memcpy((char*)(EXT2_I(inode)->i_data),symname,l);
174 inode->i_size = l-1;
176 mark_inode_dirty(inode);
178 err = ext2_add_nondir(dentry, inode);
179 out:
180 return err;
182 out_fail:
183 ext2_dec_count(inode);
184 iput (inode);
185 goto out;
188 static int ext2_link (struct dentry * old_dentry, struct inode * dir,
189 struct dentry *dentry)
191 struct inode *inode = old_dentry->d_inode;
193 if (inode->i_nlink >= EXT2_LINK_MAX)
194 return -EMLINK;
196 inode->i_ctime = CURRENT_TIME;
197 ext2_inc_count(inode);
198 atomic_inc(&inode->i_count);
200 return ext2_add_nondir(dentry, inode);
203 static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)
205 struct inode * inode;
206 int err = -EMLINK;
208 if (dir->i_nlink >= EXT2_LINK_MAX)
209 goto out;
211 ext2_inc_count(dir);
213 inode = ext2_new_inode (dir, S_IFDIR | mode);
214 err = PTR_ERR(inode);
215 if (IS_ERR(inode))
216 goto out_dir;
218 inode->i_op = &ext2_dir_inode_operations;
219 inode->i_fop = &ext2_dir_operations;
220 inode->i_mapping->a_ops = &ext2_aops;
222 ext2_inc_count(inode);
224 err = ext2_make_empty(inode, dir);
225 if (err)
226 goto out_fail;
228 err = ext2_add_link(dentry, inode);
229 if (err)
230 goto out_fail;
232 d_instantiate(dentry, inode);
233 out:
234 return err;
236 out_fail:
237 ext2_dec_count(inode);
238 ext2_dec_count(inode);
239 iput(inode);
240 out_dir:
241 ext2_dec_count(dir);
242 goto out;
245 static int ext2_unlink(struct inode * dir, struct dentry *dentry)
247 struct inode * inode = dentry->d_inode;
248 struct ext2_dir_entry_2 * de;
249 struct page * page;
250 int err = -ENOENT;
252 de = ext2_find_entry (dir, dentry, &page);
253 if (!de)
254 goto out;
256 err = ext2_delete_entry (de, page);
257 if (err)
258 goto out;
260 inode->i_ctime = dir->i_ctime;
261 ext2_dec_count(inode);
262 err = 0;
263 out:
264 return err;
267 static int ext2_rmdir (struct inode * dir, struct dentry *dentry)
269 struct inode * inode = dentry->d_inode;
270 int err = -ENOTEMPTY;
272 if (ext2_empty_dir(inode)) {
273 err = ext2_unlink(dir, dentry);
274 if (!err) {
275 inode->i_size = 0;
276 ext2_dec_count(inode);
277 ext2_dec_count(dir);
280 return err;
283 static int ext2_rename (struct inode * old_dir, struct dentry * old_dentry,
284 struct inode * new_dir, struct dentry * new_dentry )
286 struct inode * old_inode = old_dentry->d_inode;
287 struct inode * new_inode = new_dentry->d_inode;
288 struct page * dir_page = NULL;
289 struct ext2_dir_entry_2 * dir_de = NULL;
290 struct page * old_page;
291 struct ext2_dir_entry_2 * old_de;
292 int err = -ENOENT;
294 old_de = ext2_find_entry (old_dir, old_dentry, &old_page);
295 if (!old_de)
296 goto out;
298 if (S_ISDIR(old_inode->i_mode)) {
299 err = -EIO;
300 dir_de = ext2_dotdot(old_inode, &dir_page);
301 if (!dir_de)
302 goto out_old;
305 if (new_inode) {
306 struct page *new_page;
307 struct ext2_dir_entry_2 *new_de;
309 err = -ENOTEMPTY;
310 if (dir_de && !ext2_empty_dir (new_inode))
311 goto out_dir;
313 err = -ENOENT;
314 new_de = ext2_find_entry (new_dir, new_dentry, &new_page);
315 if (!new_de)
316 goto out_dir;
317 ext2_inc_count(old_inode);
318 ext2_set_link(new_dir, new_de, new_page, old_inode);
319 new_inode->i_ctime = CURRENT_TIME;
320 if (dir_de)
321 new_inode->i_nlink--;
322 ext2_dec_count(new_inode);
323 } else {
324 if (dir_de) {
325 err = -EMLINK;
326 if (new_dir->i_nlink >= EXT2_LINK_MAX)
327 goto out_dir;
329 ext2_inc_count(old_inode);
330 err = ext2_add_link(new_dentry, old_inode);
331 if (err) {
332 ext2_dec_count(old_inode);
333 goto out_dir;
335 if (dir_de)
336 ext2_inc_count(new_dir);
339 ext2_delete_entry (old_de, old_page);
340 ext2_dec_count(old_inode);
342 if (dir_de) {
343 ext2_set_link(old_inode, dir_de, dir_page, new_dir);
344 ext2_dec_count(old_dir);
346 return 0;
349 out_dir:
350 if (dir_de) {
351 kunmap(dir_page);
352 page_cache_release(dir_page);
354 out_old:
355 kunmap(old_page);
356 page_cache_release(old_page);
357 out:
358 return err;
361 struct inode_operations ext2_dir_inode_operations = {
362 .create = ext2_create,
363 .lookup = ext2_lookup,
364 .link = ext2_link,
365 .unlink = ext2_unlink,
366 .symlink = ext2_symlink,
367 .mkdir = ext2_mkdir,
368 .rmdir = ext2_rmdir,
369 .mknod = ext2_mknod,
370 .rename = ext2_rename,