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