Commit | Line | Data |
---|---|---|
7c1a000d | 1 | // SPDX-License-Identifier: GPL-2.0 |
0a8165d7 | 2 | /* |
57397d86 JK |
3 | * fs/f2fs/namei.c |
4 | * | |
5 | * Copyright (c) 2012 Samsung Electronics Co., Ltd. | |
6 | * http://www.samsung.com/ | |
57397d86 JK |
7 | */ |
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> | |
428e3bcf | 13 | #include <linux/random.h> |
50732df0 | 14 | #include <linux/dcache.h> |
feb7cbb0 | 15 | #include <linux/namei.h> |
0abd675e | 16 | #include <linux/quotaops.h> |
57397d86 JK |
17 | |
18 | #include "f2fs.h" | |
953a3e27 | 19 | #include "node.h" |
4354994f | 20 | #include "segment.h" |
57397d86 JK |
21 | #include "xattr.h" |
22 | #include "acl.h" | |
a2a4a7e4 | 23 | #include <trace/events/f2fs.h> |
57397d86 | 24 | |
984fc4e7 CY |
25 | static struct inode *f2fs_new_inode(struct user_namespace *mnt_userns, |
26 | struct inode *dir, umode_t mode) | |
57397d86 | 27 | { |
4081363f | 28 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); |
57397d86 JK |
29 | nid_t ino; |
30 | struct inode *inode; | |
31 | bool nid_free = false; | |
e075b690 | 32 | bool encrypt = false; |
6afc662e | 33 | int xattr_size = 0; |
e479556b | 34 | int err; |
57397d86 | 35 | |
a014e037 | 36 | inode = new_inode(dir->i_sb); |
57397d86 JK |
37 | if (!inode) |
38 | return ERR_PTR(-ENOMEM); | |
39 | ||
4d57b86d | 40 | if (!f2fs_alloc_nid(sbi, &ino)) { |
57397d86 JK |
41 | err = -ENOSPC; |
42 | goto fail; | |
43 | } | |
57397d86 | 44 | |
0abd675e CY |
45 | nid_free = true; |
46 | ||
984fc4e7 | 47 | inode_init_owner(mnt_userns, inode, dir, mode); |
57397d86 JK |
48 | |
49 | inode->i_ino = ino; | |
57397d86 | 50 | inode->i_blocks = 0; |
95582b00 | 51 | inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); |
24b81dfc | 52 | F2FS_I(inode)->i_crtime = inode->i_mtime; |
a251c17a | 53 | inode->i_generation = get_random_u32(); |
57397d86 | 54 | |
1c41e680 CY |
55 | if (S_ISDIR(inode->i_mode)) |
56 | F2FS_I(inode)->i_current_depth = 1; | |
57 | ||
57397d86 JK |
58 | err = insert_inode_locked(inode); |
59 | if (err) { | |
60 | err = -EINVAL; | |
a21c20f0 | 61 | goto fail; |
57397d86 | 62 | } |
622f28ae | 63 | |
7beb01f7 | 64 | if (f2fs_sb_has_project_quota(sbi) && |
59c84408 | 65 | (F2FS_I(dir)->i_flags & F2FS_PROJINHERIT_FL)) |
5c57132e CY |
66 | F2FS_I(inode)->i_projid = F2FS_I(dir)->i_projid; |
67 | else | |
984fc4e7 | 68 | F2FS_I(inode)->i_projid = make_kprojid(mnt_userns, |
5c57132e CY |
69 | F2FS_DEF_PROJID); |
70 | ||
e075b690 EB |
71 | err = fscrypt_prepare_new_inode(dir, inode, &encrypt); |
72 | if (err) | |
73 | goto fail_drop; | |
74 | ||
10a26878 | 75 | err = f2fs_dquot_initialize(inode); |
0abd675e CY |
76 | if (err) |
77 | goto fail_drop; | |
78 | ||
9ac1e2d8 DJ |
79 | set_inode_flag(inode, FI_NEW_INODE); |
80 | ||
e075b690 | 81 | if (encrypt) |
fcc85a4d JK |
82 | f2fs_set_encrypted_inode(inode); |
83 | ||
7beb01f7 | 84 | if (f2fs_sb_has_extra_attr(sbi)) { |
7a2af766 CY |
85 | set_inode_flag(inode, FI_EXTRA_ATTR); |
86 | F2FS_I(inode)->i_extra_isize = F2FS_TOTAL_EXTRA_ATTR_SIZE; | |
87 | } | |
88 | ||
91942321 JK |
89 | if (test_opt(sbi, INLINE_XATTR)) |
90 | set_inode_flag(inode, FI_INLINE_XATTR); | |
6afc662e | 91 | |
01b960e9 | 92 | if (f2fs_may_inline_dentry(inode)) |
91942321 | 93 | set_inode_flag(inode, FI_INLINE_DENTRY); |
622f28ae | 94 | |
7beb01f7 | 95 | if (f2fs_sb_has_flexible_inline_xattr(sbi)) { |
6afc662e CY |
96 | f2fs_bug_on(sbi, !f2fs_has_extra_attr(inode)); |
97 | if (f2fs_has_inline_xattr(inode)) | |
63189b78 | 98 | xattr_size = F2FS_OPTION(sbi).inline_xattr_size; |
6afc662e CY |
99 | /* Otherwise, will be 0 */ |
100 | } else if (f2fs_has_inline_xattr(inode) || | |
101 | f2fs_has_inline_dentry(inode)) { | |
102 | xattr_size = DEFAULT_INLINE_XATTR_ADDRS; | |
103 | } | |
104 | F2FS_I(inode)->i_inline_xattr_size = xattr_size; | |
105 | ||
3e72f721 JK |
106 | f2fs_init_extent_tree(inode, NULL); |
107 | ||
5c57132e CY |
108 | F2FS_I(inode)->i_flags = |
109 | f2fs_mask_flags(mode, F2FS_I(dir)->i_flags & F2FS_FL_INHERITED); | |
110 | ||
11f5020d | 111 | if (S_ISDIR(inode->i_mode)) |
59c84408 | 112 | F2FS_I(inode)->i_flags |= F2FS_INDEX_FL; |
11f5020d | 113 | |
59c84408 | 114 | if (F2FS_I(inode)->i_flags & F2FS_PROJINHERIT_FL) |
5c57132e CY |
115 | set_inode_flag(inode, FI_PROJ_INHERIT); |
116 | ||
4c8ff709 CY |
117 | if (f2fs_sb_has_compression(sbi)) { |
118 | /* Inherit the compression flag in directory */ | |
119 | if ((F2FS_I(dir)->i_flags & F2FS_COMPR_FL) && | |
120 | f2fs_may_compress(inode)) | |
121 | set_compress_context(inode); | |
122 | } | |
123 | ||
4cde00d5 JK |
124 | /* Should enable inline_data after compression set */ |
125 | if (test_opt(sbi, INLINE_DATA) && f2fs_may_inline_data(inode)) | |
126 | set_inode_flag(inode, FI_INLINE_DATA); | |
127 | ||
128 | stat_inc_inline_xattr(inode); | |
129 | stat_inc_inline_inode(inode); | |
130 | stat_inc_inline_dir(inode); | |
131 | ||
9149a5eb CY |
132 | f2fs_set_inode_flags(inode); |
133 | ||
d70b4f53 | 134 | trace_f2fs_new_inode(inode, 0); |
57397d86 JK |
135 | return inode; |
136 | ||
57397d86 | 137 | fail: |
d70b4f53 | 138 | trace_f2fs_new_inode(inode, err); |
531ad7d5 | 139 | make_bad_inode(inode); |
57397d86 | 140 | if (nid_free) |
91942321 | 141 | set_inode_flag(inode, FI_FREE_NID); |
c9b63bd0 | 142 | iput(inode); |
57397d86 | 143 | return ERR_PTR(err); |
0abd675e CY |
144 | fail_drop: |
145 | trace_f2fs_new_inode(inode, err); | |
146 | dquot_drop(inode); | |
147 | inode->i_flags |= S_NOQUOTA; | |
148 | if (nid_free) | |
149 | set_inode_flag(inode, FI_FREE_NID); | |
150 | clear_nlink(inode); | |
151 | unlock_new_inode(inode); | |
152 | iput(inode); | |
153 | return ERR_PTR(err); | |
57397d86 JK |
154 | } |
155 | ||
4a67d9b0 CY |
156 | static inline int is_extension_exist(const unsigned char *s, const char *sub, |
157 | bool tmp_ext) | |
57397d86 | 158 | { |
9836b8b9 LR |
159 | size_t slen = strlen(s); |
160 | size_t sublen = strlen(sub); | |
7732c26a | 161 | int i; |
57397d86 | 162 | |
4c8ff709 CY |
163 | if (sublen == 1 && *sub == '*') |
164 | return 1; | |
165 | ||
741a7bea CY |
166 | /* |
167 | * filename format of multimedia file should be defined as: | |
7732c26a | 168 | * "filename + '.' + extension + (optional: '.' + temp extension)". |
741a7bea CY |
169 | */ |
170 | if (slen < sublen + 2) | |
171 | return 0; | |
172 | ||
4a67d9b0 CY |
173 | if (!tmp_ext) { |
174 | /* file has no temp extension */ | |
175 | if (s[slen - sublen - 1] != '.') | |
176 | return 0; | |
177 | return !strncasecmp(s + slen - sublen, sub, sublen); | |
178 | } | |
179 | ||
7732c26a CY |
180 | for (i = 1; i < slen - sublen; i++) { |
181 | if (s[i] != '.') | |
182 | continue; | |
183 | if (!strncasecmp(s + i + 1, sub, sublen)) | |
184 | return 1; | |
185 | } | |
57397d86 | 186 | |
7732c26a | 187 | return 0; |
57397d86 JK |
188 | } |
189 | ||
0a8165d7 | 190 | /* |
7a88ddb5 | 191 | * Set file's temperature for hot/cold data separation |
57397d86 | 192 | */ |
b6a06cbb | 193 | static inline void set_file_temperature(struct f2fs_sb_info *sbi, struct inode *inode, |
57397d86 JK |
194 | const unsigned char *name) |
195 | { | |
846ae671 | 196 | __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; |
b6a06cbb | 197 | int i, cold_count, hot_count; |
846ae671 | 198 | |
e4544b63 | 199 | f2fs_down_read(&sbi->sb_lock); |
846ae671 | 200 | |
b6a06cbb CY |
201 | cold_count = le32_to_cpu(sbi->raw_super->extension_count); |
202 | hot_count = sbi->raw_super->hot_ext_count; | |
57397d86 | 203 | |
b6a06cbb | 204 | for (i = 0; i < cold_count + hot_count; i++) { |
4a67d9b0 | 205 | if (is_extension_exist(name, extlist[i], true)) |
ed15ba14 | 206 | break; |
57397d86 | 207 | } |
846ae671 | 208 | |
e4544b63 | 209 | f2fs_up_read(&sbi->sb_lock); |
ed15ba14 CY |
210 | |
211 | if (i == cold_count + hot_count) | |
212 | return; | |
213 | ||
214 | if (i < cold_count) | |
215 | file_set_cold(inode); | |
216 | else | |
217 | file_set_hot(inode); | |
846ae671 CY |
218 | } |
219 | ||
4d57b86d | 220 | int f2fs_update_extension_list(struct f2fs_sb_info *sbi, const char *name, |
b6a06cbb | 221 | bool hot, bool set) |
846ae671 CY |
222 | { |
223 | __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; | |
b6a06cbb CY |
224 | int cold_count = le32_to_cpu(sbi->raw_super->extension_count); |
225 | int hot_count = sbi->raw_super->hot_ext_count; | |
226 | int total_count = cold_count + hot_count; | |
227 | int start, count; | |
846ae671 CY |
228 | int i; |
229 | ||
b6a06cbb CY |
230 | if (set) { |
231 | if (total_count == F2FS_MAX_EXTENSION) | |
232 | return -EINVAL; | |
233 | } else { | |
234 | if (!hot && !cold_count) | |
235 | return -EINVAL; | |
236 | if (hot && !hot_count) | |
237 | return -EINVAL; | |
238 | } | |
239 | ||
240 | if (hot) { | |
241 | start = cold_count; | |
242 | count = total_count; | |
243 | } else { | |
244 | start = 0; | |
245 | count = cold_count; | |
246 | } | |
247 | ||
248 | for (i = start; i < count; i++) { | |
846ae671 CY |
249 | if (strcmp(name, extlist[i])) |
250 | continue; | |
251 | ||
252 | if (set) | |
253 | return -EINVAL; | |
254 | ||
255 | memcpy(extlist[i], extlist[i + 1], | |
b6a06cbb CY |
256 | F2FS_EXTENSION_LEN * (total_count - i - 1)); |
257 | memset(extlist[total_count - 1], 0, F2FS_EXTENSION_LEN); | |
258 | if (hot) | |
259 | sbi->raw_super->hot_ext_count = hot_count - 1; | |
260 | else | |
261 | sbi->raw_super->extension_count = | |
262 | cpu_to_le32(cold_count - 1); | |
846ae671 CY |
263 | return 0; |
264 | } | |
265 | ||
266 | if (!set) | |
267 | return -EINVAL; | |
268 | ||
b6a06cbb | 269 | if (hot) { |
b1385478 | 270 | memcpy(extlist[count], name, strlen(name)); |
b6a06cbb CY |
271 | sbi->raw_super->hot_ext_count = hot_count + 1; |
272 | } else { | |
273 | char buf[F2FS_MAX_EXTENSION][F2FS_EXTENSION_LEN]; | |
274 | ||
275 | memcpy(buf, &extlist[cold_count], | |
276 | F2FS_EXTENSION_LEN * hot_count); | |
277 | memset(extlist[cold_count], 0, F2FS_EXTENSION_LEN); | |
b1385478 | 278 | memcpy(extlist[cold_count], name, strlen(name)); |
b6a06cbb CY |
279 | memcpy(&extlist[cold_count + 1], buf, |
280 | F2FS_EXTENSION_LEN * hot_count); | |
281 | sbi->raw_super->extension_count = cpu_to_le32(cold_count + 1); | |
282 | } | |
846ae671 | 283 | return 0; |
57397d86 JK |
284 | } |
285 | ||
4c8ff709 CY |
286 | static void set_compress_inode(struct f2fs_sb_info *sbi, struct inode *inode, |
287 | const unsigned char *name) | |
288 | { | |
289 | __u8 (*extlist)[F2FS_EXTENSION_LEN] = sbi->raw_super->extension_list; | |
151b1982 FC |
290 | unsigned char (*noext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).noextensions; |
291 | unsigned char (*ext)[F2FS_EXTENSION_LEN] = F2FS_OPTION(sbi).extensions; | |
292 | unsigned char ext_cnt = F2FS_OPTION(sbi).compress_ext_cnt; | |
293 | unsigned char noext_cnt = F2FS_OPTION(sbi).nocompress_ext_cnt; | |
4c8ff709 CY |
294 | int i, cold_count, hot_count; |
295 | ||
296 | if (!f2fs_sb_has_compression(sbi) || | |
4c8ff709 | 297 | F2FS_I(inode)->i_flags & F2FS_NOCOMP_FL || |
151b1982 FC |
298 | !f2fs_may_compress(inode) || |
299 | (!ext_cnt && !noext_cnt)) | |
4c8ff709 CY |
300 | return; |
301 | ||
e4544b63 | 302 | f2fs_down_read(&sbi->sb_lock); |
4c8ff709 CY |
303 | |
304 | cold_count = le32_to_cpu(sbi->raw_super->extension_count); | |
305 | hot_count = sbi->raw_super->hot_ext_count; | |
306 | ||
307 | for (i = cold_count; i < cold_count + hot_count; i++) { | |
4a67d9b0 | 308 | if (is_extension_exist(name, extlist[i], false)) { |
e4544b63 | 309 | f2fs_up_read(&sbi->sb_lock); |
4c8ff709 CY |
310 | return; |
311 | } | |
312 | } | |
313 | ||
e4544b63 | 314 | f2fs_up_read(&sbi->sb_lock); |
4c8ff709 | 315 | |
151b1982 FC |
316 | for (i = 0; i < noext_cnt; i++) { |
317 | if (is_extension_exist(name, noext[i], false)) { | |
318 | f2fs_disable_compressed_file(inode); | |
319 | return; | |
320 | } | |
321 | } | |
322 | ||
323 | if (is_inode_flag_set(inode, FI_COMPRESSED_FILE)) | |
324 | return; | |
4c8ff709 CY |
325 | |
326 | for (i = 0; i < ext_cnt; i++) { | |
4a67d9b0 | 327 | if (!is_extension_exist(name, ext[i], false)) |
4c8ff709 CY |
328 | continue; |
329 | ||
4cde00d5 JK |
330 | /* Do not use inline_data with compression */ |
331 | stat_dec_inline_inode(inode); | |
332 | clear_inode_flag(inode, FI_INLINE_DATA); | |
4c8ff709 CY |
333 | set_compress_context(inode); |
334 | return; | |
335 | } | |
336 | } | |
337 | ||
549c7297 CB |
338 | static int f2fs_create(struct user_namespace *mnt_userns, struct inode *dir, |
339 | struct dentry *dentry, umode_t mode, bool excl) | |
57397d86 | 340 | { |
4081363f | 341 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); |
57397d86 JK |
342 | struct inode *inode; |
343 | nid_t ino = 0; | |
e479556b | 344 | int err; |
57397d86 | 345 | |
1f227a3e JK |
346 | if (unlikely(f2fs_cp_error(sbi))) |
347 | return -EIO; | |
00e09c0b CY |
348 | if (!f2fs_is_checkpoint_ready(sbi)) |
349 | return -ENOSPC; | |
1f227a3e | 350 | |
10a26878 | 351 | err = f2fs_dquot_initialize(dir); |
0abd675e CY |
352 | if (err) |
353 | return err; | |
354 | ||
984fc4e7 | 355 | inode = f2fs_new_inode(mnt_userns, dir, mode); |
57397d86 JK |
356 | if (IS_ERR(inode)) |
357 | return PTR_ERR(inode); | |
358 | ||
359 | if (!test_opt(sbi, DISABLE_EXT_IDENTIFY)) | |
b6a06cbb | 360 | set_file_temperature(sbi, inode, dentry->d_name.name); |
57397d86 | 361 | |
4c8ff709 CY |
362 | set_compress_inode(sbi, inode, dentry->d_name.name); |
363 | ||
57397d86 JK |
364 | inode->i_op = &f2fs_file_inode_operations; |
365 | inode->i_fop = &f2fs_file_operations; | |
366 | inode->i_mapping->a_ops = &f2fs_dblock_aops; | |
367 | ino = inode->i_ino; | |
368 | ||
e479556b | 369 | f2fs_lock_op(sbi); |
57397d86 JK |
370 | err = f2fs_add_link(dentry, inode); |
371 | if (err) | |
372 | goto out; | |
44c16156 | 373 | f2fs_unlock_op(sbi); |
57397d86 | 374 | |
4d57b86d | 375 | f2fs_alloc_nid_done(sbi, ino); |
57397d86 | 376 | |
1e2e547a | 377 | d_instantiate_new(dentry, inode); |
b7e1d800 JK |
378 | |
379 | if (IS_DIRSYNC(dir)) | |
380 | f2fs_sync_fs(sbi->sb, 1); | |
9bb02c36 JK |
381 | |
382 | f2fs_balance_fs(sbi, true); | |
57397d86 JK |
383 | return 0; |
384 | out: | |
4d57b86d | 385 | f2fs_handle_failed_inode(inode); |
57397d86 JK |
386 | return err; |
387 | } | |
388 | ||
389 | static int f2fs_link(struct dentry *old_dentry, struct inode *dir, | |
390 | struct dentry *dentry) | |
391 | { | |
2b0143b5 | 392 | struct inode *inode = d_inode(old_dentry); |
4081363f | 393 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); |
e479556b | 394 | int err; |
57397d86 | 395 | |
1f227a3e JK |
396 | if (unlikely(f2fs_cp_error(sbi))) |
397 | return -EIO; | |
00e09c0b CY |
398 | if (!f2fs_is_checkpoint_ready(sbi)) |
399 | return -ENOSPC; | |
1f227a3e | 400 | |
b05157e7 EB |
401 | err = fscrypt_prepare_link(old_dentry, dir, dentry); |
402 | if (err) | |
403 | return err; | |
fcc85a4d | 404 | |
5c57132e CY |
405 | if (is_inode_flag_set(dir, FI_PROJ_INHERIT) && |
406 | (!projid_eq(F2FS_I(dir)->i_projid, | |
407 | F2FS_I(old_dentry->d_inode)->i_projid))) | |
408 | return -EXDEV; | |
409 | ||
10a26878 | 410 | err = f2fs_dquot_initialize(dir); |
0abd675e CY |
411 | if (err) |
412 | return err; | |
413 | ||
2c4db1a6 | 414 | f2fs_balance_fs(sbi, true); |
1efef832 | 415 | |
078cd827 | 416 | inode->i_ctime = current_time(inode); |
6f6fd833 | 417 | ihold(inode); |
57397d86 | 418 | |
91942321 | 419 | set_inode_flag(inode, FI_INC_LINK); |
e479556b | 420 | f2fs_lock_op(sbi); |
57397d86 JK |
421 | err = f2fs_add_link(dentry, inode); |
422 | if (err) | |
423 | goto out; | |
44c16156 | 424 | f2fs_unlock_op(sbi); |
57397d86 JK |
425 | |
426 | d_instantiate(dentry, inode); | |
b7e1d800 JK |
427 | |
428 | if (IS_DIRSYNC(dir)) | |
429 | f2fs_sync_fs(sbi->sb, 1); | |
57397d86 JK |
430 | return 0; |
431 | out: | |
91942321 | 432 | clear_inode_flag(inode, FI_INC_LINK); |
57397d86 | 433 | iput(inode); |
44c16156 | 434 | f2fs_unlock_op(sbi); |
57397d86 JK |
435 | return err; |
436 | } | |
437 | ||
438 | struct dentry *f2fs_get_parent(struct dentry *child) | |
439 | { | |
91246c21 | 440 | struct page *page; |
80e5d1ff | 441 | unsigned long ino = f2fs_inode_by_name(d_inode(child), &dotdot_name, &page); |
5f029c04 | 442 | |
91246c21 CY |
443 | if (!ino) { |
444 | if (IS_ERR(page)) | |
445 | return ERR_CAST(page); | |
57397d86 | 446 | return ERR_PTR(-ENOENT); |
91246c21 | 447 | } |
fc64005c | 448 | return d_obtain_alias(f2fs_iget(child->d_sb, ino)); |
57397d86 JK |
449 | } |
450 | ||
510022a8 JK |
451 | static int __recover_dot_dentries(struct inode *dir, nid_t pino) |
452 | { | |
453 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); | |
454 | struct qstr dot = QSTR_INIT(".", 1); | |
455 | struct qstr dotdot = QSTR_INIT("..", 2); | |
456 | struct f2fs_dir_entry *de; | |
457 | struct page *page; | |
458 | int err = 0; | |
459 | ||
4e0d836d | 460 | if (f2fs_readonly(sbi->sb)) { |
dcbb4c10 JP |
461 | f2fs_info(sbi, "skip recovering inline_dots inode (ino:%lu, pino:%u) in readonly mountpoint", |
462 | dir->i_ino, pino); | |
4e0d836d CY |
463 | return 0; |
464 | } | |
465 | ||
12662d19 CY |
466 | if (!S_ISDIR(dir->i_mode)) { |
467 | f2fs_err(sbi, "inconsistent inode status, skip recovering inline_dots inode (ino:%lu, i_mode:%u, pino:%u)", | |
468 | dir->i_ino, dir->i_mode, pino); | |
469 | set_sbi_flag(sbi, SBI_NEED_FSCK); | |
470 | return -ENOTDIR; | |
471 | } | |
472 | ||
10a26878 | 473 | err = f2fs_dquot_initialize(dir); |
a6d3a479 CY |
474 | if (err) |
475 | return err; | |
476 | ||
2c4db1a6 | 477 | f2fs_balance_fs(sbi, true); |
d5384174 | 478 | |
510022a8 JK |
479 | f2fs_lock_op(sbi); |
480 | ||
481 | de = f2fs_find_entry(dir, &dot, &page); | |
482 | if (de) { | |
510022a8 | 483 | f2fs_put_page(page, 0); |
42d96401 JK |
484 | } else if (IS_ERR(page)) { |
485 | err = PTR_ERR(page); | |
486 | goto out; | |
510022a8 | 487 | } else { |
4d57b86d | 488 | err = f2fs_do_add_link(dir, &dot, NULL, dir->i_ino, S_IFDIR); |
510022a8 JK |
489 | if (err) |
490 | goto out; | |
491 | } | |
492 | ||
493 | de = f2fs_find_entry(dir, &dotdot, &page); | |
bdbc90fa | 494 | if (de) |
510022a8 | 495 | f2fs_put_page(page, 0); |
bdbc90fa | 496 | else if (IS_ERR(page)) |
42d96401 | 497 | err = PTR_ERR(page); |
bdbc90fa | 498 | else |
4d57b86d | 499 | err = f2fs_do_add_link(dir, &dotdot, NULL, pino, S_IFDIR); |
510022a8 | 500 | out: |
205b9822 | 501 | if (!err) |
91942321 | 502 | clear_inode_flag(dir, FI_INLINE_DOTS); |
510022a8 JK |
503 | |
504 | f2fs_unlock_op(sbi); | |
505 | return err; | |
506 | } | |
507 | ||
57397d86 JK |
508 | static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, |
509 | unsigned int flags) | |
510 | { | |
511 | struct inode *inode = NULL; | |
512 | struct f2fs_dir_entry *de; | |
513 | struct page *page; | |
0c5e36db CY |
514 | struct dentry *new; |
515 | nid_t ino = -1; | |
fcc85a4d | 516 | int err = 0; |
8c2b1435 | 517 | unsigned int root_ino = F2FS_ROOT_INO(F2FS_I_SB(dir)); |
43c780ba | 518 | struct f2fs_filename fname; |
57397d86 | 519 | |
0c5e36db CY |
520 | trace_f2fs_lookup_start(dir, dentry, flags); |
521 | ||
0c5e36db CY |
522 | if (dentry->d_name.len > F2FS_NAME_LEN) { |
523 | err = -ENAMETOOLONG; | |
524 | goto out; | |
525 | } | |
57397d86 | 526 | |
43c780ba | 527 | err = f2fs_prepare_lookup(dir, dentry, &fname); |
bb9cd910 | 528 | generic_set_encrypted_ci_d_ops(dentry); |
b01531db EB |
529 | if (err == -ENOENT) |
530 | goto out_splice; | |
531 | if (err) | |
532 | goto out; | |
533 | de = __f2fs_find_entry(dir, &fname, &page); | |
43c780ba | 534 | f2fs_free_filename(&fname); |
b01531db | 535 | |
eb4246dc | 536 | if (!de) { |
0c5e36db CY |
537 | if (IS_ERR(page)) { |
538 | err = PTR_ERR(page); | |
539 | goto out; | |
540 | } | |
84597b1f | 541 | err = -ENOENT; |
0c5e36db | 542 | goto out_splice; |
eb4246dc | 543 | } |
57397d86 | 544 | |
06957e8f | 545 | ino = le32_to_cpu(de->ino); |
06957e8f | 546 | f2fs_put_page(page, 0); |
510022a8 | 547 | |
06957e8f | 548 | inode = f2fs_iget(dir->i_sb, ino); |
0c5e36db CY |
549 | if (IS_ERR(inode)) { |
550 | err = PTR_ERR(inode); | |
551 | goto out; | |
552 | } | |
510022a8 | 553 | |
8c2b1435 LX |
554 | if ((dir->i_ino == root_ino) && f2fs_has_inline_dots(dir)) { |
555 | err = __recover_dot_dentries(dir, root_ino); | |
556 | if (err) | |
0c5e36db | 557 | goto out_iput; |
8c2b1435 LX |
558 | } |
559 | ||
fcc85a4d | 560 | if (f2fs_has_inline_dots(inode)) { |
06957e8f | 561 | err = __recover_dot_dentries(inode, dir->i_ino); |
fcc85a4d | 562 | if (err) |
0c5e36db | 563 | goto out_iput; |
57397d86 | 564 | } |
62230e0d | 565 | if (IS_ENCRYPTED(dir) && |
07fe8d44 DC |
566 | (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) && |
567 | !fscrypt_has_permitted_context(dir, inode)) { | |
dcbb4c10 JP |
568 | f2fs_warn(F2FS_I_SB(inode), "Inconsistent encryption contexts: %lu/%lu", |
569 | dir->i_ino, inode->i_ino); | |
faac7fd9 | 570 | err = -EPERM; |
0c5e36db | 571 | goto out_iput; |
8074bb51 | 572 | } |
0c5e36db | 573 | out_splice: |
5298d4bf | 574 | #if IS_ENABLED(CONFIG_UNICODE) |
2c2eb7a3 DR |
575 | if (!inode && IS_CASEFOLDED(dir)) { |
576 | /* Eventually we want to call d_add_ci(dentry, NULL) | |
577 | * for negative dentries in the encoding case as | |
578 | * well. For now, prevent the negative dentry | |
579 | * from being cached. | |
580 | */ | |
581 | trace_f2fs_lookup_end(dir, dentry, ino, err); | |
582 | return NULL; | |
583 | } | |
584 | #endif | |
0c5e36db | 585 | new = d_splice_alias(inode, dentry); |
b01531db | 586 | err = PTR_ERR_OR_ZERO(new); |
84597b1f | 587 | trace_f2fs_lookup_end(dir, dentry, ino, !new ? -ENOENT : err); |
0c5e36db CY |
588 | return new; |
589 | out_iput: | |
d726732c | 590 | iput(inode); |
0c5e36db CY |
591 | out: |
592 | trace_f2fs_lookup_end(dir, dentry, ino, err); | |
fcc85a4d | 593 | return ERR_PTR(err); |
57397d86 JK |
594 | } |
595 | ||
596 | static int f2fs_unlink(struct inode *dir, struct dentry *dentry) | |
597 | { | |
4081363f | 598 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); |
2b0143b5 | 599 | struct inode *inode = d_inode(dentry); |
57397d86 JK |
600 | struct f2fs_dir_entry *de; |
601 | struct page *page; | |
deaf160f | 602 | int err; |
57397d86 | 603 | |
a2a4a7e4 | 604 | trace_f2fs_unlink_enter(dir, dentry); |
1efef832 | 605 | |
9a99c17d LK |
606 | if (unlikely(f2fs_cp_error(sbi))) { |
607 | err = -EIO; | |
608 | goto fail; | |
609 | } | |
1f227a3e | 610 | |
10a26878 | 611 | err = f2fs_dquot_initialize(dir); |
d8d1389e | 612 | if (err) |
9a99c17d | 613 | goto fail; |
10a26878 | 614 | err = f2fs_dquot_initialize(inode); |
0abd675e | 615 | if (err) |
9a99c17d | 616 | goto fail; |
0abd675e | 617 | |
57397d86 | 618 | de = f2fs_find_entry(dir, &dentry->d_name, &page); |
91246c21 CY |
619 | if (!de) { |
620 | if (IS_ERR(page)) | |
621 | err = PTR_ERR(page); | |
57397d86 | 622 | goto fail; |
91246c21 | 623 | } |
57397d86 | 624 | |
2c4db1a6 | 625 | f2fs_balance_fs(sbi, true); |
00623e6b | 626 | |
ccaaca25 | 627 | f2fs_lock_op(sbi); |
4d57b86d | 628 | err = f2fs_acquire_orphan_inode(sbi); |
57397d86 | 629 | if (err) { |
ccaaca25 | 630 | f2fs_unlock_op(sbi); |
57397d86 JK |
631 | f2fs_put_page(page, 0); |
632 | goto fail; | |
633 | } | |
dbeacf02 | 634 | f2fs_delete_entry(de, page, dir, inode); |
5298d4bf | 635 | #if IS_ENABLED(CONFIG_UNICODE) |
2c2eb7a3 DR |
636 | /* VFS negative dentries are incompatible with Encoding and |
637 | * Case-insensitiveness. Eventually we'll want avoid | |
638 | * invalidating the dentries here, alongside with returning the | |
a87aff1d | 639 | * negative dentries at f2fs_lookup(), when it is better |
2c2eb7a3 DR |
640 | * supported by the VFS for the CI case. |
641 | */ | |
642 | if (IS_CASEFOLDED(dir)) | |
643 | d_invalidate(dentry); | |
644 | #endif | |
e479556b | 645 | f2fs_unlock_op(sbi); |
57397d86 | 646 | |
b7e1d800 JK |
647 | if (IS_DIRSYNC(dir)) |
648 | f2fs_sync_fs(sbi->sb, 1); | |
57397d86 | 649 | fail: |
a2a4a7e4 | 650 | trace_f2fs_unlink_exit(inode, err); |
57397d86 JK |
651 | return err; |
652 | } | |
653 | ||
6b255391 | 654 | static const char *f2fs_get_link(struct dentry *dentry, |
fceef393 AV |
655 | struct inode *inode, |
656 | struct delayed_call *done) | |
feb7cbb0 | 657 | { |
fceef393 | 658 | const char *link = page_get_link(dentry, inode, done); |
5f029c04 | 659 | |
680baacb AV |
660 | if (!IS_ERR(link) && !*link) { |
661 | /* this is broken symlink case */ | |
fceef393 AV |
662 | do_delayed_call(done); |
663 | clear_delayed_call(done); | |
680baacb | 664 | link = ERR_PTR(-ENOENT); |
feb7cbb0 | 665 | } |
680baacb | 666 | return link; |
feb7cbb0 JK |
667 | } |
668 | ||
549c7297 CB |
669 | static int f2fs_symlink(struct user_namespace *mnt_userns, struct inode *dir, |
670 | struct dentry *dentry, const char *symname) | |
57397d86 | 671 | { |
4081363f | 672 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); |
57397d86 | 673 | struct inode *inode; |
cbaf042a | 674 | size_t len = strlen(symname); |
393c038f | 675 | struct fscrypt_str disk_link; |
e479556b | 676 | int err; |
57397d86 | 677 | |
1f227a3e JK |
678 | if (unlikely(f2fs_cp_error(sbi))) |
679 | return -EIO; | |
00e09c0b CY |
680 | if (!f2fs_is_checkpoint_ready(sbi)) |
681 | return -ENOSPC; | |
1f227a3e | 682 | |
393c038f EB |
683 | err = fscrypt_prepare_symlink(dir, symname, len, dir->i_sb->s_blocksize, |
684 | &disk_link); | |
685 | if (err) | |
686 | return err; | |
cbaf042a | 687 | |
10a26878 | 688 | err = f2fs_dquot_initialize(dir); |
0abd675e CY |
689 | if (err) |
690 | return err; | |
691 | ||
984fc4e7 | 692 | inode = f2fs_new_inode(mnt_userns, dir, S_IFLNK | S_IRWXUGO); |
57397d86 JK |
693 | if (IS_ERR(inode)) |
694 | return PTR_ERR(inode); | |
695 | ||
393c038f | 696 | if (IS_ENCRYPTED(inode)) |
cbaf042a JK |
697 | inode->i_op = &f2fs_encrypted_symlink_inode_operations; |
698 | else | |
699 | inode->i_op = &f2fs_symlink_inode_operations; | |
21fc61c7 | 700 | inode_nohighmem(inode); |
57397d86 JK |
701 | inode->i_mapping->a_ops = &f2fs_dblock_aops; |
702 | ||
e479556b | 703 | f2fs_lock_op(sbi); |
57397d86 JK |
704 | err = f2fs_add_link(dentry, inode); |
705 | if (err) | |
4d57b86d | 706 | goto out_f2fs_handle_failed_inode; |
44c16156 | 707 | f2fs_unlock_op(sbi); |
4d57b86d | 708 | f2fs_alloc_nid_done(sbi, inode->i_ino); |
57397d86 | 709 | |
393c038f EB |
710 | err = fscrypt_encrypt_symlink(inode, symname, len, &disk_link); |
711 | if (err) | |
712 | goto err_out; | |
cbaf042a | 713 | |
922ec355 | 714 | err = page_symlink(inode, disk_link.name, disk_link.len); |
cbaf042a JK |
715 | |
716 | err_out: | |
1e2e547a | 717 | d_instantiate_new(dentry, inode); |
b7e1d800 | 718 | |
d0cae97c JK |
719 | /* |
720 | * Let's flush symlink data in order to avoid broken symlink as much as | |
721 | * possible. Nevertheless, fsyncing is the best way, but there is no | |
722 | * way to get a file descriptor in order to flush that. | |
723 | * | |
724 | * Note that, it needs to do dir->fsync to make this recoverable. | |
725 | * If the symlink path is stored into inline_data, there is no | |
726 | * performance regression. | |
727 | */ | |
a6be014e | 728 | if (!err) { |
922ec355 CY |
729 | filemap_write_and_wait_range(inode->i_mapping, 0, |
730 | disk_link.len - 1); | |
d0cae97c | 731 | |
a6be014e CY |
732 | if (IS_DIRSYNC(dir)) |
733 | f2fs_sync_fs(sbi->sb, 1); | |
734 | } else { | |
735 | f2fs_unlink(dir, dentry); | |
736 | } | |
cbaf042a | 737 | |
9bb02c36 | 738 | f2fs_balance_fs(sbi, true); |
393c038f EB |
739 | goto out_free_encrypted_link; |
740 | ||
4d57b86d CY |
741 | out_f2fs_handle_failed_inode: |
742 | f2fs_handle_failed_inode(inode); | |
393c038f EB |
743 | out_free_encrypted_link: |
744 | if (disk_link.name != (unsigned char *)symname) | |
c8eb7024 | 745 | kfree(disk_link.name); |
57397d86 JK |
746 | return err; |
747 | } | |
748 | ||
549c7297 CB |
749 | static int f2fs_mkdir(struct user_namespace *mnt_userns, struct inode *dir, |
750 | struct dentry *dentry, umode_t mode) | |
57397d86 | 751 | { |
4081363f | 752 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); |
57397d86 | 753 | struct inode *inode; |
e479556b | 754 | int err; |
57397d86 | 755 | |
1f227a3e JK |
756 | if (unlikely(f2fs_cp_error(sbi))) |
757 | return -EIO; | |
758 | ||
10a26878 | 759 | err = f2fs_dquot_initialize(dir); |
0abd675e CY |
760 | if (err) |
761 | return err; | |
762 | ||
984fc4e7 | 763 | inode = f2fs_new_inode(mnt_userns, dir, S_IFDIR | mode); |
57397d86 | 764 | if (IS_ERR(inode)) |
61412b64 | 765 | return PTR_ERR(inode); |
57397d86 JK |
766 | |
767 | inode->i_op = &f2fs_dir_inode_operations; | |
768 | inode->i_fop = &f2fs_dir_operations; | |
769 | inode->i_mapping->a_ops = &f2fs_dblock_aops; | |
92d602bc | 770 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); |
57397d86 | 771 | |
91942321 | 772 | set_inode_flag(inode, FI_INC_LINK); |
e479556b | 773 | f2fs_lock_op(sbi); |
57397d86 JK |
774 | err = f2fs_add_link(dentry, inode); |
775 | if (err) | |
776 | goto out_fail; | |
44c16156 | 777 | f2fs_unlock_op(sbi); |
57397d86 | 778 | |
4d57b86d | 779 | f2fs_alloc_nid_done(sbi, inode->i_ino); |
57397d86 | 780 | |
1e2e547a | 781 | d_instantiate_new(dentry, inode); |
57397d86 | 782 | |
b7e1d800 JK |
783 | if (IS_DIRSYNC(dir)) |
784 | f2fs_sync_fs(sbi->sb, 1); | |
9bb02c36 JK |
785 | |
786 | f2fs_balance_fs(sbi, true); | |
57397d86 JK |
787 | return 0; |
788 | ||
789 | out_fail: | |
91942321 | 790 | clear_inode_flag(inode, FI_INC_LINK); |
4d57b86d | 791 | f2fs_handle_failed_inode(inode); |
57397d86 JK |
792 | return err; |
793 | } | |
794 | ||
795 | static int f2fs_rmdir(struct inode *dir, struct dentry *dentry) | |
796 | { | |
2b0143b5 | 797 | struct inode *inode = d_inode(dentry); |
5f029c04 | 798 | |
57397d86 JK |
799 | if (f2fs_empty_dir(inode)) |
800 | return f2fs_unlink(dir, dentry); | |
801 | return -ENOTEMPTY; | |
802 | } | |
803 | ||
549c7297 CB |
804 | static int f2fs_mknod(struct user_namespace *mnt_userns, struct inode *dir, |
805 | struct dentry *dentry, umode_t mode, dev_t rdev) | |
57397d86 | 806 | { |
4081363f | 807 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); |
57397d86 JK |
808 | struct inode *inode; |
809 | int err = 0; | |
810 | ||
1f227a3e JK |
811 | if (unlikely(f2fs_cp_error(sbi))) |
812 | return -EIO; | |
00e09c0b CY |
813 | if (!f2fs_is_checkpoint_ready(sbi)) |
814 | return -ENOSPC; | |
1f227a3e | 815 | |
10a26878 | 816 | err = f2fs_dquot_initialize(dir); |
0abd675e CY |
817 | if (err) |
818 | return err; | |
819 | ||
984fc4e7 | 820 | inode = f2fs_new_inode(mnt_userns, dir, mode); |
57397d86 JK |
821 | if (IS_ERR(inode)) |
822 | return PTR_ERR(inode); | |
823 | ||
824 | init_special_inode(inode, inode->i_mode, rdev); | |
825 | inode->i_op = &f2fs_special_inode_operations; | |
826 | ||
e479556b | 827 | f2fs_lock_op(sbi); |
57397d86 JK |
828 | err = f2fs_add_link(dentry, inode); |
829 | if (err) | |
830 | goto out; | |
44c16156 | 831 | f2fs_unlock_op(sbi); |
57397d86 | 832 | |
4d57b86d | 833 | f2fs_alloc_nid_done(sbi, inode->i_ino); |
b7e1d800 | 834 | |
1e2e547a | 835 | d_instantiate_new(dentry, inode); |
b7e1d800 JK |
836 | |
837 | if (IS_DIRSYNC(dir)) | |
838 | f2fs_sync_fs(sbi->sb, 1); | |
9bb02c36 JK |
839 | |
840 | f2fs_balance_fs(sbi, true); | |
57397d86 JK |
841 | return 0; |
842 | out: | |
4d57b86d | 843 | f2fs_handle_failed_inode(inode); |
57397d86 JK |
844 | return err; |
845 | } | |
846 | ||
984fc4e7 | 847 | static int __f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, |
863f144f | 848 | struct file *file, umode_t mode, bool is_whiteout, |
3db1de0e | 849 | struct inode **new_inode) |
7e01e7ad CY |
850 | { |
851 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); | |
852 | struct inode *inode; | |
853 | int err; | |
854 | ||
10a26878 | 855 | err = f2fs_dquot_initialize(dir); |
0abd675e CY |
856 | if (err) |
857 | return err; | |
858 | ||
984fc4e7 | 859 | inode = f2fs_new_inode(mnt_userns, dir, mode); |
7e01e7ad CY |
860 | if (IS_ERR(inode)) |
861 | return PTR_ERR(inode); | |
862 | ||
3db1de0e | 863 | if (is_whiteout) { |
7e01e7ad CY |
864 | init_special_inode(inode, inode->i_mode, WHITEOUT_DEV); |
865 | inode->i_op = &f2fs_special_inode_operations; | |
866 | } else { | |
867 | inode->i_op = &f2fs_file_inode_operations; | |
868 | inode->i_fop = &f2fs_file_operations; | |
869 | inode->i_mapping->a_ops = &f2fs_dblock_aops; | |
870 | } | |
871 | ||
872 | f2fs_lock_op(sbi); | |
4d57b86d | 873 | err = f2fs_acquire_orphan_inode(sbi); |
7e01e7ad CY |
874 | if (err) |
875 | goto out; | |
876 | ||
877 | err = f2fs_do_tmpfile(inode, dir); | |
878 | if (err) | |
879 | goto release_out; | |
880 | ||
881 | /* | |
882 | * add this non-linked tmpfile to orphan list, in this way we could | |
883 | * remove all unused data of tmpfile after abnormal power-off. | |
884 | */ | |
4d57b86d CY |
885 | f2fs_add_orphan_inode(inode); |
886 | f2fs_alloc_nid_done(sbi, inode->i_ino); | |
7e01e7ad | 887 | |
3db1de0e | 888 | if (is_whiteout) { |
a1961246 | 889 | f2fs_i_links_write(inode, false); |
46085f37 CY |
890 | |
891 | spin_lock(&inode->i_lock); | |
5b1dbb08 | 892 | inode->i_state |= I_LINKABLE; |
46085f37 | 893 | spin_unlock(&inode->i_lock); |
7e01e7ad | 894 | } else { |
863f144f MS |
895 | if (file) |
896 | d_tmpfile(file, inode); | |
3db1de0e DJ |
897 | else |
898 | f2fs_i_links_write(inode, false); | |
7e01e7ad | 899 | } |
a1961246 JK |
900 | /* link_count was changed by d_tmpfile as well. */ |
901 | f2fs_unlock_op(sbi); | |
7e01e7ad | 902 | unlock_new_inode(inode); |
9bb02c36 | 903 | |
3db1de0e DJ |
904 | if (new_inode) |
905 | *new_inode = inode; | |
906 | ||
9bb02c36 | 907 | f2fs_balance_fs(sbi, true); |
7e01e7ad CY |
908 | return 0; |
909 | ||
910 | release_out: | |
4d57b86d | 911 | f2fs_release_orphan_inode(sbi); |
7e01e7ad | 912 | out: |
4d57b86d | 913 | f2fs_handle_failed_inode(inode); |
7e01e7ad CY |
914 | return err; |
915 | } | |
916 | ||
549c7297 | 917 | static int f2fs_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, |
863f144f | 918 | struct file *file, umode_t mode) |
7e01e7ad | 919 | { |
ff62af20 | 920 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); |
863f144f | 921 | int err; |
ff62af20 SY |
922 | |
923 | if (unlikely(f2fs_cp_error(sbi))) | |
1f227a3e | 924 | return -EIO; |
00e09c0b CY |
925 | if (!f2fs_is_checkpoint_ready(sbi)) |
926 | return -ENOSPC; | |
1f227a3e | 927 | |
863f144f MS |
928 | err = __f2fs_tmpfile(mnt_userns, dir, file, mode, false, NULL); |
929 | ||
930 | return finish_open_simple(file, err); | |
7e01e7ad CY |
931 | } |
932 | ||
984fc4e7 CY |
933 | static int f2fs_create_whiteout(struct user_namespace *mnt_userns, |
934 | struct inode *dir, struct inode **whiteout) | |
7e01e7ad | 935 | { |
1f227a3e JK |
936 | if (unlikely(f2fs_cp_error(F2FS_I_SB(dir)))) |
937 | return -EIO; | |
938 | ||
984fc4e7 | 939 | return __f2fs_tmpfile(mnt_userns, dir, NULL, |
3db1de0e DJ |
940 | S_IFCHR | WHITEOUT_MODE, true, whiteout); |
941 | } | |
942 | ||
943 | int f2fs_get_tmpfile(struct user_namespace *mnt_userns, struct inode *dir, | |
944 | struct inode **new_inode) | |
945 | { | |
946 | return __f2fs_tmpfile(mnt_userns, dir, NULL, S_IFREG, false, new_inode); | |
7e01e7ad CY |
947 | } |
948 | ||
984fc4e7 CY |
949 | static int f2fs_rename(struct user_namespace *mnt_userns, struct inode *old_dir, |
950 | struct dentry *old_dentry, struct inode *new_dir, | |
951 | struct dentry *new_dentry, unsigned int flags) | |
57397d86 | 952 | { |
4081363f | 953 | struct f2fs_sb_info *sbi = F2FS_I_SB(old_dir); |
2b0143b5 DH |
954 | struct inode *old_inode = d_inode(old_dentry); |
955 | struct inode *new_inode = d_inode(new_dentry); | |
7e01e7ad | 956 | struct inode *whiteout = NULL; |
762e4db5 | 957 | struct page *old_dir_page = NULL; |
7e01e7ad | 958 | struct page *old_page, *new_page = NULL; |
57397d86 JK |
959 | struct f2fs_dir_entry *old_dir_entry = NULL; |
960 | struct f2fs_dir_entry *old_entry; | |
961 | struct f2fs_dir_entry *new_entry; | |
d83d0f5b | 962 | int err; |
57397d86 | 963 | |
1f227a3e JK |
964 | if (unlikely(f2fs_cp_error(sbi))) |
965 | return -EIO; | |
00e09c0b CY |
966 | if (!f2fs_is_checkpoint_ready(sbi)) |
967 | return -ENOSPC; | |
1f227a3e | 968 | |
5c57132e CY |
969 | if (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && |
970 | (!projid_eq(F2FS_I(new_dir)->i_projid, | |
971 | F2FS_I(old_dentry->d_inode)->i_projid))) | |
972 | return -EXDEV; | |
973 | ||
b06af2af JK |
974 | /* |
975 | * If new_inode is null, the below renaming flow will | |
976 | * add a link in old_dir which can conver inline_dir. | |
977 | * After then, if we failed to get the entry due to other | |
978 | * reasons like ENOMEM, we had to remove the new entry. | |
979 | * Instead of adding such the error handling routine, let's | |
980 | * simply convert first here. | |
981 | */ | |
982 | if (old_dir == new_dir && !new_inode) { | |
983 | err = f2fs_try_convert_inline_dir(old_dir, new_dentry); | |
984 | if (err) | |
985 | return err; | |
986 | } | |
987 | ||
5b1dbb08 | 988 | if (flags & RENAME_WHITEOUT) { |
984fc4e7 | 989 | err = f2fs_create_whiteout(mnt_userns, old_dir, &whiteout); |
5b1dbb08 JK |
990 | if (err) |
991 | return err; | |
992 | } | |
993 | ||
10a26878 | 994 | err = f2fs_dquot_initialize(old_dir); |
0abd675e CY |
995 | if (err) |
996 | goto out; | |
997 | ||
10a26878 | 998 | err = f2fs_dquot_initialize(new_dir); |
0abd675e CY |
999 | if (err) |
1000 | goto out; | |
1001 | ||
d8d1389e | 1002 | if (new_inode) { |
10a26878 | 1003 | err = f2fs_dquot_initialize(new_inode); |
d8d1389e JK |
1004 | if (err) |
1005 | goto out; | |
1006 | } | |
1007 | ||
d83d0f5b | 1008 | err = -ENOENT; |
57397d86 | 1009 | old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
91246c21 CY |
1010 | if (!old_entry) { |
1011 | if (IS_ERR(old_page)) | |
1012 | err = PTR_ERR(old_page); | |
57397d86 | 1013 | goto out; |
91246c21 | 1014 | } |
57397d86 JK |
1015 | |
1016 | if (S_ISDIR(old_inode->i_mode)) { | |
57397d86 | 1017 | old_dir_entry = f2fs_parent_dir(old_inode, &old_dir_page); |
3e19886e | 1018 | if (!old_dir_entry) { |
91246c21 CY |
1019 | if (IS_ERR(old_dir_page)) |
1020 | err = PTR_ERR(old_dir_page); | |
57397d86 | 1021 | goto out_old; |
3e19886e | 1022 | } |
57397d86 JK |
1023 | } |
1024 | ||
57397d86 | 1025 | if (new_inode) { |
57397d86 JK |
1026 | |
1027 | err = -ENOTEMPTY; | |
1028 | if (old_dir_entry && !f2fs_empty_dir(new_inode)) | |
5b1dbb08 | 1029 | goto out_dir; |
57397d86 JK |
1030 | |
1031 | err = -ENOENT; | |
1032 | new_entry = f2fs_find_entry(new_dir, &new_dentry->d_name, | |
1033 | &new_page); | |
91246c21 CY |
1034 | if (!new_entry) { |
1035 | if (IS_ERR(new_page)) | |
1036 | err = PTR_ERR(new_page); | |
5b1dbb08 | 1037 | goto out_dir; |
91246c21 | 1038 | } |
57397d86 | 1039 | |
2c4db1a6 | 1040 | f2fs_balance_fs(sbi, true); |
00623e6b | 1041 | |
1256010a CY |
1042 | f2fs_lock_op(sbi); |
1043 | ||
4d57b86d | 1044 | err = f2fs_acquire_orphan_inode(sbi); |
cbd56e7d JK |
1045 | if (err) |
1046 | goto put_out_dir; | |
1047 | ||
57397d86 | 1048 | f2fs_set_link(new_dir, new_entry, new_page, old_inode); |
762e4db5 | 1049 | new_page = NULL; |
57397d86 | 1050 | |
078cd827 | 1051 | new_inode->i_ctime = current_time(new_inode); |
e4544b63 | 1052 | f2fs_down_write(&F2FS_I(new_inode)->i_sem); |
57397d86 | 1053 | if (old_dir_entry) |
a1961246 JK |
1054 | f2fs_i_links_write(new_inode, false); |
1055 | f2fs_i_links_write(new_inode, false); | |
e4544b63 | 1056 | f2fs_up_write(&F2FS_I(new_inode)->i_sem); |
d928bfbf | 1057 | |
57397d86 | 1058 | if (!new_inode->i_nlink) |
4d57b86d | 1059 | f2fs_add_orphan_inode(new_inode); |
cbd56e7d | 1060 | else |
4d57b86d | 1061 | f2fs_release_orphan_inode(sbi); |
57397d86 | 1062 | } else { |
2c4db1a6 | 1063 | f2fs_balance_fs(sbi, true); |
00623e6b | 1064 | |
1256010a CY |
1065 | f2fs_lock_op(sbi); |
1066 | ||
57397d86 | 1067 | err = f2fs_add_link(new_dentry, old_inode); |
1256010a CY |
1068 | if (err) { |
1069 | f2fs_unlock_op(sbi); | |
5b1dbb08 | 1070 | goto out_dir; |
1256010a | 1071 | } |
57397d86 | 1072 | |
ee6d182f | 1073 | if (old_dir_entry) |
a1961246 | 1074 | f2fs_i_links_write(new_dir, true); |
57397d86 JK |
1075 | } |
1076 | ||
e4544b63 | 1077 | f2fs_down_write(&F2FS_I(old_inode)->i_sem); |
b855bf0e SY |
1078 | if (!old_dir_entry || whiteout) |
1079 | file_lost_pino(old_inode); | |
1080 | else | |
2a60637f CY |
1081 | /* adjust dir's i_pino to pass fsck check */ |
1082 | f2fs_i_pino_write(old_inode, new_dir->i_ino); | |
e4544b63 | 1083 | f2fs_up_write(&F2FS_I(old_inode)->i_sem); |
b2c08299 | 1084 | |
078cd827 | 1085 | old_inode->i_ctime = current_time(old_inode); |
7c45729a | 1086 | f2fs_mark_inode_dirty_sync(old_inode, false); |
57397d86 | 1087 | |
dbeacf02 | 1088 | f2fs_delete_entry(old_entry, old_page, old_dir, NULL); |
762e4db5 | 1089 | old_page = NULL; |
57397d86 | 1090 | |
7e01e7ad | 1091 | if (whiteout) { |
91942321 | 1092 | set_inode_flag(whiteout, FI_INC_LINK); |
7e01e7ad CY |
1093 | err = f2fs_add_link(old_dentry, whiteout); |
1094 | if (err) | |
1095 | goto put_out_dir; | |
46085f37 CY |
1096 | |
1097 | spin_lock(&whiteout->i_lock); | |
7e01e7ad | 1098 | whiteout->i_state &= ~I_LINKABLE; |
46085f37 CY |
1099 | spin_unlock(&whiteout->i_lock); |
1100 | ||
7e01e7ad CY |
1101 | iput(whiteout); |
1102 | } | |
1103 | ||
57397d86 | 1104 | if (old_dir_entry) { |
bdbc90fa | 1105 | if (old_dir != new_dir && !whiteout) |
57397d86 JK |
1106 | f2fs_set_link(old_inode, old_dir_entry, |
1107 | old_dir_page, new_dir); | |
bdbc90fa | 1108 | else |
57397d86 | 1109 | f2fs_put_page(old_dir_page, 0); |
a1961246 | 1110 | f2fs_i_links_write(old_dir, false); |
57397d86 | 1111 | } |
ade990f9 | 1112 | if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) { |
4d57b86d | 1113 | f2fs_add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO); |
ade990f9 | 1114 | if (S_ISDIR(old_inode->i_mode)) |
4d57b86d CY |
1115 | f2fs_add_ino_entry(sbi, old_inode->i_ino, |
1116 | TRANS_DIR_INO); | |
ade990f9 | 1117 | } |
57397d86 | 1118 | |
e479556b | 1119 | f2fs_unlock_op(sbi); |
b7e1d800 JK |
1120 | |
1121 | if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) | |
1122 | f2fs_sync_fs(sbi->sb, 1); | |
6390398e ST |
1123 | |
1124 | f2fs_update_time(sbi, REQ_TIME); | |
57397d86 JK |
1125 | return 0; |
1126 | ||
cbd56e7d | 1127 | put_out_dir: |
1256010a | 1128 | f2fs_unlock_op(sbi); |
762e4db5 | 1129 | f2fs_put_page(new_page, 0); |
57397d86 | 1130 | out_dir: |
bdbc90fa | 1131 | if (old_dir_entry) |
57397d86 | 1132 | f2fs_put_page(old_dir_page, 0); |
57397d86 | 1133 | out_old: |
57397d86 JK |
1134 | f2fs_put_page(old_page, 0); |
1135 | out: | |
646f64b5 | 1136 | iput(whiteout); |
57397d86 JK |
1137 | return err; |
1138 | } | |
1139 | ||
32f9bc25 CY |
1140 | static int f2fs_cross_rename(struct inode *old_dir, struct dentry *old_dentry, |
1141 | struct inode *new_dir, struct dentry *new_dentry) | |
1142 | { | |
4081363f | 1143 | struct f2fs_sb_info *sbi = F2FS_I_SB(old_dir); |
2b0143b5 DH |
1144 | struct inode *old_inode = d_inode(old_dentry); |
1145 | struct inode *new_inode = d_inode(new_dentry); | |
32f9bc25 CY |
1146 | struct page *old_dir_page, *new_dir_page; |
1147 | struct page *old_page, *new_page; | |
1148 | struct f2fs_dir_entry *old_dir_entry = NULL, *new_dir_entry = NULL; | |
1149 | struct f2fs_dir_entry *old_entry, *new_entry; | |
1150 | int old_nlink = 0, new_nlink = 0; | |
d83d0f5b | 1151 | int err; |
363fa4e0 | 1152 | |
1f227a3e JK |
1153 | if (unlikely(f2fs_cp_error(sbi))) |
1154 | return -EIO; | |
00e09c0b CY |
1155 | if (!f2fs_is_checkpoint_ready(sbi)) |
1156 | return -ENOSPC; | |
1f227a3e | 1157 | |
5c57132e CY |
1158 | if ((is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && |
1159 | !projid_eq(F2FS_I(new_dir)->i_projid, | |
1160 | F2FS_I(old_dentry->d_inode)->i_projid)) || | |
1161 | (is_inode_flag_set(new_dir, FI_PROJ_INHERIT) && | |
1162 | !projid_eq(F2FS_I(old_dir)->i_projid, | |
1163 | F2FS_I(new_dentry->d_inode)->i_projid))) | |
1164 | return -EXDEV; | |
1165 | ||
10a26878 | 1166 | err = f2fs_dquot_initialize(old_dir); |
0abd675e CY |
1167 | if (err) |
1168 | goto out; | |
1169 | ||
10a26878 | 1170 | err = f2fs_dquot_initialize(new_dir); |
0abd675e CY |
1171 | if (err) |
1172 | goto out; | |
1173 | ||
d83d0f5b | 1174 | err = -ENOENT; |
32f9bc25 | 1175 | old_entry = f2fs_find_entry(old_dir, &old_dentry->d_name, &old_page); |
91246c21 CY |
1176 | if (!old_entry) { |
1177 | if (IS_ERR(old_page)) | |
1178 | err = PTR_ERR(old_page); | |
32f9bc25 | 1179 | goto out; |
91246c21 | 1180 | } |
32f9bc25 CY |
1181 | |
1182 | new_entry = f2fs_find_entry(new_dir, &new_dentry->d_name, &new_page); | |
91246c21 CY |
1183 | if (!new_entry) { |
1184 | if (IS_ERR(new_page)) | |
1185 | err = PTR_ERR(new_page); | |
32f9bc25 | 1186 | goto out_old; |
91246c21 | 1187 | } |
32f9bc25 CY |
1188 | |
1189 | /* prepare for updating ".." directory entry info later */ | |
1190 | if (old_dir != new_dir) { | |
1191 | if (S_ISDIR(old_inode->i_mode)) { | |
32f9bc25 CY |
1192 | old_dir_entry = f2fs_parent_dir(old_inode, |
1193 | &old_dir_page); | |
3e19886e | 1194 | if (!old_dir_entry) { |
91246c21 CY |
1195 | if (IS_ERR(old_dir_page)) |
1196 | err = PTR_ERR(old_dir_page); | |
32f9bc25 | 1197 | goto out_new; |
3e19886e | 1198 | } |
32f9bc25 CY |
1199 | } |
1200 | ||
1201 | if (S_ISDIR(new_inode->i_mode)) { | |
32f9bc25 CY |
1202 | new_dir_entry = f2fs_parent_dir(new_inode, |
1203 | &new_dir_page); | |
3e19886e | 1204 | if (!new_dir_entry) { |
91246c21 CY |
1205 | if (IS_ERR(new_dir_page)) |
1206 | err = PTR_ERR(new_dir_page); | |
32f9bc25 | 1207 | goto out_old_dir; |
3e19886e | 1208 | } |
32f9bc25 CY |
1209 | } |
1210 | } | |
1211 | ||
1212 | /* | |
1213 | * If cross rename between file and directory those are not | |
1214 | * in the same directory, we will inc nlink of file's parent | |
1215 | * later, so we should check upper boundary of its nlink. | |
1216 | */ | |
1217 | if ((!old_dir_entry || !new_dir_entry) && | |
1218 | old_dir_entry != new_dir_entry) { | |
1219 | old_nlink = old_dir_entry ? -1 : 1; | |
1220 | new_nlink = -old_nlink; | |
1221 | err = -EMLINK; | |
e2f0e962 KM |
1222 | if ((old_nlink > 0 && old_dir->i_nlink >= F2FS_LINK_MAX) || |
1223 | (new_nlink > 0 && new_dir->i_nlink >= F2FS_LINK_MAX)) | |
32f9bc25 CY |
1224 | goto out_new_dir; |
1225 | } | |
1226 | ||
2c4db1a6 | 1227 | f2fs_balance_fs(sbi, true); |
00623e6b | 1228 | |
32f9bc25 CY |
1229 | f2fs_lock_op(sbi); |
1230 | ||
32f9bc25 CY |
1231 | /* update ".." directory entry info of old dentry */ |
1232 | if (old_dir_entry) | |
1233 | f2fs_set_link(old_inode, old_dir_entry, old_dir_page, new_dir); | |
1234 | ||
1235 | /* update ".." directory entry info of new dentry */ | |
1236 | if (new_dir_entry) | |
1237 | f2fs_set_link(new_inode, new_dir_entry, new_dir_page, old_dir); | |
1238 | ||
1239 | /* update directory entry info of old dir inode */ | |
1240 | f2fs_set_link(old_dir, old_entry, old_page, new_inode); | |
1241 | ||
e4544b63 | 1242 | f2fs_down_write(&F2FS_I(old_inode)->i_sem); |
2a60637f CY |
1243 | if (!old_dir_entry) |
1244 | file_lost_pino(old_inode); | |
1245 | else | |
1246 | /* adjust dir's i_pino to pass fsck check */ | |
1247 | f2fs_i_pino_write(old_inode, new_dir->i_ino); | |
e4544b63 | 1248 | f2fs_up_write(&F2FS_I(old_inode)->i_sem); |
32f9bc25 | 1249 | |
078cd827 | 1250 | old_dir->i_ctime = current_time(old_dir); |
32f9bc25 | 1251 | if (old_nlink) { |
e4544b63 | 1252 | f2fs_down_write(&F2FS_I(old_dir)->i_sem); |
a1961246 | 1253 | f2fs_i_links_write(old_dir, old_nlink > 0); |
e4544b63 | 1254 | f2fs_up_write(&F2FS_I(old_dir)->i_sem); |
32f9bc25 | 1255 | } |
7c45729a | 1256 | f2fs_mark_inode_dirty_sync(old_dir, false); |
32f9bc25 CY |
1257 | |
1258 | /* update directory entry info of new dir inode */ | |
1259 | f2fs_set_link(new_dir, new_entry, new_page, old_inode); | |
1260 | ||
e4544b63 | 1261 | f2fs_down_write(&F2FS_I(new_inode)->i_sem); |
2a60637f CY |
1262 | if (!new_dir_entry) |
1263 | file_lost_pino(new_inode); | |
1264 | else | |
1265 | /* adjust dir's i_pino to pass fsck check */ | |
1266 | f2fs_i_pino_write(new_inode, old_dir->i_ino); | |
e4544b63 | 1267 | f2fs_up_write(&F2FS_I(new_inode)->i_sem); |
32f9bc25 | 1268 | |
078cd827 | 1269 | new_dir->i_ctime = current_time(new_dir); |
32f9bc25 | 1270 | if (new_nlink) { |
e4544b63 | 1271 | f2fs_down_write(&F2FS_I(new_dir)->i_sem); |
a1961246 | 1272 | f2fs_i_links_write(new_dir, new_nlink > 0); |
e4544b63 | 1273 | f2fs_up_write(&F2FS_I(new_dir)->i_sem); |
32f9bc25 | 1274 | } |
7c45729a | 1275 | f2fs_mark_inode_dirty_sync(new_dir, false); |
32f9bc25 | 1276 | |
63189b78 | 1277 | if (F2FS_OPTION(sbi).fsync_mode == FSYNC_MODE_STRICT) { |
4d57b86d CY |
1278 | f2fs_add_ino_entry(sbi, old_dir->i_ino, TRANS_DIR_INO); |
1279 | f2fs_add_ino_entry(sbi, new_dir->i_ino, TRANS_DIR_INO); | |
93cf93f1 | 1280 | } |
0a007b97 | 1281 | |
32f9bc25 | 1282 | f2fs_unlock_op(sbi); |
b7e1d800 JK |
1283 | |
1284 | if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir)) | |
1285 | f2fs_sync_fs(sbi->sb, 1); | |
6390398e ST |
1286 | |
1287 | f2fs_update_time(sbi, REQ_TIME); | |
32f9bc25 | 1288 | return 0; |
32f9bc25 CY |
1289 | out_new_dir: |
1290 | if (new_dir_entry) { | |
32f9bc25 CY |
1291 | f2fs_put_page(new_dir_page, 0); |
1292 | } | |
1293 | out_old_dir: | |
1294 | if (old_dir_entry) { | |
32f9bc25 CY |
1295 | f2fs_put_page(old_dir_page, 0); |
1296 | } | |
1297 | out_new: | |
32f9bc25 CY |
1298 | f2fs_put_page(new_page, 0); |
1299 | out_old: | |
32f9bc25 CY |
1300 | f2fs_put_page(old_page, 0); |
1301 | out: | |
1302 | return err; | |
1303 | } | |
1304 | ||
549c7297 CB |
1305 | static int f2fs_rename2(struct user_namespace *mnt_userns, |
1306 | struct inode *old_dir, struct dentry *old_dentry, | |
32f9bc25 CY |
1307 | struct inode *new_dir, struct dentry *new_dentry, |
1308 | unsigned int flags) | |
1309 | { | |
2e45b07f EB |
1310 | int err; |
1311 | ||
7e01e7ad | 1312 | if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT)) |
32f9bc25 CY |
1313 | return -EINVAL; |
1314 | ||
2e45b07f EB |
1315 | err = fscrypt_prepare_rename(old_dir, old_dentry, new_dir, new_dentry, |
1316 | flags); | |
1317 | if (err) | |
1318 | return err; | |
1319 | ||
32f9bc25 CY |
1320 | if (flags & RENAME_EXCHANGE) { |
1321 | return f2fs_cross_rename(old_dir, old_dentry, | |
1322 | new_dir, new_dentry); | |
1323 | } | |
1324 | /* | |
1325 | * VFS has already handled the new dentry existence case, | |
1326 | * here, we just deal with "RENAME_NOREPLACE" as regular rename. | |
1327 | */ | |
984fc4e7 CY |
1328 | return f2fs_rename(mnt_userns, old_dir, old_dentry, |
1329 | new_dir, new_dentry, flags); | |
32f9bc25 CY |
1330 | } |
1331 | ||
6b255391 | 1332 | static const char *f2fs_encrypted_get_link(struct dentry *dentry, |
fceef393 AV |
1333 | struct inode *inode, |
1334 | struct delayed_call *done) | |
50732df0 | 1335 | { |
f2329cb6 EB |
1336 | struct page *page; |
1337 | const char *target; | |
cbaf042a | 1338 | |
6b255391 AV |
1339 | if (!dentry) |
1340 | return ERR_PTR(-ECHILD); | |
1341 | ||
f2329cb6 EB |
1342 | page = read_mapping_page(inode->i_mapping, 0, NULL); |
1343 | if (IS_ERR(page)) | |
1344 | return ERR_CAST(page); | |
cbaf042a | 1345 | |
f2329cb6 EB |
1346 | target = fscrypt_get_symlink(inode, page_address(page), |
1347 | inode->i_sb->s_blocksize, done); | |
1348 | put_page(page); | |
1349 | return target; | |
50732df0 CY |
1350 | } |
1351 | ||
461b43a8 EB |
1352 | static int f2fs_encrypted_symlink_getattr(struct user_namespace *mnt_userns, |
1353 | const struct path *path, | |
1354 | struct kstat *stat, u32 request_mask, | |
1355 | unsigned int query_flags) | |
1356 | { | |
1357 | f2fs_getattr(mnt_userns, path, stat, request_mask, query_flags); | |
1358 | ||
1359 | return fscrypt_symlink_getattr(path, stat); | |
1360 | } | |
1361 | ||
cbaf042a | 1362 | const struct inode_operations f2fs_encrypted_symlink_inode_operations = { |
a87aff1d | 1363 | .get_link = f2fs_encrypted_get_link, |
461b43a8 | 1364 | .getattr = f2fs_encrypted_symlink_getattr, |
cbaf042a | 1365 | .setattr = f2fs_setattr, |
cbaf042a | 1366 | .listxattr = f2fs_listxattr, |
cbaf042a | 1367 | }; |
cbaf042a | 1368 | |
57397d86 JK |
1369 | const struct inode_operations f2fs_dir_inode_operations = { |
1370 | .create = f2fs_create, | |
1371 | .lookup = f2fs_lookup, | |
1372 | .link = f2fs_link, | |
1373 | .unlink = f2fs_unlink, | |
1374 | .symlink = f2fs_symlink, | |
1375 | .mkdir = f2fs_mkdir, | |
1376 | .rmdir = f2fs_rmdir, | |
1377 | .mknod = f2fs_mknod, | |
2773bf00 | 1378 | .rename = f2fs_rename2, |
50732df0 | 1379 | .tmpfile = f2fs_tmpfile, |
2d4d9fb5 | 1380 | .getattr = f2fs_getattr, |
57397d86 JK |
1381 | .setattr = f2fs_setattr, |
1382 | .get_acl = f2fs_get_acl, | |
a6dda0e6 | 1383 | .set_acl = f2fs_set_acl, |
57397d86 | 1384 | .listxattr = f2fs_listxattr, |
7975f349 | 1385 | .fiemap = f2fs_fiemap, |
9b1bb01c MS |
1386 | .fileattr_get = f2fs_fileattr_get, |
1387 | .fileattr_set = f2fs_fileattr_set, | |
57397d86 JK |
1388 | }; |
1389 | ||
1390 | const struct inode_operations f2fs_symlink_inode_operations = { | |
a87aff1d | 1391 | .get_link = f2fs_get_link, |
2d4d9fb5 | 1392 | .getattr = f2fs_getattr, |
57397d86 | 1393 | .setattr = f2fs_setattr, |
57397d86 | 1394 | .listxattr = f2fs_listxattr, |
57397d86 JK |
1395 | }; |
1396 | ||
1397 | const struct inode_operations f2fs_special_inode_operations = { | |
2d4d9fb5 | 1398 | .getattr = f2fs_getattr, |
a87aff1d | 1399 | .setattr = f2fs_setattr, |
57397d86 | 1400 | .get_acl = f2fs_get_acl, |
a6dda0e6 | 1401 | .set_acl = f2fs_set_acl, |
57397d86 | 1402 | .listxattr = f2fs_listxattr, |
57397d86 | 1403 | }; |