xref: /openbmc/linux/fs/nilfs2/namei.c (revision d37cf9b63113f13d742713881ce691fc615d8b3b)
1ae98043fSRyusuke Konishi // SPDX-License-Identifier: GPL-2.0+
2d2500652SRyusuke Konishi /*
394ee1d91SRyusuke Konishi  * NILFS pathname lookup operations.
4d2500652SRyusuke Konishi  *
5d2500652SRyusuke Konishi  * Copyright (C) 2005-2008 Nippon Telegraph and Telephone Corporation.
6d2500652SRyusuke Konishi  *
74b420ab4SRyusuke Konishi  * Modified for NILFS by Amagai Yoshiji and Ryusuke Konishi.
8d2500652SRyusuke Konishi  */
9d2500652SRyusuke Konishi /*
10d2500652SRyusuke Konishi  *  linux/fs/ext2/namei.c
11d2500652SRyusuke Konishi  *
12d2500652SRyusuke Konishi  * Copyright (C) 1992, 1993, 1994, 1995
13d2500652SRyusuke Konishi  * Remy Card (card@masi.ibp.fr)
14d2500652SRyusuke Konishi  * Laboratoire MASI - Institut Blaise Pascal
15d2500652SRyusuke Konishi  * Universite Pierre et Marie Curie (Paris VI)
16d2500652SRyusuke Konishi  *
17d2500652SRyusuke Konishi  *  from
18d2500652SRyusuke Konishi  *
19d2500652SRyusuke Konishi  *  linux/fs/minix/namei.c
20d2500652SRyusuke Konishi  *
21d2500652SRyusuke Konishi  *  Copyright (C) 1991, 1992  Linus Torvalds
22d2500652SRyusuke Konishi  *
23d2500652SRyusuke Konishi  *  Big-endian to little-endian byte-swapping/bitmaps by
24d2500652SRyusuke Konishi  *        David S. Miller (davem@caip.rutgers.edu), 1995
25d2500652SRyusuke Konishi  */
26d2500652SRyusuke Konishi 
27d2500652SRyusuke Konishi #include <linux/pagemap.h>
28d2500652SRyusuke Konishi #include "nilfs.h"
298e656fd5SRyusuke Konishi #include "export.h"
30d2500652SRyusuke Konishi 
318e656fd5SRyusuke Konishi #define NILFS_FID_SIZE_NON_CONNECTABLE \
328e656fd5SRyusuke Konishi 	(offsetof(struct nilfs_fid, parent_gen) / 4)
338e656fd5SRyusuke Konishi #define NILFS_FID_SIZE_CONNECTABLE	(sizeof(struct nilfs_fid) / 4)
34d2500652SRyusuke Konishi 
nilfs_add_nondir(struct dentry * dentry,struct inode * inode)35d2500652SRyusuke Konishi static inline int nilfs_add_nondir(struct dentry *dentry, struct inode *inode)
36d2500652SRyusuke Konishi {
37d2500652SRyusuke Konishi 	int err = nilfs_add_link(dentry, inode);
384ad364caSRyusuke Konishi 
39d2500652SRyusuke Konishi 	if (!err) {
401e2e547aSAl Viro 		d_instantiate_new(dentry, inode);
41d2500652SRyusuke Konishi 		return 0;
42d2500652SRyusuke Konishi 	}
43d2500652SRyusuke Konishi 	inode_dec_link_count(inode);
44705304a8SRyusuke Konishi 	unlock_new_inode(inode);
45d2500652SRyusuke Konishi 	iput(inode);
46d2500652SRyusuke Konishi 	return err;
47d2500652SRyusuke Konishi }
48d2500652SRyusuke Konishi 
49d2500652SRyusuke Konishi /*
50d2500652SRyusuke Konishi  * Methods themselves.
51d2500652SRyusuke Konishi  */
52d2500652SRyusuke Konishi 
53d2500652SRyusuke Konishi static struct dentry *
nilfs_lookup(struct inode * dir,struct dentry * dentry,unsigned int flags)5400cd8dd3SAl Viro nilfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
55d2500652SRyusuke Konishi {
56d2500652SRyusuke Konishi 	struct inode *inode;
57d2500652SRyusuke Konishi 	ino_t ino;
589698088aSRyusuke Konishi 	int res;
59d2500652SRyusuke Konishi 
60d2500652SRyusuke Konishi 	if (dentry->d_name.len > NILFS_NAME_LEN)
61d2500652SRyusuke Konishi 		return ERR_PTR(-ENAMETOOLONG);
62d2500652SRyusuke Konishi 
639698088aSRyusuke Konishi 	res = nilfs_inode_by_name(dir, &dentry->d_name, &ino);
649698088aSRyusuke Konishi 	if (res) {
659698088aSRyusuke Konishi 		if (res != -ENOENT)
669698088aSRyusuke Konishi 			return ERR_PTR(res);
679698088aSRyusuke Konishi 		inode = NULL;
689698088aSRyusuke Konishi 	} else {
699698088aSRyusuke Konishi 		inode = nilfs_iget(dir->i_sb, NILFS_I(dir)->i_root, ino);
70284760b3SEdward Adam Davis 		if (inode == ERR_PTR(-ESTALE)) {
71284760b3SEdward Adam Davis 			nilfs_error(dir->i_sb,
72284760b3SEdward Adam Davis 					"deleted inode referenced: %lu", ino);
73284760b3SEdward Adam Davis 			return ERR_PTR(-EIO);
74284760b3SEdward Adam Davis 		}
759698088aSRyusuke Konishi 	}
769698088aSRyusuke Konishi 
77d2500652SRyusuke Konishi 	return d_splice_alias(inode, dentry);
78d2500652SRyusuke Konishi }
79d2500652SRyusuke Konishi 
80d2500652SRyusuke Konishi /*
81d2500652SRyusuke Konishi  * By the time this is called, we already have created
82d2500652SRyusuke Konishi  * the directory cache entry for the new file, but it
83d2500652SRyusuke Konishi  * is so far negative - it has no inode.
84d2500652SRyusuke Konishi  *
85d2500652SRyusuke Konishi  * If the create succeeds, we fill in the inode information
86d2500652SRyusuke Konishi  * with d_instantiate().
87d2500652SRyusuke Konishi  */
nilfs_create(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,umode_t mode,bool excl)886c960e68SChristian Brauner static int nilfs_create(struct mnt_idmap *idmap, struct inode *dir,
89549c7297SChristian Brauner 			struct dentry *dentry, umode_t mode, bool excl)
90d2500652SRyusuke Konishi {
91d2500652SRyusuke Konishi 	struct inode *inode;
92d2500652SRyusuke Konishi 	struct nilfs_transaction_info ti;
9347420c79SRyusuke Konishi 	int err;
94d2500652SRyusuke Konishi 
95d2500652SRyusuke Konishi 	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
96d2500652SRyusuke Konishi 	if (err)
97d2500652SRyusuke Konishi 		return err;
98d2500652SRyusuke Konishi 	inode = nilfs_new_inode(dir, mode);
99d2500652SRyusuke Konishi 	err = PTR_ERR(inode);
100d2500652SRyusuke Konishi 	if (!IS_ERR(inode)) {
101d2500652SRyusuke Konishi 		inode->i_op = &nilfs_file_inode_operations;
102d2500652SRyusuke Konishi 		inode->i_fop = &nilfs_file_operations;
103d2500652SRyusuke Konishi 		inode->i_mapping->a_ops = &nilfs_aops;
104abdb318bSJiro SEKIBA 		nilfs_mark_inode_dirty(inode);
105d2500652SRyusuke Konishi 		err = nilfs_add_nondir(dentry, inode);
106d2500652SRyusuke Konishi 	}
10747420c79SRyusuke Konishi 	if (!err)
10847420c79SRyusuke Konishi 		err = nilfs_transaction_commit(dir->i_sb);
10947420c79SRyusuke Konishi 	else
11047420c79SRyusuke Konishi 		nilfs_transaction_abort(dir->i_sb);
11147420c79SRyusuke Konishi 
11247420c79SRyusuke Konishi 	return err;
113d2500652SRyusuke Konishi }
114d2500652SRyusuke Konishi 
115d2500652SRyusuke Konishi static int
nilfs_mknod(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,umode_t mode,dev_t rdev)1165ebb29beSChristian Brauner nilfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
117549c7297SChristian Brauner 	    struct dentry *dentry, umode_t mode, dev_t rdev)
118d2500652SRyusuke Konishi {
119d2500652SRyusuke Konishi 	struct inode *inode;
120d2500652SRyusuke Konishi 	struct nilfs_transaction_info ti;
12147420c79SRyusuke Konishi 	int err;
122d2500652SRyusuke Konishi 
123d2500652SRyusuke Konishi 	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
124d2500652SRyusuke Konishi 	if (err)
125d2500652SRyusuke Konishi 		return err;
126d2500652SRyusuke Konishi 	inode = nilfs_new_inode(dir, mode);
127d2500652SRyusuke Konishi 	err = PTR_ERR(inode);
128d2500652SRyusuke Konishi 	if (!IS_ERR(inode)) {
129d2500652SRyusuke Konishi 		init_special_inode(inode, inode->i_mode, rdev);
130abdb318bSJiro SEKIBA 		nilfs_mark_inode_dirty(inode);
131d2500652SRyusuke Konishi 		err = nilfs_add_nondir(dentry, inode);
132d2500652SRyusuke Konishi 	}
13347420c79SRyusuke Konishi 	if (!err)
13447420c79SRyusuke Konishi 		err = nilfs_transaction_commit(dir->i_sb);
13547420c79SRyusuke Konishi 	else
13647420c79SRyusuke Konishi 		nilfs_transaction_abort(dir->i_sb);
13747420c79SRyusuke Konishi 
13847420c79SRyusuke Konishi 	return err;
139d2500652SRyusuke Konishi }
140d2500652SRyusuke Konishi 
nilfs_symlink(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,const char * symname)1417a77db95SChristian Brauner static int nilfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
142549c7297SChristian Brauner 			 struct dentry *dentry, const char *symname)
143d2500652SRyusuke Konishi {
144d2500652SRyusuke Konishi 	struct nilfs_transaction_info ti;
145d2500652SRyusuke Konishi 	struct super_block *sb = dir->i_sb;
1460c6c44cbSRyusuke Konishi 	unsigned int l = strlen(symname) + 1;
147d2500652SRyusuke Konishi 	struct inode *inode;
14847420c79SRyusuke Konishi 	int err;
149d2500652SRyusuke Konishi 
150d2500652SRyusuke Konishi 	if (l > sb->s_blocksize)
151d2500652SRyusuke Konishi 		return -ENAMETOOLONG;
152d2500652SRyusuke Konishi 
153d2500652SRyusuke Konishi 	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
154d2500652SRyusuke Konishi 	if (err)
155d2500652SRyusuke Konishi 		return err;
156d2500652SRyusuke Konishi 
1573147db89SRyusuke Konishi 	inode = nilfs_new_inode(dir, S_IFLNK | 0777);
158d2500652SRyusuke Konishi 	err = PTR_ERR(inode);
159d2500652SRyusuke Konishi 	if (IS_ERR(inode))
160d2500652SRyusuke Konishi 		goto out;
161d2500652SRyusuke Konishi 
162d2500652SRyusuke Konishi 	/* slow symlink */
163d2500652SRyusuke Konishi 	inode->i_op = &nilfs_symlink_inode_operations;
16421fc61c7SAl Viro 	inode_nohighmem(inode);
1651246d86eSRyusuke Konishi 	mapping_set_gfp_mask(inode->i_mapping,
1661246d86eSRyusuke Konishi 			     mapping_gfp_constraint(inode->i_mapping,
1671246d86eSRyusuke Konishi 						    ~__GFP_FS));
168d2500652SRyusuke Konishi 	inode->i_mapping->a_ops = &nilfs_aops;
169d2500652SRyusuke Konishi 	err = page_symlink(inode, symname, l);
170d2500652SRyusuke Konishi 	if (err)
171d2500652SRyusuke Konishi 		goto out_fail;
172d2500652SRyusuke Konishi 
173d2500652SRyusuke Konishi 	/* mark_inode_dirty(inode); */
1749ca941d4SJiro SEKIBA 	/* page_symlink() do this */
175d2500652SRyusuke Konishi 
176d2500652SRyusuke Konishi 	err = nilfs_add_nondir(dentry, inode);
177d2500652SRyusuke Konishi out:
17847420c79SRyusuke Konishi 	if (!err)
17947420c79SRyusuke Konishi 		err = nilfs_transaction_commit(dir->i_sb);
18047420c79SRyusuke Konishi 	else
18147420c79SRyusuke Konishi 		nilfs_transaction_abort(dir->i_sb);
18247420c79SRyusuke Konishi 
18347420c79SRyusuke Konishi 	return err;
184d2500652SRyusuke Konishi 
185d2500652SRyusuke Konishi out_fail:
186565de406SJiro SEKIBA 	drop_nlink(inode);
187abdb318bSJiro SEKIBA 	nilfs_mark_inode_dirty(inode);
188705304a8SRyusuke Konishi 	unlock_new_inode(inode);
189d2500652SRyusuke Konishi 	iput(inode);
190d2500652SRyusuke Konishi 	goto out;
191d2500652SRyusuke Konishi }
192d2500652SRyusuke Konishi 
nilfs_link(struct dentry * old_dentry,struct inode * dir,struct dentry * dentry)193d2500652SRyusuke Konishi static int nilfs_link(struct dentry *old_dentry, struct inode *dir,
194d2500652SRyusuke Konishi 		      struct dentry *dentry)
195d2500652SRyusuke Konishi {
1962b0143b5SDavid Howells 	struct inode *inode = d_inode(old_dentry);
197d2500652SRyusuke Konishi 	struct nilfs_transaction_info ti;
19847420c79SRyusuke Konishi 	int err;
199d2500652SRyusuke Konishi 
200d2500652SRyusuke Konishi 	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
201d2500652SRyusuke Konishi 	if (err)
202d2500652SRyusuke Konishi 		return err;
203d2500652SRyusuke Konishi 
204e21d4f41SJeff Layton 	inode_set_ctime_current(inode);
205d2500652SRyusuke Konishi 	inode_inc_link_count(inode);
2067de9c6eeSAl Viro 	ihold(inode);
207d2500652SRyusuke Konishi 
208705304a8SRyusuke Konishi 	err = nilfs_add_link(dentry, inode);
209705304a8SRyusuke Konishi 	if (!err) {
210705304a8SRyusuke Konishi 		d_instantiate(dentry, inode);
21147420c79SRyusuke Konishi 		err = nilfs_transaction_commit(dir->i_sb);
212705304a8SRyusuke Konishi 	} else {
213705304a8SRyusuke Konishi 		inode_dec_link_count(inode);
214705304a8SRyusuke Konishi 		iput(inode);
21547420c79SRyusuke Konishi 		nilfs_transaction_abort(dir->i_sb);
216705304a8SRyusuke Konishi 	}
21747420c79SRyusuke Konishi 
21847420c79SRyusuke Konishi 	return err;
219d2500652SRyusuke Konishi }
220d2500652SRyusuke Konishi 
nilfs_mkdir(struct mnt_idmap * idmap,struct inode * dir,struct dentry * dentry,umode_t mode)221c54bd91eSChristian Brauner static int nilfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
222549c7297SChristian Brauner 		       struct dentry *dentry, umode_t mode)
223d2500652SRyusuke Konishi {
224d2500652SRyusuke Konishi 	struct inode *inode;
225d2500652SRyusuke Konishi 	struct nilfs_transaction_info ti;
22647420c79SRyusuke Konishi 	int err;
227d2500652SRyusuke Konishi 
228d2500652SRyusuke Konishi 	err = nilfs_transaction_begin(dir->i_sb, &ti, 1);
229d2500652SRyusuke Konishi 	if (err)
230d2500652SRyusuke Konishi 		return err;
231d2500652SRyusuke Konishi 
232565de406SJiro SEKIBA 	inc_nlink(dir);
233d2500652SRyusuke Konishi 
234d2500652SRyusuke Konishi 	inode = nilfs_new_inode(dir, S_IFDIR | mode);
235d2500652SRyusuke Konishi 	err = PTR_ERR(inode);
236d2500652SRyusuke Konishi 	if (IS_ERR(inode))
237d2500652SRyusuke Konishi 		goto out_dir;
238d2500652SRyusuke Konishi 
239d2500652SRyusuke Konishi 	inode->i_op = &nilfs_dir_inode_operations;
240d2500652SRyusuke Konishi 	inode->i_fop = &nilfs_dir_operations;
241d2500652SRyusuke Konishi 	inode->i_mapping->a_ops = &nilfs_aops;
242d2500652SRyusuke Konishi 
243565de406SJiro SEKIBA 	inc_nlink(inode);
244d2500652SRyusuke Konishi 
245d2500652SRyusuke Konishi 	err = nilfs_make_empty(inode, dir);
246d2500652SRyusuke Konishi 	if (err)
247d2500652SRyusuke Konishi 		goto out_fail;
248d2500652SRyusuke Konishi 
249d2500652SRyusuke Konishi 	err = nilfs_add_link(dentry, inode);
250d2500652SRyusuke Konishi 	if (err)
251d2500652SRyusuke Konishi 		goto out_fail;
252d2500652SRyusuke Konishi 
253abdb318bSJiro SEKIBA 	nilfs_mark_inode_dirty(inode);
2541e2e547aSAl Viro 	d_instantiate_new(dentry, inode);
255d2500652SRyusuke Konishi out:
25647420c79SRyusuke Konishi 	if (!err)
25747420c79SRyusuke Konishi 		err = nilfs_transaction_commit(dir->i_sb);
25847420c79SRyusuke Konishi 	else
25947420c79SRyusuke Konishi 		nilfs_transaction_abort(dir->i_sb);
26047420c79SRyusuke Konishi 
26147420c79SRyusuke Konishi 	return err;
262d2500652SRyusuke Konishi 
263d2500652SRyusuke Konishi out_fail:
264565de406SJiro SEKIBA 	drop_nlink(inode);
265565de406SJiro SEKIBA 	drop_nlink(inode);
266abdb318bSJiro SEKIBA 	nilfs_mark_inode_dirty(inode);
267705304a8SRyusuke Konishi 	unlock_new_inode(inode);
268d2500652SRyusuke Konishi 	iput(inode);
269d2500652SRyusuke Konishi out_dir:
270565de406SJiro SEKIBA 	drop_nlink(dir);
271abdb318bSJiro SEKIBA 	nilfs_mark_inode_dirty(dir);
272d2500652SRyusuke Konishi 	goto out;
273d2500652SRyusuke Konishi }
274d2500652SRyusuke Konishi 
nilfs_do_unlink(struct inode * dir,struct dentry * dentry)2754cd76c3cSJiro SEKIBA static int nilfs_do_unlink(struct inode *dir, struct dentry *dentry)
276d2500652SRyusuke Konishi {
277d2500652SRyusuke Konishi 	struct inode *inode;
278d2500652SRyusuke Konishi 	struct nilfs_dir_entry *de;
279d2500652SRyusuke Konishi 	struct page *page;
28047420c79SRyusuke Konishi 	int err;
281d2500652SRyusuke Konishi 
2820319003dSAl Viro 	de = nilfs_find_entry(dir, &dentry->d_name, &page);
2839698088aSRyusuke Konishi 	if (IS_ERR(de)) {
2849698088aSRyusuke Konishi 		err = PTR_ERR(de);
285d2500652SRyusuke Konishi 		goto out;
2869698088aSRyusuke Konishi 	}
287d2500652SRyusuke Konishi 
2882b0143b5SDavid Howells 	inode = d_inode(dentry);
289d2500652SRyusuke Konishi 	err = -EIO;
290d2500652SRyusuke Konishi 	if (le64_to_cpu(de->inode) != inode->i_ino)
291d2500652SRyusuke Konishi 		goto out;
292d2500652SRyusuke Konishi 
293d2500652SRyusuke Konishi 	if (!inode->i_nlink) {
294a1d0747aSJoe Perches 		nilfs_warn(inode->i_sb,
295d6517debSRyusuke Konishi 			   "deleting nonexistent file (ino=%lu), %d",
296d2500652SRyusuke Konishi 			   inode->i_ino, inode->i_nlink);
297bfe86848SMiklos Szeredi 		set_nlink(inode, 1);
298d2500652SRyusuke Konishi 	}
299d2500652SRyusuke Konishi 	err = nilfs_delete_entry(de, page);
300944a4f8fSRyusuke Konishi 	nilfs_put_page(page);
301d2500652SRyusuke Konishi 	if (err)
302d2500652SRyusuke Konishi 		goto out;
303d2500652SRyusuke Konishi 
304e21d4f41SJeff Layton 	inode_set_ctime_to_ts(inode, inode_get_ctime(dir));
305565de406SJiro SEKIBA 	drop_nlink(inode);
306d2500652SRyusuke Konishi 	err = 0;
307d2500652SRyusuke Konishi out:
3084cd76c3cSJiro SEKIBA 	return err;
3094cd76c3cSJiro SEKIBA }
3104cd76c3cSJiro SEKIBA 
nilfs_unlink(struct inode * dir,struct dentry * dentry)3114cd76c3cSJiro SEKIBA static int nilfs_unlink(struct inode *dir, struct dentry *dentry)
3124cd76c3cSJiro SEKIBA {
3134cd76c3cSJiro SEKIBA 	struct nilfs_transaction_info ti;
3144cd76c3cSJiro SEKIBA 	int err;
3154cd76c3cSJiro SEKIBA 
3164cd76c3cSJiro SEKIBA 	err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
3174cd76c3cSJiro SEKIBA 	if (err)
3184cd76c3cSJiro SEKIBA 		return err;
3194cd76c3cSJiro SEKIBA 
3204cd76c3cSJiro SEKIBA 	err = nilfs_do_unlink(dir, dentry);
3214cd76c3cSJiro SEKIBA 
3224cd76c3cSJiro SEKIBA 	if (!err) {
323abdb318bSJiro SEKIBA 		nilfs_mark_inode_dirty(dir);
3242b0143b5SDavid Howells 		nilfs_mark_inode_dirty(d_inode(dentry));
32547420c79SRyusuke Konishi 		err = nilfs_transaction_commit(dir->i_sb);
3264cd76c3cSJiro SEKIBA 	} else
32747420c79SRyusuke Konishi 		nilfs_transaction_abort(dir->i_sb);
32847420c79SRyusuke Konishi 
32947420c79SRyusuke Konishi 	return err;
330d2500652SRyusuke Konishi }
331d2500652SRyusuke Konishi 
nilfs_rmdir(struct inode * dir,struct dentry * dentry)332d2500652SRyusuke Konishi static int nilfs_rmdir(struct inode *dir, struct dentry *dentry)
333d2500652SRyusuke Konishi {
3342b0143b5SDavid Howells 	struct inode *inode = d_inode(dentry);
335d2500652SRyusuke Konishi 	struct nilfs_transaction_info ti;
33647420c79SRyusuke Konishi 	int err;
337d2500652SRyusuke Konishi 
338d2500652SRyusuke Konishi 	err = nilfs_transaction_begin(dir->i_sb, &ti, 0);
339d2500652SRyusuke Konishi 	if (err)
340d2500652SRyusuke Konishi 		return err;
341d2500652SRyusuke Konishi 
342d2500652SRyusuke Konishi 	err = -ENOTEMPTY;
343d2500652SRyusuke Konishi 	if (nilfs_empty_dir(inode)) {
3444cd76c3cSJiro SEKIBA 		err = nilfs_do_unlink(dir, dentry);
345d2500652SRyusuke Konishi 		if (!err) {
346d2500652SRyusuke Konishi 			inode->i_size = 0;
347565de406SJiro SEKIBA 			drop_nlink(inode);
348abdb318bSJiro SEKIBA 			nilfs_mark_inode_dirty(inode);
349565de406SJiro SEKIBA 			drop_nlink(dir);
350abdb318bSJiro SEKIBA 			nilfs_mark_inode_dirty(dir);
351d2500652SRyusuke Konishi 		}
352d2500652SRyusuke Konishi 	}
35347420c79SRyusuke Konishi 	if (!err)
35447420c79SRyusuke Konishi 		err = nilfs_transaction_commit(dir->i_sb);
35547420c79SRyusuke Konishi 	else
35647420c79SRyusuke Konishi 		nilfs_transaction_abort(dir->i_sb);
35747420c79SRyusuke Konishi 
35847420c79SRyusuke Konishi 	return err;
359d2500652SRyusuke Konishi }
360d2500652SRyusuke Konishi 
nilfs_rename(struct mnt_idmap * idmap,struct inode * old_dir,struct dentry * old_dentry,struct inode * new_dir,struct dentry * new_dentry,unsigned int flags)361e18275aeSChristian Brauner static int nilfs_rename(struct mnt_idmap *idmap,
362549c7297SChristian Brauner 			struct inode *old_dir, struct dentry *old_dentry,
363f03b8ad8SMiklos Szeredi 			struct inode *new_dir, struct dentry *new_dentry,
364f03b8ad8SMiklos Szeredi 			unsigned int flags)
365d2500652SRyusuke Konishi {
3662b0143b5SDavid Howells 	struct inode *old_inode = d_inode(old_dentry);
3672b0143b5SDavid Howells 	struct inode *new_inode = d_inode(new_dentry);
368d2500652SRyusuke Konishi 	struct page *dir_page = NULL;
369d2500652SRyusuke Konishi 	struct nilfs_dir_entry *dir_de = NULL;
370d2500652SRyusuke Konishi 	struct page *old_page;
371d2500652SRyusuke Konishi 	struct nilfs_dir_entry *old_de;
372d2500652SRyusuke Konishi 	struct nilfs_transaction_info ti;
373d2500652SRyusuke Konishi 	int err;
374d2500652SRyusuke Konishi 
375f03b8ad8SMiklos Szeredi 	if (flags & ~RENAME_NOREPLACE)
376f03b8ad8SMiklos Szeredi 		return -EINVAL;
377f03b8ad8SMiklos Szeredi 
378d2500652SRyusuke Konishi 	err = nilfs_transaction_begin(old_dir->i_sb, &ti, 1);
379d2500652SRyusuke Konishi 	if (unlikely(err))
380d2500652SRyusuke Konishi 		return err;
381d2500652SRyusuke Konishi 
3820319003dSAl Viro 	old_de = nilfs_find_entry(old_dir, &old_dentry->d_name, &old_page);
3839698088aSRyusuke Konishi 	if (IS_ERR(old_de)) {
3849698088aSRyusuke Konishi 		err = PTR_ERR(old_de);
385d2500652SRyusuke Konishi 		goto out;
3869698088aSRyusuke Konishi 	}
387d2500652SRyusuke Konishi 
388d2500652SRyusuke Konishi 	if (S_ISDIR(old_inode->i_mode)) {
389d2500652SRyusuke Konishi 		err = -EIO;
390d2500652SRyusuke Konishi 		dir_de = nilfs_dotdot(old_inode, &dir_page);
391d2500652SRyusuke Konishi 		if (!dir_de)
392d2500652SRyusuke Konishi 			goto out_old;
393d2500652SRyusuke Konishi 	}
394d2500652SRyusuke Konishi 
395d2500652SRyusuke Konishi 	if (new_inode) {
396d2500652SRyusuke Konishi 		struct page *new_page;
397d2500652SRyusuke Konishi 		struct nilfs_dir_entry *new_de;
398d2500652SRyusuke Konishi 
399d2500652SRyusuke Konishi 		err = -ENOTEMPTY;
400d2500652SRyusuke Konishi 		if (dir_de && !nilfs_empty_dir(new_inode))
401d2500652SRyusuke Konishi 			goto out_dir;
402d2500652SRyusuke Konishi 
4039698088aSRyusuke Konishi 		new_de = nilfs_find_entry(new_dir, &new_dentry->d_name,
4049698088aSRyusuke Konishi 					  &new_page);
4059698088aSRyusuke Konishi 		if (IS_ERR(new_de)) {
4069698088aSRyusuke Konishi 			err = PTR_ERR(new_de);
407d2500652SRyusuke Konishi 			goto out_dir;
4089698088aSRyusuke Konishi 		}
409*7891ac3bSRyusuke Konishi 		err = nilfs_set_link(new_dir, new_de, new_page, old_inode);
410944a4f8fSRyusuke Konishi 		nilfs_put_page(new_page);
411*7891ac3bSRyusuke Konishi 		if (unlikely(err))
412*7891ac3bSRyusuke Konishi 			goto out_dir;
413abdb318bSJiro SEKIBA 		nilfs_mark_inode_dirty(new_dir);
414e21d4f41SJeff Layton 		inode_set_ctime_current(new_inode);
415d2500652SRyusuke Konishi 		if (dir_de)
416d2500652SRyusuke Konishi 			drop_nlink(new_inode);
417565de406SJiro SEKIBA 		drop_nlink(new_inode);
418abdb318bSJiro SEKIBA 		nilfs_mark_inode_dirty(new_inode);
419d2500652SRyusuke Konishi 	} else {
420d2500652SRyusuke Konishi 		err = nilfs_add_link(new_dentry, old_inode);
42130eb43d3SAl Viro 		if (err)
422d2500652SRyusuke Konishi 			goto out_dir;
423565de406SJiro SEKIBA 		if (dir_de) {
424565de406SJiro SEKIBA 			inc_nlink(new_dir);
425abdb318bSJiro SEKIBA 			nilfs_mark_inode_dirty(new_dir);
426565de406SJiro SEKIBA 		}
427d2500652SRyusuke Konishi 	}
428d2500652SRyusuke Konishi 
429d2500652SRyusuke Konishi 	/*
430d2500652SRyusuke Konishi 	 * Like most other Unix systems, set the ctime for inodes on a
431d2500652SRyusuke Konishi 	 * rename.
432d2500652SRyusuke Konishi 	 */
433e21d4f41SJeff Layton 	inode_set_ctime_current(old_inode);
434d2500652SRyusuke Konishi 
435*7891ac3bSRyusuke Konishi 	err = nilfs_delete_entry(old_de, old_page);
436*7891ac3bSRyusuke Konishi 	if (likely(!err)) {
437d2500652SRyusuke Konishi 		if (dir_de) {
438*7891ac3bSRyusuke Konishi 			err = nilfs_set_link(old_inode, dir_de, dir_page,
439*7891ac3bSRyusuke Konishi 					     new_dir);
440565de406SJiro SEKIBA 			drop_nlink(old_dir);
441d2500652SRyusuke Konishi 		}
442abdb318bSJiro SEKIBA 		nilfs_mark_inode_dirty(old_dir);
443*7891ac3bSRyusuke Konishi 	}
444abdb318bSJiro SEKIBA 	nilfs_mark_inode_dirty(old_inode);
445d2500652SRyusuke Konishi 
446d2500652SRyusuke Konishi out_dir:
447944a4f8fSRyusuke Konishi 	if (dir_de)
448944a4f8fSRyusuke Konishi 		nilfs_put_page(dir_page);
449d2500652SRyusuke Konishi out_old:
450944a4f8fSRyusuke Konishi 	nilfs_put_page(old_page);
451d2500652SRyusuke Konishi out:
452*7891ac3bSRyusuke Konishi 	if (likely(!err))
453*7891ac3bSRyusuke Konishi 		err = nilfs_transaction_commit(old_dir->i_sb);
454*7891ac3bSRyusuke Konishi 	else
45547420c79SRyusuke Konishi 		nilfs_transaction_abort(old_dir->i_sb);
456d2500652SRyusuke Konishi 	return err;
457d2500652SRyusuke Konishi }
458d2500652SRyusuke Konishi 
4598e656fd5SRyusuke Konishi /*
4608e656fd5SRyusuke Konishi  * Export operations
4618e656fd5SRyusuke Konishi  */
nilfs_get_parent(struct dentry * child)4628e656fd5SRyusuke Konishi static struct dentry *nilfs_get_parent(struct dentry *child)
4638e656fd5SRyusuke Konishi {
4649698088aSRyusuke Konishi 	ino_t ino;
4659698088aSRyusuke Konishi 	int res;
4668e656fd5SRyusuke Konishi 	struct inode *inode;
4678e656fd5SRyusuke Konishi 	struct nilfs_root *root;
4688e656fd5SRyusuke Konishi 
4699698088aSRyusuke Konishi 	res = nilfs_inode_by_name(d_inode(child), &dotdot_name, &ino);
4709698088aSRyusuke Konishi 	if (res)
4719698088aSRyusuke Konishi 		return ERR_PTR(res);
4728e656fd5SRyusuke Konishi 
4732b0143b5SDavid Howells 	root = NILFS_I(d_inode(child))->i_root;
4748e656fd5SRyusuke Konishi 
475fc64005cSAl Viro 	inode = nilfs_iget(child->d_sb, root, ino);
4768e656fd5SRyusuke Konishi 	if (IS_ERR(inode))
4778e656fd5SRyusuke Konishi 		return ERR_CAST(inode);
4788e656fd5SRyusuke Konishi 
4798e656fd5SRyusuke Konishi 	return d_obtain_alias(inode);
4808e656fd5SRyusuke Konishi }
4818e656fd5SRyusuke Konishi 
nilfs_get_dentry(struct super_block * sb,u64 cno,u64 ino,u32 gen)4828e656fd5SRyusuke Konishi static struct dentry *nilfs_get_dentry(struct super_block *sb, u64 cno,
4838e656fd5SRyusuke Konishi 				       u64 ino, u32 gen)
4848e656fd5SRyusuke Konishi {
4858e656fd5SRyusuke Konishi 	struct nilfs_root *root;
4868e656fd5SRyusuke Konishi 	struct inode *inode;
4878e656fd5SRyusuke Konishi 
4888e656fd5SRyusuke Konishi 	if (ino < NILFS_FIRST_INO(sb) && ino != NILFS_ROOT_INO)
4898e656fd5SRyusuke Konishi 		return ERR_PTR(-ESTALE);
4908e656fd5SRyusuke Konishi 
491e3154e97SRyusuke Konishi 	root = nilfs_lookup_root(sb->s_fs_info, cno);
4928e656fd5SRyusuke Konishi 	if (!root)
4938e656fd5SRyusuke Konishi 		return ERR_PTR(-ESTALE);
4948e656fd5SRyusuke Konishi 
4958e656fd5SRyusuke Konishi 	inode = nilfs_iget(sb, root, ino);
4968e656fd5SRyusuke Konishi 	nilfs_put_root(root);
4978e656fd5SRyusuke Konishi 
4988e656fd5SRyusuke Konishi 	if (IS_ERR(inode))
4998e656fd5SRyusuke Konishi 		return ERR_CAST(inode);
5008e656fd5SRyusuke Konishi 	if (gen && inode->i_generation != gen) {
5018e656fd5SRyusuke Konishi 		iput(inode);
5028e656fd5SRyusuke Konishi 		return ERR_PTR(-ESTALE);
5038e656fd5SRyusuke Konishi 	}
5048e656fd5SRyusuke Konishi 	return d_obtain_alias(inode);
5058e656fd5SRyusuke Konishi }
5068e656fd5SRyusuke Konishi 
nilfs_fh_to_dentry(struct super_block * sb,struct fid * fh,int fh_len,int fh_type)5078e656fd5SRyusuke Konishi static struct dentry *nilfs_fh_to_dentry(struct super_block *sb, struct fid *fh,
5088e656fd5SRyusuke Konishi 					 int fh_len, int fh_type)
5098e656fd5SRyusuke Konishi {
5108e656fd5SRyusuke Konishi 	struct nilfs_fid *fid = (struct nilfs_fid *)fh;
5118e656fd5SRyusuke Konishi 
512f73c2f1fSNeilBrown 	if (fh_len < NILFS_FID_SIZE_NON_CONNECTABLE ||
5138e656fd5SRyusuke Konishi 	    (fh_type != FILEID_NILFS_WITH_PARENT &&
5148e656fd5SRyusuke Konishi 	     fh_type != FILEID_NILFS_WITHOUT_PARENT))
5158e656fd5SRyusuke Konishi 		return NULL;
5168e656fd5SRyusuke Konishi 
5178e656fd5SRyusuke Konishi 	return nilfs_get_dentry(sb, fid->cno, fid->ino, fid->gen);
5188e656fd5SRyusuke Konishi }
5198e656fd5SRyusuke Konishi 
nilfs_fh_to_parent(struct super_block * sb,struct fid * fh,int fh_len,int fh_type)5208e656fd5SRyusuke Konishi static struct dentry *nilfs_fh_to_parent(struct super_block *sb, struct fid *fh,
5218e656fd5SRyusuke Konishi 					 int fh_len, int fh_type)
5228e656fd5SRyusuke Konishi {
5238e656fd5SRyusuke Konishi 	struct nilfs_fid *fid = (struct nilfs_fid *)fh;
5248e656fd5SRyusuke Konishi 
525f73c2f1fSNeilBrown 	if (fh_len < NILFS_FID_SIZE_CONNECTABLE ||
5268e656fd5SRyusuke Konishi 	    fh_type != FILEID_NILFS_WITH_PARENT)
5278e656fd5SRyusuke Konishi 		return NULL;
5288e656fd5SRyusuke Konishi 
5298e656fd5SRyusuke Konishi 	return nilfs_get_dentry(sb, fid->cno, fid->parent_ino, fid->parent_gen);
5308e656fd5SRyusuke Konishi }
5318e656fd5SRyusuke Konishi 
nilfs_encode_fh(struct inode * inode,__u32 * fh,int * lenp,struct inode * parent)532b0b0382bSAl Viro static int nilfs_encode_fh(struct inode *inode, __u32 *fh, int *lenp,
533b0b0382bSAl Viro 			   struct inode *parent)
5348e656fd5SRyusuke Konishi {
5358e656fd5SRyusuke Konishi 	struct nilfs_fid *fid = (struct nilfs_fid *)fh;
5368e656fd5SRyusuke Konishi 	struct nilfs_root *root = NILFS_I(inode)->i_root;
5378e656fd5SRyusuke Konishi 	int type;
5388e656fd5SRyusuke Konishi 
539b0b0382bSAl Viro 	if (parent && *lenp < NILFS_FID_SIZE_CONNECTABLE) {
540b0b0382bSAl Viro 		*lenp = NILFS_FID_SIZE_CONNECTABLE;
54194e07a75SNamjae Jeon 		return FILEID_INVALID;
542b0b0382bSAl Viro 	}
543b0b0382bSAl Viro 	if (*lenp < NILFS_FID_SIZE_NON_CONNECTABLE) {
544b0b0382bSAl Viro 		*lenp = NILFS_FID_SIZE_NON_CONNECTABLE;
54594e07a75SNamjae Jeon 		return FILEID_INVALID;
546b0b0382bSAl Viro 	}
5478e656fd5SRyusuke Konishi 
5488e656fd5SRyusuke Konishi 	fid->cno = root->cno;
5498e656fd5SRyusuke Konishi 	fid->ino = inode->i_ino;
5508e656fd5SRyusuke Konishi 	fid->gen = inode->i_generation;
5518e656fd5SRyusuke Konishi 
552b0b0382bSAl Viro 	if (parent) {
5538e656fd5SRyusuke Konishi 		fid->parent_ino = parent->i_ino;
5548e656fd5SRyusuke Konishi 		fid->parent_gen = parent->i_generation;
5558e656fd5SRyusuke Konishi 		type = FILEID_NILFS_WITH_PARENT;
5568e656fd5SRyusuke Konishi 		*lenp = NILFS_FID_SIZE_CONNECTABLE;
5578e656fd5SRyusuke Konishi 	} else {
5588e656fd5SRyusuke Konishi 		type = FILEID_NILFS_WITHOUT_PARENT;
5598e656fd5SRyusuke Konishi 		*lenp = NILFS_FID_SIZE_NON_CONNECTABLE;
5608e656fd5SRyusuke Konishi 	}
5618e656fd5SRyusuke Konishi 
5628e656fd5SRyusuke Konishi 	return type;
5638e656fd5SRyusuke Konishi }
5648e656fd5SRyusuke Konishi 
5656e1d5dccSAlexey Dobriyan const struct inode_operations nilfs_dir_inode_operations = {
566d2500652SRyusuke Konishi 	.create		= nilfs_create,
567d2500652SRyusuke Konishi 	.lookup		= nilfs_lookup,
568d2500652SRyusuke Konishi 	.link		= nilfs_link,
569d2500652SRyusuke Konishi 	.unlink		= nilfs_unlink,
570d2500652SRyusuke Konishi 	.symlink	= nilfs_symlink,
571d2500652SRyusuke Konishi 	.mkdir		= nilfs_mkdir,
572d2500652SRyusuke Konishi 	.rmdir		= nilfs_rmdir,
573d2500652SRyusuke Konishi 	.mknod		= nilfs_mknod,
574d2500652SRyusuke Konishi 	.rename		= nilfs_rename,
575d2500652SRyusuke Konishi 	.setattr	= nilfs_setattr,
576d2500652SRyusuke Konishi 	.permission	= nilfs_permission,
577622daaffSRyusuke Konishi 	.fiemap		= nilfs_fiemap,
5787c7c436eSMiklos Szeredi 	.fileattr_get	= nilfs_fileattr_get,
5797c7c436eSMiklos Szeredi 	.fileattr_set	= nilfs_fileattr_set,
580d2500652SRyusuke Konishi };
581d2500652SRyusuke Konishi 
5826e1d5dccSAlexey Dobriyan const struct inode_operations nilfs_special_inode_operations = {
583d2500652SRyusuke Konishi 	.setattr	= nilfs_setattr,
584d2500652SRyusuke Konishi 	.permission	= nilfs_permission,
585d2500652SRyusuke Konishi };
586d2500652SRyusuke Konishi 
5876e1d5dccSAlexey Dobriyan const struct inode_operations nilfs_symlink_inode_operations = {
5886b255391SAl Viro 	.get_link	= page_get_link,
589dc3d3b81SRyusuke Konishi 	.permission     = nilfs_permission,
590d2500652SRyusuke Konishi };
5918e656fd5SRyusuke Konishi 
5928e656fd5SRyusuke Konishi const struct export_operations nilfs_export_ops = {
5938e656fd5SRyusuke Konishi 	.encode_fh = nilfs_encode_fh,
5948e656fd5SRyusuke Konishi 	.fh_to_dentry = nilfs_fh_to_dentry,
5958e656fd5SRyusuke Konishi 	.fh_to_parent = nilfs_fh_to_parent,
5968e656fd5SRyusuke Konishi 	.get_parent = nilfs_get_parent,
5978e656fd5SRyusuke Konishi };
598