xref: /openbmc/linux/fs/ufs/namei.c (revision 826843a3)
1 /*
2  * linux/fs/ufs/namei.c
3  *
4  * Copyright (C) 1998
5  * Daniel Pirkl <daniel.pirkl@email.cz>
6  * Charles University, Faculty of Mathematics and Physics
7  *
8  *  from
9  *
10  *  linux/fs/ext2/namei.c
11  *
12  * Copyright (C) 1992, 1993, 1994, 1995
13  * Remy Card (card@masi.ibp.fr)
14  * Laboratoire MASI - Institut Blaise Pascal
15  * Universite Pierre et Marie Curie (Paris VI)
16  *
17  *  from
18  *
19  *  linux/fs/minix/namei.c
20  *
21  *  Copyright (C) 1991, 1992  Linus Torvalds
22  *
23  *  Big-endian to little-endian byte-swapping/bitmaps by
24  *        David S. Miller (davem@caip.rutgers.edu), 1995
25  */
26 
27 #include <linux/time.h>
28 #include <linux/fs.h>
29 #include <linux/ufs_fs.h>
30 #include <linux/smp_lock.h>
31 #include <linux/buffer_head.h>
32 #include "swab.h"	/* will go away - see comment in mknod() */
33 #include "util.h"
34 
35 /*
36 #undef UFS_NAMEI_DEBUG
37 */
38 #define UFS_NAMEI_DEBUG
39 
40 #ifdef UFS_NAMEI_DEBUG
41 #define UFSD(x) printk("(%s, %d), %s: ", __FILE__, __LINE__, __FUNCTION__); printk x;
42 #else
43 #define UFSD(x)
44 #endif
45 
46 static inline int ufs_add_nondir(struct dentry *dentry, struct inode *inode)
47 {
48 	int err = ufs_add_link(dentry, inode);
49 	if (!err) {
50 		d_instantiate(dentry, inode);
51 		return 0;
52 	}
53 	inode_dec_link_count(inode);
54 	iput(inode);
55 	return err;
56 }
57 
58 static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, struct nameidata *nd)
59 {
60 	struct inode * inode = NULL;
61 	ino_t ino;
62 
63 	if (dentry->d_name.len > UFS_MAXNAMLEN)
64 		return ERR_PTR(-ENAMETOOLONG);
65 
66 	lock_kernel();
67 	ino = ufs_inode_by_name(dir, dentry);
68 	if (ino) {
69 		inode = iget(dir->i_sb, ino);
70 		if (!inode) {
71 			unlock_kernel();
72 			return ERR_PTR(-EACCES);
73 		}
74 	}
75 	unlock_kernel();
76 	d_add(dentry, inode);
77 	return NULL;
78 }
79 
80 /*
81  * By the time this is called, we already have created
82  * the directory cache entry for the new file, but it
83  * is so far negative - it has no inode.
84  *
85  * If the create succeeds, we fill in the inode information
86  * with d_instantiate().
87  */
88 static int ufs_create (struct inode * dir, struct dentry * dentry, int mode,
89 		struct nameidata *nd)
90 {
91 	struct inode * inode = ufs_new_inode(dir, mode);
92 	int err = PTR_ERR(inode);
93 	if (!IS_ERR(inode)) {
94 		inode->i_op = &ufs_file_inode_operations;
95 		inode->i_fop = &ufs_file_operations;
96 		inode->i_mapping->a_ops = &ufs_aops;
97 		mark_inode_dirty(inode);
98 		lock_kernel();
99 		err = ufs_add_nondir(dentry, inode);
100 		unlock_kernel();
101 	}
102 	return err;
103 }
104 
105 static int ufs_mknod (struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
106 {
107 	struct inode *inode;
108 	int err;
109 
110 	if (!old_valid_dev(rdev))
111 		return -EINVAL;
112 	inode = ufs_new_inode(dir, mode);
113 	err = PTR_ERR(inode);
114 	if (!IS_ERR(inode)) {
115 		init_special_inode(inode, mode, rdev);
116 		/* NOTE: that'll go when we get wide dev_t */
117 		ufs_set_inode_dev(inode->i_sb, UFS_I(inode), rdev);
118 		mark_inode_dirty(inode);
119 		lock_kernel();
120 		err = ufs_add_nondir(dentry, inode);
121 		unlock_kernel();
122 	}
123 	return err;
124 }
125 
126 static int ufs_symlink (struct inode * dir, struct dentry * dentry,
127 	const char * symname)
128 {
129 	struct super_block * sb = dir->i_sb;
130 	int err = -ENAMETOOLONG;
131 	unsigned l = strlen(symname)+1;
132 	struct inode * inode;
133 
134 	if (l > sb->s_blocksize)
135 		goto out;
136 
137 	lock_kernel();
138 	inode = ufs_new_inode(dir, S_IFLNK | S_IRWXUGO);
139 	err = PTR_ERR(inode);
140 	if (IS_ERR(inode))
141 		goto out;
142 
143 	if (l > UFS_SB(sb)->s_uspi->s_maxsymlinklen) {
144 		/* slow symlink */
145 		inode->i_op = &page_symlink_inode_operations;
146 		inode->i_mapping->a_ops = &ufs_aops;
147 		err = page_symlink(inode, symname, l);
148 		if (err)
149 			goto out_fail;
150 	} else {
151 		/* fast symlink */
152 		inode->i_op = &ufs_fast_symlink_inode_operations;
153 		memcpy((char*)&UFS_I(inode)->i_u1.i_data,symname,l);
154 		inode->i_size = l-1;
155 	}
156 	mark_inode_dirty(inode);
157 
158 	err = ufs_add_nondir(dentry, inode);
159 out:
160 	unlock_kernel();
161 	return err;
162 
163 out_fail:
164 	inode_dec_link_count(inode);
165 	iput(inode);
166 	goto out;
167 }
168 
169 static int ufs_link (struct dentry * old_dentry, struct inode * dir,
170 	struct dentry *dentry)
171 {
172 	struct inode *inode = old_dentry->d_inode;
173 	int error;
174 
175 	lock_kernel();
176 	if (inode->i_nlink >= UFS_LINK_MAX) {
177 		unlock_kernel();
178 		return -EMLINK;
179 	}
180 
181 	inode->i_ctime = CURRENT_TIME_SEC;
182 	inode_inc_link_count(inode);
183 	atomic_inc(&inode->i_count);
184 
185 	error = ufs_add_nondir(dentry, inode);
186 	unlock_kernel();
187 	return error;
188 }
189 
190 static int ufs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
191 {
192 	struct inode * inode;
193 	int err = -EMLINK;
194 
195 	if (dir->i_nlink >= UFS_LINK_MAX)
196 		goto out;
197 
198 	lock_kernel();
199 	inode_inc_link_count(dir);
200 
201 	inode = ufs_new_inode(dir, S_IFDIR|mode);
202 	err = PTR_ERR(inode);
203 	if (IS_ERR(inode))
204 		goto out_dir;
205 
206 	inode->i_op = &ufs_dir_inode_operations;
207 	inode->i_fop = &ufs_dir_operations;
208 	inode->i_mapping->a_ops = &ufs_aops;
209 
210 	inode_inc_link_count(inode);
211 
212 	err = ufs_make_empty(inode, dir);
213 	if (err)
214 		goto out_fail;
215 
216 	err = ufs_add_link(dentry, inode);
217 	if (err)
218 		goto out_fail;
219 	unlock_kernel();
220 
221 	d_instantiate(dentry, inode);
222 out:
223 	return err;
224 
225 out_fail:
226 	inode_dec_link_count(inode);
227 	inode_dec_link_count(inode);
228 	iput (inode);
229 out_dir:
230 	inode_dec_link_count(dir);
231 	unlock_kernel();
232 	goto out;
233 }
234 
235 static int ufs_unlink(struct inode * dir, struct dentry *dentry)
236 {
237 	struct inode * inode = dentry->d_inode;
238 	struct buffer_head * bh;
239 	struct ufs_dir_entry * de;
240 	int err = -ENOENT;
241 
242 	lock_kernel();
243 	de = ufs_find_entry (dentry, &bh);
244 	if (!de)
245 		goto out;
246 
247 	err = ufs_delete_entry (dir, de, bh);
248 	if (err)
249 		goto out;
250 
251 	inode->i_ctime = dir->i_ctime;
252 	inode_dec_link_count(inode);
253 	err = 0;
254 out:
255 	unlock_kernel();
256 	return err;
257 }
258 
259 static int ufs_rmdir (struct inode * dir, struct dentry *dentry)
260 {
261 	struct inode * inode = dentry->d_inode;
262 	int err= -ENOTEMPTY;
263 
264 	lock_kernel();
265 	if (ufs_empty_dir (inode)) {
266 		err = ufs_unlink(dir, dentry);
267 		if (!err) {
268 			inode->i_size = 0;
269 			inode_dec_link_count(inode);
270 			inode_dec_link_count(dir);
271 		}
272 	}
273 	unlock_kernel();
274 	return err;
275 }
276 
277 static int ufs_rename (struct inode * old_dir, struct dentry * old_dentry,
278 	struct inode * new_dir,	struct dentry * new_dentry )
279 {
280 	struct inode *old_inode = old_dentry->d_inode;
281 	struct inode *new_inode = new_dentry->d_inode;
282 	struct buffer_head *dir_bh = NULL;
283 	struct ufs_dir_entry *dir_de = NULL;
284 	struct buffer_head *old_bh;
285 	struct ufs_dir_entry *old_de;
286 	int err = -ENOENT;
287 
288 	lock_kernel();
289 	old_de = ufs_find_entry (old_dentry, &old_bh);
290 	if (!old_de)
291 		goto out;
292 
293 	if (S_ISDIR(old_inode->i_mode)) {
294 		err = -EIO;
295 		dir_de = ufs_dotdot(old_inode, &dir_bh);
296 		if (!dir_de)
297 			goto out_old;
298 	}
299 
300 	if (new_inode) {
301 		struct buffer_head *new_bh;
302 		struct ufs_dir_entry *new_de;
303 
304 		err = -ENOTEMPTY;
305 		if (dir_de && !ufs_empty_dir (new_inode))
306 			goto out_dir;
307 		err = -ENOENT;
308 		new_de = ufs_find_entry (new_dentry, &new_bh);
309 		if (!new_de)
310 			goto out_dir;
311 		inode_inc_link_count(old_inode);
312 		ufs_set_link(new_dir, new_de, new_bh, old_inode);
313 		new_inode->i_ctime = CURRENT_TIME_SEC;
314 		if (dir_de)
315 			new_inode->i_nlink--;
316 		inode_dec_link_count(new_inode);
317 	} else {
318 		if (dir_de) {
319 			err = -EMLINK;
320 			if (new_dir->i_nlink >= UFS_LINK_MAX)
321 				goto out_dir;
322 		}
323 		inode_inc_link_count(old_inode);
324 		err = ufs_add_link(new_dentry, old_inode);
325 		if (err) {
326 			inode_dec_link_count(old_inode);
327 			goto out_dir;
328 		}
329 		if (dir_de)
330 			inode_inc_link_count(new_dir);
331 	}
332 
333 	ufs_delete_entry (old_dir, old_de, old_bh);
334 
335 	inode_dec_link_count(old_inode);
336 
337 	if (dir_de) {
338 		ufs_set_link(old_inode, dir_de, dir_bh, new_dir);
339 		inode_dec_link_count(old_dir);
340 	}
341 	unlock_kernel();
342 	return 0;
343 
344 out_dir:
345 	if (dir_de)
346 		brelse(dir_bh);
347 out_old:
348 	brelse (old_bh);
349 out:
350 	unlock_kernel();
351 	return err;
352 }
353 
354 struct inode_operations ufs_dir_inode_operations = {
355 	.create		= ufs_create,
356 	.lookup		= ufs_lookup,
357 	.link		= ufs_link,
358 	.unlink		= ufs_unlink,
359 	.symlink	= ufs_symlink,
360 	.mkdir		= ufs_mkdir,
361 	.rmdir		= ufs_rmdir,
362 	.mknod		= ufs_mknod,
363 	.rename		= ufs_rename,
364 };
365