xref: /openbmc/linux/fs/ufs/namei.c (revision 3257545e)
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 
209 	inode_inc_link_count(inode);
210 
211 	err = ufs_make_empty(inode, dir);
212 	if (err)
213 		goto out_fail;
214 
215 	err = ufs_add_link(dentry, inode);
216 	if (err)
217 		goto out_fail;
218 	unlock_kernel();
219 
220 	d_instantiate(dentry, inode);
221 out:
222 	return err;
223 
224 out_fail:
225 	inode_dec_link_count(inode);
226 	inode_dec_link_count(inode);
227 	iput (inode);
228 out_dir:
229 	inode_dec_link_count(dir);
230 	unlock_kernel();
231 	goto out;
232 }
233 
234 static int ufs_unlink(struct inode * dir, struct dentry *dentry)
235 {
236 	struct inode * inode = dentry->d_inode;
237 	struct buffer_head * bh;
238 	struct ufs_dir_entry * de;
239 	int err = -ENOENT;
240 
241 	lock_kernel();
242 	de = ufs_find_entry (dentry, &bh);
243 	if (!de)
244 		goto out;
245 
246 	err = ufs_delete_entry (dir, de, bh);
247 	if (err)
248 		goto out;
249 
250 	inode->i_ctime = dir->i_ctime;
251 	inode_dec_link_count(inode);
252 	err = 0;
253 out:
254 	unlock_kernel();
255 	return err;
256 }
257 
258 static int ufs_rmdir (struct inode * dir, struct dentry *dentry)
259 {
260 	struct inode * inode = dentry->d_inode;
261 	int err= -ENOTEMPTY;
262 
263 	lock_kernel();
264 	if (ufs_empty_dir (inode)) {
265 		err = ufs_unlink(dir, dentry);
266 		if (!err) {
267 			inode->i_size = 0;
268 			inode_dec_link_count(inode);
269 			inode_dec_link_count(dir);
270 		}
271 	}
272 	unlock_kernel();
273 	return err;
274 }
275 
276 static int ufs_rename (struct inode * old_dir, struct dentry * old_dentry,
277 	struct inode * new_dir,	struct dentry * new_dentry )
278 {
279 	struct inode *old_inode = old_dentry->d_inode;
280 	struct inode *new_inode = new_dentry->d_inode;
281 	struct buffer_head *dir_bh = NULL;
282 	struct ufs_dir_entry *dir_de = NULL;
283 	struct buffer_head *old_bh;
284 	struct ufs_dir_entry *old_de;
285 	int err = -ENOENT;
286 
287 	lock_kernel();
288 	old_de = ufs_find_entry (old_dentry, &old_bh);
289 	if (!old_de)
290 		goto out;
291 
292 	if (S_ISDIR(old_inode->i_mode)) {
293 		err = -EIO;
294 		dir_de = ufs_dotdot(old_inode, &dir_bh);
295 		if (!dir_de)
296 			goto out_old;
297 	}
298 
299 	if (new_inode) {
300 		struct buffer_head *new_bh;
301 		struct ufs_dir_entry *new_de;
302 
303 		err = -ENOTEMPTY;
304 		if (dir_de && !ufs_empty_dir (new_inode))
305 			goto out_dir;
306 		err = -ENOENT;
307 		new_de = ufs_find_entry (new_dentry, &new_bh);
308 		if (!new_de)
309 			goto out_dir;
310 		inode_inc_link_count(old_inode);
311 		ufs_set_link(new_dir, new_de, new_bh, old_inode);
312 		new_inode->i_ctime = CURRENT_TIME_SEC;
313 		if (dir_de)
314 			new_inode->i_nlink--;
315 		inode_dec_link_count(new_inode);
316 	} else {
317 		if (dir_de) {
318 			err = -EMLINK;
319 			if (new_dir->i_nlink >= UFS_LINK_MAX)
320 				goto out_dir;
321 		}
322 		inode_inc_link_count(old_inode);
323 		err = ufs_add_link(new_dentry, old_inode);
324 		if (err) {
325 			inode_dec_link_count(old_inode);
326 			goto out_dir;
327 		}
328 		if (dir_de)
329 			inode_inc_link_count(new_dir);
330 	}
331 
332 	ufs_delete_entry (old_dir, old_de, old_bh);
333 
334 	inode_dec_link_count(old_inode);
335 
336 	if (dir_de) {
337 		ufs_set_link(old_inode, dir_de, dir_bh, new_dir);
338 		inode_dec_link_count(old_dir);
339 	}
340 	unlock_kernel();
341 	return 0;
342 
343 out_dir:
344 	if (dir_de)
345 		brelse(dir_bh);
346 out_old:
347 	brelse (old_bh);
348 out:
349 	unlock_kernel();
350 	return err;
351 }
352 
353 struct inode_operations ufs_dir_inode_operations = {
354 	.create		= ufs_create,
355 	.lookup		= ufs_lookup,
356 	.link		= ufs_link,
357 	.unlink		= ufs_unlink,
358 	.symlink	= ufs_symlink,
359 	.mkdir		= ufs_mkdir,
360 	.rmdir		= ufs_rmdir,
361 	.mknod		= ufs_mknod,
362 	.rename		= ufs_rename,
363 };
364