blob: 9bc8f69a4ec47be6ca9e27f686ec7aaac51b1417 [file] [log] [blame]
Chao Yu6d1a8322018-09-12 09:16:07 +08001// SPDX-License-Identifier: GPL-2.0
Jaegeuk Kim0a8165d2012-11-29 13:28:09 +09002/*
Jaegeuk Kim57397d82012-11-02 17:11:10 +09003 * fs/f2fs/namei.c
4 *
5 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
6 * http://www.samsung.com/
Jaegeuk Kim57397d82012-11-02 17:11:10 +09007 */
8#include <linux/fs.h>
9#include <linux/f2fs_fs.h>
10#include <linux/pagemap.h>
11#include <linux/sched.h>
12#include <linux/ctype.h>
Chao Yu50732df2014-06-19 16:23:19 +080013#include <linux/dcache.h>
Jaegeuk Kimfeb7cbb2015-04-15 13:49:55 -070014#include <linux/namei.h>
Chao Yu09c3a722017-07-09 00:13:07 +080015#include <linux/quotaops.h>
Jaegeuk Kim57397d82012-11-02 17:11:10 +090016
17#include "f2fs.h"
Jaegeuk Kim953a3e22013-03-21 15:21:57 +090018#include "node.h"
Daniel Rosenbergf22f93a2018-08-20 19:21:43 -070019#include "segment.h"
Jaegeuk Kim57397d82012-11-02 17:11:10 +090020#include "xattr.h"
21#include "acl.h"
Namjae Jeona2a4a7e2013-04-20 01:28:40 +090022#include <trace/events/f2fs.h>
Jaegeuk Kim57397d82012-11-02 17:11:10 +090023
24static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
25{
Jaegeuk Kim40813632014-09-02 15:31:18 -070026 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Jaegeuk Kim57397d82012-11-02 17:11:10 +090027 nid_t ino;
28 struct inode *inode;
29 bool nid_free = false;
Chao Yu50ffaa92017-09-06 21:59:50 +080030 int xattr_size = 0;
Gu Zhenge4795562013-09-27 18:08:30 +080031 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +090032
Jaegeuk Kima014e032014-06-20 21:44:02 -070033 inode = new_inode(dir->i_sb);
Jaegeuk Kim57397d82012-11-02 17:11:10 +090034 if (!inode)
35 return ERR_PTR(-ENOMEM);
36
Gu Zhenge4795562013-09-27 18:08:30 +080037 f2fs_lock_op(sbi);
Chao Yu6b4d6a82018-05-30 00:20:41 +080038 if (!f2fs_alloc_nid(sbi, &ino)) {
Gu Zhenge4795562013-09-27 18:08:30 +080039 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +090040 err = -ENOSPC;
41 goto fail;
42 }
Gu Zhenge4795562013-09-27 18:08:30 +080043 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +090044
Chao Yu09c3a722017-07-09 00:13:07 +080045 nid_free = true;
46
Chao Yu70ff5df2014-05-08 17:09:30 +080047 inode_init_owner(inode, dir, mode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +090048
49 inode->i_ino = ino;
Jaegeuk Kim57397d82012-11-02 17:11:10 +090050 inode->i_blocks = 0;
Jaegeuk Kimb2d1e922018-10-01 10:45:32 -070051 inode->i_mtime = inode->i_atime = inode->i_ctime =
52 F2FS_I(inode)->i_crtime = current_time(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +090053 inode->i_generation = sbi->s_next_generation++;
54
Chao Yu2d96ad52018-05-07 20:28:52 +080055 if (S_ISDIR(inode->i_mode))
56 F2FS_I(inode)->i_current_depth = 1;
57
Jaegeuk Kim57397d82012-11-02 17:11:10 +090058 err = insert_inode_locked(inode);
59 if (err) {
60 err = -EINVAL;
Jaegeuk Kima21c20f2015-08-16 12:38:15 -070061 goto fail;
Jaegeuk Kim57397d82012-11-02 17:11:10 +090062 }
Chao Yu622f28a2014-09-24 18:19:10 +080063
Chao Yu5647b302017-07-26 00:01:41 +080064 if (f2fs_sb_has_project_quota(sbi->sb) &&
Chao Yu9bafde62018-04-03 15:08:17 +080065 (F2FS_I(dir)->i_flags & F2FS_PROJINHERIT_FL))
Chao Yu5647b302017-07-26 00:01:41 +080066 F2FS_I(inode)->i_projid = F2FS_I(dir)->i_projid;
67 else
68 F2FS_I(inode)->i_projid = make_kprojid(&init_user_ns,
69 F2FS_DEF_PROJID);
70
Chao Yu09c3a722017-07-09 00:13:07 +080071 err = dquot_initialize(inode);
72 if (err)
73 goto fail_drop;
74
75 err = dquot_alloc_inode(inode);
76 if (err)
77 goto fail_drop;
78
Daeho Jeong9ef5e652018-01-11 11:26:19 +090079 set_inode_flag(inode, FI_NEW_INODE);
80
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -070081 /* If the directory encrypted, then we should encrypt the inode. */
Sheng Yongaa5bcfd2018-03-15 18:51:42 +080082 if ((f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
83 f2fs_may_encrypt(inode))
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -070084 f2fs_set_encrypted_inode(inode);
85
Chao Yufbcf9312017-07-19 00:19:06 +080086 if (f2fs_sb_has_extra_attr(sbi->sb)) {
87 set_inode_flag(inode, FI_EXTRA_ATTR);
88 F2FS_I(inode)->i_extra_isize = F2FS_TOTAL_EXTRA_ATTR_SIZE;
89 }
90
Jaegeuk Kim91942322016-05-20 10:13:22 -070091 if (test_opt(sbi, INLINE_XATTR))
92 set_inode_flag(inode, FI_INLINE_XATTR);
Chao Yu50ffaa92017-09-06 21:59:50 +080093
Chao Yufba48a82015-12-23 17:51:35 +080094 if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode))
Jaegeuk Kim91942322016-05-20 10:13:22 -070095 set_inode_flag(inode, FI_INLINE_DATA);
Jaegeuk Kim01b960e2015-04-23 10:27:21 -070096 if (f2fs_may_inline_dentry(inode))
Jaegeuk Kim91942322016-05-20 10:13:22 -070097 set_inode_flag(inode, FI_INLINE_DENTRY);
Chao Yu622f28a2014-09-24 18:19:10 +080098
Chao Yu50ffaa92017-09-06 21:59:50 +080099 if (f2fs_sb_has_flexible_inline_xattr(sbi->sb)) {
100 f2fs_bug_on(sbi, !f2fs_has_extra_attr(inode));
101 if (f2fs_has_inline_xattr(inode))
Chao Yue9a50e62018-03-08 14:22:56 +0800102 xattr_size = F2FS_OPTION(sbi).inline_xattr_size;
Chao Yu50ffaa92017-09-06 21:59:50 +0800103 /* Otherwise, will be 0 */
104 } else if (f2fs_has_inline_xattr(inode) ||
105 f2fs_has_inline_dentry(inode)) {
106 xattr_size = DEFAULT_INLINE_XATTR_ADDRS;
107 }
108 F2FS_I(inode)->i_inline_xattr_size = xattr_size;
109
Jaegeuk Kim3e72f722015-06-19 17:53:26 -0700110 f2fs_init_extent_tree(inode, NULL);
111
Chao Yud5e8f6c2015-07-15 17:28:53 +0800112 stat_inc_inline_xattr(inode);
Jaegeuk Kim2fb2c952015-04-30 18:58:22 -0700113 stat_inc_inline_inode(inode);
114 stat_inc_inline_dir(inode);
115
Chao Yu5647b302017-07-26 00:01:41 +0800116 F2FS_I(inode)->i_flags =
117 f2fs_mask_flags(mode, F2FS_I(dir)->i_flags & F2FS_FL_INHERITED);
118
Chao Yu8a7d1912017-08-30 18:04:47 +0800119 if (S_ISDIR(inode->i_mode))
Chao Yu9bafde62018-04-03 15:08:17 +0800120 F2FS_I(inode)->i_flags |= F2FS_INDEX_FL;
Chao Yu8a7d1912017-08-30 18:04:47 +0800121
Chao Yu9bafde62018-04-03 15:08:17 +0800122 if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL)
Chao Yu5647b302017-07-26 00:01:41 +0800123 set_inode_flag(inode, FI_PROJ_INHERIT);
124
Jaegeuk Kimd70b4f52013-04-25 13:24:33 +0900125 trace_f2fs_new_inode(inode, 0);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900126 return inode;
127
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900128fail:
Jaegeuk Kimd70b4f52013-04-25 13:24:33 +0900129 trace_f2fs_new_inode(inode, err);
Jaegeuk Kim531ad7d2013-04-30 11:33:27 +0900130 make_bad_inode(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900131 if (nid_free)
Jaegeuk Kim91942322016-05-20 10:13:22 -0700132 set_inode_flag(inode, FI_FREE_NID);
Jaegeuk Kimc9b63bd2015-06-23 10:36:08 -0700133 iput(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900134 return ERR_PTR(err);
Chao Yu09c3a722017-07-09 00:13:07 +0800135fail_drop:
136 trace_f2fs_new_inode(inode, err);
137 dquot_drop(inode);
138 inode->i_flags |= S_NOQUOTA;
139 if (nid_free)
140 set_inode_flag(inode, FI_FREE_NID);
141 clear_nlink(inode);
142 unlock_new_inode(inode);
143 iput(inode);
144 return ERR_PTR(err);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900145}
146
Chao Yuac734c42018-02-28 17:07:27 +0800147static int is_extension_exist(const unsigned char *s, const char *sub)
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900148{
Leon Romanovsky9836b8b2012-12-27 19:55:46 +0200149 size_t slen = strlen(s);
150 size_t sublen = strlen(sub);
Chao Yu7732c262016-09-05 12:28:27 +0800151 int i;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900152
Chao Yu741a7be2015-07-06 20:30:40 +0800153 /*
154 * filename format of multimedia file should be defined as:
Chao Yu7732c262016-09-05 12:28:27 +0800155 * "filename + '.' + extension + (optional: '.' + temp extension)".
Chao Yu741a7be2015-07-06 20:30:40 +0800156 */
157 if (slen < sublen + 2)
158 return 0;
159
Chao Yu7732c262016-09-05 12:28:27 +0800160 for (i = 1; i < slen - sublen; i++) {
161 if (s[i] != '.')
162 continue;
163 if (!strncasecmp(s + i + 1, sub, sublen))
164 return 1;
165 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900166
Chao Yu7732c262016-09-05 12:28:27 +0800167 return 0;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900168}
169
Jaegeuk Kim0a8165d2012-11-29 13:28:09 +0900170/*
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900171 * Set multimedia files as cold files for hot/cold data separation
172 */
Chao Yuac734c42018-02-28 17:07:27 +0800173static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode *inode,
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900174 const unsigned char *name)
175{
Chao Yu1e72cb22018-02-26 22:04:13 +0800176 __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
Chao Yuac734c42018-02-28 17:07:27 +0800177 int i, cold_count, hot_count;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900178
Chao Yu1e72cb22018-02-26 22:04:13 +0800179 down_read(&sbi->sb_lock);
180
Chao Yuac734c42018-02-28 17:07:27 +0800181 cold_count = le32_to_cpu(sbi->raw_super->extension_count);
182 hot_count = sbi->raw_super->hot_ext_count;
Chao Yu1e72cb22018-02-26 22:04:13 +0800183
Chao Yuac734c42018-02-28 17:07:27 +0800184 for (i = 0; i < cold_count + hot_count; i++) {
185 if (!is_extension_exist(name, extlist[i]))
186 continue;
187 if (i < cold_count)
Jaegeuk Kim354a3392013-06-14 08:52:35 +0900188 file_set_cold(inode);
Chao Yuac734c42018-02-28 17:07:27 +0800189 else
190 file_set_hot(inode);
191 break;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900192 }
Chao Yu1e72cb22018-02-26 22:04:13 +0800193
194 up_read(&sbi->sb_lock);
195}
196
Chao Yu6b4d6a82018-05-30 00:20:41 +0800197int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
Chao Yuac734c42018-02-28 17:07:27 +0800198 bool hot, bool set)
Chao Yu1e72cb22018-02-26 22:04:13 +0800199{
200 __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
Chao Yuac734c42018-02-28 17:07:27 +0800201 int cold_count = le32_to_cpu(sbi->raw_super->extension_count);
202 int hot_count = sbi->raw_super->hot_ext_count;
203 int total_count = cold_count + hot_count;
204 int start, count;
Chao Yu1e72cb22018-02-26 22:04:13 +0800205 int i;
206
Chao Yuac734c42018-02-28 17:07:27 +0800207 if (set) {
208 if (total_count == F2FS_MAX_EXTENSION)
209 return -EINVAL;
210 } else {
211 if (!hot && !cold_count)
212 return -EINVAL;
213 if (hot && !hot_count)
214 return -EINVAL;
215 }
216
217 if (hot) {
218 start = cold_count;
219 count = total_count;
220 } else {
221 start = 0;
222 count = cold_count;
223 }
224
225 for (i = start; i < count; i++) {
Chao Yu1e72cb22018-02-26 22:04:13 +0800226 if (strcmp(name, extlist[i]))
227 continue;
228
229 if (set)
230 return -EINVAL;
231
232 memcpy(extlist[i], extlist[i + 1],
Chao Yuac734c42018-02-28 17:07:27 +0800233 F2FS_EXTENSION_LEN * (total_count - i - 1));
234 memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN);
235 if (hot)
236 sbi->raw_super->hot_ext_count = hot_count - 1;
237 else
238 sbi->raw_super->extension_count =
239 cpu_to_le32(cold_count - 1);
Chao Yu1e72cb22018-02-26 22:04:13 +0800240 return 0;
241 }
242
243 if (!set)
244 return -EINVAL;
245
Chao Yuac734c42018-02-28 17:07:27 +0800246 if (hot) {
Guenter Roeck5c8e7ab2018-07-01 13:57:06 -0700247 memcpy(extlist[count], name, strlen(name));
Chao Yuac734c42018-02-28 17:07:27 +0800248 sbi->raw_super->hot_ext_count = hot_count + 1;
249 } else {
250 char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN];
Chao Yu1e72cb22018-02-26 22:04:13 +0800251
Chao Yuac734c42018-02-28 17:07:27 +0800252 memcpy(buf, &extlist[cold_count],
253 F2FS_EXTENSION_LEN * hot_count);
254 memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN);
Guenter Roeck5c8e7ab2018-07-01 13:57:06 -0700255 memcpy(extlist[cold_count], name, strlen(name));
Chao Yuac734c42018-02-28 17:07:27 +0800256 memcpy(&extlist[cold_count + 1], buf,
257 F2FS_EXTENSION_LEN * hot_count);
258 sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1);
259 }
Chao Yu1e72cb22018-02-26 22:04:13 +0800260 return 0;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900261}
262
263static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
264 bool excl)
265{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700266 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900267 struct inode *inode;
268 nid_t ino = 0;
Gu Zhenge4795562013-09-27 18:08:30 +0800269 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900270
Jaegeuk Kim66634222017-10-23 23:48:49 +0200271 if (unlikely(f2fs_cp_error(sbi)))
272 return -EIO;
Daniel Rosenbergf22f93a2018-08-20 19:21:43 -0700273 err = f2fs_is_checkpoint_ready(sbi);
274 if (err)
275 return err;
Jaegeuk Kim66634222017-10-23 23:48:49 +0200276
Chao Yu09c3a722017-07-09 00:13:07 +0800277 err = dquot_initialize(dir);
278 if (err)
279 return err;
280
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900281 inode = f2fs_new_inode(dir, mode);
282 if (IS_ERR(inode))
283 return PTR_ERR(inode);
284
285 if (!test_opt(sbi, DISABLE_EXT_IDENTIFY))
Chao Yuac734c42018-02-28 17:07:27 +0800286 set_file_temperature(sbi, inode, dentry->d_name.name);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900287
288 inode->i_op = &f2fs_file_inode_operations;
289 inode->i_fop = &f2fs_file_operations;
290 inode->i_mapping->a_ops = &f2fs_dblock_aops;
291 ino = inode->i_ino;
292
Gu Zhenge4795562013-09-27 18:08:30 +0800293 f2fs_lock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900294 err = f2fs_add_link(dentry, inode);
295 if (err)
296 goto out;
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700297 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900298
Chao Yu6b4d6a82018-05-30 00:20:41 +0800299 f2fs_alloc_nid_done(sbi, ino);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900300
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900301 unlock_new_inode(inode);
Eric Biggerse605f832018-04-18 15:48:42 -0700302 d_instantiate(dentry, inode);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800303
304 if (IS_DIRSYNC(dir))
305 f2fs_sync_fs(sbi->sb, 1);
Jaegeuk Kime6b120d2017-07-10 12:55:09 -0700306
307 f2fs_balance_fs(sbi, true);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900308 return 0;
309out:
Chao Yu6b4d6a82018-05-30 00:20:41 +0800310 f2fs_handle_failed_inode(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900311 return err;
312}
313
314static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
315 struct dentry *dentry)
316{
David Howells2b0143b2015-03-17 22:25:59 +0000317 struct inode *inode = d_inode(old_dentry);
Jaegeuk Kim40813632014-09-02 15:31:18 -0700318 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Gu Zhenge4795562013-09-27 18:08:30 +0800319 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900320
Jaegeuk Kim66634222017-10-23 23:48:49 +0200321 if (unlikely(f2fs_cp_error(sbi)))
322 return -EIO;
Daniel Rosenbergf22f93a2018-08-20 19:21:43 -0700323 err = f2fs_is_checkpoint_ready(sbi);
324 if (err)
325 return err;
Jaegeuk Kim66634222017-10-23 23:48:49 +0200326
Eric Biggersd5382cc2017-11-29 12:35:29 -0800327 err = fscrypt_prepare_link(old_dentry, dir, dentry);
328 if (err)
329 return err;
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -0700330
Chao Yu5647b302017-07-26 00:01:41 +0800331 if (is_inode_flag_set(dir, FI_PROJ_INHERIT) &&
332 (!projid_eq(F2FS_I(dir)->i_projid,
333 F2FS_I(old_dentry->d_inode)->i_projid)))
334 return -EXDEV;
335
Chao Yu09c3a722017-07-09 00:13:07 +0800336 err = dquot_initialize(dir);
337 if (err)
338 return err;
339
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -0800340 f2fs_balance_fs(sbi, true);
Jaegeuk Kim1efef832012-12-19 16:25:21 +0900341
Deepa Dinamani078cd822016-09-14 07:48:04 -0700342 inode->i_ctime = current_time(inode);
Jaegeuk Kim6f6fd832013-05-22 12:06:26 +0900343 ihold(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900344
Jaegeuk Kim91942322016-05-20 10:13:22 -0700345 set_inode_flag(inode, FI_INC_LINK);
Gu Zhenge4795562013-09-27 18:08:30 +0800346 f2fs_lock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900347 err = f2fs_add_link(dentry, inode);
348 if (err)
349 goto out;
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700350 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900351
352 d_instantiate(dentry, inode);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800353
354 if (IS_DIRSYNC(dir))
355 f2fs_sync_fs(sbi->sb, 1);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900356 return 0;
357out:
Jaegeuk Kim91942322016-05-20 10:13:22 -0700358 clear_inode_flag(inode, FI_INC_LINK);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900359 iput(inode);
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700360 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900361 return err;
362}
363
364struct dentry *f2fs_get_parent(struct dentry *child)
365{
366 struct qstr dotdot = QSTR_INIT("..", 2);
Chao Yu91246c22016-07-19 08:27:47 +0800367 struct page *page;
368 unsigned long ino = f2fs_inode_by_name(d_inode(child), &dotdot, &page);
369 if (!ino) {
370 if (IS_ERR(page))
371 return ERR_CAST(page);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900372 return ERR_PTR(-ENOENT);
Chao Yu91246c22016-07-19 08:27:47 +0800373 }
Al Virofc640052016-04-10 01:33:30 -0400374 return d_obtain_alias(f2fs_iget(child->d_sb, ino));
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900375}
376
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700377static int __recover_dot_dentries(struct inode *dir, nid_t pino)
378{
379 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
380 struct qstr dot = QSTR_INIT(".", 1);
381 struct qstr dotdot = QSTR_INIT("..", 2);
382 struct f2fs_dir_entry *de;
383 struct page *page;
384 int err = 0;
385
Chao Yu4e0d8362015-12-30 17:40:31 +0800386 if (f2fs_readonly(sbi->sb)) {
387 f2fs_msg(sbi->sb, KERN_INFO,
388 "skip recovering inline_dots inode (ino:%lu, pino:%u) "
389 "in readonly mountpoint", dir->i_ino, pino);
390 return 0;
391 }
392
Chao Yu4b312af2017-07-24 17:12:06 +0800393 err = dquot_initialize(dir);
394 if (err)
395 return err;
396
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -0800397 f2fs_balance_fs(sbi, true);
Chao Yud5384172015-12-24 18:03:29 +0800398
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700399 f2fs_lock_op(sbi);
400
401 de = f2fs_find_entry(dir, &dot, &page);
402 if (de) {
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700403 f2fs_put_page(page, 0);
Jaegeuk Kim42d96402016-05-25 14:29:11 -0700404 } else if (IS_ERR(page)) {
405 err = PTR_ERR(page);
406 goto out;
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700407 } else {
Chao Yu6b4d6a82018-05-30 00:20:41 +0800408 err = f2fs_do_add_link(dir, &dot, NULL, dir->i_ino, S_IFDIR);
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700409 if (err)
410 goto out;
411 }
412
413 de = f2fs_find_entry(dir, &dotdot, &page);
Yunlong Song975c5672018-02-28 20:31:52 +0800414 if (de)
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700415 f2fs_put_page(page, 0);
Yunlong Song975c5672018-02-28 20:31:52 +0800416 else if (IS_ERR(page))
Jaegeuk Kim42d96402016-05-25 14:29:11 -0700417 err = PTR_ERR(page);
Yunlong Song975c5672018-02-28 20:31:52 +0800418 else
Chao Yu6b4d6a82018-05-30 00:20:41 +0800419 err = f2fs_do_add_link(dir, &dotdot, NULL, pino, S_IFDIR);
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700420out:
Jaegeuk Kim205b9822016-05-20 09:52:20 -0700421 if (!err)
Jaegeuk Kim91942322016-05-20 10:13:22 -0700422 clear_inode_flag(dir, FI_INLINE_DOTS);
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700423
424 f2fs_unlock_op(sbi);
425 return err;
426}
427
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900428static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
429 unsigned int flags)
430{
431 struct inode *inode = NULL;
432 struct f2fs_dir_entry *de;
433 struct page *page;
Chao Yud67586d2017-10-17 17:33:41 +0800434 struct dentry *new;
435 nid_t ino = -1;
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -0700436 int err = 0;
Liu Xue8c2b1432016-02-26 06:39:23 +0000437 unsigned int root_ino = F2FS_ROOT_INO(F2FS_I_SB(dir));
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900438
Chao Yud67586d2017-10-17 17:33:41 +0800439 trace_f2fs_lookup_start(dir, dentry, flags);
440
Eric Biggers268c7f62017-11-29 12:35:31 -0800441 err = fscrypt_prepare_lookup(dir, dentry, flags);
442 if (err)
443 goto out;
Jaegeuk Kim8074bb52016-02-23 09:21:37 -0800444
Chao Yud67586d2017-10-17 17:33:41 +0800445 if (dentry->d_name.len > F2FS_NAME_LEN) {
446 err = -ENAMETOOLONG;
447 goto out;
448 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900449
450 de = f2fs_find_entry(dir, &dentry->d_name, &page);
Jaegeuk Kimeb4246d2016-05-27 10:10:41 -0700451 if (!de) {
Chao Yud67586d2017-10-17 17:33:41 +0800452 if (IS_ERR(page)) {
453 err = PTR_ERR(page);
454 goto out;
455 }
456 goto out_splice;
Jaegeuk Kimeb4246d2016-05-27 10:10:41 -0700457 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900458
Jaegeuk Kim06957e82015-04-22 11:40:27 -0700459 ino = le32_to_cpu(de->ino);
Jaegeuk Kim06957e82015-04-22 11:40:27 -0700460 f2fs_put_page(page, 0);
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700461
Jaegeuk Kim06957e82015-04-22 11:40:27 -0700462 inode = f2fs_iget(dir->i_sb, ino);
Chao Yud67586d2017-10-17 17:33:41 +0800463 if (IS_ERR(inode)) {
464 err = PTR_ERR(inode);
465 goto out;
466 }
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700467
Liu Xue8c2b1432016-02-26 06:39:23 +0000468 if ((dir->i_ino == root_ino) && f2fs_has_inline_dots(dir)) {
469 err = __recover_dot_dentries(dir, root_ino);
470 if (err)
Chao Yud67586d2017-10-17 17:33:41 +0800471 goto out_iput;
Liu Xue8c2b1432016-02-26 06:39:23 +0000472 }
473
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -0700474 if (f2fs_has_inline_dots(inode)) {
Jaegeuk Kim06957e82015-04-22 11:40:27 -0700475 err = __recover_dot_dentries(inode, dir->i_ino);
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -0700476 if (err)
Chao Yud67586d2017-10-17 17:33:41 +0800477 goto out_iput;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900478 }
Jaegeuk Kime6b120d2017-07-10 12:55:09 -0700479 if (f2fs_encrypted_inode(dir) &&
480 (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
481 !fscrypt_has_permitted_context(dir, inode)) {
482 f2fs_msg(inode->i_sb, KERN_WARNING,
483 "Inconsistent encryption contexts: %lu/%lu",
484 dir->i_ino, inode->i_ino);
485 err = -EPERM;
Chao Yud67586d2017-10-17 17:33:41 +0800486 goto out_iput;
Jaegeuk Kim8074bb52016-02-23 09:21:37 -0800487 }
Chao Yud67586d2017-10-17 17:33:41 +0800488out_splice:
489 new = d_splice_alias(inode, dentry);
490 if (IS_ERR(new))
491 err = PTR_ERR(new);
492 trace_f2fs_lookup_end(dir, dentry, ino, err);
493 return new;
494out_iput:
Chao Yud7267322016-03-10 22:24:23 +0800495 iput(inode);
Chao Yud67586d2017-10-17 17:33:41 +0800496out:
497 trace_f2fs_lookup_end(dir, dentry, ino, err);
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -0700498 return ERR_PTR(err);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900499}
500
501static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
502{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700503 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
David Howells2b0143b2015-03-17 22:25:59 +0000504 struct inode *inode = d_inode(dentry);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900505 struct f2fs_dir_entry *de;
506 struct page *page;
507 int err = -ENOENT;
508
Namjae Jeona2a4a7e2013-04-20 01:28:40 +0900509 trace_f2fs_unlink_enter(dir, dentry);
Jaegeuk Kim1efef832012-12-19 16:25:21 +0900510
Jaegeuk Kim66634222017-10-23 23:48:49 +0200511 if (unlikely(f2fs_cp_error(sbi)))
512 return -EIO;
513
Chao Yu09c3a722017-07-09 00:13:07 +0800514 err = dquot_initialize(dir);
515 if (err)
516 return err;
Jaegeuk Kimd888fcd2017-10-23 23:50:15 +0200517 err = dquot_initialize(inode);
518 if (err)
519 return err;
Chao Yu09c3a722017-07-09 00:13:07 +0800520
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900521 de = f2fs_find_entry(dir, &dentry->d_name, &page);
Chao Yu91246c22016-07-19 08:27:47 +0800522 if (!de) {
523 if (IS_ERR(page))
524 err = PTR_ERR(page);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900525 goto fail;
Chao Yu91246c22016-07-19 08:27:47 +0800526 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900527
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -0800528 f2fs_balance_fs(sbi, true);
Jaegeuk Kim00623e62015-12-22 11:56:08 -0800529
Jaegeuk Kimccaaca22013-10-08 10:19:28 +0900530 f2fs_lock_op(sbi);
Chao Yu6b4d6a82018-05-30 00:20:41 +0800531 err = f2fs_acquire_orphan_inode(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900532 if (err) {
Jaegeuk Kimccaaca22013-10-08 10:19:28 +0900533 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900534 f2fs_put_page(page, 0);
535 goto fail;
536 }
Chao Yudbeacf02014-09-24 18:17:04 +0800537 f2fs_delete_entry(de, page, dir, inode);
Gu Zhenge4795562013-09-27 18:08:30 +0800538 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900539
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800540 if (IS_DIRSYNC(dir))
541 f2fs_sync_fs(sbi->sb, 1);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900542fail:
Namjae Jeona2a4a7e2013-04-20 01:28:40 +0900543 trace_f2fs_unlink_exit(inode, err);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900544 return err;
545}
546
Al Viro6b255392015-11-17 10:20:54 -0500547static const char *f2fs_get_link(struct dentry *dentry,
Al Virofceef392015-12-29 15:58:39 -0500548 struct inode *inode,
549 struct delayed_call *done)
Jaegeuk Kimfeb7cbb2015-04-15 13:49:55 -0700550{
Al Virofceef392015-12-29 15:58:39 -0500551 const char *link = page_get_link(dentry, inode, done);
Al Viro680baac2015-05-02 13:32:22 -0400552 if (!IS_ERR(link) && !*link) {
553 /* this is broken symlink case */
Al Virofceef392015-12-29 15:58:39 -0500554 do_delayed_call(done);
555 clear_delayed_call(done);
Al Viro680baac2015-05-02 13:32:22 -0400556 link = ERR_PTR(-ENOENT);
Jaegeuk Kimfeb7cbb2015-04-15 13:49:55 -0700557 }
Al Viro680baac2015-05-02 13:32:22 -0400558 return link;
Jaegeuk Kimfeb7cbb2015-04-15 13:49:55 -0700559}
560
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900561static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
562 const char *symname)
563{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700564 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900565 struct inode *inode;
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700566 size_t len = strlen(symname);
Eric Biggersf62d3d32018-01-11 23:26:49 -0500567 struct fscrypt_str disk_link;
Gu Zhenge4795562013-09-27 18:08:30 +0800568 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900569
Jaegeuk Kim66634222017-10-23 23:48:49 +0200570 if (unlikely(f2fs_cp_error(sbi)))
571 return -EIO;
Daniel Rosenbergf22f93a2018-08-20 19:21:43 -0700572 err = f2fs_is_checkpoint_ready(sbi);
573 if (err)
574 return err;
Jaegeuk Kim66634222017-10-23 23:48:49 +0200575
Eric Biggersf62d3d32018-01-11 23:26:49 -0500576 err = fscrypt_prepare_symlink(dir, symname, len, dir->i_sb->s_blocksize,
577 &disk_link);
578 if (err)
579 return err;
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700580
Chao Yu09c3a722017-07-09 00:13:07 +0800581 err = dquot_initialize(dir);
582 if (err)
583 return err;
584
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900585 inode = f2fs_new_inode(dir, S_IFLNK | S_IRWXUGO);
586 if (IS_ERR(inode))
587 return PTR_ERR(inode);
588
Eric Biggersf62d3d32018-01-11 23:26:49 -0500589 if (IS_ENCRYPTED(inode))
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700590 inode->i_op = &f2fs_encrypted_symlink_inode_operations;
591 else
592 inode->i_op = &f2fs_symlink_inode_operations;
Al Viro21fc61c2015-11-17 01:07:57 -0500593 inode_nohighmem(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900594 inode->i_mapping->a_ops = &f2fs_dblock_aops;
595
Gu Zhenge4795562013-09-27 18:08:30 +0800596 f2fs_lock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900597 err = f2fs_add_link(dentry, inode);
598 if (err)
Chao Yu6b4d6a82018-05-30 00:20:41 +0800599 goto out_f2fs_handle_failed_inode;
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700600 f2fs_unlock_op(sbi);
Chao Yu6b4d6a82018-05-30 00:20:41 +0800601 f2fs_alloc_nid_done(sbi, inode->i_ino);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900602
Eric Biggersf62d3d32018-01-11 23:26:49 -0500603 err = fscrypt_encrypt_symlink(inode, symname, len, &disk_link);
604 if (err)
605 goto err_out;
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700606
Chao Yu922ec352016-02-15 17:54:26 +0800607 err = page_symlink(inode, disk_link.name, disk_link.len);
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700608
609err_out:
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900610 unlock_new_inode(inode);
Eric Biggerse605f832018-04-18 15:48:42 -0700611 d_instantiate(dentry, inode);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800612
Jaegeuk Kimd0cae972015-04-15 13:37:53 -0700613 /*
614 * Let's flush symlink data in order to avoid broken symlink as much as
615 * possible. Nevertheless, fsyncing is the best way, but there is no
616 * way to get a file descriptor in order to flush that.
617 *
618 * Note that, it needs to do dir->fsync to make this recoverable.
619 * If the symlink path is stored into inline_data, there is no
620 * performance regression.
621 */
Chao Yua6be0142015-10-22 18:23:08 +0800622 if (!err) {
Chao Yu922ec352016-02-15 17:54:26 +0800623 filemap_write_and_wait_range(inode->i_mapping, 0,
624 disk_link.len - 1);
Jaegeuk Kimd0cae972015-04-15 13:37:53 -0700625
Chao Yua6be0142015-10-22 18:23:08 +0800626 if (IS_DIRSYNC(dir))
627 f2fs_sync_fs(sbi->sb, 1);
628 } else {
629 f2fs_unlink(dir, dentry);
630 }
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700631
Jaegeuk Kime6b120d2017-07-10 12:55:09 -0700632 f2fs_balance_fs(sbi, true);
Eric Biggersf62d3d32018-01-11 23:26:49 -0500633 goto out_free_encrypted_link;
634
Chao Yu6b4d6a82018-05-30 00:20:41 +0800635out_f2fs_handle_failed_inode:
636 f2fs_handle_failed_inode(inode);
Eric Biggersf62d3d32018-01-11 23:26:49 -0500637out_free_encrypted_link:
638 if (disk_link.name != (unsigned char *)symname)
639 kfree(disk_link.name);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900640 return err;
641}
642
643static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
644{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700645 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900646 struct inode *inode;
Gu Zhenge4795562013-09-27 18:08:30 +0800647 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900648
Jaegeuk Kim66634222017-10-23 23:48:49 +0200649 if (unlikely(f2fs_cp_error(sbi)))
650 return -EIO;
651
Chao Yu09c3a722017-07-09 00:13:07 +0800652 err = dquot_initialize(dir);
653 if (err)
654 return err;
655
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900656 inode = f2fs_new_inode(dir, S_IFDIR | mode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900657 if (IS_ERR(inode))
Namjae Jeon61412b62012-12-01 10:56:25 +0900658 return PTR_ERR(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900659
660 inode->i_op = &f2fs_dir_inode_operations;
661 inode->i_fop = &f2fs_dir_operations;
662 inode->i_mapping->a_ops = &f2fs_dblock_aops;
Yunlong Song975c5672018-02-28 20:31:52 +0800663 inode_nohighmem(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900664
Jaegeuk Kim91942322016-05-20 10:13:22 -0700665 set_inode_flag(inode, FI_INC_LINK);
Gu Zhenge4795562013-09-27 18:08:30 +0800666 f2fs_lock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900667 err = f2fs_add_link(dentry, inode);
668 if (err)
669 goto out_fail;
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700670 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900671
Chao Yu6b4d6a82018-05-30 00:20:41 +0800672 f2fs_alloc_nid_done(sbi, inode->i_ino);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900673
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900674 unlock_new_inode(inode);
Eric Biggerse605f832018-04-18 15:48:42 -0700675 d_instantiate(dentry, inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900676
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800677 if (IS_DIRSYNC(dir))
678 f2fs_sync_fs(sbi->sb, 1);
Jaegeuk Kime6b120d2017-07-10 12:55:09 -0700679
680 f2fs_balance_fs(sbi, true);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900681 return 0;
682
683out_fail:
Jaegeuk Kim91942322016-05-20 10:13:22 -0700684 clear_inode_flag(inode, FI_INC_LINK);
Chao Yu6b4d6a82018-05-30 00:20:41 +0800685 f2fs_handle_failed_inode(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900686 return err;
687}
688
689static int f2fs_rmdir(struct inode *dir, struct dentry *dentry)
690{
David Howells2b0143b2015-03-17 22:25:59 +0000691 struct inode *inode = d_inode(dentry);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900692 if (f2fs_empty_dir(inode))
693 return f2fs_unlink(dir, dentry);
694 return -ENOTEMPTY;
695}
696
697static int f2fs_mknod(struct inode *dir, struct dentry *dentry,
698 umode_t mode, dev_t rdev)
699{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700700 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900701 struct inode *inode;
702 int err = 0;
703
Jaegeuk Kim66634222017-10-23 23:48:49 +0200704 if (unlikely(f2fs_cp_error(sbi)))
705 return -EIO;
Daniel Rosenbergf22f93a2018-08-20 19:21:43 -0700706 err = f2fs_is_checkpoint_ready(sbi);
707 if (err)
708 return err;
Jaegeuk Kim66634222017-10-23 23:48:49 +0200709
Chao Yu09c3a722017-07-09 00:13:07 +0800710 err = dquot_initialize(dir);
711 if (err)
712 return err;
713
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900714 inode = f2fs_new_inode(dir, mode);
715 if (IS_ERR(inode))
716 return PTR_ERR(inode);
717
718 init_special_inode(inode, inode->i_mode, rdev);
719 inode->i_op = &f2fs_special_inode_operations;
720
Gu Zhenge4795562013-09-27 18:08:30 +0800721 f2fs_lock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900722 err = f2fs_add_link(dentry, inode);
723 if (err)
724 goto out;
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700725 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900726
Chao Yu6b4d6a82018-05-30 00:20:41 +0800727 f2fs_alloc_nid_done(sbi, inode->i_ino);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800728
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900729 unlock_new_inode(inode);
Eric Biggerse605f832018-04-18 15:48:42 -0700730 d_instantiate(dentry, inode);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800731
732 if (IS_DIRSYNC(dir))
733 f2fs_sync_fs(sbi->sb, 1);
Jaegeuk Kime6b120d2017-07-10 12:55:09 -0700734
735 f2fs_balance_fs(sbi, true);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900736 return 0;
737out:
Chao Yu6b4d6a82018-05-30 00:20:41 +0800738 f2fs_handle_failed_inode(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900739 return err;
740}
741
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800742static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry,
743 umode_t mode, struct inode **whiteout)
744{
745 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
746 struct inode *inode;
747 int err;
748
Chao Yu09c3a722017-07-09 00:13:07 +0800749 err = dquot_initialize(dir);
750 if (err)
751 return err;
752
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800753 inode = f2fs_new_inode(dir, mode);
754 if (IS_ERR(inode))
755 return PTR_ERR(inode);
756
757 if (whiteout) {
758 init_special_inode(inode, inode->i_mode, WHITEOUT_DEV);
759 inode->i_op = &f2fs_special_inode_operations;
760 } else {
761 inode->i_op = &f2fs_file_inode_operations;
762 inode->i_fop = &f2fs_file_operations;
763 inode->i_mapping->a_ops = &f2fs_dblock_aops;
764 }
765
766 f2fs_lock_op(sbi);
Chao Yu6b4d6a82018-05-30 00:20:41 +0800767 err = f2fs_acquire_orphan_inode(sbi);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800768 if (err)
769 goto out;
770
771 err = f2fs_do_tmpfile(inode, dir);
772 if (err)
773 goto release_out;
774
775 /*
776 * add this non-linked tmpfile to orphan list, in this way we could
777 * remove all unused data of tmpfile after abnormal power-off.
778 */
Chao Yu6b4d6a82018-05-30 00:20:41 +0800779 f2fs_add_orphan_inode(inode);
780 f2fs_alloc_nid_done(sbi, inode->i_ino);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800781
782 if (whiteout) {
Jaegeuk Kima1961242016-05-20 09:43:20 -0700783 f2fs_i_links_write(inode, false);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800784 *whiteout = inode;
785 } else {
786 d_tmpfile(dentry, inode);
787 }
Jaegeuk Kima1961242016-05-20 09:43:20 -0700788 /* link_count was changed by d_tmpfile as well. */
789 f2fs_unlock_op(sbi);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800790 unlock_new_inode(inode);
Jaegeuk Kime6b120d2017-07-10 12:55:09 -0700791
792 f2fs_balance_fs(sbi, true);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800793 return 0;
794
795release_out:
Chao Yu6b4d6a82018-05-30 00:20:41 +0800796 f2fs_release_orphan_inode(sbi);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800797out:
Chao Yu6b4d6a82018-05-30 00:20:41 +0800798 f2fs_handle_failed_inode(inode);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800799 return err;
800}
801
802static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
803{
Sheng Yongaa5bcfd2018-03-15 18:51:42 +0800804 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
805
806 if (unlikely(f2fs_cp_error(sbi)))
Jaegeuk Kim66634222017-10-23 23:48:49 +0200807 return -EIO;
808
Sheng Yongaa5bcfd2018-03-15 18:51:42 +0800809 if (f2fs_encrypted_inode(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) {
Jaegeuk Kim0b81d072015-05-15 16:26:10 -0700810 int err = fscrypt_get_encryption_info(dir);
Jaegeuk Kim304eecc2015-05-19 16:11:40 -0700811 if (err)
812 return err;
813 }
814
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800815 return __f2fs_tmpfile(dir, dentry, mode, NULL);
816}
817
818static int f2fs_create_whiteout(struct inode *dir, struct inode **whiteout)
819{
Jaegeuk Kim66634222017-10-23 23:48:49 +0200820 if (unlikely(f2fs_cp_error(F2FS_I_SB(dir))))
821 return -EIO;
822
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800823 return __f2fs_tmpfile(dir, NULL, S_IFCHR | WHITEOUT_MODE, whiteout);
824}
825
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900826static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800827 struct inode *new_dir, struct dentry *new_dentry,
828 unsigned int flags)
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900829{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700830 struct f2fs_sb_info *sbi = F2FS_I_SB(old_dir);
David Howells2b0143b2015-03-17 22:25:59 +0000831 struct inode *old_inode = d_inode(old_dentry);
832 struct inode *new_inode = d_inode(new_dentry);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800833 struct inode *whiteout = NULL;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900834 struct page *old_dir_page;
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800835 struct page *old_page, *new_page = NULL;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900836 struct f2fs_dir_entry *old_dir_entry = NULL;
837 struct f2fs_dir_entry *old_entry;
838 struct f2fs_dir_entry *new_entry;
Chao Yu993a0492016-02-17 16:47:05 +0800839 bool is_old_inline = f2fs_has_inline_dentry(old_dir);
Jaegeuk Kimfaa6beb2018-09-17 13:25:04 -0700840 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900841
Jaegeuk Kim66634222017-10-23 23:48:49 +0200842 if (unlikely(f2fs_cp_error(sbi)))
843 return -EIO;
Daniel Rosenbergf22f93a2018-08-20 19:21:43 -0700844 err = f2fs_is_checkpoint_ready(sbi);
845 if (err)
846 return err;
Jaegeuk Kim66634222017-10-23 23:48:49 +0200847
Chao Yu5647b302017-07-26 00:01:41 +0800848 if (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
849 (!projid_eq(F2FS_I(new_dir)->i_projid,
850 F2FS_I(old_dentry->d_inode)->i_projid)))
851 return -EXDEV;
852
Chao Yu09c3a722017-07-09 00:13:07 +0800853 err = dquot_initialize(old_dir);
854 if (err)
855 goto out;
856
857 err = dquot_initialize(new_dir);
858 if (err)
859 goto out;
860
Jaegeuk Kimd888fcd2017-10-23 23:50:15 +0200861 if (new_inode) {
862 err = dquot_initialize(new_inode);
863 if (err)
864 goto out;
865 }
866
Jaegeuk Kimfaa6beb2018-09-17 13:25:04 -0700867 err = -ENOENT;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900868 old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page);
Chao Yu91246c22016-07-19 08:27:47 +0800869 if (!old_entry) {
870 if (IS_ERR(old_page))
871 err = PTR_ERR(old_page);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900872 goto out;
Chao Yu91246c22016-07-19 08:27:47 +0800873 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900874
875 if (S_ISDIR(old_inode->i_mode)) {
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900876 old_dir_entry = f2fs_parent_dir(old_inode, &old_dir_page);
Jaegeuk Kim3e198862016-06-09 14:57:19 -0700877 if (!old_dir_entry) {
Chao Yu91246c22016-07-19 08:27:47 +0800878 if (IS_ERR(old_dir_page))
879 err = PTR_ERR(old_dir_page);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900880 goto out_old;
Jaegeuk Kim3e198862016-06-09 14:57:19 -0700881 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900882 }
883
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800884 if (flags & RENAME_WHITEOUT) {
885 err = f2fs_create_whiteout(old_dir, &whiteout);
886 if (err)
887 goto out_dir;
888 }
889
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900890 if (new_inode) {
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900891
892 err = -ENOTEMPTY;
893 if (old_dir_entry && !f2fs_empty_dir(new_inode))
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800894 goto out_whiteout;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900895
896 err = -ENOENT;
897 new_entry = f2fs_find_entry(new_dir, &new_dentry->d_name,
898 &new_page);
Chao Yu91246c22016-07-19 08:27:47 +0800899 if (!new_entry) {
900 if (IS_ERR(new_page))
901 err = PTR_ERR(new_page);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800902 goto out_whiteout;
Chao Yu91246c22016-07-19 08:27:47 +0800903 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900904
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -0800905 f2fs_balance_fs(sbi, true);
Jaegeuk Kim00623e62015-12-22 11:56:08 -0800906
Chao Yu12560102014-06-24 14:16:24 +0800907 f2fs_lock_op(sbi);
908
Chao Yu6b4d6a82018-05-30 00:20:41 +0800909 err = f2fs_acquire_orphan_inode(sbi);
Jaegeuk Kimcbd56e72013-07-30 11:36:53 +0900910 if (err)
911 goto put_out_dir;
912
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900913 f2fs_set_link(new_dir, new_entry, new_page, old_inode);
914
Deepa Dinamani078cd822016-09-14 07:48:04 -0700915 new_inode->i_ctime = current_time(new_inode);
Jaegeuk Kimd928bfb2014-03-20 19:10:08 +0900916 down_write(&F2FS_I(new_inode)->i_sem);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900917 if (old_dir_entry)
Jaegeuk Kima1961242016-05-20 09:43:20 -0700918 f2fs_i_links_write(new_inode, false);
919 f2fs_i_links_write(new_inode, false);
Jaegeuk Kimd928bfb2014-03-20 19:10:08 +0900920 up_write(&F2FS_I(new_inode)->i_sem);
921
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900922 if (!new_inode->i_nlink)
Chao Yu6b4d6a82018-05-30 00:20:41 +0800923 f2fs_add_orphan_inode(new_inode);
Jaegeuk Kimcbd56e72013-07-30 11:36:53 +0900924 else
Chao Yu6b4d6a82018-05-30 00:20:41 +0800925 f2fs_release_orphan_inode(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900926 } else {
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -0800927 f2fs_balance_fs(sbi, true);
Jaegeuk Kim00623e62015-12-22 11:56:08 -0800928
Chao Yu12560102014-06-24 14:16:24 +0800929 f2fs_lock_op(sbi);
930
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900931 err = f2fs_add_link(new_dentry, old_inode);
Chao Yu12560102014-06-24 14:16:24 +0800932 if (err) {
933 f2fs_unlock_op(sbi);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800934 goto out_whiteout;
Chao Yu12560102014-06-24 14:16:24 +0800935 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900936
Jaegeuk Kimee6d1822016-05-20 16:32:49 -0700937 if (old_dir_entry)
Jaegeuk Kima1961242016-05-20 09:43:20 -0700938 f2fs_i_links_write(new_dir, true);
Chao Yu993a0492016-02-17 16:47:05 +0800939
940 /*
941 * old entry and new entry can locate in the same inline
942 * dentry in inode, when attaching new entry in inline dentry,
943 * it could force inline dentry conversion, after that,
944 * old_entry and old_page will point to wrong address, in
945 * order to avoid this, let's do the check and update here.
946 */
947 if (is_old_inline && !f2fs_has_inline_dentry(old_dir)) {
948 f2fs_put_page(old_page, 0);
949 old_page = NULL;
950
951 old_entry = f2fs_find_entry(old_dir,
952 &old_dentry->d_name, &old_page);
953 if (!old_entry) {
Chao Yu91246c22016-07-19 08:27:47 +0800954 err = -ENOENT;
955 if (IS_ERR(old_page))
956 err = PTR_ERR(old_page);
Chao Yu993a0492016-02-17 16:47:05 +0800957 f2fs_unlock_op(sbi);
958 goto out_whiteout;
959 }
960 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900961 }
962
Jaegeuk Kimb2c08292014-06-30 18:09:55 +0900963 down_write(&F2FS_I(old_inode)->i_sem);
Sheng Yongc2e69012017-06-26 10:41:36 +0800964 if (!old_dir_entry || whiteout)
965 file_lost_pino(old_inode);
966 else
967 F2FS_I(old_inode)->i_pino = new_dir->i_ino;
Jaegeuk Kimb2c08292014-06-30 18:09:55 +0900968 up_write(&F2FS_I(old_inode)->i_sem);
969
Deepa Dinamani078cd822016-09-14 07:48:04 -0700970 old_inode->i_ctime = current_time(old_inode);
Jaegeuk Kime6b120d2017-07-10 12:55:09 -0700971 f2fs_mark_inode_dirty_sync(old_inode, false);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900972
Chao Yudbeacf02014-09-24 18:17:04 +0800973 f2fs_delete_entry(old_entry, old_page, old_dir, NULL);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900974
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800975 if (whiteout) {
976 whiteout->i_state |= I_LINKABLE;
Jaegeuk Kim91942322016-05-20 10:13:22 -0700977 set_inode_flag(whiteout, FI_INC_LINK);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800978 err = f2fs_add_link(old_dentry, whiteout);
979 if (err)
980 goto put_out_dir;
981 whiteout->i_state &= ~I_LINKABLE;
982 iput(whiteout);
983 }
984
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900985 if (old_dir_entry) {
Yunlong Song975c5672018-02-28 20:31:52 +0800986 if (old_dir != new_dir && !whiteout)
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900987 f2fs_set_link(old_inode, old_dir_entry,
988 old_dir_page, new_dir);
Yunlong Song975c5672018-02-28 20:31:52 +0800989 else
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900990 f2fs_put_page(old_dir_page, 0);
Jaegeuk Kima1961242016-05-20 09:43:20 -0700991 f2fs_i_links_write(old_dir, false);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900992 }
Jaegeuk Kimd487b152018-04-24 22:43:01 -0600993 if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) {
Chao Yu6b4d6a82018-05-30 00:20:41 +0800994 f2fs_add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
Jaegeuk Kimd487b152018-04-24 22:43:01 -0600995 if (S_ISDIR(old_inode->i_mode))
Chao Yu6b4d6a82018-05-30 00:20:41 +0800996 f2fs_add_ino_entry(sbi, old_inode->i_ino,
997 TRANS_DIR_INO);
Jaegeuk Kimd487b152018-04-24 22:43:01 -0600998 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900999
Gu Zhenge4795562013-09-27 18:08:30 +08001000 f2fs_unlock_op(sbi);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -08001001
1002 if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
1003 f2fs_sync_fs(sbi->sb, 1);
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001004 return 0;
1005
Jaegeuk Kimcbd56e72013-07-30 11:36:53 +09001006put_out_dir:
Chao Yu12560102014-06-24 14:16:24 +08001007 f2fs_unlock_op(sbi);
Yunlong Song975c5672018-02-28 20:31:52 +08001008 if (new_page)
Chao Yu7e01e7ad2015-05-19 17:37:26 +08001009 f2fs_put_page(new_page, 0);
Chao Yu7e01e7ad2015-05-19 17:37:26 +08001010out_whiteout:
1011 if (whiteout)
1012 iput(whiteout);
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001013out_dir:
Yunlong Song975c5672018-02-28 20:31:52 +08001014 if (old_dir_entry)
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001015 f2fs_put_page(old_dir_page, 0);
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001016out_old:
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001017 f2fs_put_page(old_page, 0);
1018out:
1019 return err;
1020}
1021
Chao Yu32f9bc22014-07-12 19:13:54 +08001022static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
1023 struct inode *new_dir, struct dentry *new_dentry)
1024{
Jaegeuk Kim40813632014-09-02 15:31:18 -07001025 struct f2fs_sb_info *sbi = F2FS_I_SB(old_dir);
David Howells2b0143b2015-03-17 22:25:59 +00001026 struct inode *old_inode = d_inode(old_dentry);
1027 struct inode *new_inode = d_inode(new_dentry);
Chao Yu32f9bc22014-07-12 19:13:54 +08001028 struct page *old_dir_page, *new_dir_page;
1029 struct page *old_page, *new_page;
1030 struct f2fs_dir_entry *old_dir_entry = NULL, *new_dir_entry = NULL;
1031 struct f2fs_dir_entry *old_entry, *new_entry;
1032 int old_nlink = 0, new_nlink = 0;
Jaegeuk Kimfaa6beb2018-09-17 13:25:04 -07001033 int err;
Chao Yu32f9bc22014-07-12 19:13:54 +08001034
Jaegeuk Kim66634222017-10-23 23:48:49 +02001035 if (unlikely(f2fs_cp_error(sbi)))
1036 return -EIO;
Daniel Rosenbergf22f93a2018-08-20 19:21:43 -07001037 err = f2fs_is_checkpoint_ready(sbi);
1038 if (err)
1039 return err;
Jaegeuk Kim66634222017-10-23 23:48:49 +02001040
Chao Yu5647b302017-07-26 00:01:41 +08001041 if ((is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
1042 !projid_eq(F2FS_I(new_dir)->i_projid,
1043 F2FS_I(old_dentry->d_inode)->i_projid)) ||
1044 (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
1045 !projid_eq(F2FS_I(old_dir)->i_projid,
1046 F2FS_I(new_dentry->d_inode)->i_projid)))
1047 return -EXDEV;
1048
Chao Yu09c3a722017-07-09 00:13:07 +08001049 err = dquot_initialize(old_dir);
1050 if (err)
1051 goto out;
1052
1053 err = dquot_initialize(new_dir);
1054 if (err)
1055 goto out;
1056
Jaegeuk Kimfaa6beb2018-09-17 13:25:04 -07001057 err = -ENOENT;
Chao Yu32f9bc22014-07-12 19:13:54 +08001058 old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page);
Chao Yu91246c22016-07-19 08:27:47 +08001059 if (!old_entry) {
1060 if (IS_ERR(old_page))
1061 err = PTR_ERR(old_page);
Chao Yu32f9bc22014-07-12 19:13:54 +08001062 goto out;
Chao Yu91246c22016-07-19 08:27:47 +08001063 }
Chao Yu32f9bc22014-07-12 19:13:54 +08001064
1065 new_entry = f2fs_find_entry(new_dir, &new_dentry->d_name, &new_page);
Chao Yu91246c22016-07-19 08:27:47 +08001066 if (!new_entry) {
1067 if (IS_ERR(new_page))
1068 err = PTR_ERR(new_page);
Chao Yu32f9bc22014-07-12 19:13:54 +08001069 goto out_old;
Chao Yu91246c22016-07-19 08:27:47 +08001070 }
Chao Yu32f9bc22014-07-12 19:13:54 +08001071
1072 /* prepare for updating ".." directory entry info later */
1073 if (old_dir != new_dir) {
1074 if (S_ISDIR(old_inode->i_mode)) {
Chao Yu32f9bc22014-07-12 19:13:54 +08001075 old_dir_entry = f2fs_parent_dir(old_inode,
1076 &old_dir_page);
Jaegeuk Kim3e198862016-06-09 14:57:19 -07001077 if (!old_dir_entry) {
Chao Yu91246c22016-07-19 08:27:47 +08001078 if (IS_ERR(old_dir_page))
1079 err = PTR_ERR(old_dir_page);
Chao Yu32f9bc22014-07-12 19:13:54 +08001080 goto out_new;
Jaegeuk Kim3e198862016-06-09 14:57:19 -07001081 }
Chao Yu32f9bc22014-07-12 19:13:54 +08001082 }
1083
1084 if (S_ISDIR(new_inode->i_mode)) {
Chao Yu32f9bc22014-07-12 19:13:54 +08001085 new_dir_entry = f2fs_parent_dir(new_inode,
1086 &new_dir_page);
Jaegeuk Kim3e198862016-06-09 14:57:19 -07001087 if (!new_dir_entry) {
Chao Yu91246c22016-07-19 08:27:47 +08001088 if (IS_ERR(new_dir_page))
1089 err = PTR_ERR(new_dir_page);
Chao Yu32f9bc22014-07-12 19:13:54 +08001090 goto out_old_dir;
Jaegeuk Kim3e198862016-06-09 14:57:19 -07001091 }
Chao Yu32f9bc22014-07-12 19:13:54 +08001092 }
1093 }
1094
1095 /*
1096 * If cross rename between file and directory those are not
1097 * in the same directory, we will inc nlink of file's parent
1098 * later, so we should check upper boundary of its nlink.
1099 */
1100 if ((!old_dir_entry || !new_dir_entry) &&
1101 old_dir_entry != new_dir_entry) {
1102 old_nlink = old_dir_entry ? -1 : 1;
1103 new_nlink = -old_nlink;
1104 err = -EMLINK;
Jaegeuk Kime6b120d2017-07-10 12:55:09 -07001105 if ((old_nlink > 0 && old_dir->i_nlink >= F2FS_LINK_MAX) ||
1106 (new_nlink > 0 && new_dir->i_nlink >= F2FS_LINK_MAX))
Chao Yu32f9bc22014-07-12 19:13:54 +08001107 goto out_new_dir;
1108 }
1109
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -08001110 f2fs_balance_fs(sbi, true);
Jaegeuk Kim00623e62015-12-22 11:56:08 -08001111
Chao Yu32f9bc22014-07-12 19:13:54 +08001112 f2fs_lock_op(sbi);
1113
Chao Yu32f9bc22014-07-12 19:13:54 +08001114 /* update ".." directory entry info of old dentry */
1115 if (old_dir_entry)
1116 f2fs_set_link(old_inode, old_dir_entry, old_dir_page, new_dir);
1117
1118 /* update ".." directory entry info of new dentry */
1119 if (new_dir_entry)
1120 f2fs_set_link(new_inode, new_dir_entry, new_dir_page, old_dir);
1121
1122 /* update directory entry info of old dir inode */
1123 f2fs_set_link(old_dir, old_entry, old_page, new_inode);
1124
1125 down_write(&F2FS_I(old_inode)->i_sem);
1126 file_lost_pino(old_inode);
1127 up_write(&F2FS_I(old_inode)->i_sem);
1128
Deepa Dinamani078cd822016-09-14 07:48:04 -07001129 old_dir->i_ctime = current_time(old_dir);
Chao Yu32f9bc22014-07-12 19:13:54 +08001130 if (old_nlink) {
1131 down_write(&F2FS_I(old_dir)->i_sem);
Jaegeuk Kima1961242016-05-20 09:43:20 -07001132 f2fs_i_links_write(old_dir, old_nlink > 0);
Chao Yu32f9bc22014-07-12 19:13:54 +08001133 up_write(&F2FS_I(old_dir)->i_sem);
1134 }
Jaegeuk Kime6b120d2017-07-10 12:55:09 -07001135 f2fs_mark_inode_dirty_sync(old_dir, false);
Chao Yu32f9bc22014-07-12 19:13:54 +08001136
1137 /* update directory entry info of new dir inode */
1138 f2fs_set_link(new_dir, new_entry, new_page, old_inode);
1139
1140 down_write(&F2FS_I(new_inode)->i_sem);
1141 file_lost_pino(new_inode);
1142 up_write(&F2FS_I(new_inode)->i_sem);
1143
Deepa Dinamani078cd822016-09-14 07:48:04 -07001144 new_dir->i_ctime = current_time(new_dir);
Chao Yu32f9bc22014-07-12 19:13:54 +08001145 if (new_nlink) {
1146 down_write(&F2FS_I(new_dir)->i_sem);
Jaegeuk Kima1961242016-05-20 09:43:20 -07001147 f2fs_i_links_write(new_dir, new_nlink > 0);
Chao Yu32f9bc22014-07-12 19:13:54 +08001148 up_write(&F2FS_I(new_dir)->i_sem);
1149 }
Jaegeuk Kime6b120d2017-07-10 12:55:09 -07001150 f2fs_mark_inode_dirty_sync(new_dir, false);
Chao Yu32f9bc22014-07-12 19:13:54 +08001151
Chao Yue9a50e62018-03-08 14:22:56 +08001152 if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) {
Chao Yu6b4d6a82018-05-30 00:20:41 +08001153 f2fs_add_ino_entry(sbi, old_dir->i_ino, TRANS_DIR_INO);
1154 f2fs_add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
Junling Zheng9a954812018-03-07 12:07:49 +08001155 }
Jaegeuk Kim211cb7b2017-12-28 08:09:44 -08001156
Chao Yu32f9bc22014-07-12 19:13:54 +08001157 f2fs_unlock_op(sbi);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -08001158
1159 if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
1160 f2fs_sync_fs(sbi->sb, 1);
Chao Yu32f9bc22014-07-12 19:13:54 +08001161 return 0;
Chao Yu32f9bc22014-07-12 19:13:54 +08001162out_new_dir:
1163 if (new_dir_entry) {
Chao Yu32f9bc22014-07-12 19:13:54 +08001164 f2fs_put_page(new_dir_page, 0);
1165 }
1166out_old_dir:
1167 if (old_dir_entry) {
Chao Yu32f9bc22014-07-12 19:13:54 +08001168 f2fs_put_page(old_dir_page, 0);
1169 }
1170out_new:
Chao Yu32f9bc22014-07-12 19:13:54 +08001171 f2fs_put_page(new_page, 0);
1172out_old:
Chao Yu32f9bc22014-07-12 19:13:54 +08001173 f2fs_put_page(old_page, 0);
1174out:
1175 return err;
1176}
1177
1178static int f2fs_rename2(struct inode *old_dir, struct dentry *old_dentry,
1179 struct inode *new_dir, struct dentry *new_dentry,
1180 unsigned int flags)
1181{
Eric Biggers8dfa6462017-11-29 12:35:30 -08001182 int err;
1183
Chao Yu7e01e7ad2015-05-19 17:37:26 +08001184 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
Chao Yu32f9bc22014-07-12 19:13:54 +08001185 return -EINVAL;
1186
Eric Biggers8dfa6462017-11-29 12:35:30 -08001187 err = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry,
1188 flags);
1189 if (err)
1190 return err;
1191
Chao Yu32f9bc22014-07-12 19:13:54 +08001192 if (flags & RENAME_EXCHANGE) {
1193 return f2fs_cross_rename(old_dir, old_dentry,
1194 new_dir, new_dentry);
1195 }
1196 /*
1197 * VFS has already handled the new dentry existence case,
1198 * here, we just deal with "RENAME_NOREPLACE" as regular rename.
1199 */
Chao Yu7e01e7ad2015-05-19 17:37:26 +08001200 return f2fs_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
Chao Yu32f9bc22014-07-12 19:13:54 +08001201}
1202
Al Viro6b255392015-11-17 10:20:54 -05001203static const char *f2fs_encrypted_get_link(struct dentry *dentry,
Al Virofceef392015-12-29 15:58:39 -05001204 struct inode *inode,
1205 struct delayed_call *done)
Chao Yu50732df2014-06-19 16:23:19 +08001206{
Eric Biggers45028b52018-01-11 23:26:49 -05001207 struct page *page;
1208 const char *target;
Chao Yu50732df2014-06-19 16:23:19 +08001209
Al Viro6b255392015-11-17 10:20:54 -05001210 if (!dentry)
1211 return ERR_PTR(-ECHILD);
1212
Eric Biggers45028b52018-01-11 23:26:49 -05001213 page = read_mapping_page(inode->i_mapping, 0, NULL);
1214 if (IS_ERR(page))
1215 return ERR_CAST(page);
Chao Yu50732df2014-06-19 16:23:19 +08001216
Eric Biggers45028b52018-01-11 23:26:49 -05001217 target = fscrypt_get_symlink(inode, page_address(page),
1218 inode->i_sb->s_blocksize, done);
1219 put_page(page);
1220 return target;
Chao Yu50732df2014-06-19 16:23:19 +08001221}
1222
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -07001223const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
1224 .readlink = generic_readlink,
Al Viro6b255392015-11-17 10:20:54 -05001225 .get_link = f2fs_encrypted_get_link,
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -07001226 .getattr = f2fs_getattr,
1227 .setattr = f2fs_setattr,
Chao Yu3a9e6432015-12-31 18:20:10 +08001228#ifdef CONFIG_F2FS_FS_XATTR
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -07001229 .listxattr = f2fs_listxattr,
Chao Yu3a9e6432015-12-31 18:20:10 +08001230#endif
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -07001231};
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -07001232
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001233const struct inode_operations f2fs_dir_inode_operations = {
1234 .create = f2fs_create,
1235 .lookup = f2fs_lookup,
1236 .link = f2fs_link,
1237 .unlink = f2fs_unlink,
1238 .symlink = f2fs_symlink,
1239 .mkdir = f2fs_mkdir,
1240 .rmdir = f2fs_rmdir,
1241 .mknod = f2fs_mknod,
Miklos Szeredi2773bf02016-09-27 11:03:58 +02001242 .rename = f2fs_rename2,
Chao Yu50732df2014-06-19 16:23:19 +08001243 .tmpfile = f2fs_tmpfile,
Jaegeuk Kim2d4d9fb52013-06-07 16:33:07 +09001244 .getattr = f2fs_getattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001245 .setattr = f2fs_setattr,
1246 .get_acl = f2fs_get_acl,
Christoph Hellwiga6dda0e2013-12-20 05:16:45 -08001247 .set_acl = f2fs_set_acl,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001248#ifdef CONFIG_F2FS_FS_XATTR
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001249 .listxattr = f2fs_listxattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001250#endif
1251};
1252
1253const struct inode_operations f2fs_symlink_inode_operations = {
1254 .readlink = generic_readlink,
Al Viro6b255392015-11-17 10:20:54 -05001255 .get_link = f2fs_get_link,
Jaegeuk Kim2d4d9fb52013-06-07 16:33:07 +09001256 .getattr = f2fs_getattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001257 .setattr = f2fs_setattr,
1258#ifdef CONFIG_F2FS_FS_XATTR
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001259 .listxattr = f2fs_listxattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001260#endif
1261};
1262
1263const struct inode_operations f2fs_special_inode_operations = {
Jaegeuk Kim2d4d9fb52013-06-07 16:33:07 +09001264 .getattr = f2fs_getattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001265 .setattr = f2fs_setattr,
1266 .get_acl = f2fs_get_acl,
Christoph Hellwiga6dda0e2013-12-20 05:16:45 -08001267 .set_acl = f2fs_set_acl,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001268#ifdef CONFIG_F2FS_FS_XATTR
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001269 .listxattr = f2fs_listxattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001270#endif
1271};