blob: 84e4bbc1a64de0bf4f84c12c65b9467d7b42d378 [file] [log] [blame]
Chao Yu7c1a0002018-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>
Jaegeuk Kim428e3bc2019-02-25 09:46:45 -080013#include <linux/random.h>
Chao Yu50732df2014-06-19 16:23:19 +080014#include <linux/dcache.h>
Jaegeuk Kimfeb7cbb2015-04-15 13:49:55 -070015#include <linux/namei.h>
Chao Yu0abd6752017-07-09 00:13:07 +080016#include <linux/quotaops.h>
Jaegeuk Kim57397d82012-11-02 17:11:10 +090017
18#include "f2fs.h"
Jaegeuk Kim953a3e22013-03-21 15:21:57 +090019#include "node.h"
Daniel Rosenberg43549942018-08-20 19:21:43 -070020#include "segment.h"
Jaegeuk Kim57397d82012-11-02 17:11:10 +090021#include "xattr.h"
22#include "acl.h"
Namjae Jeona2a4a7e2013-04-20 01:28:40 +090023#include <trace/events/f2fs.h>
Jaegeuk Kim57397d82012-11-02 17:11:10 +090024
25static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
26{
Jaegeuk Kim40813632014-09-02 15:31:18 -070027 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Jaegeuk Kim57397d82012-11-02 17:11:10 +090028 nid_t ino;
29 struct inode *inode;
30 bool nid_free = false;
Chao Yu6afc6622017-09-06 21:59:50 +080031 int xattr_size = 0;
Gu Zhenge4795562013-09-27 18:08:30 +080032 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +090033
Jaegeuk Kima014e032014-06-20 21:44:02 -070034 inode = new_inode(dir->i_sb);
Jaegeuk Kim57397d82012-11-02 17:11:10 +090035 if (!inode)
36 return ERR_PTR(-ENOMEM);
37
Gu Zhenge4795562013-09-27 18:08:30 +080038 f2fs_lock_op(sbi);
Chao Yu4d57b862018-05-30 00:20:41 +080039 if (!f2fs_alloc_nid(sbi, &ino)) {
Gu Zhenge4795562013-09-27 18:08:30 +080040 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +090041 err = -ENOSPC;
42 goto fail;
43 }
Gu Zhenge4795562013-09-27 18:08:30 +080044 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +090045
Chao Yu0abd6752017-07-09 00:13:07 +080046 nid_free = true;
47
Chao Yu70ff5df2014-05-08 17:09:30 +080048 inode_init_owner(inode, dir, mode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +090049
50 inode->i_ino = ino;
Jaegeuk Kim57397d82012-11-02 17:11:10 +090051 inode->i_blocks = 0;
Deepa Dinamani95582b02018-05-08 19:36:02 -070052 inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
Arnd Bergmann24b81df2018-06-20 10:02:19 +020053 F2FS_I(inode)->i_crtime = inode->i_mtime;
Jaegeuk Kim428e3bc2019-02-25 09:46:45 -080054 inode->i_generation = prandom_u32();
Jaegeuk Kim57397d82012-11-02 17:11:10 +090055
Chao Yu1c41e6802018-05-07 20:28:52 +080056 if (S_ISDIR(inode->i_mode))
57 F2FS_I(inode)->i_current_depth = 1;
58
Jaegeuk Kim57397d82012-11-02 17:11:10 +090059 err = insert_inode_locked(inode);
60 if (err) {
61 err = -EINVAL;
Jaegeuk Kima21c20f2015-08-16 12:38:15 -070062 goto fail;
Jaegeuk Kim57397d82012-11-02 17:11:10 +090063 }
Chao Yu622f28a2014-09-24 18:19:10 +080064
Chao Yu7beb01f2018-10-24 18:34:26 +080065 if (f2fs_sb_has_project_quota(sbi) &&
Chao Yu59c84402018-04-03 15:08:17 +080066 (F2FS_I(dir)->i_flags & F2FS_PROJINHERIT_FL))
Chao Yu5c571322017-07-26 00:01:41 +080067 F2FS_I(inode)->i_projid = F2FS_I(dir)->i_projid;
68 else
69 F2FS_I(inode)->i_projid = make_kprojid(&init_user_ns,
70 F2FS_DEF_PROJID);
71
Chao Yu0abd6752017-07-09 00:13:07 +080072 err = dquot_initialize(inode);
73 if (err)
74 goto fail_drop;
75
Daeho Jeong9ac1e2d2018-01-11 11:26:19 +090076 set_inode_flag(inode, FI_NEW_INODE);
77
Chao Yu8c7d4b52020-03-21 20:19:33 +080078 if (f2fs_may_encrypt(dir, inode))
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -070079 f2fs_set_encrypted_inode(inode);
80
Chao Yu7beb01f2018-10-24 18:34:26 +080081 if (f2fs_sb_has_extra_attr(sbi)) {
Chao Yu7a2af762017-07-19 00:19:06 +080082 set_inode_flag(inode, FI_EXTRA_ATTR);
83 F2FS_I(inode)->i_extra_isize = F2FS_TOTAL_EXTRA_ATTR_SIZE;
84 }
85
Jaegeuk Kim91942322016-05-20 10:13:22 -070086 if (test_opt(sbi, INLINE_XATTR))
87 set_inode_flag(inode, FI_INLINE_XATTR);
Chao Yu6afc6622017-09-06 21:59:50 +080088
Chao Yufba48a82015-12-23 17:51:35 +080089 if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode))
Jaegeuk Kim91942322016-05-20 10:13:22 -070090 set_inode_flag(inode, FI_INLINE_DATA);
Jaegeuk Kim01b960e2015-04-23 10:27:21 -070091 if (f2fs_may_inline_dentry(inode))
Jaegeuk Kim91942322016-05-20 10:13:22 -070092 set_inode_flag(inode, FI_INLINE_DENTRY);
Chao Yu622f28a2014-09-24 18:19:10 +080093
Chao Yu7beb01f2018-10-24 18:34:26 +080094 if (f2fs_sb_has_flexible_inline_xattr(sbi)) {
Chao Yu6afc6622017-09-06 21:59:50 +080095 f2fs_bug_on(sbi, !f2fs_has_extra_attr(inode));
96 if (f2fs_has_inline_xattr(inode))
Chao Yu63189b72018-03-08 14:22:56 +080097 xattr_size = F2FS_OPTION(sbi).inline_xattr_size;
Chao Yu6afc6622017-09-06 21:59:50 +080098 /* Otherwise, will be 0 */
99 } else if (f2fs_has_inline_xattr(inode) ||
100 f2fs_has_inline_dentry(inode)) {
101 xattr_size = DEFAULT_INLINE_XATTR_ADDRS;
102 }
103 F2FS_I(inode)->i_inline_xattr_size = xattr_size;
104
Jaegeuk Kim3e72f722015-06-19 17:53:26 -0700105 f2fs_init_extent_tree(inode, NULL);
106
Chao Yud5e8f6c2015-07-15 17:28:53 +0800107 stat_inc_inline_xattr(inode);
Jaegeuk Kim2fb2c952015-04-30 18:58:22 -0700108 stat_inc_inline_inode(inode);
109 stat_inc_inline_dir(inode);
110
Chao Yu5c571322017-07-26 00:01:41 +0800111 F2FS_I(inode)->i_flags =
112 f2fs_mask_flags(mode, F2FS_I(dir)->i_flags & F2FS_FL_INHERITED);
113
Chao Yu11f50202017-08-30 18:04:47 +0800114 if (S_ISDIR(inode->i_mode))
Chao Yu59c84402018-04-03 15:08:17 +0800115 F2FS_I(inode)->i_flags |= F2FS_INDEX_FL;
Chao Yu11f50202017-08-30 18:04:47 +0800116
Chao Yu59c84402018-04-03 15:08:17 +0800117 if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL)
Chao Yu5c571322017-07-26 00:01:41 +0800118 set_inode_flag(inode, FI_PROJ_INHERIT);
119
Chao Yu4c8ff702019-11-01 18:07:14 +0800120 if (f2fs_sb_has_compression(sbi)) {
121 /* Inherit the compression flag in directory */
122 if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) &&
123 f2fs_may_compress(inode))
124 set_compress_context(inode);
125 }
126
Chao Yu9149a5e2018-10-07 19:06:15 +0800127 f2fs_set_inode_flags(inode);
128
Jaegeuk Kimd70b4f52013-04-25 13:24:33 +0900129 trace_f2fs_new_inode(inode, 0);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900130 return inode;
131
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900132fail:
Jaegeuk Kimd70b4f52013-04-25 13:24:33 +0900133 trace_f2fs_new_inode(inode, err);
Jaegeuk Kim531ad7d2013-04-30 11:33:27 +0900134 make_bad_inode(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900135 if (nid_free)
Jaegeuk Kim91942322016-05-20 10:13:22 -0700136 set_inode_flag(inode, FI_FREE_NID);
Jaegeuk Kimc9b63bd2015-06-23 10:36:08 -0700137 iput(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900138 return ERR_PTR(err);
Chao Yu0abd6752017-07-09 00:13:07 +0800139fail_drop:
140 trace_f2fs_new_inode(inode, err);
141 dquot_drop(inode);
142 inode->i_flags |= S_NOQUOTA;
143 if (nid_free)
144 set_inode_flag(inode, FI_FREE_NID);
145 clear_nlink(inode);
146 unlock_new_inode(inode);
147 iput(inode);
148 return ERR_PTR(err);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900149}
150
Park Ju Hyung5c533b12019-04-17 18:57:38 +0900151static inline int is_extension_exist(const unsigned char *s, const char *sub)
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900152{
Leon Romanovsky9836b8b2012-12-27 19:55:46 +0200153 size_t slen = strlen(s);
154 size_t sublen = strlen(sub);
Chao Yu7732c262016-09-05 12:28:27 +0800155 int i;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900156
Chao Yu4c8ff702019-11-01 18:07:14 +0800157 if (sublen == 1 && *sub == '*')
158 return 1;
159
Chao Yu741a7be2015-07-06 20:30:40 +0800160 /*
161 * filename format of multimedia file should be defined as:
Chao Yu7732c262016-09-05 12:28:27 +0800162 * "filename + '.' + extension + (optional: '.' + temp extension)".
Chao Yu741a7be2015-07-06 20:30:40 +0800163 */
164 if (slen < sublen + 2)
165 return 0;
166
Chao Yu7732c262016-09-05 12:28:27 +0800167 for (i = 1; i < slen - sublen; i++) {
168 if (s[i] != '.')
169 continue;
170 if (!strncasecmp(s + i + 1, sub, sublen))
171 return 1;
172 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900173
Chao Yu7732c262016-09-05 12:28:27 +0800174 return 0;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900175}
176
Jaegeuk Kim0a8165d2012-11-29 13:28:09 +0900177/*
Chao Yu7a88ddb2020-02-27 19:30:05 +0800178 * Set file's temperature for hot/cold data separation
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900179 */
Chao Yub6a06cb2018-02-28 17:07:27 +0800180static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode *inode,
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900181 const unsigned char *name)
182{
Chao Yu846ae672018-02-26 22:04:13 +0800183 __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
Chao Yub6a06cb2018-02-28 17:07:27 +0800184 int i, cold_count, hot_count;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900185
Chao Yu846ae672018-02-26 22:04:13 +0800186 down_read(&sbi->sb_lock);
187
Chao Yub6a06cb2018-02-28 17:07:27 +0800188 cold_count = le32_to_cpu(sbi->raw_super->extension_count);
189 hot_count = sbi->raw_super->hot_ext_count;
Chao Yu846ae672018-02-26 22:04:13 +0800190
Chao Yub6a06cb2018-02-28 17:07:27 +0800191 for (i = 0; i < cold_count + hot_count; i++) {
Chao Yued15ba12018-10-04 11:15:18 +0800192 if (is_extension_exist(name, extlist[i]))
193 break;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900194 }
Chao Yu846ae672018-02-26 22:04:13 +0800195
196 up_read(&sbi->sb_lock);
Chao Yued15ba12018-10-04 11:15:18 +0800197
198 if (i == cold_count + hot_count)
199 return;
200
201 if (i < cold_count)
202 file_set_cold(inode);
203 else
204 file_set_hot(inode);
Chao Yu846ae672018-02-26 22:04:13 +0800205}
206
Chao Yu4d57b862018-05-30 00:20:41 +0800207int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name,
Chao Yub6a06cb2018-02-28 17:07:27 +0800208 bool hot, bool set)
Chao Yu846ae672018-02-26 22:04:13 +0800209{
210 __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
Chao Yub6a06cb2018-02-28 17:07:27 +0800211 int cold_count = le32_to_cpu(sbi->raw_super->extension_count);
212 int hot_count = sbi->raw_super->hot_ext_count;
213 int total_count = cold_count + hot_count;
214 int start, count;
Chao Yu846ae672018-02-26 22:04:13 +0800215 int i;
216
Chao Yub6a06cb2018-02-28 17:07:27 +0800217 if (set) {
218 if (total_count == F2FS_MAX_EXTENSION)
219 return -EINVAL;
220 } else {
221 if (!hot && !cold_count)
222 return -EINVAL;
223 if (hot && !hot_count)
224 return -EINVAL;
225 }
226
227 if (hot) {
228 start = cold_count;
229 count = total_count;
230 } else {
231 start = 0;
232 count = cold_count;
233 }
234
235 for (i = start; i < count; i++) {
Chao Yu846ae672018-02-26 22:04:13 +0800236 if (strcmp(name, extlist[i]))
237 continue;
238
239 if (set)
240 return -EINVAL;
241
242 memcpy(extlist[i], extlist[i + 1],
Chao Yub6a06cb2018-02-28 17:07:27 +0800243 F2FS_EXTENSION_LEN * (total_count - i - 1));
244 memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN);
245 if (hot)
246 sbi->raw_super->hot_ext_count = hot_count - 1;
247 else
248 sbi->raw_super->extension_count =
249 cpu_to_le32(cold_count - 1);
Chao Yu846ae672018-02-26 22:04:13 +0800250 return 0;
251 }
252
253 if (!set)
254 return -EINVAL;
255
Chao Yub6a06cb2018-02-28 17:07:27 +0800256 if (hot) {
Guenter Roeckb1385472018-07-01 13:57:06 -0700257 memcpy(extlist[count], name, strlen(name));
Chao Yub6a06cb2018-02-28 17:07:27 +0800258 sbi->raw_super->hot_ext_count = hot_count + 1;
259 } else {
260 char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN];
Chao Yu846ae672018-02-26 22:04:13 +0800261
Chao Yub6a06cb2018-02-28 17:07:27 +0800262 memcpy(buf, &extlist[cold_count],
263 F2FS_EXTENSION_LEN * hot_count);
264 memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN);
Guenter Roeckb1385472018-07-01 13:57:06 -0700265 memcpy(extlist[cold_count], name, strlen(name));
Chao Yub6a06cb2018-02-28 17:07:27 +0800266 memcpy(&extlist[cold_count + 1], buf,
267 F2FS_EXTENSION_LEN * hot_count);
268 sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1);
269 }
Chao Yu846ae672018-02-26 22:04:13 +0800270 return 0;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900271}
272
Chao Yu4c8ff702019-11-01 18:07:14 +0800273static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode,
274 const unsigned char *name)
275{
276 __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list;
277 unsigned char (*ext)[F2FS_EXTENSION_LEN];
278 unsigned int ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt;
279 int i, cold_count, hot_count;
280
281 if (!f2fs_sb_has_compression(sbi) ||
282 is_inode_flag_set(inode, FI_COMPRESSED_FILE) ||
283 F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL ||
284 !f2fs_may_compress(inode))
285 return;
286
287 down_read(&sbi->sb_lock);
288
289 cold_count = le32_to_cpu(sbi->raw_super->extension_count);
290 hot_count = sbi->raw_super->hot_ext_count;
291
292 for (i = cold_count; i < cold_count + hot_count; i++) {
293 if (is_extension_exist(name, extlist[i])) {
294 up_read(&sbi->sb_lock);
295 return;
296 }
297 }
298
299 up_read(&sbi->sb_lock);
300
301 ext = F2FS_OPTION(sbi).extensions;
302
303 for (i = 0; i < ext_cnt; i++) {
304 if (!is_extension_exist(name, ext[i]))
305 continue;
306
307 set_compress_context(inode);
308 return;
309 }
310}
311
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900312static int f2fs_create(struct inode *dir, struct dentry *dentry, umode_t mode,
313 bool excl)
314{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700315 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900316 struct inode *inode;
317 nid_t ino = 0;
Gu Zhenge4795562013-09-27 18:08:30 +0800318 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900319
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200320 if (unlikely(f2fs_cp_error(sbi)))
321 return -EIO;
Chao Yu00e09c02019-08-23 17:58:36 +0800322 if (!f2fs_is_checkpoint_ready(sbi))
323 return -ENOSPC;
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200324
Chao Yu0abd6752017-07-09 00:13:07 +0800325 err = dquot_initialize(dir);
326 if (err)
327 return err;
328
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900329 inode = f2fs_new_inode(dir, mode);
330 if (IS_ERR(inode))
331 return PTR_ERR(inode);
332
333 if (!test_opt(sbi, DISABLE_EXT_IDENTIFY))
Chao Yub6a06cb2018-02-28 17:07:27 +0800334 set_file_temperature(sbi, inode, dentry->d_name.name);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900335
Chao Yu4c8ff702019-11-01 18:07:14 +0800336 set_compress_inode(sbi, inode, dentry->d_name.name);
337
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900338 inode->i_op = &f2fs_file_inode_operations;
339 inode->i_fop = &f2fs_file_operations;
340 inode->i_mapping->a_ops = &f2fs_dblock_aops;
341 ino = inode->i_ino;
342
Gu Zhenge4795562013-09-27 18:08:30 +0800343 f2fs_lock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900344 err = f2fs_add_link(dentry, inode);
345 if (err)
346 goto out;
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700347 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900348
Chao Yu4d57b862018-05-30 00:20:41 +0800349 f2fs_alloc_nid_done(sbi, ino);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900350
Al Viro1e2e5472018-05-04 08:23:01 -0400351 d_instantiate_new(dentry, inode);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800352
353 if (IS_DIRSYNC(dir))
354 f2fs_sync_fs(sbi->sb, 1);
Jaegeuk Kim9bb02c32017-04-11 19:01:26 -0700355
356 f2fs_balance_fs(sbi, true);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900357 return 0;
358out:
Chao Yu4d57b862018-05-30 00:20:41 +0800359 f2fs_handle_failed_inode(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900360 return err;
361}
362
363static int f2fs_link(struct dentry *old_dentry, struct inode *dir,
364 struct dentry *dentry)
365{
David Howells2b0143b2015-03-17 22:25:59 +0000366 struct inode *inode = d_inode(old_dentry);
Jaegeuk Kim40813632014-09-02 15:31:18 -0700367 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Gu Zhenge4795562013-09-27 18:08:30 +0800368 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900369
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200370 if (unlikely(f2fs_cp_error(sbi)))
371 return -EIO;
Chao Yu00e09c02019-08-23 17:58:36 +0800372 if (!f2fs_is_checkpoint_ready(sbi))
373 return -ENOSPC;
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200374
Eric Biggersb05157e2017-11-29 12:35:29 -0800375 err = fscrypt_prepare_link(old_dentry, dir, dentry);
376 if (err)
377 return err;
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -0700378
Chao Yu5c571322017-07-26 00:01:41 +0800379 if (is_inode_flag_set(dir, FI_PROJ_INHERIT) &&
380 (!projid_eq(F2FS_I(dir)->i_projid,
381 F2FS_I(old_dentry->d_inode)->i_projid)))
382 return -EXDEV;
383
Chao Yu0abd6752017-07-09 00:13:07 +0800384 err = dquot_initialize(dir);
385 if (err)
386 return err;
387
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -0800388 f2fs_balance_fs(sbi, true);
Jaegeuk Kim1efef832012-12-19 16:25:21 +0900389
Deepa Dinamani078cd822016-09-14 07:48:04 -0700390 inode->i_ctime = current_time(inode);
Jaegeuk Kim6f6fd832013-05-22 12:06:26 +0900391 ihold(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900392
Jaegeuk Kim91942322016-05-20 10:13:22 -0700393 set_inode_flag(inode, FI_INC_LINK);
Gu Zhenge4795562013-09-27 18:08:30 +0800394 f2fs_lock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900395 err = f2fs_add_link(dentry, inode);
396 if (err)
397 goto out;
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700398 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900399
400 d_instantiate(dentry, inode);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800401
402 if (IS_DIRSYNC(dir))
403 f2fs_sync_fs(sbi->sb, 1);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900404 return 0;
405out:
Jaegeuk Kim91942322016-05-20 10:13:22 -0700406 clear_inode_flag(inode, FI_INC_LINK);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900407 iput(inode);
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700408 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900409 return err;
410}
411
412struct dentry *f2fs_get_parent(struct dentry *child)
413{
414 struct qstr dotdot = QSTR_INIT("..", 2);
Chao Yu91246c22016-07-19 08:27:47 +0800415 struct page *page;
416 unsigned long ino = f2fs_inode_by_name(d_inode(child), &dotdot, &page);
417 if (!ino) {
418 if (IS_ERR(page))
419 return ERR_CAST(page);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900420 return ERR_PTR(-ENOENT);
Chao Yu91246c22016-07-19 08:27:47 +0800421 }
Al Virofc640052016-04-10 01:33:30 -0400422 return d_obtain_alias(f2fs_iget(child->d_sb, ino));
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900423}
424
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700425static int __recover_dot_dentries(struct inode *dir, nid_t pino)
426{
427 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
428 struct qstr dot = QSTR_INIT(".", 1);
429 struct qstr dotdot = QSTR_INIT("..", 2);
430 struct f2fs_dir_entry *de;
431 struct page *page;
432 int err = 0;
433
Chao Yu4e0d8362015-12-30 17:40:31 +0800434 if (f2fs_readonly(sbi->sb)) {
Joe Perchesdcbb4c12019-06-18 17:48:42 +0800435 f2fs_info(sbi, "skip recovering inline_dots inode (ino:%lu, pino:%u) in readonly mountpoint",
436 dir->i_ino, pino);
Chao Yu4e0d8362015-12-30 17:40:31 +0800437 return 0;
438 }
439
Chao Yua6d3a472017-07-24 17:12:06 +0800440 err = dquot_initialize(dir);
441 if (err)
442 return err;
443
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -0800444 f2fs_balance_fs(sbi, true);
Chao Yud5384172015-12-24 18:03:29 +0800445
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700446 f2fs_lock_op(sbi);
447
448 de = f2fs_find_entry(dir, &dot, &page);
449 if (de) {
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700450 f2fs_put_page(page, 0);
Jaegeuk Kim42d96402016-05-25 14:29:11 -0700451 } else if (IS_ERR(page)) {
452 err = PTR_ERR(page);
453 goto out;
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700454 } else {
Chao Yu4d57b862018-05-30 00:20:41 +0800455 err = f2fs_do_add_link(dir, &dot, NULL, dir->i_ino, S_IFDIR);
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700456 if (err)
457 goto out;
458 }
459
460 de = f2fs_find_entry(dir, &dotdot, &page);
Yunlong Songbdbc90f2018-02-28 20:31:52 +0800461 if (de)
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700462 f2fs_put_page(page, 0);
Yunlong Songbdbc90f2018-02-28 20:31:52 +0800463 else if (IS_ERR(page))
Jaegeuk Kim42d96402016-05-25 14:29:11 -0700464 err = PTR_ERR(page);
Yunlong Songbdbc90f2018-02-28 20:31:52 +0800465 else
Chao Yu4d57b862018-05-30 00:20:41 +0800466 err = f2fs_do_add_link(dir, &dotdot, NULL, pino, S_IFDIR);
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700467out:
Jaegeuk Kim205b9822016-05-20 09:52:20 -0700468 if (!err)
Jaegeuk Kim91942322016-05-20 10:13:22 -0700469 clear_inode_flag(dir, FI_INLINE_DOTS);
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700470
471 f2fs_unlock_op(sbi);
472 return err;
473}
474
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900475static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry,
476 unsigned int flags)
477{
478 struct inode *inode = NULL;
479 struct f2fs_dir_entry *de;
480 struct page *page;
Chao Yu0c5e36d2017-10-17 17:33:41 +0800481 struct dentry *new;
482 nid_t ino = -1;
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -0700483 int err = 0;
Liu Xue8c2b1432016-02-26 06:39:23 +0000484 unsigned int root_ino = F2FS_ROOT_INO(F2FS_I_SB(dir));
Eric Biggers43c780b2020-05-07 00:59:04 -0700485 struct f2fs_filename fname;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900486
Chao Yu0c5e36d2017-10-17 17:33:41 +0800487 trace_f2fs_lookup_start(dir, dentry, flags);
488
Chao Yu0c5e36d2017-10-17 17:33:41 +0800489 if (dentry->d_name.len > F2FS_NAME_LEN) {
490 err = -ENAMETOOLONG;
491 goto out;
492 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900493
Eric Biggers43c780b2020-05-07 00:59:04 -0700494 err = f2fs_prepare_lookup(dir, dentry, &fname);
Eric Biggersb01531d2019-03-20 11:39:13 -0700495 if (err == -ENOENT)
496 goto out_splice;
497 if (err)
498 goto out;
499 de = __f2fs_find_entry(dir, &fname, &page);
Eric Biggers43c780b2020-05-07 00:59:04 -0700500 f2fs_free_filename(&fname);
Eric Biggersb01531d2019-03-20 11:39:13 -0700501
Jaegeuk Kimeb4246d2016-05-27 10:10:41 -0700502 if (!de) {
Chao Yu0c5e36d2017-10-17 17:33:41 +0800503 if (IS_ERR(page)) {
504 err = PTR_ERR(page);
505 goto out;
506 }
Chao Yu84597b12020-05-27 18:27:51 +0800507 err = -ENOENT;
Chao Yu0c5e36d2017-10-17 17:33:41 +0800508 goto out_splice;
Jaegeuk Kimeb4246d2016-05-27 10:10:41 -0700509 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900510
Jaegeuk Kim06957e82015-04-22 11:40:27 -0700511 ino = le32_to_cpu(de->ino);
Jaegeuk Kim06957e82015-04-22 11:40:27 -0700512 f2fs_put_page(page, 0);
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700513
Jaegeuk Kim06957e82015-04-22 11:40:27 -0700514 inode = f2fs_iget(dir->i_sb, ino);
Chao Yu0c5e36d2017-10-17 17:33:41 +0800515 if (IS_ERR(inode)) {
516 err = PTR_ERR(inode);
517 goto out;
518 }
Jaegeuk Kim510022a2015-03-30 15:07:16 -0700519
Liu Xue8c2b1432016-02-26 06:39:23 +0000520 if ((dir->i_ino == root_ino) && f2fs_has_inline_dots(dir)) {
521 err = __recover_dot_dentries(dir, root_ino);
522 if (err)
Chao Yu0c5e36d2017-10-17 17:33:41 +0800523 goto out_iput;
Liu Xue8c2b1432016-02-26 06:39:23 +0000524 }
525
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -0700526 if (f2fs_has_inline_dots(inode)) {
Jaegeuk Kim06957e82015-04-22 11:40:27 -0700527 err = __recover_dot_dentries(inode, dir->i_ino);
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -0700528 if (err)
Chao Yu0c5e36d2017-10-17 17:33:41 +0800529 goto out_iput;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900530 }
Chandan Rajendra62230e0d2018-12-12 15:20:11 +0530531 if (IS_ENCRYPTED(dir) &&
Dan Carpenter07fe8d42016-12-16 11:18:15 +0300532 (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) &&
533 !fscrypt_has_permitted_context(dir, inode)) {
Joe Perchesdcbb4c12019-06-18 17:48:42 +0800534 f2fs_warn(F2FS_I_SB(inode), "Inconsistent encryption contexts: %lu/%lu",
535 dir->i_ino, inode->i_ino);
Eric Biggersfaac7fd2017-04-07 10:58:39 -0700536 err = -EPERM;
Chao Yu0c5e36d2017-10-17 17:33:41 +0800537 goto out_iput;
Jaegeuk Kim8074bb52016-02-23 09:21:37 -0800538 }
Chao Yu0c5e36d2017-10-17 17:33:41 +0800539out_splice:
Daniel Rosenberg2c2eb7a2019-07-23 16:05:29 -0700540#ifdef CONFIG_UNICODE
541 if (!inode && IS_CASEFOLDED(dir)) {
542 /* Eventually we want to call d_add_ci(dentry, NULL)
543 * for negative dentries in the encoding case as
544 * well. For now, prevent the negative dentry
545 * from being cached.
546 */
547 trace_f2fs_lookup_end(dir, dentry, ino, err);
548 return NULL;
549 }
550#endif
Chao Yu0c5e36d2017-10-17 17:33:41 +0800551 new = d_splice_alias(inode, dentry);
Eric Biggersb01531d2019-03-20 11:39:13 -0700552 err = PTR_ERR_OR_ZERO(new);
Chao Yu84597b12020-05-27 18:27:51 +0800553 trace_f2fs_lookup_end(dir, dentry, ino, !new ? -ENOENT : err);
Chao Yu0c5e36d2017-10-17 17:33:41 +0800554 return new;
555out_iput:
Chao Yud7267322016-03-10 22:24:23 +0800556 iput(inode);
Chao Yu0c5e36d2017-10-17 17:33:41 +0800557out:
558 trace_f2fs_lookup_end(dir, dentry, ino, err);
Jaegeuk Kimfcc85a42015-04-21 20:39:58 -0700559 return ERR_PTR(err);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900560}
561
562static int f2fs_unlink(struct inode *dir, struct dentry *dentry)
563{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700564 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
David Howells2b0143b2015-03-17 22:25:59 +0000565 struct inode *inode = d_inode(dentry);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900566 struct f2fs_dir_entry *de;
567 struct page *page;
Colin Ian Kingdeaf1602020-04-20 23:00:57 +0100568 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900569
Namjae Jeona2a4a7e2013-04-20 01:28:40 +0900570 trace_f2fs_unlink_enter(dir, dentry);
Jaegeuk Kim1efef832012-12-19 16:25:21 +0900571
Lihong Kou9a99c17d2020-06-20 10:12:17 +0800572 if (unlikely(f2fs_cp_error(sbi))) {
573 err = -EIO;
574 goto fail;
575 }
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200576
Chao Yu0abd6752017-07-09 00:13:07 +0800577 err = dquot_initialize(dir);
578 if (err)
Lihong Kou9a99c17d2020-06-20 10:12:17 +0800579 goto fail;
Jaegeuk Kimd8d13892017-10-23 23:50:15 +0200580 err = dquot_initialize(inode);
581 if (err)
Lihong Kou9a99c17d2020-06-20 10:12:17 +0800582 goto fail;
Chao Yu0abd6752017-07-09 00:13:07 +0800583
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900584 de = f2fs_find_entry(dir, &dentry->d_name, &page);
Chao Yu91246c22016-07-19 08:27:47 +0800585 if (!de) {
586 if (IS_ERR(page))
587 err = PTR_ERR(page);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900588 goto fail;
Chao Yu91246c22016-07-19 08:27:47 +0800589 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900590
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -0800591 f2fs_balance_fs(sbi, true);
Jaegeuk Kim00623e62015-12-22 11:56:08 -0800592
Jaegeuk Kimccaaca22013-10-08 10:19:28 +0900593 f2fs_lock_op(sbi);
Chao Yu4d57b862018-05-30 00:20:41 +0800594 err = f2fs_acquire_orphan_inode(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900595 if (err) {
Jaegeuk Kimccaaca22013-10-08 10:19:28 +0900596 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900597 f2fs_put_page(page, 0);
598 goto fail;
599 }
Chao Yudbeacf02014-09-24 18:17:04 +0800600 f2fs_delete_entry(de, page, dir, inode);
Daniel Rosenberg2c2eb7a2019-07-23 16:05:29 -0700601#ifdef CONFIG_UNICODE
602 /* VFS negative dentries are incompatible with Encoding and
603 * Case-insensitiveness. Eventually we'll want avoid
604 * invalidating the dentries here, alongside with returning the
Jack Qiua87aff12020-07-24 16:55:28 +0800605 * negative dentries at f2fs_lookup(), when it is better
Daniel Rosenberg2c2eb7a2019-07-23 16:05:29 -0700606 * supported by the VFS for the CI case.
607 */
608 if (IS_CASEFOLDED(dir))
609 d_invalidate(dentry);
610#endif
Gu Zhenge4795562013-09-27 18:08:30 +0800611 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900612
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800613 if (IS_DIRSYNC(dir))
614 f2fs_sync_fs(sbi->sb, 1);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900615fail:
Namjae Jeona2a4a7e2013-04-20 01:28:40 +0900616 trace_f2fs_unlink_exit(inode, err);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900617 return err;
618}
619
Al Viro6b255392015-11-17 10:20:54 -0500620static const char *f2fs_get_link(struct dentry *dentry,
Al Virofceef392015-12-29 15:58:39 -0500621 struct inode *inode,
622 struct delayed_call *done)
Jaegeuk Kimfeb7cbb2015-04-15 13:49:55 -0700623{
Al Virofceef392015-12-29 15:58:39 -0500624 const char *link = page_get_link(dentry, inode, done);
Al Viro680baac2015-05-02 13:32:22 -0400625 if (!IS_ERR(link) && !*link) {
626 /* this is broken symlink case */
Al Virofceef392015-12-29 15:58:39 -0500627 do_delayed_call(done);
628 clear_delayed_call(done);
Al Viro680baac2015-05-02 13:32:22 -0400629 link = ERR_PTR(-ENOENT);
Jaegeuk Kimfeb7cbb2015-04-15 13:49:55 -0700630 }
Al Viro680baac2015-05-02 13:32:22 -0400631 return link;
Jaegeuk Kimfeb7cbb2015-04-15 13:49:55 -0700632}
633
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900634static int f2fs_symlink(struct inode *dir, struct dentry *dentry,
635 const char *symname)
636{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700637 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900638 struct inode *inode;
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700639 size_t len = strlen(symname);
Eric Biggers393c0382018-01-11 23:26:49 -0500640 struct fscrypt_str disk_link;
Gu Zhenge4795562013-09-27 18:08:30 +0800641 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900642
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200643 if (unlikely(f2fs_cp_error(sbi)))
644 return -EIO;
Chao Yu00e09c02019-08-23 17:58:36 +0800645 if (!f2fs_is_checkpoint_ready(sbi))
646 return -ENOSPC;
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200647
Eric Biggers393c0382018-01-11 23:26:49 -0500648 err = fscrypt_prepare_symlink(dir, symname, len, dir->i_sb->s_blocksize,
649 &disk_link);
650 if (err)
651 return err;
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700652
Chao Yu0abd6752017-07-09 00:13:07 +0800653 err = dquot_initialize(dir);
654 if (err)
655 return err;
656
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900657 inode = f2fs_new_inode(dir, S_IFLNK | S_IRWXUGO);
658 if (IS_ERR(inode))
659 return PTR_ERR(inode);
660
Eric Biggers393c0382018-01-11 23:26:49 -0500661 if (IS_ENCRYPTED(inode))
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700662 inode->i_op = &f2fs_encrypted_symlink_inode_operations;
663 else
664 inode->i_op = &f2fs_symlink_inode_operations;
Al Viro21fc61c2015-11-17 01:07:57 -0500665 inode_nohighmem(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900666 inode->i_mapping->a_ops = &f2fs_dblock_aops;
667
Gu Zhenge4795562013-09-27 18:08:30 +0800668 f2fs_lock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900669 err = f2fs_add_link(dentry, inode);
670 if (err)
Chao Yu4d57b862018-05-30 00:20:41 +0800671 goto out_f2fs_handle_failed_inode;
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700672 f2fs_unlock_op(sbi);
Chao Yu4d57b862018-05-30 00:20:41 +0800673 f2fs_alloc_nid_done(sbi, inode->i_ino);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900674
Eric Biggers393c0382018-01-11 23:26:49 -0500675 err = fscrypt_encrypt_symlink(inode, symname, len, &disk_link);
676 if (err)
677 goto err_out;
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700678
Chao Yu922ec352016-02-15 17:54:26 +0800679 err = page_symlink(inode, disk_link.name, disk_link.len);
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700680
681err_out:
Al Viro1e2e5472018-05-04 08:23:01 -0400682 d_instantiate_new(dentry, inode);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800683
Jaegeuk Kimd0cae972015-04-15 13:37:53 -0700684 /*
685 * Let's flush symlink data in order to avoid broken symlink as much as
686 * possible. Nevertheless, fsyncing is the best way, but there is no
687 * way to get a file descriptor in order to flush that.
688 *
689 * Note that, it needs to do dir->fsync to make this recoverable.
690 * If the symlink path is stored into inline_data, there is no
691 * performance regression.
692 */
Chao Yua6be0142015-10-22 18:23:08 +0800693 if (!err) {
Chao Yu922ec352016-02-15 17:54:26 +0800694 filemap_write_and_wait_range(inode->i_mapping, 0,
695 disk_link.len - 1);
Jaegeuk Kimd0cae972015-04-15 13:37:53 -0700696
Chao Yua6be0142015-10-22 18:23:08 +0800697 if (IS_DIRSYNC(dir))
698 f2fs_sync_fs(sbi->sb, 1);
699 } else {
700 f2fs_unlink(dir, dentry);
701 }
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -0700702
Jaegeuk Kim9bb02c32017-04-11 19:01:26 -0700703 f2fs_balance_fs(sbi, true);
Eric Biggers393c0382018-01-11 23:26:49 -0500704 goto out_free_encrypted_link;
705
Chao Yu4d57b862018-05-30 00:20:41 +0800706out_f2fs_handle_failed_inode:
707 f2fs_handle_failed_inode(inode);
Eric Biggers393c0382018-01-11 23:26:49 -0500708out_free_encrypted_link:
709 if (disk_link.name != (unsigned char *)symname)
Jaegeuk Kim52225952018-12-13 18:38:33 -0800710 kvfree(disk_link.name);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900711 return err;
712}
713
714static int f2fs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
715{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700716 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900717 struct inode *inode;
Gu Zhenge4795562013-09-27 18:08:30 +0800718 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900719
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200720 if (unlikely(f2fs_cp_error(sbi)))
721 return -EIO;
722
Chao Yu0abd6752017-07-09 00:13:07 +0800723 err = dquot_initialize(dir);
724 if (err)
725 return err;
726
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900727 inode = f2fs_new_inode(dir, S_IFDIR | mode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900728 if (IS_ERR(inode))
Namjae Jeon61412b62012-12-01 10:56:25 +0900729 return PTR_ERR(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900730
731 inode->i_op = &f2fs_dir_inode_operations;
732 inode->i_fop = &f2fs_dir_operations;
733 inode->i_mapping->a_ops = &f2fs_dblock_aops;
Yunlong Songbdbc90f2018-02-28 20:31:52 +0800734 inode_nohighmem(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900735
Jaegeuk Kim91942322016-05-20 10:13:22 -0700736 set_inode_flag(inode, FI_INC_LINK);
Gu Zhenge4795562013-09-27 18:08:30 +0800737 f2fs_lock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900738 err = f2fs_add_link(dentry, inode);
739 if (err)
740 goto out_fail;
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700741 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900742
Chao Yu4d57b862018-05-30 00:20:41 +0800743 f2fs_alloc_nid_done(sbi, inode->i_ino);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900744
Al Viro1e2e5472018-05-04 08:23:01 -0400745 d_instantiate_new(dentry, inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900746
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800747 if (IS_DIRSYNC(dir))
748 f2fs_sync_fs(sbi->sb, 1);
Jaegeuk Kim9bb02c32017-04-11 19:01:26 -0700749
750 f2fs_balance_fs(sbi, true);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900751 return 0;
752
753out_fail:
Jaegeuk Kim91942322016-05-20 10:13:22 -0700754 clear_inode_flag(inode, FI_INC_LINK);
Chao Yu4d57b862018-05-30 00:20:41 +0800755 f2fs_handle_failed_inode(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900756 return err;
757}
758
759static int f2fs_rmdir(struct inode *dir, struct dentry *dentry)
760{
David Howells2b0143b2015-03-17 22:25:59 +0000761 struct inode *inode = d_inode(dentry);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900762 if (f2fs_empty_dir(inode))
763 return f2fs_unlink(dir, dentry);
764 return -ENOTEMPTY;
765}
766
767static int f2fs_mknod(struct inode *dir, struct dentry *dentry,
768 umode_t mode, dev_t rdev)
769{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700770 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900771 struct inode *inode;
772 int err = 0;
773
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200774 if (unlikely(f2fs_cp_error(sbi)))
775 return -EIO;
Chao Yu00e09c02019-08-23 17:58:36 +0800776 if (!f2fs_is_checkpoint_ready(sbi))
777 return -ENOSPC;
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200778
Chao Yu0abd6752017-07-09 00:13:07 +0800779 err = dquot_initialize(dir);
780 if (err)
781 return err;
782
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900783 inode = f2fs_new_inode(dir, mode);
784 if (IS_ERR(inode))
785 return PTR_ERR(inode);
786
787 init_special_inode(inode, inode->i_mode, rdev);
788 inode->i_op = &f2fs_special_inode_operations;
789
Gu Zhenge4795562013-09-27 18:08:30 +0800790 f2fs_lock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900791 err = f2fs_add_link(dentry, inode);
792 if (err)
793 goto out;
Jaegeuk Kim44c16152014-09-25 11:55:53 -0700794 f2fs_unlock_op(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900795
Chao Yu4d57b862018-05-30 00:20:41 +0800796 f2fs_alloc_nid_done(sbi, inode->i_ino);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800797
Al Viro1e2e5472018-05-04 08:23:01 -0400798 d_instantiate_new(dentry, inode);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -0800799
800 if (IS_DIRSYNC(dir))
801 f2fs_sync_fs(sbi->sb, 1);
Jaegeuk Kim9bb02c32017-04-11 19:01:26 -0700802
803 f2fs_balance_fs(sbi, true);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900804 return 0;
805out:
Chao Yu4d57b862018-05-30 00:20:41 +0800806 f2fs_handle_failed_inode(inode);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900807 return err;
808}
809
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800810static int __f2fs_tmpfile(struct inode *dir, struct dentry *dentry,
811 umode_t mode, struct inode **whiteout)
812{
813 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
814 struct inode *inode;
815 int err;
816
Chao Yu0abd6752017-07-09 00:13:07 +0800817 err = dquot_initialize(dir);
818 if (err)
819 return err;
820
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800821 inode = f2fs_new_inode(dir, mode);
822 if (IS_ERR(inode))
823 return PTR_ERR(inode);
824
825 if (whiteout) {
826 init_special_inode(inode, inode->i_mode, WHITEOUT_DEV);
827 inode->i_op = &f2fs_special_inode_operations;
828 } else {
829 inode->i_op = &f2fs_file_inode_operations;
830 inode->i_fop = &f2fs_file_operations;
831 inode->i_mapping->a_ops = &f2fs_dblock_aops;
832 }
833
834 f2fs_lock_op(sbi);
Chao Yu4d57b862018-05-30 00:20:41 +0800835 err = f2fs_acquire_orphan_inode(sbi);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800836 if (err)
837 goto out;
838
839 err = f2fs_do_tmpfile(inode, dir);
840 if (err)
841 goto release_out;
842
843 /*
844 * add this non-linked tmpfile to orphan list, in this way we could
845 * remove all unused data of tmpfile after abnormal power-off.
846 */
Chao Yu4d57b862018-05-30 00:20:41 +0800847 f2fs_add_orphan_inode(inode);
848 f2fs_alloc_nid_done(sbi, inode->i_ino);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800849
850 if (whiteout) {
Jaegeuk Kima1961242016-05-20 09:43:20 -0700851 f2fs_i_links_write(inode, false);
Jaegeuk Kim5b1dbb02019-12-06 16:59:58 -0800852 inode->i_state |= I_LINKABLE;
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800853 *whiteout = inode;
854 } else {
855 d_tmpfile(dentry, inode);
856 }
Jaegeuk Kima1961242016-05-20 09:43:20 -0700857 /* link_count was changed by d_tmpfile as well. */
858 f2fs_unlock_op(sbi);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800859 unlock_new_inode(inode);
Jaegeuk Kim9bb02c32017-04-11 19:01:26 -0700860
861 f2fs_balance_fs(sbi, true);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800862 return 0;
863
864release_out:
Chao Yu4d57b862018-05-30 00:20:41 +0800865 f2fs_release_orphan_inode(sbi);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800866out:
Chao Yu4d57b862018-05-30 00:20:41 +0800867 f2fs_handle_failed_inode(inode);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800868 return err;
869}
870
871static int f2fs_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
872{
Sheng Yongff62af22018-03-15 18:51:42 +0800873 struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
874
875 if (unlikely(f2fs_cp_error(sbi)))
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200876 return -EIO;
Chao Yu00e09c02019-08-23 17:58:36 +0800877 if (!f2fs_is_checkpoint_ready(sbi))
878 return -ENOSPC;
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200879
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800880 return __f2fs_tmpfile(dir, dentry, mode, NULL);
881}
882
883static int f2fs_create_whiteout(struct inode *dir, struct inode **whiteout)
884{
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200885 if (unlikely(f2fs_cp_error(F2FS_I_SB(dir))))
886 return -EIO;
887
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800888 return __f2fs_tmpfile(dir, NULL, S_IFCHR | WHITEOUT_MODE, whiteout);
889}
890
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900891static int f2fs_rename(struct inode *old_dir, struct dentry *old_dentry,
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800892 struct inode *new_dir, struct dentry *new_dentry,
893 unsigned int flags)
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900894{
Jaegeuk Kim40813632014-09-02 15:31:18 -0700895 struct f2fs_sb_info *sbi = F2FS_I_SB(old_dir);
David Howells2b0143b2015-03-17 22:25:59 +0000896 struct inode *old_inode = d_inode(old_dentry);
897 struct inode *new_inode = d_inode(new_dentry);
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800898 struct inode *whiteout = NULL;
Jaegeuk Kim762e4db2019-12-11 15:10:47 -0800899 struct page *old_dir_page = NULL;
Chao Yu7e01e7ad2015-05-19 17:37:26 +0800900 struct page *old_page, *new_page = NULL;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900901 struct f2fs_dir_entry *old_dir_entry = NULL;
902 struct f2fs_dir_entry *old_entry;
903 struct f2fs_dir_entry *new_entry;
Jaegeuk Kimd83d0f52018-09-17 13:25:04 -0700904 int err;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900905
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200906 if (unlikely(f2fs_cp_error(sbi)))
907 return -EIO;
Chao Yu00e09c02019-08-23 17:58:36 +0800908 if (!f2fs_is_checkpoint_ready(sbi))
909 return -ENOSPC;
Jaegeuk Kim1f227a32017-10-23 23:48:49 +0200910
Chao Yu5c571322017-07-26 00:01:41 +0800911 if (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
912 (!projid_eq(F2FS_I(new_dir)->i_projid,
913 F2FS_I(old_dentry->d_inode)->i_projid)))
914 return -EXDEV;
915
Jaegeuk Kimb06af2a2019-12-09 19:03:05 -0800916 /*
917 * If new_inode is null, the below renaming flow will
918 * add a link in old_dir which can conver inline_dir.
919 * After then, if we failed to get the entry due to other
920 * reasons like ENOMEM, we had to remove the new entry.
921 * Instead of adding such the error handling routine, let's
922 * simply convert first here.
923 */
924 if (old_dir == new_dir && !new_inode) {
925 err = f2fs_try_convert_inline_dir(old_dir, new_dentry);
926 if (err)
927 return err;
928 }
929
Jaegeuk Kim5b1dbb02019-12-06 16:59:58 -0800930 if (flags & RENAME_WHITEOUT) {
931 err = f2fs_create_whiteout(old_dir, &whiteout);
932 if (err)
933 return err;
934 }
935
Chao Yu0abd6752017-07-09 00:13:07 +0800936 err = dquot_initialize(old_dir);
937 if (err)
938 goto out;
939
940 err = dquot_initialize(new_dir);
941 if (err)
942 goto out;
943
Jaegeuk Kimd8d13892017-10-23 23:50:15 +0200944 if (new_inode) {
945 err = dquot_initialize(new_inode);
946 if (err)
947 goto out;
948 }
949
Jaegeuk Kimd83d0f52018-09-17 13:25:04 -0700950 err = -ENOENT;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900951 old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page);
Chao Yu91246c22016-07-19 08:27:47 +0800952 if (!old_entry) {
953 if (IS_ERR(old_page))
954 err = PTR_ERR(old_page);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900955 goto out;
Chao Yu91246c22016-07-19 08:27:47 +0800956 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900957
958 if (S_ISDIR(old_inode->i_mode)) {
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900959 old_dir_entry = f2fs_parent_dir(old_inode, &old_dir_page);
Jaegeuk Kim3e198862016-06-09 14:57:19 -0700960 if (!old_dir_entry) {
Chao Yu91246c22016-07-19 08:27:47 +0800961 if (IS_ERR(old_dir_page))
962 err = PTR_ERR(old_dir_page);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900963 goto out_old;
Jaegeuk Kim3e198862016-06-09 14:57:19 -0700964 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900965 }
966
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900967 if (new_inode) {
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900968
969 err = -ENOTEMPTY;
970 if (old_dir_entry && !f2fs_empty_dir(new_inode))
Jaegeuk Kim5b1dbb02019-12-06 16:59:58 -0800971 goto out_dir;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900972
973 err = -ENOENT;
974 new_entry = f2fs_find_entry(new_dir, &new_dentry->d_name,
975 &new_page);
Chao Yu91246c22016-07-19 08:27:47 +0800976 if (!new_entry) {
977 if (IS_ERR(new_page))
978 err = PTR_ERR(new_page);
Jaegeuk Kim5b1dbb02019-12-06 16:59:58 -0800979 goto out_dir;
Chao Yu91246c22016-07-19 08:27:47 +0800980 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900981
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -0800982 f2fs_balance_fs(sbi, true);
Jaegeuk Kim00623e62015-12-22 11:56:08 -0800983
Chao Yu12560102014-06-24 14:16:24 +0800984 f2fs_lock_op(sbi);
985
Chao Yu4d57b862018-05-30 00:20:41 +0800986 err = f2fs_acquire_orphan_inode(sbi);
Jaegeuk Kimcbd56e72013-07-30 11:36:53 +0900987 if (err)
988 goto put_out_dir;
989
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900990 f2fs_set_link(new_dir, new_entry, new_page, old_inode);
Jaegeuk Kim762e4db2019-12-11 15:10:47 -0800991 new_page = NULL;
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900992
Deepa Dinamani078cd822016-09-14 07:48:04 -0700993 new_inode->i_ctime = current_time(new_inode);
Jaegeuk Kimd928bfb2014-03-20 19:10:08 +0900994 down_write(&F2FS_I(new_inode)->i_sem);
Jaegeuk Kim57397d82012-11-02 17:11:10 +0900995 if (old_dir_entry)
Jaegeuk Kima1961242016-05-20 09:43:20 -0700996 f2fs_i_links_write(new_inode, false);
997 f2fs_i_links_write(new_inode, false);
Jaegeuk Kimd928bfb2014-03-20 19:10:08 +0900998 up_write(&F2FS_I(new_inode)->i_sem);
999
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001000 if (!new_inode->i_nlink)
Chao Yu4d57b862018-05-30 00:20:41 +08001001 f2fs_add_orphan_inode(new_inode);
Jaegeuk Kimcbd56e72013-07-30 11:36:53 +09001002 else
Chao Yu4d57b862018-05-30 00:20:41 +08001003 f2fs_release_orphan_inode(sbi);
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001004 } else {
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -08001005 f2fs_balance_fs(sbi, true);
Jaegeuk Kim00623e62015-12-22 11:56:08 -08001006
Chao Yu12560102014-06-24 14:16:24 +08001007 f2fs_lock_op(sbi);
1008
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001009 err = f2fs_add_link(new_dentry, old_inode);
Chao Yu12560102014-06-24 14:16:24 +08001010 if (err) {
1011 f2fs_unlock_op(sbi);
Jaegeuk Kim5b1dbb02019-12-06 16:59:58 -08001012 goto out_dir;
Chao Yu12560102014-06-24 14:16:24 +08001013 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001014
Jaegeuk Kimee6d1822016-05-20 16:32:49 -07001015 if (old_dir_entry)
Jaegeuk Kima1961242016-05-20 09:43:20 -07001016 f2fs_i_links_write(new_dir, true);
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001017 }
1018
Jaegeuk Kimb2c08292014-06-30 18:09:55 +09001019 down_write(&F2FS_I(old_inode)->i_sem);
Sheng Yongb855bf02017-06-26 10:41:36 +08001020 if (!old_dir_entry || whiteout)
1021 file_lost_pino(old_inode);
1022 else
Chao Yu2a606372019-11-07 14:12:05 +08001023 /* adjust dir's i_pino to pass fsck check */
1024 f2fs_i_pino_write(old_inode, new_dir->i_ino);
Jaegeuk Kimb2c08292014-06-30 18:09:55 +09001025 up_write(&F2FS_I(old_inode)->i_sem);
1026
Deepa Dinamani078cd822016-09-14 07:48:04 -07001027 old_inode->i_ctime = current_time(old_inode);
Jaegeuk Kim7c457292016-10-14 11:51:23 -07001028 f2fs_mark_inode_dirty_sync(old_inode, false);
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001029
Chao Yudbeacf02014-09-24 18:17:04 +08001030 f2fs_delete_entry(old_entry, old_page, old_dir, NULL);
Jaegeuk Kim762e4db2019-12-11 15:10:47 -08001031 old_page = NULL;
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001032
Chao Yu7e01e7ad2015-05-19 17:37:26 +08001033 if (whiteout) {
Jaegeuk Kim91942322016-05-20 10:13:22 -07001034 set_inode_flag(whiteout, FI_INC_LINK);
Chao Yu7e01e7ad2015-05-19 17:37:26 +08001035 err = f2fs_add_link(old_dentry, whiteout);
1036 if (err)
1037 goto put_out_dir;
1038 whiteout->i_state &= ~I_LINKABLE;
1039 iput(whiteout);
1040 }
1041
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001042 if (old_dir_entry) {
Yunlong Songbdbc90f2018-02-28 20:31:52 +08001043 if (old_dir != new_dir && !whiteout)
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001044 f2fs_set_link(old_inode, old_dir_entry,
1045 old_dir_page, new_dir);
Yunlong Songbdbc90f2018-02-28 20:31:52 +08001046 else
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001047 f2fs_put_page(old_dir_page, 0);
Jaegeuk Kima1961242016-05-20 09:43:20 -07001048 f2fs_i_links_write(old_dir, false);
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001049 }
Jaegeuk Kimade990f2018-04-24 22:43:01 -06001050 if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) {
Chao Yu4d57b862018-05-30 00:20:41 +08001051 f2fs_add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
Jaegeuk Kimade990f2018-04-24 22:43:01 -06001052 if (S_ISDIR(old_inode->i_mode))
Chao Yu4d57b862018-05-30 00:20:41 +08001053 f2fs_add_ino_entry(sbi, old_inode->i_ino,
1054 TRANS_DIR_INO);
Jaegeuk Kimade990f2018-04-24 22:43:01 -06001055 }
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001056
Gu Zhenge4795562013-09-27 18:08:30 +08001057 f2fs_unlock_op(sbi);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -08001058
1059 if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
1060 f2fs_sync_fs(sbi->sb, 1);
Sahitya Tummala63903982018-10-05 10:47:40 +05301061
1062 f2fs_update_time(sbi, REQ_TIME);
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001063 return 0;
1064
Jaegeuk Kimcbd56e72013-07-30 11:36:53 +09001065put_out_dir:
Chao Yu12560102014-06-24 14:16:24 +08001066 f2fs_unlock_op(sbi);
Jaegeuk Kim762e4db2019-12-11 15:10:47 -08001067 f2fs_put_page(new_page, 0);
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001068out_dir:
Yunlong Songbdbc90f2018-02-28 20:31:52 +08001069 if (old_dir_entry)
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001070 f2fs_put_page(old_dir_page, 0);
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001071out_old:
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001072 f2fs_put_page(old_page, 0);
1073out:
Jaegeuk Kim5b1dbb02019-12-06 16:59:58 -08001074 if (whiteout)
1075 iput(whiteout);
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001076 return err;
1077}
1078
Chao Yu32f9bc22014-07-12 19:13:54 +08001079static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
1080 struct inode *new_dir, struct dentry *new_dentry)
1081{
Jaegeuk Kim40813632014-09-02 15:31:18 -07001082 struct f2fs_sb_info *sbi = F2FS_I_SB(old_dir);
David Howells2b0143b2015-03-17 22:25:59 +00001083 struct inode *old_inode = d_inode(old_dentry);
1084 struct inode *new_inode = d_inode(new_dentry);
Chao Yu32f9bc22014-07-12 19:13:54 +08001085 struct page *old_dir_page, *new_dir_page;
1086 struct page *old_page, *new_page;
1087 struct f2fs_dir_entry *old_dir_entry = NULL, *new_dir_entry = NULL;
1088 struct f2fs_dir_entry *old_entry, *new_entry;
1089 int old_nlink = 0, new_nlink = 0;
Jaegeuk Kimd83d0f52018-09-17 13:25:04 -07001090 int err;
Chao Yu32f9bc22014-07-12 19:13:54 +08001091
Jaegeuk Kim1f227a32017-10-23 23:48:49 +02001092 if (unlikely(f2fs_cp_error(sbi)))
1093 return -EIO;
Chao Yu00e09c02019-08-23 17:58:36 +08001094 if (!f2fs_is_checkpoint_ready(sbi))
1095 return -ENOSPC;
Jaegeuk Kim1f227a32017-10-23 23:48:49 +02001096
Chao Yu5c571322017-07-26 00:01:41 +08001097 if ((is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
1098 !projid_eq(F2FS_I(new_dir)->i_projid,
1099 F2FS_I(old_dentry->d_inode)->i_projid)) ||
1100 (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) &&
1101 !projid_eq(F2FS_I(old_dir)->i_projid,
1102 F2FS_I(new_dentry->d_inode)->i_projid)))
1103 return -EXDEV;
1104
Chao Yu0abd6752017-07-09 00:13:07 +08001105 err = dquot_initialize(old_dir);
1106 if (err)
1107 goto out;
1108
1109 err = dquot_initialize(new_dir);
1110 if (err)
1111 goto out;
1112
Jaegeuk Kimd83d0f52018-09-17 13:25:04 -07001113 err = -ENOENT;
Chao Yu32f9bc22014-07-12 19:13:54 +08001114 old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page);
Chao Yu91246c22016-07-19 08:27:47 +08001115 if (!old_entry) {
1116 if (IS_ERR(old_page))
1117 err = PTR_ERR(old_page);
Chao Yu32f9bc22014-07-12 19:13:54 +08001118 goto out;
Chao Yu91246c22016-07-19 08:27:47 +08001119 }
Chao Yu32f9bc22014-07-12 19:13:54 +08001120
1121 new_entry = f2fs_find_entry(new_dir, &new_dentry->d_name, &new_page);
Chao Yu91246c22016-07-19 08:27:47 +08001122 if (!new_entry) {
1123 if (IS_ERR(new_page))
1124 err = PTR_ERR(new_page);
Chao Yu32f9bc22014-07-12 19:13:54 +08001125 goto out_old;
Chao Yu91246c22016-07-19 08:27:47 +08001126 }
Chao Yu32f9bc22014-07-12 19:13:54 +08001127
1128 /* prepare for updating ".." directory entry info later */
1129 if (old_dir != new_dir) {
1130 if (S_ISDIR(old_inode->i_mode)) {
Chao Yu32f9bc22014-07-12 19:13:54 +08001131 old_dir_entry = f2fs_parent_dir(old_inode,
1132 &old_dir_page);
Jaegeuk Kim3e198862016-06-09 14:57:19 -07001133 if (!old_dir_entry) {
Chao Yu91246c22016-07-19 08:27:47 +08001134 if (IS_ERR(old_dir_page))
1135 err = PTR_ERR(old_dir_page);
Chao Yu32f9bc22014-07-12 19:13:54 +08001136 goto out_new;
Jaegeuk Kim3e198862016-06-09 14:57:19 -07001137 }
Chao Yu32f9bc22014-07-12 19:13:54 +08001138 }
1139
1140 if (S_ISDIR(new_inode->i_mode)) {
Chao Yu32f9bc22014-07-12 19:13:54 +08001141 new_dir_entry = f2fs_parent_dir(new_inode,
1142 &new_dir_page);
Jaegeuk Kim3e198862016-06-09 14:57:19 -07001143 if (!new_dir_entry) {
Chao Yu91246c22016-07-19 08:27:47 +08001144 if (IS_ERR(new_dir_page))
1145 err = PTR_ERR(new_dir_page);
Chao Yu32f9bc22014-07-12 19:13:54 +08001146 goto out_old_dir;
Jaegeuk Kim3e198862016-06-09 14:57:19 -07001147 }
Chao Yu32f9bc22014-07-12 19:13:54 +08001148 }
1149 }
1150
1151 /*
1152 * If cross rename between file and directory those are not
1153 * in the same directory, we will inc nlink of file's parent
1154 * later, so we should check upper boundary of its nlink.
1155 */
1156 if ((!old_dir_entry || !new_dir_entry) &&
1157 old_dir_entry != new_dir_entry) {
1158 old_nlink = old_dir_entry ? -1 : 1;
1159 new_nlink = -old_nlink;
1160 err = -EMLINK;
Kinglong Meee2f0e962017-03-04 21:48:28 +08001161 if ((old_nlink > 0 && old_dir->i_nlink >= F2FS_LINK_MAX) ||
1162 (new_nlink > 0 && new_dir->i_nlink >= F2FS_LINK_MAX))
Chao Yu32f9bc22014-07-12 19:13:54 +08001163 goto out_new_dir;
1164 }
1165
Jaegeuk Kim2c4db1a2016-01-07 14:15:04 -08001166 f2fs_balance_fs(sbi, true);
Jaegeuk Kim00623e62015-12-22 11:56:08 -08001167
Chao Yu32f9bc22014-07-12 19:13:54 +08001168 f2fs_lock_op(sbi);
1169
Chao Yu32f9bc22014-07-12 19:13:54 +08001170 /* update ".." directory entry info of old dentry */
1171 if (old_dir_entry)
1172 f2fs_set_link(old_inode, old_dir_entry, old_dir_page, new_dir);
1173
1174 /* update ".." directory entry info of new dentry */
1175 if (new_dir_entry)
1176 f2fs_set_link(new_inode, new_dir_entry, new_dir_page, old_dir);
1177
1178 /* update directory entry info of old dir inode */
1179 f2fs_set_link(old_dir, old_entry, old_page, new_inode);
1180
1181 down_write(&F2FS_I(old_inode)->i_sem);
Chao Yu2a606372019-11-07 14:12:05 +08001182 if (!old_dir_entry)
1183 file_lost_pino(old_inode);
1184 else
1185 /* adjust dir's i_pino to pass fsck check */
1186 f2fs_i_pino_write(old_inode, new_dir->i_ino);
Chao Yu32f9bc22014-07-12 19:13:54 +08001187 up_write(&F2FS_I(old_inode)->i_sem);
1188
Deepa Dinamani078cd822016-09-14 07:48:04 -07001189 old_dir->i_ctime = current_time(old_dir);
Chao Yu32f9bc22014-07-12 19:13:54 +08001190 if (old_nlink) {
1191 down_write(&F2FS_I(old_dir)->i_sem);
Jaegeuk Kima1961242016-05-20 09:43:20 -07001192 f2fs_i_links_write(old_dir, old_nlink > 0);
Chao Yu32f9bc22014-07-12 19:13:54 +08001193 up_write(&F2FS_I(old_dir)->i_sem);
1194 }
Jaegeuk Kim7c457292016-10-14 11:51:23 -07001195 f2fs_mark_inode_dirty_sync(old_dir, false);
Chao Yu32f9bc22014-07-12 19:13:54 +08001196
1197 /* update directory entry info of new dir inode */
1198 f2fs_set_link(new_dir, new_entry, new_page, old_inode);
1199
1200 down_write(&F2FS_I(new_inode)->i_sem);
Chao Yu2a606372019-11-07 14:12:05 +08001201 if (!new_dir_entry)
1202 file_lost_pino(new_inode);
1203 else
1204 /* adjust dir's i_pino to pass fsck check */
1205 f2fs_i_pino_write(new_inode, old_dir->i_ino);
Chao Yu32f9bc22014-07-12 19:13:54 +08001206 up_write(&F2FS_I(new_inode)->i_sem);
1207
Deepa Dinamani078cd822016-09-14 07:48:04 -07001208 new_dir->i_ctime = current_time(new_dir);
Chao Yu32f9bc22014-07-12 19:13:54 +08001209 if (new_nlink) {
1210 down_write(&F2FS_I(new_dir)->i_sem);
Jaegeuk Kima1961242016-05-20 09:43:20 -07001211 f2fs_i_links_write(new_dir, new_nlink > 0);
Chao Yu32f9bc22014-07-12 19:13:54 +08001212 up_write(&F2FS_I(new_dir)->i_sem);
1213 }
Jaegeuk Kim7c457292016-10-14 11:51:23 -07001214 f2fs_mark_inode_dirty_sync(new_dir, false);
Chao Yu32f9bc22014-07-12 19:13:54 +08001215
Chao Yu63189b72018-03-08 14:22:56 +08001216 if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) {
Chao Yu4d57b862018-05-30 00:20:41 +08001217 f2fs_add_ino_entry(sbi, old_dir->i_ino, TRANS_DIR_INO);
1218 f2fs_add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO);
Junling Zheng93cf93f2018-03-07 12:07:49 +08001219 }
Jaegeuk Kim0a007b972017-12-28 08:09:44 -08001220
Chao Yu32f9bc22014-07-12 19:13:54 +08001221 f2fs_unlock_op(sbi);
Jaegeuk Kimb7e1d802014-11-09 22:15:31 -08001222
1223 if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
1224 f2fs_sync_fs(sbi->sb, 1);
Sahitya Tummala63903982018-10-05 10:47:40 +05301225
1226 f2fs_update_time(sbi, REQ_TIME);
Chao Yu32f9bc22014-07-12 19:13:54 +08001227 return 0;
Chao Yu32f9bc22014-07-12 19:13:54 +08001228out_new_dir:
1229 if (new_dir_entry) {
Chao Yu32f9bc22014-07-12 19:13:54 +08001230 f2fs_put_page(new_dir_page, 0);
1231 }
1232out_old_dir:
1233 if (old_dir_entry) {
Chao Yu32f9bc22014-07-12 19:13:54 +08001234 f2fs_put_page(old_dir_page, 0);
1235 }
1236out_new:
Chao Yu32f9bc22014-07-12 19:13:54 +08001237 f2fs_put_page(new_page, 0);
1238out_old:
Chao Yu32f9bc22014-07-12 19:13:54 +08001239 f2fs_put_page(old_page, 0);
1240out:
1241 return err;
1242}
1243
1244static int f2fs_rename2(struct inode *old_dir, struct dentry *old_dentry,
1245 struct inode *new_dir, struct dentry *new_dentry,
1246 unsigned int flags)
1247{
Eric Biggers2e45b072017-11-29 12:35:30 -08001248 int err;
1249
Chao Yu7e01e7ad2015-05-19 17:37:26 +08001250 if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
Chao Yu32f9bc22014-07-12 19:13:54 +08001251 return -EINVAL;
1252
Eric Biggers2e45b072017-11-29 12:35:30 -08001253 err = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry,
1254 flags);
1255 if (err)
1256 return err;
1257
Chao Yu32f9bc22014-07-12 19:13:54 +08001258 if (flags & RENAME_EXCHANGE) {
1259 return f2fs_cross_rename(old_dir, old_dentry,
1260 new_dir, new_dentry);
1261 }
1262 /*
1263 * VFS has already handled the new dentry existence case,
1264 * here, we just deal with "RENAME_NOREPLACE" as regular rename.
1265 */
Chao Yu7e01e7ad2015-05-19 17:37:26 +08001266 return f2fs_rename(old_dir, old_dentry, new_dir, new_dentry, flags);
Chao Yu32f9bc22014-07-12 19:13:54 +08001267}
1268
Al Viro6b255392015-11-17 10:20:54 -05001269static const char *f2fs_encrypted_get_link(struct dentry *dentry,
Al Virofceef392015-12-29 15:58:39 -05001270 struct inode *inode,
1271 struct delayed_call *done)
Chao Yu50732df2014-06-19 16:23:19 +08001272{
Eric Biggersf2329cb2018-01-11 23:26:49 -05001273 struct page *page;
1274 const char *target;
Chao Yu50732df2014-06-19 16:23:19 +08001275
Al Viro6b255392015-11-17 10:20:54 -05001276 if (!dentry)
1277 return ERR_PTR(-ECHILD);
1278
Eric Biggersf2329cb2018-01-11 23:26:49 -05001279 page = read_mapping_page(inode->i_mapping, 0, NULL);
1280 if (IS_ERR(page))
1281 return ERR_CAST(page);
Chao Yu50732df2014-06-19 16:23:19 +08001282
Eric Biggersf2329cb2018-01-11 23:26:49 -05001283 target = fscrypt_get_symlink(inode, page_address(page),
1284 inode->i_sb->s_blocksize, done);
1285 put_page(page);
1286 return target;
Chao Yu50732df2014-06-19 16:23:19 +08001287}
1288
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -07001289const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
Jack Qiua87aff12020-07-24 16:55:28 +08001290 .get_link = f2fs_encrypted_get_link,
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -07001291 .getattr = f2fs_getattr,
1292 .setattr = f2fs_setattr,
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -07001293 .listxattr = f2fs_listxattr,
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -07001294};
Jaegeuk Kimcbaf0422015-04-29 15:10:53 -07001295
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001296const struct inode_operations f2fs_dir_inode_operations = {
1297 .create = f2fs_create,
1298 .lookup = f2fs_lookup,
1299 .link = f2fs_link,
1300 .unlink = f2fs_unlink,
1301 .symlink = f2fs_symlink,
1302 .mkdir = f2fs_mkdir,
1303 .rmdir = f2fs_rmdir,
1304 .mknod = f2fs_mknod,
Miklos Szeredi2773bf02016-09-27 11:03:58 +02001305 .rename = f2fs_rename2,
Chao Yu50732df2014-06-19 16:23:19 +08001306 .tmpfile = f2fs_tmpfile,
Jaegeuk Kim2d4d9fb52013-06-07 16:33:07 +09001307 .getattr = f2fs_getattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001308 .setattr = f2fs_setattr,
1309 .get_acl = f2fs_get_acl,
Christoph Hellwiga6dda0e2013-12-20 05:16:45 -08001310 .set_acl = f2fs_set_acl,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001311 .listxattr = f2fs_listxattr,
Chao Yu7975f342019-07-22 18:03:50 +08001312 .fiemap = f2fs_fiemap,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001313};
1314
1315const struct inode_operations f2fs_symlink_inode_operations = {
Jack Qiua87aff12020-07-24 16:55:28 +08001316 .get_link = f2fs_get_link,
Jaegeuk Kim2d4d9fb52013-06-07 16:33:07 +09001317 .getattr = f2fs_getattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001318 .setattr = f2fs_setattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001319 .listxattr = f2fs_listxattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001320};
1321
1322const struct inode_operations f2fs_special_inode_operations = {
Jaegeuk Kim2d4d9fb52013-06-07 16:33:07 +09001323 .getattr = f2fs_getattr,
Jack Qiua87aff12020-07-24 16:55:28 +08001324 .setattr = f2fs_setattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001325 .get_acl = f2fs_get_acl,
Christoph Hellwiga6dda0e2013-12-20 05:16:45 -08001326 .set_acl = f2fs_set_acl,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001327 .listxattr = f2fs_listxattr,
Jaegeuk Kim57397d82012-11-02 17:11:10 +09001328};