]>
Commit | Line | Data |
---|---|---|
5b88fdd9 SF |
1 | /* |
2 | * Copyright (C) 2005-2016 Junjiro R. Okajima | |
3 | * | |
4 | * This program, aufs is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * This program is distributed in the hope that it will be useful, | |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | * GNU General Public License for more details. | |
13 | * | |
14 | * You should have received a copy of the GNU General Public License | |
15 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
16 | */ | |
17 | ||
18 | /* | |
19 | * inode operation (rename entry) | |
20 | * todo: this is crazy monster | |
21 | */ | |
22 | ||
23 | #include "aufs.h" | |
24 | ||
25 | enum { AuSRC, AuDST, AuSrcDst }; | |
26 | enum { AuPARENT, AuCHILD, AuParentChild }; | |
27 | ||
28 | #define AuRen_ISDIR 1 | |
29 | #define AuRen_ISSAMEDIR (1 << 1) | |
30 | #define AuRen_WHSRC (1 << 2) | |
31 | #define AuRen_WHDST (1 << 3) | |
32 | #define AuRen_MNT_WRITE (1 << 4) | |
33 | #define AuRen_DT_DSTDIR (1 << 5) | |
34 | #define AuRen_DIROPQ (1 << 6) | |
35 | #define au_ftest_ren(flags, name) ((flags) & AuRen_##name) | |
36 | #define au_fset_ren(flags, name) \ | |
37 | do { (flags) |= AuRen_##name; } while (0) | |
38 | #define au_fclr_ren(flags, name) \ | |
39 | do { (flags) &= ~AuRen_##name; } while (0) | |
40 | ||
41 | struct au_ren_args { | |
42 | struct { | |
43 | struct dentry *dentry, *h_dentry, *parent, *h_parent, | |
44 | *wh_dentry; | |
45 | struct inode *dir, *inode; | |
46 | struct au_hinode *hdir; | |
47 | struct au_dtime dt[AuParentChild]; | |
48 | aufs_bindex_t btop; | |
49 | } sd[AuSrcDst]; | |
50 | ||
51 | #define src_dentry sd[AuSRC].dentry | |
52 | #define src_dir sd[AuSRC].dir | |
53 | #define src_inode sd[AuSRC].inode | |
54 | #define src_h_dentry sd[AuSRC].h_dentry | |
55 | #define src_parent sd[AuSRC].parent | |
56 | #define src_h_parent sd[AuSRC].h_parent | |
57 | #define src_wh_dentry sd[AuSRC].wh_dentry | |
58 | #define src_hdir sd[AuSRC].hdir | |
59 | #define src_h_dir sd[AuSRC].hdir->hi_inode | |
60 | #define src_dt sd[AuSRC].dt | |
61 | #define src_btop sd[AuSRC].btop | |
62 | ||
63 | #define dst_dentry sd[AuDST].dentry | |
64 | #define dst_dir sd[AuDST].dir | |
65 | #define dst_inode sd[AuDST].inode | |
66 | #define dst_h_dentry sd[AuDST].h_dentry | |
67 | #define dst_parent sd[AuDST].parent | |
68 | #define dst_h_parent sd[AuDST].h_parent | |
69 | #define dst_wh_dentry sd[AuDST].wh_dentry | |
70 | #define dst_hdir sd[AuDST].hdir | |
71 | #define dst_h_dir sd[AuDST].hdir->hi_inode | |
72 | #define dst_dt sd[AuDST].dt | |
73 | #define dst_btop sd[AuDST].btop | |
74 | ||
75 | struct dentry *h_trap; | |
76 | struct au_branch *br; | |
77 | struct au_hinode *src_hinode; | |
78 | struct path h_path; | |
79 | struct au_nhash whlist; | |
80 | aufs_bindex_t btgt, src_bwh, src_bdiropq; | |
81 | ||
82 | unsigned int flags; | |
83 | ||
84 | struct au_whtmp_rmdir *thargs; | |
85 | struct dentry *h_dst; | |
86 | }; | |
87 | ||
88 | /* ---------------------------------------------------------------------- */ | |
89 | ||
90 | /* | |
91 | * functions for reverting. | |
92 | * when an error happened in a single rename systemcall, we should revert | |
93 | * everything as if nothing happened. | |
94 | * we don't need to revert the copied-up/down the parent dir since they are | |
95 | * harmless. | |
96 | */ | |
97 | ||
98 | #define RevertFailure(fmt, ...) do { \ | |
99 | AuIOErr("revert failure: " fmt " (%d, %d)\n", \ | |
100 | ##__VA_ARGS__, err, rerr); \ | |
101 | err = -EIO; \ | |
102 | } while (0) | |
103 | ||
104 | static void au_ren_rev_diropq(int err, struct au_ren_args *a) | |
105 | { | |
106 | int rerr; | |
107 | ||
108 | au_hn_inode_lock_nested(a->src_hinode, AuLsc_I_CHILD); | |
109 | rerr = au_diropq_remove(a->src_dentry, a->btgt); | |
110 | au_hn_inode_unlock(a->src_hinode); | |
111 | au_set_dbdiropq(a->src_dentry, a->src_bdiropq); | |
112 | if (rerr) | |
113 | RevertFailure("remove diropq %pd", a->src_dentry); | |
114 | } | |
115 | ||
116 | static void au_ren_rev_rename(int err, struct au_ren_args *a) | |
117 | { | |
118 | int rerr; | |
119 | struct inode *delegated; | |
120 | ||
121 | a->h_path.dentry = vfsub_lkup_one(&a->src_dentry->d_name, | |
122 | a->src_h_parent); | |
123 | rerr = PTR_ERR(a->h_path.dentry); | |
124 | if (IS_ERR(a->h_path.dentry)) { | |
125 | RevertFailure("lkup one %pd", a->src_dentry); | |
126 | return; | |
127 | } | |
128 | ||
129 | delegated = NULL; | |
130 | rerr = vfsub_rename(a->dst_h_dir, | |
131 | au_h_dptr(a->src_dentry, a->btgt), | |
132 | a->src_h_dir, &a->h_path, &delegated); | |
133 | if (unlikely(rerr == -EWOULDBLOCK)) { | |
134 | pr_warn("cannot retry for NFSv4 delegation" | |
135 | " for an internal rename\n"); | |
136 | iput(delegated); | |
137 | } | |
138 | d_drop(a->h_path.dentry); | |
139 | dput(a->h_path.dentry); | |
140 | /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */ | |
141 | if (rerr) | |
142 | RevertFailure("rename %pd", a->src_dentry); | |
143 | } | |
144 | ||
145 | static void au_ren_rev_whtmp(int err, struct au_ren_args *a) | |
146 | { | |
147 | int rerr; | |
148 | struct inode *delegated; | |
149 | ||
150 | a->h_path.dentry = vfsub_lkup_one(&a->dst_dentry->d_name, | |
151 | a->dst_h_parent); | |
152 | rerr = PTR_ERR(a->h_path.dentry); | |
153 | if (IS_ERR(a->h_path.dentry)) { | |
154 | RevertFailure("lkup one %pd", a->dst_dentry); | |
155 | return; | |
156 | } | |
157 | if (d_is_positive(a->h_path.dentry)) { | |
158 | d_drop(a->h_path.dentry); | |
159 | dput(a->h_path.dentry); | |
160 | return; | |
161 | } | |
162 | ||
163 | delegated = NULL; | |
164 | rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path, | |
165 | &delegated); | |
166 | if (unlikely(rerr == -EWOULDBLOCK)) { | |
167 | pr_warn("cannot retry for NFSv4 delegation" | |
168 | " for an internal rename\n"); | |
169 | iput(delegated); | |
170 | } | |
171 | d_drop(a->h_path.dentry); | |
172 | dput(a->h_path.dentry); | |
173 | if (!rerr) | |
174 | au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst)); | |
175 | else | |
176 | RevertFailure("rename %pd", a->h_dst); | |
177 | } | |
178 | ||
179 | static void au_ren_rev_whsrc(int err, struct au_ren_args *a) | |
180 | { | |
181 | int rerr; | |
182 | ||
183 | a->h_path.dentry = a->src_wh_dentry; | |
184 | rerr = au_wh_unlink_dentry(a->src_h_dir, &a->h_path, a->src_dentry); | |
185 | au_set_dbwh(a->src_dentry, a->src_bwh); | |
186 | if (rerr) | |
187 | RevertFailure("unlink %pd", a->src_wh_dentry); | |
188 | } | |
189 | #undef RevertFailure | |
190 | ||
191 | /* ---------------------------------------------------------------------- */ | |
192 | ||
193 | /* | |
194 | * when we have to copyup the renaming entry, do it with the rename-target name | |
195 | * in order to minimize the cost (the later actual rename is unnecessary). | |
196 | * otherwise rename it on the target branch. | |
197 | */ | |
198 | static int au_ren_or_cpup(struct au_ren_args *a) | |
199 | { | |
200 | int err; | |
201 | struct dentry *d; | |
202 | struct inode *delegated; | |
203 | ||
204 | d = a->src_dentry; | |
205 | if (au_dbtop(d) == a->btgt) { | |
206 | a->h_path.dentry = a->dst_h_dentry; | |
207 | if (au_ftest_ren(a->flags, DIROPQ) | |
208 | && au_dbdiropq(d) == a->btgt) | |
209 | au_fclr_ren(a->flags, DIROPQ); | |
210 | AuDebugOn(au_dbtop(d) != a->btgt); | |
211 | delegated = NULL; | |
212 | err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt), | |
213 | a->dst_h_dir, &a->h_path, &delegated); | |
214 | if (unlikely(err == -EWOULDBLOCK)) { | |
215 | pr_warn("cannot retry for NFSv4 delegation" | |
216 | " for an internal rename\n"); | |
217 | iput(delegated); | |
218 | } | |
219 | } else | |
220 | BUG(); | |
221 | ||
222 | if (!err && a->h_dst) | |
223 | /* it will be set to dinfo later */ | |
224 | dget(a->h_dst); | |
225 | ||
226 | return err; | |
227 | } | |
228 | ||
229 | /* cf. aufs_rmdir() */ | |
230 | static int au_ren_del_whtmp(struct au_ren_args *a) | |
231 | { | |
232 | int err; | |
233 | struct inode *dir; | |
234 | ||
235 | dir = a->dst_dir; | |
236 | SiMustAnyLock(dir->i_sb); | |
237 | if (!au_nhash_test_longer_wh(&a->whlist, a->btgt, | |
238 | au_sbi(dir->i_sb)->si_dirwh) | |
239 | || au_test_fs_remote(a->h_dst->d_sb)) { | |
240 | err = au_whtmp_rmdir(dir, a->btgt, a->h_dst, &a->whlist); | |
241 | if (unlikely(err)) | |
242 | pr_warn("failed removing whtmp dir %pd (%d), " | |
243 | "ignored.\n", a->h_dst, err); | |
244 | } else { | |
245 | au_nhash_wh_free(&a->thargs->whlist); | |
246 | a->thargs->whlist = a->whlist; | |
247 | a->whlist.nh_num = 0; | |
248 | au_whtmp_kick_rmdir(dir, a->btgt, a->h_dst, a->thargs); | |
249 | dput(a->h_dst); | |
250 | a->thargs = NULL; | |
251 | } | |
252 | ||
253 | return 0; | |
254 | } | |
255 | ||
256 | /* make it 'opaque' dir. */ | |
257 | static int au_ren_diropq(struct au_ren_args *a) | |
258 | { | |
259 | int err; | |
260 | struct dentry *diropq; | |
261 | ||
262 | err = 0; | |
263 | a->src_bdiropq = au_dbdiropq(a->src_dentry); | |
264 | a->src_hinode = au_hi(a->src_inode, a->btgt); | |
265 | au_hn_inode_lock_nested(a->src_hinode, AuLsc_I_CHILD); | |
266 | diropq = au_diropq_create(a->src_dentry, a->btgt); | |
267 | au_hn_inode_unlock(a->src_hinode); | |
268 | if (IS_ERR(diropq)) | |
269 | err = PTR_ERR(diropq); | |
270 | else | |
271 | dput(diropq); | |
272 | ||
273 | return err; | |
274 | } | |
275 | ||
276 | static int do_rename(struct au_ren_args *a) | |
277 | { | |
278 | int err; | |
279 | struct dentry *d, *h_d; | |
280 | ||
281 | /* prepare workqueue args for asynchronous rmdir */ | |
282 | h_d = a->dst_h_dentry; | |
283 | if (au_ftest_ren(a->flags, ISDIR) && d_is_positive(h_d)) { | |
284 | err = -ENOMEM; | |
285 | a->thargs = au_whtmp_rmdir_alloc(a->src_dentry->d_sb, GFP_NOFS); | |
286 | if (unlikely(!a->thargs)) | |
287 | goto out; | |
288 | a->h_dst = dget(h_d); | |
289 | } | |
290 | ||
291 | /* create whiteout for src_dentry */ | |
292 | if (au_ftest_ren(a->flags, WHSRC)) { | |
293 | a->src_bwh = au_dbwh(a->src_dentry); | |
294 | AuDebugOn(a->src_bwh >= 0); | |
295 | a->src_wh_dentry | |
296 | = au_wh_create(a->src_dentry, a->btgt, a->src_h_parent); | |
297 | err = PTR_ERR(a->src_wh_dentry); | |
298 | if (IS_ERR(a->src_wh_dentry)) | |
299 | goto out_thargs; | |
300 | } | |
301 | ||
302 | /* lookup whiteout for dentry */ | |
303 | if (au_ftest_ren(a->flags, WHDST)) { | |
304 | h_d = au_wh_lkup(a->dst_h_parent, &a->dst_dentry->d_name, | |
305 | a->br); | |
306 | err = PTR_ERR(h_d); | |
307 | if (IS_ERR(h_d)) | |
308 | goto out_whsrc; | |
309 | if (d_is_negative(h_d)) | |
310 | dput(h_d); | |
311 | else | |
312 | a->dst_wh_dentry = h_d; | |
313 | } | |
314 | ||
315 | /* rename dentry to tmpwh */ | |
316 | if (a->thargs) { | |
317 | err = au_whtmp_ren(a->dst_h_dentry, a->br); | |
318 | if (unlikely(err)) | |
319 | goto out_whdst; | |
320 | ||
321 | d = a->dst_dentry; | |
322 | au_set_h_dptr(d, a->btgt, NULL); | |
323 | err = au_lkup_neg(d, a->btgt, /*wh*/0); | |
324 | if (unlikely(err)) | |
325 | goto out_whtmp; | |
326 | a->dst_h_dentry = au_h_dptr(d, a->btgt); | |
327 | } | |
328 | ||
329 | BUG_ON(d_is_positive(a->dst_h_dentry) && a->src_btop != a->btgt); | |
330 | ||
331 | /* rename by vfs_rename or cpup */ | |
332 | d = a->dst_dentry; | |
333 | if (au_ftest_ren(a->flags, ISDIR) | |
334 | && (a->dst_wh_dentry | |
335 | || au_dbdiropq(d) == a->btgt | |
336 | /* hide the lower to keep xino */ | |
337 | || a->btgt < au_dbbot(d) | |
338 | || au_opt_test(au_mntflags(d->d_sb), ALWAYS_DIROPQ))) | |
339 | au_fset_ren(a->flags, DIROPQ); | |
340 | err = au_ren_or_cpup(a); | |
341 | if (unlikely(err)) | |
342 | /* leave the copied-up one */ | |
343 | goto out_whtmp; | |
344 | ||
345 | /* make dir opaque */ | |
346 | if (au_ftest_ren(a->flags, DIROPQ)) { | |
347 | err = au_ren_diropq(a); | |
348 | if (unlikely(err)) | |
349 | goto out_rename; | |
350 | } | |
351 | ||
352 | /* update target timestamps */ | |
353 | AuDebugOn(au_dbtop(a->src_dentry) != a->btgt); | |
354 | a->h_path.dentry = au_h_dptr(a->src_dentry, a->btgt); | |
355 | vfsub_update_h_iattr(&a->h_path, /*did*/NULL); /*ignore*/ | |
356 | a->src_inode->i_ctime = d_inode(a->h_path.dentry)->i_ctime; | |
357 | ||
358 | /* remove whiteout for dentry */ | |
359 | if (a->dst_wh_dentry) { | |
360 | a->h_path.dentry = a->dst_wh_dentry; | |
361 | err = au_wh_unlink_dentry(a->dst_h_dir, &a->h_path, | |
362 | a->dst_dentry); | |
363 | if (unlikely(err)) | |
364 | goto out_diropq; | |
365 | } | |
366 | ||
367 | /* remove whtmp */ | |
368 | if (a->thargs) | |
369 | au_ren_del_whtmp(a); /* ignore this error */ | |
370 | ||
371 | au_fhsm_wrote(a->src_dentry->d_sb, a->btgt, /*force*/0); | |
372 | err = 0; | |
373 | goto out_success; | |
374 | ||
375 | out_diropq: | |
376 | if (au_ftest_ren(a->flags, DIROPQ)) | |
377 | au_ren_rev_diropq(err, a); | |
378 | out_rename: | |
379 | au_ren_rev_rename(err, a); | |
380 | dput(a->h_dst); | |
381 | out_whtmp: | |
382 | if (a->thargs) | |
383 | au_ren_rev_whtmp(err, a); | |
384 | out_whdst: | |
385 | dput(a->dst_wh_dentry); | |
386 | a->dst_wh_dentry = NULL; | |
387 | out_whsrc: | |
388 | if (a->src_wh_dentry) | |
389 | au_ren_rev_whsrc(err, a); | |
390 | out_success: | |
391 | dput(a->src_wh_dentry); | |
392 | dput(a->dst_wh_dentry); | |
393 | out_thargs: | |
394 | if (a->thargs) { | |
395 | dput(a->h_dst); | |
396 | au_whtmp_rmdir_free(a->thargs); | |
397 | a->thargs = NULL; | |
398 | } | |
399 | out: | |
400 | return err; | |
401 | } | |
402 | ||
403 | /* ---------------------------------------------------------------------- */ | |
404 | ||
405 | /* | |
406 | * test if @dentry dir can be rename destination or not. | |
407 | * success means, it is a logically empty dir. | |
408 | */ | |
409 | static int may_rename_dstdir(struct dentry *dentry, struct au_nhash *whlist) | |
410 | { | |
411 | return au_test_empty(dentry, whlist); | |
412 | } | |
413 | ||
414 | /* | |
415 | * test if @dentry dir can be rename source or not. | |
416 | * if it can, return 0 and @children is filled. | |
417 | * success means, | |
418 | * - it is a logically empty dir. | |
419 | * - or, it exists on writable branch and has no children including whiteouts | |
420 | * on the lower branch. | |
421 | */ | |
422 | static int may_rename_srcdir(struct dentry *dentry, aufs_bindex_t btgt) | |
423 | { | |
424 | int err; | |
425 | unsigned int rdhash; | |
426 | aufs_bindex_t btop; | |
427 | ||
428 | btop = au_dbtop(dentry); | |
429 | if (btop != btgt) { | |
430 | struct au_nhash whlist; | |
431 | ||
432 | SiMustAnyLock(dentry->d_sb); | |
433 | rdhash = au_sbi(dentry->d_sb)->si_rdhash; | |
434 | if (!rdhash) | |
435 | rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, | |
436 | dentry)); | |
437 | err = au_nhash_alloc(&whlist, rdhash, GFP_NOFS); | |
438 | if (unlikely(err)) | |
439 | goto out; | |
440 | err = au_test_empty(dentry, &whlist); | |
441 | au_nhash_wh_free(&whlist); | |
442 | goto out; | |
443 | } | |
444 | ||
445 | if (btop == au_dbtaildir(dentry)) | |
446 | return 0; /* success */ | |
447 | ||
448 | err = au_test_empty_lower(dentry); | |
449 | ||
450 | out: | |
451 | if (err == -ENOTEMPTY) { | |
452 | AuWarn1("renaming dir who has child(ren) on multiple branches," | |
453 | " is not supported\n"); | |
454 | err = -EXDEV; | |
455 | } | |
456 | return err; | |
457 | } | |
458 | ||
459 | /* side effect: sets whlist and h_dentry */ | |
460 | static int au_ren_may_dir(struct au_ren_args *a) | |
461 | { | |
462 | int err; | |
463 | unsigned int rdhash; | |
464 | struct dentry *d; | |
465 | ||
466 | d = a->dst_dentry; | |
467 | SiMustAnyLock(d->d_sb); | |
468 | ||
469 | err = 0; | |
470 | if (au_ftest_ren(a->flags, ISDIR) && a->dst_inode) { | |
471 | rdhash = au_sbi(d->d_sb)->si_rdhash; | |
472 | if (!rdhash) | |
473 | rdhash = au_rdhash_est(au_dir_size(/*file*/NULL, d)); | |
474 | err = au_nhash_alloc(&a->whlist, rdhash, GFP_NOFS); | |
475 | if (unlikely(err)) | |
476 | goto out; | |
477 | ||
478 | au_set_dbtop(d, a->dst_btop); | |
479 | err = may_rename_dstdir(d, &a->whlist); | |
480 | au_set_dbtop(d, a->btgt); | |
481 | } | |
482 | a->dst_h_dentry = au_h_dptr(d, au_dbtop(d)); | |
483 | if (unlikely(err)) | |
484 | goto out; | |
485 | ||
486 | d = a->src_dentry; | |
487 | a->src_h_dentry = au_h_dptr(d, au_dbtop(d)); | |
488 | if (au_ftest_ren(a->flags, ISDIR)) { | |
489 | err = may_rename_srcdir(d, a->btgt); | |
490 | if (unlikely(err)) { | |
491 | au_nhash_wh_free(&a->whlist); | |
492 | a->whlist.nh_num = 0; | |
493 | } | |
494 | } | |
495 | out: | |
496 | return err; | |
497 | } | |
498 | ||
499 | /* ---------------------------------------------------------------------- */ | |
500 | ||
501 | /* | |
502 | * simple tests for rename. | |
503 | * following the checks in vfs, plus the parent-child relationship. | |
504 | */ | |
505 | static int au_may_ren(struct au_ren_args *a) | |
506 | { | |
507 | int err, isdir; | |
508 | struct inode *h_inode; | |
509 | ||
510 | if (a->src_btop == a->btgt) { | |
511 | err = au_may_del(a->src_dentry, a->btgt, a->src_h_parent, | |
512 | au_ftest_ren(a->flags, ISDIR)); | |
513 | if (unlikely(err)) | |
514 | goto out; | |
515 | err = -EINVAL; | |
516 | if (unlikely(a->src_h_dentry == a->h_trap)) | |
517 | goto out; | |
518 | } | |
519 | ||
520 | err = 0; | |
521 | if (a->dst_btop != a->btgt) | |
522 | goto out; | |
523 | ||
524 | err = -ENOTEMPTY; | |
525 | if (unlikely(a->dst_h_dentry == a->h_trap)) | |
526 | goto out; | |
527 | ||
528 | err = -EIO; | |
529 | isdir = !!au_ftest_ren(a->flags, ISDIR); | |
530 | if (d_really_is_negative(a->dst_dentry)) { | |
531 | if (d_is_negative(a->dst_h_dentry)) | |
532 | err = au_may_add(a->dst_dentry, a->btgt, | |
533 | a->dst_h_parent, isdir); | |
534 | } else { | |
535 | if (unlikely(d_is_negative(a->dst_h_dentry))) | |
536 | goto out; | |
537 | h_inode = d_inode(a->dst_h_dentry); | |
538 | if (h_inode->i_nlink) | |
539 | err = au_may_del(a->dst_dentry, a->btgt, | |
540 | a->dst_h_parent, isdir); | |
541 | } | |
542 | ||
543 | out: | |
544 | if (unlikely(err == -ENOENT || err == -EEXIST)) | |
545 | err = -EIO; | |
546 | AuTraceErr(err); | |
547 | return err; | |
548 | } | |
549 | ||
550 | /* ---------------------------------------------------------------------- */ | |
551 | ||
552 | /* | |
553 | * locking order | |
554 | * (VFS) | |
555 | * - src_dir and dir by lock_rename() | |
556 | * - inode if exitsts | |
557 | * (aufs) | |
558 | * - lock all | |
559 | * + src_dentry and dentry by aufs_read_and_write_lock2() which calls, | |
560 | * + si_read_lock | |
561 | * + di_write_lock2_child() | |
562 | * + di_write_lock_child() | |
563 | * + ii_write_lock_child() | |
564 | * + di_write_lock_child2() | |
565 | * + ii_write_lock_child2() | |
566 | * + src_parent and parent | |
567 | * + di_write_lock_parent() | |
568 | * + ii_write_lock_parent() | |
569 | * + di_write_lock_parent2() | |
570 | * + ii_write_lock_parent2() | |
571 | * + lower src_dir and dir by vfsub_lock_rename() | |
572 | * + verify the every relationships between child and parent. if any | |
573 | * of them failed, unlock all and return -EBUSY. | |
574 | */ | |
575 | static void au_ren_unlock(struct au_ren_args *a) | |
576 | { | |
577 | vfsub_unlock_rename(a->src_h_parent, a->src_hdir, | |
578 | a->dst_h_parent, a->dst_hdir); | |
579 | if (au_ftest_ren(a->flags, MNT_WRITE)) | |
580 | vfsub_mnt_drop_write(au_br_mnt(a->br)); | |
581 | } | |
582 | ||
583 | static int au_ren_lock(struct au_ren_args *a) | |
584 | { | |
585 | int err; | |
586 | unsigned int udba; | |
587 | ||
588 | err = 0; | |
589 | a->src_h_parent = au_h_dptr(a->src_parent, a->btgt); | |
590 | a->src_hdir = au_hi(a->src_dir, a->btgt); | |
591 | a->dst_h_parent = au_h_dptr(a->dst_parent, a->btgt); | |
592 | a->dst_hdir = au_hi(a->dst_dir, a->btgt); | |
593 | ||
594 | err = vfsub_mnt_want_write(au_br_mnt(a->br)); | |
595 | if (unlikely(err)) | |
596 | goto out; | |
597 | au_fset_ren(a->flags, MNT_WRITE); | |
598 | a->h_trap = vfsub_lock_rename(a->src_h_parent, a->src_hdir, | |
599 | a->dst_h_parent, a->dst_hdir); | |
600 | udba = au_opt_udba(a->src_dentry->d_sb); | |
601 | if (unlikely(a->src_hdir->hi_inode != d_inode(a->src_h_parent) | |
602 | || a->dst_hdir->hi_inode != d_inode(a->dst_h_parent))) | |
603 | err = au_busy_or_stale(); | |
604 | if (!err && au_dbtop(a->src_dentry) == a->btgt) | |
605 | err = au_h_verify(a->src_h_dentry, udba, | |
606 | d_inode(a->src_h_parent), a->src_h_parent, | |
607 | a->br); | |
608 | if (!err && au_dbtop(a->dst_dentry) == a->btgt) | |
609 | err = au_h_verify(a->dst_h_dentry, udba, | |
610 | d_inode(a->dst_h_parent), a->dst_h_parent, | |
611 | a->br); | |
612 | if (!err) | |
613 | goto out; /* success */ | |
614 | ||
615 | err = au_busy_or_stale(); | |
616 | au_ren_unlock(a); | |
617 | ||
618 | out: | |
619 | return err; | |
620 | } | |
621 | ||
622 | /* ---------------------------------------------------------------------- */ | |
623 | ||
624 | static void au_ren_refresh_dir(struct au_ren_args *a) | |
625 | { | |
626 | struct inode *dir; | |
627 | ||
628 | dir = a->dst_dir; | |
629 | dir->i_version++; | |
630 | if (au_ftest_ren(a->flags, ISDIR)) { | |
631 | /* is this updating defined in POSIX? */ | |
632 | au_cpup_attr_timesizes(a->src_inode); | |
633 | au_cpup_attr_nlink(dir, /*force*/1); | |
634 | } | |
635 | ||
636 | au_dir_ts(dir, a->btgt); | |
637 | ||
638 | if (au_ftest_ren(a->flags, ISSAMEDIR)) | |
639 | return; | |
640 | ||
641 | dir = a->src_dir; | |
642 | dir->i_version++; | |
643 | if (au_ftest_ren(a->flags, ISDIR)) | |
644 | au_cpup_attr_nlink(dir, /*force*/1); | |
645 | au_dir_ts(dir, a->btgt); | |
646 | } | |
647 | ||
648 | static void au_ren_refresh(struct au_ren_args *a) | |
649 | { | |
650 | aufs_bindex_t bbot, bindex; | |
651 | struct dentry *d, *h_d; | |
652 | struct inode *i, *h_i; | |
653 | struct super_block *sb; | |
654 | ||
655 | d = a->dst_dentry; | |
656 | d_drop(d); | |
657 | if (a->h_dst) | |
658 | /* already dget-ed by au_ren_or_cpup() */ | |
659 | au_set_h_dptr(d, a->btgt, a->h_dst); | |
660 | ||
661 | i = a->dst_inode; | |
662 | if (i) { | |
663 | if (!au_ftest_ren(a->flags, ISDIR)) | |
664 | vfsub_drop_nlink(i); | |
665 | else { | |
666 | vfsub_dead_dir(i); | |
667 | au_cpup_attr_timesizes(i); | |
668 | } | |
669 | au_update_dbrange(d, /*do_put_zero*/1); | |
670 | } else { | |
671 | bbot = a->btgt; | |
672 | for (bindex = au_dbtop(d); bindex < bbot; bindex++) | |
673 | au_set_h_dptr(d, bindex, NULL); | |
674 | bbot = au_dbbot(d); | |
675 | for (bindex = a->btgt + 1; bindex <= bbot; bindex++) | |
676 | au_set_h_dptr(d, bindex, NULL); | |
677 | au_update_dbrange(d, /*do_put_zero*/0); | |
678 | } | |
679 | ||
680 | d = a->src_dentry; | |
681 | au_set_dbwh(d, -1); | |
682 | bbot = au_dbbot(d); | |
683 | for (bindex = a->btgt + 1; bindex <= bbot; bindex++) { | |
684 | h_d = au_h_dptr(d, bindex); | |
685 | if (h_d) | |
686 | au_set_h_dptr(d, bindex, NULL); | |
687 | } | |
688 | au_set_dbbot(d, a->btgt); | |
689 | ||
690 | sb = d->d_sb; | |
691 | i = a->src_inode; | |
692 | if (au_opt_test(au_mntflags(sb), PLINK) && au_plink_test(i)) | |
693 | return; /* success */ | |
694 | ||
695 | bbot = au_ibbot(i); | |
696 | for (bindex = a->btgt + 1; bindex <= bbot; bindex++) { | |
697 | h_i = au_h_iptr(i, bindex); | |
698 | if (h_i) { | |
699 | au_xino_write(sb, bindex, h_i->i_ino, /*ino*/0); | |
700 | /* ignore this error */ | |
701 | au_set_h_iptr(i, bindex, NULL, 0); | |
702 | } | |
703 | } | |
704 | au_set_ibbot(i, a->btgt); | |
705 | } | |
706 | ||
707 | /* ---------------------------------------------------------------------- */ | |
708 | ||
709 | /* mainly for link(2) and rename(2) */ | |
710 | int au_wbr(struct dentry *dentry, aufs_bindex_t btgt) | |
711 | { | |
712 | aufs_bindex_t bdiropq, bwh; | |
713 | struct dentry *parent; | |
714 | struct au_branch *br; | |
715 | ||
716 | parent = dentry->d_parent; | |
717 | IMustLock(d_inode(parent)); /* dir is locked */ | |
718 | ||
719 | bdiropq = au_dbdiropq(parent); | |
720 | bwh = au_dbwh(dentry); | |
721 | br = au_sbr(dentry->d_sb, btgt); | |
722 | if (au_br_rdonly(br) | |
723 | || (0 <= bdiropq && bdiropq < btgt) | |
724 | || (0 <= bwh && bwh < btgt)) | |
725 | btgt = -1; | |
726 | ||
727 | AuDbg("btgt %d\n", btgt); | |
728 | return btgt; | |
729 | } | |
730 | ||
731 | /* sets src_btop, dst_btop and btgt */ | |
732 | static int au_ren_wbr(struct au_ren_args *a) | |
733 | { | |
734 | int err; | |
735 | struct au_wr_dir_args wr_dir_args = { | |
736 | /* .force_btgt = -1, */ | |
737 | .flags = AuWrDir_ADD_ENTRY | |
738 | }; | |
739 | ||
740 | a->src_btop = au_dbtop(a->src_dentry); | |
741 | a->dst_btop = au_dbtop(a->dst_dentry); | |
742 | if (au_ftest_ren(a->flags, ISDIR)) | |
743 | au_fset_wrdir(wr_dir_args.flags, ISDIR); | |
744 | wr_dir_args.force_btgt = a->src_btop; | |
745 | if (a->dst_inode && a->dst_btop < a->src_btop) | |
746 | wr_dir_args.force_btgt = a->dst_btop; | |
747 | wr_dir_args.force_btgt = au_wbr(a->dst_dentry, wr_dir_args.force_btgt); | |
748 | err = au_wr_dir(a->dst_dentry, a->src_dentry, &wr_dir_args); | |
749 | a->btgt = err; | |
750 | ||
751 | return err; | |
752 | } | |
753 | ||
754 | static void au_ren_dt(struct au_ren_args *a) | |
755 | { | |
756 | a->h_path.dentry = a->src_h_parent; | |
757 | au_dtime_store(a->src_dt + AuPARENT, a->src_parent, &a->h_path); | |
758 | if (!au_ftest_ren(a->flags, ISSAMEDIR)) { | |
759 | a->h_path.dentry = a->dst_h_parent; | |
760 | au_dtime_store(a->dst_dt + AuPARENT, a->dst_parent, &a->h_path); | |
761 | } | |
762 | ||
763 | au_fclr_ren(a->flags, DT_DSTDIR); | |
764 | if (!au_ftest_ren(a->flags, ISDIR)) | |
765 | return; | |
766 | ||
767 | a->h_path.dentry = a->src_h_dentry; | |
768 | au_dtime_store(a->src_dt + AuCHILD, a->src_dentry, &a->h_path); | |
769 | if (d_is_positive(a->dst_h_dentry)) { | |
770 | au_fset_ren(a->flags, DT_DSTDIR); | |
771 | a->h_path.dentry = a->dst_h_dentry; | |
772 | au_dtime_store(a->dst_dt + AuCHILD, a->dst_dentry, &a->h_path); | |
773 | } | |
774 | } | |
775 | ||
776 | static void au_ren_rev_dt(int err, struct au_ren_args *a) | |
777 | { | |
778 | struct dentry *h_d; | |
779 | struct inode *h_inode; | |
780 | ||
781 | au_dtime_revert(a->src_dt + AuPARENT); | |
782 | if (!au_ftest_ren(a->flags, ISSAMEDIR)) | |
783 | au_dtime_revert(a->dst_dt + AuPARENT); | |
784 | ||
785 | if (au_ftest_ren(a->flags, ISDIR) && err != -EIO) { | |
786 | h_d = a->src_dt[AuCHILD].dt_h_path.dentry; | |
787 | h_inode = d_inode(h_d); | |
788 | inode_lock_nested(h_inode, AuLsc_I_CHILD); | |
789 | au_dtime_revert(a->src_dt + AuCHILD); | |
790 | inode_unlock(h_inode); | |
791 | ||
792 | if (au_ftest_ren(a->flags, DT_DSTDIR)) { | |
793 | h_d = a->dst_dt[AuCHILD].dt_h_path.dentry; | |
794 | h_inode = d_inode(h_d); | |
795 | inode_lock_nested(h_inode, AuLsc_I_CHILD); | |
796 | au_dtime_revert(a->dst_dt + AuCHILD); | |
797 | inode_unlock(h_inode); | |
798 | } | |
799 | } | |
800 | } | |
801 | ||
802 | /* ---------------------------------------------------------------------- */ | |
803 | ||
804 | int aufs_rename(struct inode *_src_dir, struct dentry *_src_dentry, | |
41eff299 | 805 | struct inode *_dst_dir, struct dentry *_dst_dentry) |
5b88fdd9 SF |
806 | { |
807 | int err, flags; | |
808 | /* reduce stack space */ | |
809 | struct au_ren_args *a; | |
810 | ||
811 | AuDbg("%pd, %pd\n", _src_dentry, _dst_dentry); | |
812 | IMustLock(_src_dir); | |
813 | IMustLock(_dst_dir); | |
814 | ||
815 | err = -ENOMEM; | |
816 | BUILD_BUG_ON(sizeof(*a) > PAGE_SIZE); | |
817 | a = kzalloc(sizeof(*a), GFP_NOFS); | |
818 | if (unlikely(!a)) | |
819 | goto out; | |
820 | ||
821 | a->src_dir = _src_dir; | |
822 | a->src_dentry = _src_dentry; | |
823 | a->src_inode = NULL; | |
824 | if (d_really_is_positive(a->src_dentry)) | |
825 | a->src_inode = d_inode(a->src_dentry); | |
826 | a->src_parent = a->src_dentry->d_parent; /* dir inode is locked */ | |
827 | a->dst_dir = _dst_dir; | |
828 | a->dst_dentry = _dst_dentry; | |
829 | a->dst_inode = NULL; | |
830 | if (d_really_is_positive(a->dst_dentry)) | |
831 | a->dst_inode = d_inode(a->dst_dentry); | |
832 | a->dst_parent = a->dst_dentry->d_parent; /* dir inode is locked */ | |
833 | if (a->dst_inode) { | |
834 | IMustLock(a->dst_inode); | |
835 | au_igrab(a->dst_inode); | |
836 | } | |
837 | ||
838 | err = -ENOTDIR; | |
839 | flags = AuLock_FLUSH | AuLock_NOPLM | AuLock_GEN; | |
840 | if (d_is_dir(a->src_dentry)) { | |
841 | au_fset_ren(a->flags, ISDIR); | |
842 | if (unlikely(d_really_is_positive(a->dst_dentry) | |
843 | && !d_is_dir(a->dst_dentry))) | |
844 | goto out_free; | |
845 | flags |= AuLock_DIRS; | |
846 | } | |
847 | err = aufs_read_and_write_lock2(a->dst_dentry, a->src_dentry, flags); | |
848 | if (unlikely(err)) | |
849 | goto out_free; | |
850 | ||
851 | err = au_d_hashed_positive(a->src_dentry); | |
852 | if (unlikely(err)) | |
853 | goto out_unlock; | |
854 | err = -ENOENT; | |
855 | if (a->dst_inode) { | |
856 | /* | |
857 | * If it is a dir, VFS unhash dst_dentry before this | |
858 | * function. It means we cannot rely upon d_unhashed(). | |
859 | */ | |
860 | if (unlikely(!a->dst_inode->i_nlink)) | |
861 | goto out_unlock; | |
862 | if (!S_ISDIR(a->dst_inode->i_mode)) { | |
863 | err = au_d_hashed_positive(a->dst_dentry); | |
864 | if (unlikely(err)) | |
865 | goto out_unlock; | |
866 | } else if (unlikely(IS_DEADDIR(a->dst_inode))) | |
867 | goto out_unlock; | |
868 | } else if (unlikely(d_unhashed(a->dst_dentry))) | |
869 | goto out_unlock; | |
870 | ||
871 | /* | |
872 | * is it possible? | |
873 | * yes, it happened (in linux-3.3-rcN) but I don't know why. | |
874 | * there may exist a problem somewhere else. | |
875 | */ | |
876 | err = -EINVAL; | |
877 | if (unlikely(d_inode(a->dst_parent) == d_inode(a->src_dentry))) | |
878 | goto out_unlock; | |
879 | ||
880 | au_fset_ren(a->flags, ISSAMEDIR); /* temporary */ | |
881 | di_write_lock_parent(a->dst_parent); | |
882 | ||
883 | /* which branch we process */ | |
884 | err = au_ren_wbr(a); | |
885 | if (unlikely(err < 0)) | |
886 | goto out_parent; | |
887 | a->br = au_sbr(a->dst_dentry->d_sb, a->btgt); | |
888 | a->h_path.mnt = au_br_mnt(a->br); | |
889 | ||
890 | /* are they available to be renamed */ | |
891 | err = au_ren_may_dir(a); | |
892 | if (unlikely(err)) | |
893 | goto out_children; | |
894 | ||
895 | /* prepare the writable parent dir on the same branch */ | |
896 | if (a->dst_btop == a->btgt) { | |
897 | au_fset_ren(a->flags, WHDST); | |
898 | } else { | |
899 | err = au_cpup_dirs(a->dst_dentry, a->btgt); | |
900 | if (unlikely(err)) | |
901 | goto out_children; | |
902 | } | |
903 | ||
904 | if (a->src_dir != a->dst_dir) { | |
905 | /* | |
906 | * this temporary unlock is safe, | |
907 | * because both dir->i_mutex are locked. | |
908 | */ | |
909 | di_write_unlock(a->dst_parent); | |
910 | di_write_lock_parent(a->src_parent); | |
911 | err = au_wr_dir_need_wh(a->src_dentry, | |
912 | au_ftest_ren(a->flags, ISDIR), | |
913 | &a->btgt); | |
914 | di_write_unlock(a->src_parent); | |
915 | di_write_lock2_parent(a->src_parent, a->dst_parent, /*isdir*/1); | |
916 | au_fclr_ren(a->flags, ISSAMEDIR); | |
917 | } else | |
918 | err = au_wr_dir_need_wh(a->src_dentry, | |
919 | au_ftest_ren(a->flags, ISDIR), | |
920 | &a->btgt); | |
921 | if (unlikely(err < 0)) | |
922 | goto out_children; | |
923 | if (err) | |
924 | au_fset_ren(a->flags, WHSRC); | |
925 | ||
926 | /* cpup src */ | |
927 | if (a->src_btop != a->btgt) { | |
928 | struct au_pin pin; | |
929 | ||
930 | err = au_pin(&pin, a->src_dentry, a->btgt, | |
931 | au_opt_udba(a->src_dentry->d_sb), | |
932 | AuPin_DI_LOCKED | AuPin_MNT_WRITE); | |
933 | if (!err) { | |
934 | struct au_cp_generic cpg = { | |
935 | .dentry = a->src_dentry, | |
936 | .bdst = a->btgt, | |
937 | .bsrc = a->src_btop, | |
938 | .len = -1, | |
939 | .pin = &pin, | |
940 | .flags = AuCpup_DTIME | AuCpup_HOPEN | |
941 | }; | |
942 | AuDebugOn(au_dbtop(a->src_dentry) != a->src_btop); | |
943 | err = au_sio_cpup_simple(&cpg); | |
944 | au_unpin(&pin); | |
945 | } | |
946 | if (unlikely(err)) | |
947 | goto out_children; | |
948 | a->src_btop = a->btgt; | |
949 | a->src_h_dentry = au_h_dptr(a->src_dentry, a->btgt); | |
950 | au_fset_ren(a->flags, WHSRC); | |
951 | } | |
952 | ||
953 | /* lock them all */ | |
954 | err = au_ren_lock(a); | |
955 | if (unlikely(err)) | |
956 | /* leave the copied-up one */ | |
957 | goto out_children; | |
958 | ||
959 | if (!au_opt_test(au_mntflags(a->dst_dir->i_sb), UDBA_NONE)) | |
960 | err = au_may_ren(a); | |
961 | else if (unlikely(a->dst_dentry->d_name.len > AUFS_MAX_NAMELEN)) | |
962 | err = -ENAMETOOLONG; | |
963 | if (unlikely(err)) | |
964 | goto out_hdir; | |
965 | ||
966 | /* store timestamps to be revertible */ | |
967 | au_ren_dt(a); | |
968 | ||
969 | /* here we go */ | |
970 | err = do_rename(a); | |
971 | if (unlikely(err)) | |
972 | goto out_dt; | |
973 | ||
974 | /* update dir attributes */ | |
975 | au_ren_refresh_dir(a); | |
976 | ||
977 | /* dput/iput all lower dentries */ | |
978 | au_ren_refresh(a); | |
979 | ||
980 | goto out_hdir; /* success */ | |
981 | ||
982 | out_dt: | |
983 | au_ren_rev_dt(err, a); | |
984 | out_hdir: | |
985 | au_ren_unlock(a); | |
986 | out_children: | |
987 | au_nhash_wh_free(&a->whlist); | |
988 | if (err && a->dst_inode && a->dst_btop != a->btgt) { | |
989 | AuDbg("btop %d, btgt %d\n", a->dst_btop, a->btgt); | |
990 | au_set_h_dptr(a->dst_dentry, a->btgt, NULL); | |
991 | au_set_dbtop(a->dst_dentry, a->dst_btop); | |
992 | } | |
993 | out_parent: | |
994 | if (!err) | |
995 | d_move(a->src_dentry, a->dst_dentry); | |
996 | else { | |
997 | au_update_dbtop(a->dst_dentry); | |
998 | if (!a->dst_inode) | |
999 | d_drop(a->dst_dentry); | |
1000 | } | |
1001 | if (au_ftest_ren(a->flags, ISSAMEDIR)) | |
1002 | di_write_unlock(a->dst_parent); | |
1003 | else | |
1004 | di_write_unlock2(a->src_parent, a->dst_parent); | |
1005 | out_unlock: | |
1006 | aufs_read_and_write_unlock2(a->dst_dentry, a->src_dentry); | |
1007 | out_free: | |
1008 | iput(a->dst_inode); | |
1009 | if (a->thargs) | |
1010 | au_whtmp_rmdir_free(a->thargs); | |
1011 | au_delayed_kfree(a); | |
1012 | out: | |
1013 | AuTraceErr(err); | |
1014 | return err; | |
1015 | } |