]>
Commit | Line | Data |
---|---|---|
c088e31d SF |
1 | /* |
2 | * Copyright (C) 2005-2017 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 | * copy-up functions, see wbr_policy.c for copy-down | |
20 | */ | |
21 | ||
22 | #include <linux/fs_stack.h> | |
23 | #include <linux/mm.h> | |
24 | #include <linux/task_work.h> | |
25 | #include "aufs.h" | |
26 | ||
27 | void au_cpup_attr_flags(struct inode *dst, unsigned int iflags) | |
28 | { | |
29 | const unsigned int mask = S_DEAD | S_SWAPFILE | S_PRIVATE | |
30 | | S_NOATIME | S_NOCMTIME | S_AUTOMOUNT; | |
31 | ||
32 | BUILD_BUG_ON(sizeof(iflags) != sizeof(dst->i_flags)); | |
33 | ||
34 | dst->i_flags |= iflags & ~mask; | |
35 | if (au_test_fs_notime(dst->i_sb)) | |
36 | dst->i_flags |= S_NOATIME | S_NOCMTIME; | |
37 | } | |
38 | ||
39 | void au_cpup_attr_timesizes(struct inode *inode) | |
40 | { | |
41 | struct inode *h_inode; | |
42 | ||
43 | h_inode = au_h_iptr(inode, au_ibtop(inode)); | |
44 | fsstack_copy_attr_times(inode, h_inode); | |
45 | fsstack_copy_inode_size(inode, h_inode); | |
46 | } | |
47 | ||
48 | void au_cpup_attr_nlink(struct inode *inode, int force) | |
49 | { | |
50 | struct inode *h_inode; | |
51 | struct super_block *sb; | |
52 | aufs_bindex_t bindex, bbot; | |
53 | ||
54 | sb = inode->i_sb; | |
55 | bindex = au_ibtop(inode); | |
56 | h_inode = au_h_iptr(inode, bindex); | |
57 | if (!force | |
58 | && !S_ISDIR(h_inode->i_mode) | |
59 | && au_opt_test(au_mntflags(sb), PLINK) | |
60 | && au_plink_test(inode)) | |
61 | return; | |
62 | ||
63 | /* | |
64 | * 0 can happen in revalidating. | |
65 | * h_inode->i_mutex may not be held here, but it is harmless since once | |
66 | * i_nlink reaches 0, it will never become positive except O_TMPFILE | |
67 | * case. | |
68 | * todo: O_TMPFILE+linkat(AT_SYMLINK_FOLLOW) bypassing aufs may cause | |
69 | * the incorrect link count. | |
70 | */ | |
71 | set_nlink(inode, h_inode->i_nlink); | |
72 | ||
73 | /* | |
74 | * fewer nlink makes find(1) noisy, but larger nlink doesn't. | |
75 | * it may includes whplink directory. | |
76 | */ | |
77 | if (S_ISDIR(h_inode->i_mode)) { | |
78 | bbot = au_ibbot(inode); | |
79 | for (bindex++; bindex <= bbot; bindex++) { | |
80 | h_inode = au_h_iptr(inode, bindex); | |
81 | if (h_inode) | |
82 | au_add_nlink(inode, h_inode); | |
83 | } | |
84 | } | |
85 | } | |
86 | ||
87 | void au_cpup_attr_changeable(struct inode *inode) | |
88 | { | |
89 | struct inode *h_inode; | |
90 | ||
91 | h_inode = au_h_iptr(inode, au_ibtop(inode)); | |
92 | inode->i_mode = h_inode->i_mode; | |
93 | inode->i_uid = h_inode->i_uid; | |
94 | inode->i_gid = h_inode->i_gid; | |
95 | au_cpup_attr_timesizes(inode); | |
96 | au_cpup_attr_flags(inode, h_inode->i_flags); | |
97 | } | |
98 | ||
99 | void au_cpup_igen(struct inode *inode, struct inode *h_inode) | |
100 | { | |
101 | struct au_iinfo *iinfo = au_ii(inode); | |
102 | ||
103 | IiMustWriteLock(inode); | |
104 | ||
105 | iinfo->ii_higen = h_inode->i_generation; | |
106 | iinfo->ii_hsb1 = h_inode->i_sb; | |
107 | } | |
108 | ||
109 | void au_cpup_attr_all(struct inode *inode, int force) | |
110 | { | |
111 | struct inode *h_inode; | |
112 | ||
113 | h_inode = au_h_iptr(inode, au_ibtop(inode)); | |
114 | au_cpup_attr_changeable(inode); | |
115 | if (inode->i_nlink > 0) | |
116 | au_cpup_attr_nlink(inode, force); | |
117 | inode->i_rdev = h_inode->i_rdev; | |
118 | inode->i_blkbits = h_inode->i_blkbits; | |
119 | au_cpup_igen(inode, h_inode); | |
120 | } | |
121 | ||
122 | /* ---------------------------------------------------------------------- */ | |
123 | ||
124 | /* Note: dt_dentry and dt_h_dentry are not dget/dput-ed */ | |
125 | ||
126 | /* keep the timestamps of the parent dir when cpup */ | |
127 | void au_dtime_store(struct au_dtime *dt, struct dentry *dentry, | |
128 | struct path *h_path) | |
129 | { | |
130 | struct inode *h_inode; | |
131 | ||
132 | dt->dt_dentry = dentry; | |
133 | dt->dt_h_path = *h_path; | |
134 | h_inode = d_inode(h_path->dentry); | |
135 | dt->dt_atime = h_inode->i_atime; | |
136 | dt->dt_mtime = h_inode->i_mtime; | |
137 | /* smp_mb(); */ | |
138 | } | |
139 | ||
140 | void au_dtime_revert(struct au_dtime *dt) | |
141 | { | |
142 | struct iattr attr; | |
143 | int err; | |
144 | ||
145 | attr.ia_atime = dt->dt_atime; | |
146 | attr.ia_mtime = dt->dt_mtime; | |
147 | attr.ia_valid = ATTR_FORCE | ATTR_MTIME | ATTR_MTIME_SET | |
148 | | ATTR_ATIME | ATTR_ATIME_SET; | |
149 | ||
150 | /* no delegation since this is a directory */ | |
151 | err = vfsub_notify_change(&dt->dt_h_path, &attr, /*delegated*/NULL); | |
152 | if (unlikely(err)) | |
153 | pr_warn("restoring timestamps failed(%d). ignored\n", err); | |
154 | } | |
155 | ||
156 | /* ---------------------------------------------------------------------- */ | |
157 | ||
158 | /* internal use only */ | |
159 | struct au_cpup_reg_attr { | |
160 | int valid; | |
161 | struct kstat st; | |
162 | unsigned int iflags; /* inode->i_flags */ | |
163 | }; | |
164 | ||
165 | static noinline_for_stack | |
166 | int cpup_iattr(struct dentry *dst, aufs_bindex_t bindex, struct dentry *h_src, | |
167 | struct au_cpup_reg_attr *h_src_attr) | |
168 | { | |
169 | int err, sbits, icex; | |
170 | unsigned int mnt_flags; | |
171 | unsigned char verbose; | |
172 | struct iattr ia; | |
173 | struct path h_path; | |
174 | struct inode *h_isrc, *h_idst; | |
175 | struct kstat *h_st; | |
176 | struct au_branch *br; | |
177 | ||
178 | h_path.dentry = au_h_dptr(dst, bindex); | |
179 | h_idst = d_inode(h_path.dentry); | |
180 | br = au_sbr(dst->d_sb, bindex); | |
181 | h_path.mnt = au_br_mnt(br); | |
182 | h_isrc = d_inode(h_src); | |
183 | ia.ia_valid = ATTR_FORCE | ATTR_UID | ATTR_GID | |
184 | | ATTR_ATIME | ATTR_MTIME | |
185 | | ATTR_ATIME_SET | ATTR_MTIME_SET; | |
186 | if (h_src_attr && h_src_attr->valid) { | |
187 | h_st = &h_src_attr->st; | |
188 | ia.ia_uid = h_st->uid; | |
189 | ia.ia_gid = h_st->gid; | |
190 | ia.ia_atime = h_st->atime; | |
191 | ia.ia_mtime = h_st->mtime; | |
192 | if (h_idst->i_mode != h_st->mode | |
193 | && !S_ISLNK(h_idst->i_mode)) { | |
194 | ia.ia_valid |= ATTR_MODE; | |
195 | ia.ia_mode = h_st->mode; | |
196 | } | |
197 | sbits = !!(h_st->mode & (S_ISUID | S_ISGID)); | |
198 | au_cpup_attr_flags(h_idst, h_src_attr->iflags); | |
199 | } else { | |
200 | ia.ia_uid = h_isrc->i_uid; | |
201 | ia.ia_gid = h_isrc->i_gid; | |
202 | ia.ia_atime = h_isrc->i_atime; | |
203 | ia.ia_mtime = h_isrc->i_mtime; | |
204 | if (h_idst->i_mode != h_isrc->i_mode | |
205 | && !S_ISLNK(h_idst->i_mode)) { | |
206 | ia.ia_valid |= ATTR_MODE; | |
207 | ia.ia_mode = h_isrc->i_mode; | |
208 | } | |
209 | sbits = !!(h_isrc->i_mode & (S_ISUID | S_ISGID)); | |
210 | au_cpup_attr_flags(h_idst, h_isrc->i_flags); | |
211 | } | |
212 | /* no delegation since it is just created */ | |
213 | err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL); | |
214 | ||
215 | /* is this nfs only? */ | |
216 | if (!err && sbits && au_test_nfs(h_path.dentry->d_sb)) { | |
217 | ia.ia_valid = ATTR_FORCE | ATTR_MODE; | |
218 | ia.ia_mode = h_isrc->i_mode; | |
219 | err = vfsub_notify_change(&h_path, &ia, /*delegated*/NULL); | |
220 | } | |
221 | ||
222 | icex = br->br_perm & AuBrAttr_ICEX; | |
223 | if (!err) { | |
224 | mnt_flags = au_mntflags(dst->d_sb); | |
225 | verbose = !!au_opt_test(mnt_flags, VERBOSE); | |
226 | err = au_cpup_xattr(h_path.dentry, h_src, icex, verbose); | |
227 | } | |
228 | ||
229 | return err; | |
230 | } | |
231 | ||
232 | /* ---------------------------------------------------------------------- */ | |
233 | ||
234 | static int au_do_copy_file(struct file *dst, struct file *src, loff_t len, | |
235 | char *buf, unsigned long blksize) | |
236 | { | |
237 | int err; | |
238 | size_t sz, rbytes, wbytes; | |
239 | unsigned char all_zero; | |
240 | char *p, *zp; | |
241 | struct inode *h_inode; | |
242 | /* reduce stack usage */ | |
243 | struct iattr *ia; | |
244 | ||
245 | zp = page_address(ZERO_PAGE(0)); | |
246 | if (unlikely(!zp)) | |
247 | return -ENOMEM; /* possible? */ | |
248 | ||
249 | err = 0; | |
250 | all_zero = 0; | |
251 | while (len) { | |
252 | AuDbg("len %lld\n", len); | |
253 | sz = blksize; | |
254 | if (len < blksize) | |
255 | sz = len; | |
256 | ||
257 | rbytes = 0; | |
258 | /* todo: signal_pending? */ | |
259 | while (!rbytes || err == -EAGAIN || err == -EINTR) { | |
260 | rbytes = vfsub_read_k(src, buf, sz, &src->f_pos); | |
261 | err = rbytes; | |
262 | } | |
263 | if (unlikely(err < 0)) | |
264 | break; | |
265 | ||
266 | all_zero = 0; | |
267 | if (len >= rbytes && rbytes == blksize) | |
268 | all_zero = !memcmp(buf, zp, rbytes); | |
269 | if (!all_zero) { | |
270 | wbytes = rbytes; | |
271 | p = buf; | |
272 | while (wbytes) { | |
273 | size_t b; | |
274 | ||
275 | b = vfsub_write_k(dst, p, wbytes, &dst->f_pos); | |
276 | err = b; | |
277 | /* todo: signal_pending? */ | |
278 | if (unlikely(err == -EAGAIN || err == -EINTR)) | |
279 | continue; | |
280 | if (unlikely(err < 0)) | |
281 | break; | |
282 | wbytes -= b; | |
283 | p += b; | |
284 | } | |
285 | if (unlikely(err < 0)) | |
286 | break; | |
287 | } else { | |
288 | loff_t res; | |
289 | ||
290 | AuLabel(hole); | |
291 | res = vfsub_llseek(dst, rbytes, SEEK_CUR); | |
292 | err = res; | |
293 | if (unlikely(res < 0)) | |
294 | break; | |
295 | } | |
296 | len -= rbytes; | |
297 | err = 0; | |
298 | } | |
299 | ||
300 | /* the last block may be a hole */ | |
301 | if (!err && all_zero) { | |
302 | AuLabel(last hole); | |
303 | ||
304 | err = 1; | |
305 | if (au_test_nfs(dst->f_path.dentry->d_sb)) { | |
306 | /* nfs requires this step to make last hole */ | |
307 | /* is this only nfs? */ | |
308 | do { | |
309 | /* todo: signal_pending? */ | |
310 | err = vfsub_write_k(dst, "\0", 1, &dst->f_pos); | |
311 | } while (err == -EAGAIN || err == -EINTR); | |
312 | if (err == 1) | |
313 | dst->f_pos--; | |
314 | } | |
315 | ||
316 | if (err == 1) { | |
317 | ia = (void *)buf; | |
318 | ia->ia_size = dst->f_pos; | |
319 | ia->ia_valid = ATTR_SIZE | ATTR_FILE; | |
320 | ia->ia_file = dst; | |
321 | h_inode = file_inode(dst); | |
322 | inode_lock_nested(h_inode, AuLsc_I_CHILD2); | |
323 | /* no delegation since it is just created */ | |
324 | err = vfsub_notify_change(&dst->f_path, ia, | |
325 | /*delegated*/NULL); | |
326 | inode_unlock(h_inode); | |
327 | } | |
328 | } | |
329 | ||
330 | return err; | |
331 | } | |
332 | ||
333 | int au_copy_file(struct file *dst, struct file *src, loff_t len) | |
334 | { | |
335 | int err; | |
336 | unsigned long blksize; | |
337 | unsigned char do_kfree; | |
338 | char *buf; | |
339 | ||
340 | err = -ENOMEM; | |
341 | blksize = dst->f_path.dentry->d_sb->s_blocksize; | |
342 | if (!blksize || PAGE_SIZE < blksize) | |
343 | blksize = PAGE_SIZE; | |
344 | AuDbg("blksize %lu\n", blksize); | |
345 | do_kfree = (blksize != PAGE_SIZE && blksize >= sizeof(struct iattr *)); | |
346 | if (do_kfree) | |
347 | buf = kmalloc(blksize, GFP_NOFS); | |
348 | else | |
349 | buf = (void *)__get_free_page(GFP_NOFS); | |
350 | if (unlikely(!buf)) | |
351 | goto out; | |
352 | ||
353 | if (len > (1 << 22)) | |
354 | AuDbg("copying a large file %lld\n", (long long)len); | |
355 | ||
356 | src->f_pos = 0; | |
357 | dst->f_pos = 0; | |
358 | err = au_do_copy_file(dst, src, len, buf, blksize); | |
359 | if (do_kfree) | |
360 | kfree(buf); | |
361 | else | |
362 | free_page((unsigned long)buf); | |
363 | ||
364 | out: | |
365 | return err; | |
366 | } | |
367 | ||
368 | static int au_do_copy(struct file *dst, struct file *src, loff_t len) | |
369 | { | |
370 | int err; | |
371 | struct super_block *h_src_sb; | |
372 | struct inode *h_src_inode; | |
373 | ||
374 | h_src_inode = file_inode(src); | |
375 | h_src_sb = h_src_inode->i_sb; | |
376 | ||
377 | /* XFS acquires inode_lock */ | |
378 | if (!au_test_xfs(h_src_sb)) | |
379 | err = au_copy_file(dst, src, len); | |
380 | else { | |
381 | inode_unlock_shared(h_src_inode); | |
382 | err = au_copy_file(dst, src, len); | |
383 | vfsub_inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); | |
384 | } | |
385 | ||
386 | return err; | |
387 | } | |
388 | ||
389 | static int au_clone_or_copy(struct file *dst, struct file *src, loff_t len) | |
390 | { | |
391 | int err; | |
392 | struct super_block *h_src_sb; | |
393 | struct inode *h_src_inode; | |
394 | ||
395 | h_src_inode = file_inode(src); | |
396 | h_src_sb = h_src_inode->i_sb; | |
397 | if (h_src_sb != file_inode(dst)->i_sb | |
398 | || !dst->f_op->clone_file_range) { | |
399 | err = au_do_copy(dst, src, len); | |
400 | goto out; | |
401 | } | |
402 | ||
403 | if (!au_test_nfs(h_src_sb)) { | |
404 | inode_unlock_shared(h_src_inode); | |
405 | err = vfsub_clone_file_range(src, dst, len); | |
406 | vfsub_inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); | |
407 | } else | |
408 | err = vfsub_clone_file_range(src, dst, len); | |
409 | /* older XFS has a condition in cloning */ | |
410 | if (unlikely(err != -EOPNOTSUPP)) | |
411 | goto out; | |
412 | ||
413 | /* the backend fs on NFS may not support cloning */ | |
414 | err = au_do_copy(dst, src, len); | |
415 | ||
416 | out: | |
417 | AuTraceErr(err); | |
418 | return err; | |
419 | } | |
420 | ||
421 | /* | |
422 | * to support a sparse file which is opened with O_APPEND, | |
423 | * we need to close the file. | |
424 | */ | |
425 | static int au_cp_regular(struct au_cp_generic *cpg) | |
426 | { | |
427 | int err, i; | |
428 | enum { SRC, DST }; | |
429 | struct { | |
430 | aufs_bindex_t bindex; | |
431 | unsigned int flags; | |
432 | struct dentry *dentry; | |
433 | int force_wr; | |
434 | struct file *file; | |
435 | void *label; | |
436 | } *f, file[] = { | |
437 | { | |
438 | .bindex = cpg->bsrc, | |
439 | .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, | |
440 | .label = &&out | |
441 | }, | |
442 | { | |
443 | .bindex = cpg->bdst, | |
444 | .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, | |
445 | .force_wr = !!au_ftest_cpup(cpg->flags, RWDST), | |
446 | .label = &&out_src | |
447 | } | |
448 | }; | |
449 | struct super_block *sb, *h_src_sb; | |
450 | struct inode *h_src_inode; | |
451 | struct task_struct *tsk = current; | |
452 | ||
453 | /* bsrc branch can be ro/rw. */ | |
454 | sb = cpg->dentry->d_sb; | |
455 | f = file; | |
456 | for (i = 0; i < 2; i++, f++) { | |
457 | f->dentry = au_h_dptr(cpg->dentry, f->bindex); | |
458 | f->file = au_h_open(cpg->dentry, f->bindex, f->flags, | |
459 | /*file*/NULL, f->force_wr); | |
460 | err = PTR_ERR(f->file); | |
461 | if (IS_ERR(f->file)) | |
462 | goto *f->label; | |
463 | } | |
464 | ||
465 | /* try stopping to update while we copyup */ | |
466 | h_src_inode = d_inode(file[SRC].dentry); | |
467 | h_src_sb = h_src_inode->i_sb; | |
468 | if (!au_test_nfs(h_src_sb)) | |
469 | IMustLock(h_src_inode); | |
470 | err = au_clone_or_copy(file[DST].file, file[SRC].file, cpg->len); | |
471 | ||
472 | /* i wonder if we had O_NO_DELAY_FPUT flag */ | |
473 | if (tsk->flags & PF_KTHREAD) | |
474 | __fput_sync(file[DST].file); | |
475 | else { | |
476 | /* it happend actually */ | |
477 | fput(file[DST].file); | |
478 | /* | |
479 | * too bad. | |
480 | * we have to call both since we don't know which place the file | |
481 | * was added to. | |
482 | */ | |
483 | task_work_run(); | |
484 | flush_delayed_fput(); | |
485 | } | |
486 | au_sbr_put(sb, file[DST].bindex); | |
487 | ||
488 | out_src: | |
489 | fput(file[SRC].file); | |
490 | au_sbr_put(sb, file[SRC].bindex); | |
491 | out: | |
492 | return err; | |
493 | } | |
494 | ||
495 | static int au_do_cpup_regular(struct au_cp_generic *cpg, | |
496 | struct au_cpup_reg_attr *h_src_attr) | |
497 | { | |
498 | int err, rerr; | |
499 | loff_t l; | |
500 | struct path h_path; | |
501 | struct inode *h_src_inode, *h_dst_inode; | |
502 | ||
503 | err = 0; | |
504 | h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc); | |
505 | l = i_size_read(h_src_inode); | |
506 | if (cpg->len == -1 || l < cpg->len) | |
507 | cpg->len = l; | |
508 | if (cpg->len) { | |
509 | /* try stopping to update while we are referencing */ | |
510 | vfsub_inode_lock_shared_nested(h_src_inode, AuLsc_I_CHILD); | |
511 | au_pin_hdir_unlock(cpg->pin); | |
512 | ||
513 | h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc); | |
514 | h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc); | |
515 | h_src_attr->iflags = h_src_inode->i_flags; | |
516 | if (!au_test_nfs(h_src_inode->i_sb)) | |
517 | err = vfsub_getattr(&h_path, &h_src_attr->st); | |
518 | else { | |
519 | inode_unlock_shared(h_src_inode); | |
520 | err = vfsub_getattr(&h_path, &h_src_attr->st); | |
521 | vfsub_inode_lock_shared_nested(h_src_inode, | |
522 | AuLsc_I_CHILD); | |
523 | } | |
524 | if (unlikely(err)) { | |
525 | inode_unlock_shared(h_src_inode); | |
526 | goto out; | |
527 | } | |
528 | h_src_attr->valid = 1; | |
529 | if (!au_test_nfs(h_src_inode->i_sb)) { | |
530 | err = au_cp_regular(cpg); | |
531 | inode_unlock_shared(h_src_inode); | |
532 | } else { | |
533 | inode_unlock_shared(h_src_inode); | |
534 | err = au_cp_regular(cpg); | |
535 | } | |
536 | rerr = au_pin_hdir_relock(cpg->pin); | |
537 | if (!err && rerr) | |
538 | err = rerr; | |
539 | } | |
540 | if (!err && (h_src_inode->i_state & I_LINKABLE)) { | |
541 | h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst); | |
542 | h_dst_inode = d_inode(h_path.dentry); | |
543 | spin_lock(&h_dst_inode->i_lock); | |
544 | h_dst_inode->i_state |= I_LINKABLE; | |
545 | spin_unlock(&h_dst_inode->i_lock); | |
546 | } | |
547 | ||
548 | out: | |
549 | return err; | |
550 | } | |
551 | ||
552 | static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src, | |
553 | struct inode *h_dir) | |
554 | { | |
555 | int err, symlen; | |
556 | mm_segment_t old_fs; | |
557 | union { | |
558 | char *k; | |
559 | char __user *u; | |
560 | } sym; | |
561 | ||
562 | err = -ENOMEM; | |
563 | sym.k = (void *)__get_free_page(GFP_NOFS); | |
564 | if (unlikely(!sym.k)) | |
565 | goto out; | |
566 | ||
567 | /* unnecessary to support mmap_sem since symlink is not mmap-able */ | |
568 | old_fs = get_fs(); | |
569 | set_fs(KERNEL_DS); | |
570 | symlen = vfs_readlink(h_src, sym.u, PATH_MAX); | |
571 | err = symlen; | |
572 | set_fs(old_fs); | |
573 | ||
574 | if (symlen > 0) { | |
575 | sym.k[symlen] = 0; | |
576 | err = vfsub_symlink(h_dir, h_path, sym.k); | |
577 | } | |
578 | free_page((unsigned long)sym.k); | |
579 | ||
580 | out: | |
581 | return err; | |
582 | } | |
583 | ||
584 | /* | |
585 | * regardless 'acl' option, reset all ACL. | |
586 | * All ACL will be copied up later from the original entry on the lower branch. | |
587 | */ | |
588 | static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode) | |
589 | { | |
590 | int err; | |
591 | struct dentry *h_dentry; | |
592 | struct inode *h_inode; | |
593 | ||
594 | h_dentry = h_path->dentry; | |
595 | h_inode = d_inode(h_dentry); | |
596 | /* forget_all_cached_acls(h_inode)); */ | |
597 | err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS); | |
598 | AuTraceErr(err); | |
599 | if (err == -EOPNOTSUPP) | |
600 | err = 0; | |
601 | if (!err) | |
602 | err = vfsub_acl_chmod(h_inode, mode); | |
603 | ||
604 | AuTraceErr(err); | |
605 | return err; | |
606 | } | |
607 | ||
608 | static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent, | |
609 | struct inode *h_dir, struct path *h_path) | |
610 | { | |
611 | int err; | |
612 | struct inode *dir, *inode; | |
613 | ||
614 | err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT); | |
615 | AuTraceErr(err); | |
616 | if (err == -EOPNOTSUPP) | |
617 | err = 0; | |
618 | if (unlikely(err)) | |
619 | goto out; | |
620 | ||
621 | /* | |
622 | * strange behaviour from the users view, | |
623 | * particularry setattr case | |
624 | */ | |
625 | dir = d_inode(dst_parent); | |
626 | if (au_ibtop(dir) == cpg->bdst) | |
627 | au_cpup_attr_nlink(dir, /*force*/1); | |
628 | inode = d_inode(cpg->dentry); | |
629 | au_cpup_attr_nlink(inode, /*force*/1); | |
630 | ||
631 | out: | |
632 | return err; | |
633 | } | |
634 | ||
635 | static noinline_for_stack | |
636 | int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent, | |
637 | struct au_cpup_reg_attr *h_src_attr) | |
638 | { | |
639 | int err; | |
640 | umode_t mode; | |
641 | unsigned int mnt_flags; | |
642 | unsigned char isdir, isreg, force; | |
643 | const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME); | |
644 | struct au_dtime dt; | |
645 | struct path h_path; | |
646 | struct dentry *h_src, *h_dst, *h_parent; | |
647 | struct inode *h_inode, *h_dir; | |
648 | struct super_block *sb; | |
649 | ||
650 | /* bsrc branch can be ro/rw. */ | |
651 | h_src = au_h_dptr(cpg->dentry, cpg->bsrc); | |
652 | h_inode = d_inode(h_src); | |
653 | AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc)); | |
654 | ||
655 | /* try stopping to be referenced while we are creating */ | |
656 | h_dst = au_h_dptr(cpg->dentry, cpg->bdst); | |
657 | if (au_ftest_cpup(cpg->flags, RENAME)) | |
658 | AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX, | |
659 | AUFS_WH_PFX_LEN)); | |
660 | h_parent = h_dst->d_parent; /* dir inode is locked */ | |
661 | h_dir = d_inode(h_parent); | |
662 | IMustLock(h_dir); | |
663 | AuDebugOn(h_parent != h_dst->d_parent); | |
664 | ||
665 | sb = cpg->dentry->d_sb; | |
666 | h_path.mnt = au_sbr_mnt(sb, cpg->bdst); | |
667 | if (do_dt) { | |
668 | h_path.dentry = h_parent; | |
669 | au_dtime_store(&dt, dst_parent, &h_path); | |
670 | } | |
671 | h_path.dentry = h_dst; | |
672 | ||
673 | isreg = 0; | |
674 | isdir = 0; | |
675 | mode = h_inode->i_mode; | |
676 | switch (mode & S_IFMT) { | |
677 | case S_IFREG: | |
678 | isreg = 1; | |
679 | err = vfsub_create(h_dir, &h_path, S_IRUSR | S_IWUSR, | |
680 | /*want_excl*/true); | |
681 | if (!err) | |
682 | err = au_do_cpup_regular(cpg, h_src_attr); | |
683 | break; | |
684 | case S_IFDIR: | |
685 | isdir = 1; | |
686 | err = vfsub_mkdir(h_dir, &h_path, mode); | |
687 | if (!err) | |
688 | err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path); | |
689 | break; | |
690 | case S_IFLNK: | |
691 | err = au_do_cpup_symlink(&h_path, h_src, h_dir); | |
692 | break; | |
693 | case S_IFCHR: | |
694 | case S_IFBLK: | |
695 | AuDebugOn(!capable(CAP_MKNOD)); | |
696 | /*FALLTHROUGH*/ | |
697 | case S_IFIFO: | |
698 | case S_IFSOCK: | |
699 | err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev); | |
700 | break; | |
701 | default: | |
702 | AuIOErr("Unknown inode type 0%o\n", mode); | |
703 | err = -EIO; | |
704 | } | |
705 | if (!err) | |
706 | err = au_reset_acl(h_dir, &h_path, mode); | |
707 | ||
708 | mnt_flags = au_mntflags(sb); | |
709 | if (!au_opt_test(mnt_flags, UDBA_NONE) | |
710 | && !isdir | |
711 | && au_opt_test(mnt_flags, XINO) | |
712 | && (h_inode->i_nlink == 1 | |
713 | || (h_inode->i_state & I_LINKABLE)) | |
714 | /* todo: unnecessary? */ | |
715 | /* && d_inode(cpg->dentry)->i_nlink == 1 */ | |
716 | && cpg->bdst < cpg->bsrc | |
717 | && !au_ftest_cpup(cpg->flags, KEEPLINO)) | |
718 | au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0); | |
719 | /* ignore this error */ | |
720 | ||
721 | if (!err) { | |
722 | force = 0; | |
723 | if (isreg) { | |
724 | force = !!cpg->len; | |
725 | if (cpg->len == -1) | |
726 | force = !!i_size_read(h_inode); | |
727 | } | |
728 | au_fhsm_wrote(sb, cpg->bdst, force); | |
729 | } | |
730 | ||
731 | if (do_dt) | |
732 | au_dtime_revert(&dt); | |
733 | return err; | |
734 | } | |
735 | ||
736 | static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path) | |
737 | { | |
738 | int err; | |
739 | struct dentry *dentry, *h_dentry, *h_parent, *parent; | |
740 | struct inode *h_dir; | |
741 | aufs_bindex_t bdst; | |
742 | ||
743 | dentry = cpg->dentry; | |
744 | bdst = cpg->bdst; | |
745 | h_dentry = au_h_dptr(dentry, bdst); | |
746 | if (!au_ftest_cpup(cpg->flags, OVERWRITE)) { | |
747 | dget(h_dentry); | |
748 | au_set_h_dptr(dentry, bdst, NULL); | |
749 | err = au_lkup_neg(dentry, bdst, /*wh*/0); | |
750 | if (!err) | |
751 | h_path->dentry = dget(au_h_dptr(dentry, bdst)); | |
752 | au_set_h_dptr(dentry, bdst, h_dentry); | |
753 | } else { | |
754 | err = 0; | |
755 | parent = dget_parent(dentry); | |
756 | h_parent = au_h_dptr(parent, bdst); | |
757 | dput(parent); | |
758 | h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent); | |
759 | if (IS_ERR(h_path->dentry)) | |
760 | err = PTR_ERR(h_path->dentry); | |
761 | } | |
762 | if (unlikely(err)) | |
763 | goto out; | |
764 | ||
765 | h_parent = h_dentry->d_parent; /* dir inode is locked */ | |
766 | h_dir = d_inode(h_parent); | |
767 | IMustLock(h_dir); | |
768 | AuDbg("%pd %pd\n", h_dentry, h_path->dentry); | |
769 | /* no delegation since it is just created */ | |
770 | err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL, | |
771 | /*flags*/0); | |
772 | dput(h_path->dentry); | |
773 | ||
774 | out: | |
775 | return err; | |
776 | } | |
777 | ||
778 | /* | |
779 | * copyup the @dentry from @bsrc to @bdst. | |
780 | * the caller must set the both of lower dentries. | |
781 | * @len is for truncating when it is -1 copyup the entire file. | |
782 | * in link/rename cases, @dst_parent may be different from the real one. | |
783 | * basic->bsrc can be larger than basic->bdst. | |
784 | * aufs doesn't touch the credential so | |
785 | * security_inode_copy_up{,_xattr}() are unnecrssary. | |
786 | */ | |
787 | static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) | |
788 | { | |
789 | int err, rerr; | |
790 | aufs_bindex_t old_ibtop; | |
791 | unsigned char isdir, plink; | |
792 | struct dentry *h_src, *h_dst, *h_parent; | |
793 | struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode; | |
794 | struct super_block *sb; | |
795 | struct au_branch *br; | |
796 | /* to reuduce stack size */ | |
797 | struct { | |
798 | struct au_dtime dt; | |
799 | struct path h_path; | |
800 | struct au_cpup_reg_attr h_src_attr; | |
801 | } *a; | |
802 | ||
803 | err = -ENOMEM; | |
804 | a = kmalloc(sizeof(*a), GFP_NOFS); | |
805 | if (unlikely(!a)) | |
806 | goto out; | |
807 | a->h_src_attr.valid = 0; | |
808 | ||
809 | sb = cpg->dentry->d_sb; | |
810 | br = au_sbr(sb, cpg->bdst); | |
811 | a->h_path.mnt = au_br_mnt(br); | |
812 | h_dst = au_h_dptr(cpg->dentry, cpg->bdst); | |
813 | h_parent = h_dst->d_parent; /* dir inode is locked */ | |
814 | h_dir = d_inode(h_parent); | |
815 | IMustLock(h_dir); | |
816 | ||
817 | h_src = au_h_dptr(cpg->dentry, cpg->bsrc); | |
818 | inode = d_inode(cpg->dentry); | |
819 | ||
820 | if (!dst_parent) | |
821 | dst_parent = dget_parent(cpg->dentry); | |
822 | else | |
823 | dget(dst_parent); | |
824 | ||
825 | plink = !!au_opt_test(au_mntflags(sb), PLINK); | |
826 | dst_inode = au_h_iptr(inode, cpg->bdst); | |
827 | if (dst_inode) { | |
828 | if (unlikely(!plink)) { | |
829 | err = -EIO; | |
830 | AuIOErr("hi%lu(i%lu) exists on b%d " | |
831 | "but plink is disabled\n", | |
832 | dst_inode->i_ino, inode->i_ino, cpg->bdst); | |
833 | goto out_parent; | |
834 | } | |
835 | ||
836 | if (dst_inode->i_nlink) { | |
837 | const int do_dt = au_ftest_cpup(cpg->flags, DTIME); | |
838 | ||
839 | h_src = au_plink_lkup(inode, cpg->bdst); | |
840 | err = PTR_ERR(h_src); | |
841 | if (IS_ERR(h_src)) | |
842 | goto out_parent; | |
843 | if (unlikely(d_is_negative(h_src))) { | |
844 | err = -EIO; | |
845 | AuIOErr("i%lu exists on b%d " | |
846 | "but not pseudo-linked\n", | |
847 | inode->i_ino, cpg->bdst); | |
848 | dput(h_src); | |
849 | goto out_parent; | |
850 | } | |
851 | ||
852 | if (do_dt) { | |
853 | a->h_path.dentry = h_parent; | |
854 | au_dtime_store(&a->dt, dst_parent, &a->h_path); | |
855 | } | |
856 | ||
857 | a->h_path.dentry = h_dst; | |
858 | delegated = NULL; | |
859 | err = vfsub_link(h_src, h_dir, &a->h_path, &delegated); | |
860 | if (!err && au_ftest_cpup(cpg->flags, RENAME)) | |
861 | err = au_do_ren_after_cpup(cpg, &a->h_path); | |
862 | if (do_dt) | |
863 | au_dtime_revert(&a->dt); | |
864 | if (unlikely(err == -EWOULDBLOCK)) { | |
865 | pr_warn("cannot retry for NFSv4 delegation" | |
866 | " for an internal link\n"); | |
867 | iput(delegated); | |
868 | } | |
869 | dput(h_src); | |
870 | goto out_parent; | |
871 | } else | |
872 | /* todo: cpup_wh_file? */ | |
873 | /* udba work */ | |
874 | au_update_ibrange(inode, /*do_put_zero*/1); | |
875 | } | |
876 | ||
877 | isdir = S_ISDIR(inode->i_mode); | |
878 | old_ibtop = au_ibtop(inode); | |
879 | err = cpup_entry(cpg, dst_parent, &a->h_src_attr); | |
880 | if (unlikely(err)) | |
881 | goto out_rev; | |
882 | dst_inode = d_inode(h_dst); | |
883 | inode_lock_nested(dst_inode, AuLsc_I_CHILD2); | |
884 | /* todo: necessary? */ | |
885 | /* au_pin_hdir_unlock(cpg->pin); */ | |
886 | ||
887 | err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr); | |
888 | if (unlikely(err)) { | |
889 | /* todo: necessary? */ | |
890 | /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */ | |
891 | inode_unlock(dst_inode); | |
892 | goto out_rev; | |
893 | } | |
894 | ||
895 | if (cpg->bdst < old_ibtop) { | |
896 | if (S_ISREG(inode->i_mode)) { | |
897 | err = au_dy_iaop(inode, cpg->bdst, dst_inode); | |
898 | if (unlikely(err)) { | |
899 | /* ignore an error */ | |
900 | /* au_pin_hdir_relock(cpg->pin); */ | |
901 | inode_unlock(dst_inode); | |
902 | goto out_rev; | |
903 | } | |
904 | } | |
905 | au_set_ibtop(inode, cpg->bdst); | |
906 | } else | |
907 | au_set_ibbot(inode, cpg->bdst); | |
908 | au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode), | |
909 | au_hi_flags(inode, isdir)); | |
910 | ||
911 | /* todo: necessary? */ | |
912 | /* err = au_pin_hdir_relock(cpg->pin); */ | |
913 | inode_unlock(dst_inode); | |
914 | if (unlikely(err)) | |
915 | goto out_rev; | |
916 | ||
917 | src_inode = d_inode(h_src); | |
918 | if (!isdir | |
919 | && (src_inode->i_nlink > 1 | |
920 | || src_inode->i_state & I_LINKABLE) | |
921 | && plink) | |
922 | au_plink_append(inode, cpg->bdst, h_dst); | |
923 | ||
924 | if (au_ftest_cpup(cpg->flags, RENAME)) { | |
925 | a->h_path.dentry = h_dst; | |
926 | err = au_do_ren_after_cpup(cpg, &a->h_path); | |
927 | } | |
928 | if (!err) | |
929 | goto out_parent; /* success */ | |
930 | ||
931 | /* revert */ | |
932 | out_rev: | |
933 | a->h_path.dentry = h_parent; | |
934 | au_dtime_store(&a->dt, dst_parent, &a->h_path); | |
935 | a->h_path.dentry = h_dst; | |
936 | rerr = 0; | |
937 | if (d_is_positive(h_dst)) { | |
938 | if (!isdir) { | |
939 | /* no delegation since it is just created */ | |
940 | rerr = vfsub_unlink(h_dir, &a->h_path, | |
941 | /*delegated*/NULL, /*force*/0); | |
942 | } else | |
943 | rerr = vfsub_rmdir(h_dir, &a->h_path); | |
944 | } | |
945 | au_dtime_revert(&a->dt); | |
946 | if (rerr) { | |
947 | AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); | |
948 | err = -EIO; | |
949 | } | |
950 | out_parent: | |
951 | dput(dst_parent); | |
952 | kfree(a); | |
953 | out: | |
954 | return err; | |
955 | } | |
956 | ||
957 | #if 0 /* reserved */ | |
958 | struct au_cpup_single_args { | |
959 | int *errp; | |
960 | struct au_cp_generic *cpg; | |
961 | struct dentry *dst_parent; | |
962 | }; | |
963 | ||
964 | static void au_call_cpup_single(void *args) | |
965 | { | |
966 | struct au_cpup_single_args *a = args; | |
967 | ||
968 | au_pin_hdir_acquire_nest(a->cpg->pin); | |
969 | *a->errp = au_cpup_single(a->cpg, a->dst_parent); | |
970 | au_pin_hdir_release(a->cpg->pin); | |
971 | } | |
972 | #endif | |
973 | ||
974 | /* | |
975 | * prevent SIGXFSZ in copy-up. | |
976 | * testing CAP_MKNOD is for generic fs, | |
977 | * but CAP_FSETID is for xfs only, currently. | |
978 | */ | |
979 | static int au_cpup_sio_test(struct au_pin *pin, umode_t mode) | |
980 | { | |
981 | int do_sio; | |
982 | struct super_block *sb; | |
983 | struct inode *h_dir; | |
984 | ||
985 | do_sio = 0; | |
986 | sb = au_pinned_parent(pin)->d_sb; | |
987 | if (!au_wkq_test() | |
988 | && (!au_sbi(sb)->si_plink_maint_pid | |
989 | || au_plink_maint(sb, AuLock_NOPLM))) { | |
990 | switch (mode & S_IFMT) { | |
991 | case S_IFREG: | |
992 | /* no condition about RLIMIT_FSIZE and the file size */ | |
993 | do_sio = 1; | |
994 | break; | |
995 | case S_IFCHR: | |
996 | case S_IFBLK: | |
997 | do_sio = !capable(CAP_MKNOD); | |
998 | break; | |
999 | } | |
1000 | if (!do_sio) | |
1001 | do_sio = ((mode & (S_ISUID | S_ISGID)) | |
1002 | && !capable(CAP_FSETID)); | |
1003 | /* this workaround may be removed in the future */ | |
1004 | if (!do_sio) { | |
1005 | h_dir = au_pinned_h_dir(pin); | |
1006 | do_sio = h_dir->i_mode & S_ISVTX; | |
1007 | } | |
1008 | } | |
1009 | ||
1010 | return do_sio; | |
1011 | } | |
1012 | ||
1013 | #if 0 /* reserved */ | |
1014 | int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) | |
1015 | { | |
1016 | int err, wkq_err; | |
1017 | struct dentry *h_dentry; | |
1018 | ||
1019 | h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc); | |
1020 | if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode)) | |
1021 | err = au_cpup_single(cpg, dst_parent); | |
1022 | else { | |
1023 | struct au_cpup_single_args args = { | |
1024 | .errp = &err, | |
1025 | .cpg = cpg, | |
1026 | .dst_parent = dst_parent | |
1027 | }; | |
1028 | wkq_err = au_wkq_wait(au_call_cpup_single, &args); | |
1029 | if (unlikely(wkq_err)) | |
1030 | err = wkq_err; | |
1031 | } | |
1032 | ||
1033 | return err; | |
1034 | } | |
1035 | #endif | |
1036 | ||
1037 | /* | |
1038 | * copyup the @dentry from the first active lower branch to @bdst, | |
1039 | * using au_cpup_single(). | |
1040 | */ | |
1041 | static int au_cpup_simple(struct au_cp_generic *cpg) | |
1042 | { | |
1043 | int err; | |
1044 | unsigned int flags_orig; | |
1045 | struct dentry *dentry; | |
1046 | ||
1047 | AuDebugOn(cpg->bsrc < 0); | |
1048 | ||
1049 | dentry = cpg->dentry; | |
1050 | DiMustWriteLock(dentry); | |
1051 | ||
1052 | err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1); | |
1053 | if (!err) { | |
1054 | flags_orig = cpg->flags; | |
1055 | au_fset_cpup(cpg->flags, RENAME); | |
1056 | err = au_cpup_single(cpg, NULL); | |
1057 | cpg->flags = flags_orig; | |
1058 | if (!err) | |
1059 | return 0; /* success */ | |
1060 | ||
1061 | /* revert */ | |
1062 | au_set_h_dptr(dentry, cpg->bdst, NULL); | |
1063 | au_set_dbtop(dentry, cpg->bsrc); | |
1064 | } | |
1065 | ||
1066 | return err; | |
1067 | } | |
1068 | ||
1069 | struct au_cpup_simple_args { | |
1070 | int *errp; | |
1071 | struct au_cp_generic *cpg; | |
1072 | }; | |
1073 | ||
1074 | static void au_call_cpup_simple(void *args) | |
1075 | { | |
1076 | struct au_cpup_simple_args *a = args; | |
1077 | ||
1078 | au_pin_hdir_acquire_nest(a->cpg->pin); | |
1079 | *a->errp = au_cpup_simple(a->cpg); | |
1080 | au_pin_hdir_release(a->cpg->pin); | |
1081 | } | |
1082 | ||
1083 | static int au_do_sio_cpup_simple(struct au_cp_generic *cpg) | |
1084 | { | |
1085 | int err, wkq_err; | |
1086 | struct dentry *dentry, *parent; | |
1087 | struct file *h_file; | |
1088 | struct inode *h_dir; | |
1089 | ||
1090 | dentry = cpg->dentry; | |
1091 | h_file = NULL; | |
1092 | if (au_ftest_cpup(cpg->flags, HOPEN)) { | |
1093 | AuDebugOn(cpg->bsrc < 0); | |
1094 | h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0); | |
1095 | err = PTR_ERR(h_file); | |
1096 | if (IS_ERR(h_file)) | |
1097 | goto out; | |
1098 | } | |
1099 | ||
1100 | parent = dget_parent(dentry); | |
1101 | h_dir = au_h_iptr(d_inode(parent), cpg->bdst); | |
1102 | if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE) | |
1103 | && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) | |
1104 | err = au_cpup_simple(cpg); | |
1105 | else { | |
1106 | struct au_cpup_simple_args args = { | |
1107 | .errp = &err, | |
1108 | .cpg = cpg | |
1109 | }; | |
1110 | wkq_err = au_wkq_wait(au_call_cpup_simple, &args); | |
1111 | if (unlikely(wkq_err)) | |
1112 | err = wkq_err; | |
1113 | } | |
1114 | ||
1115 | dput(parent); | |
1116 | if (h_file) | |
1117 | au_h_open_post(dentry, cpg->bsrc, h_file); | |
1118 | ||
1119 | out: | |
1120 | return err; | |
1121 | } | |
1122 | ||
1123 | int au_sio_cpup_simple(struct au_cp_generic *cpg) | |
1124 | { | |
1125 | aufs_bindex_t bsrc, bbot; | |
1126 | struct dentry *dentry, *h_dentry; | |
1127 | ||
1128 | if (cpg->bsrc < 0) { | |
1129 | dentry = cpg->dentry; | |
1130 | bbot = au_dbbot(dentry); | |
1131 | for (bsrc = cpg->bdst + 1; bsrc <= bbot; bsrc++) { | |
1132 | h_dentry = au_h_dptr(dentry, bsrc); | |
1133 | if (h_dentry) { | |
1134 | AuDebugOn(d_is_negative(h_dentry)); | |
1135 | break; | |
1136 | } | |
1137 | } | |
1138 | AuDebugOn(bsrc > bbot); | |
1139 | cpg->bsrc = bsrc; | |
1140 | } | |
1141 | AuDebugOn(cpg->bsrc <= cpg->bdst); | |
1142 | return au_do_sio_cpup_simple(cpg); | |
1143 | } | |
1144 | ||
1145 | int au_sio_cpdown_simple(struct au_cp_generic *cpg) | |
1146 | { | |
1147 | AuDebugOn(cpg->bdst <= cpg->bsrc); | |
1148 | return au_do_sio_cpup_simple(cpg); | |
1149 | } | |
1150 | ||
1151 | /* ---------------------------------------------------------------------- */ | |
1152 | ||
1153 | /* | |
1154 | * copyup the deleted file for writing. | |
1155 | */ | |
1156 | static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry, | |
1157 | struct file *file) | |
1158 | { | |
1159 | int err; | |
1160 | unsigned int flags_orig; | |
1161 | aufs_bindex_t bsrc_orig; | |
1162 | struct au_dinfo *dinfo; | |
1163 | struct { | |
1164 | struct au_hdentry *hd; | |
1165 | struct dentry *h_dentry; | |
1166 | } hdst, hsrc; | |
1167 | ||
1168 | dinfo = au_di(cpg->dentry); | |
1169 | AuRwMustWriteLock(&dinfo->di_rwsem); | |
1170 | ||
1171 | bsrc_orig = cpg->bsrc; | |
1172 | cpg->bsrc = dinfo->di_btop; | |
1173 | hdst.hd = au_hdentry(dinfo, cpg->bdst); | |
1174 | hdst.h_dentry = hdst.hd->hd_dentry; | |
1175 | hdst.hd->hd_dentry = wh_dentry; | |
1176 | dinfo->di_btop = cpg->bdst; | |
1177 | ||
1178 | hsrc.h_dentry = NULL; | |
1179 | if (file) { | |
1180 | hsrc.hd = au_hdentry(dinfo, cpg->bsrc); | |
1181 | hsrc.h_dentry = hsrc.hd->hd_dentry; | |
1182 | hsrc.hd->hd_dentry = au_hf_top(file)->f_path.dentry; | |
1183 | } | |
1184 | flags_orig = cpg->flags; | |
1185 | cpg->flags = !AuCpup_DTIME; | |
1186 | err = au_cpup_single(cpg, /*h_parent*/NULL); | |
1187 | cpg->flags = flags_orig; | |
1188 | if (file) { | |
1189 | if (!err) | |
1190 | err = au_reopen_nondir(file); | |
1191 | hsrc.hd->hd_dentry = hsrc.h_dentry; | |
1192 | } | |
1193 | hdst.hd->hd_dentry = hdst.h_dentry; | |
1194 | dinfo->di_btop = cpg->bsrc; | |
1195 | cpg->bsrc = bsrc_orig; | |
1196 | ||
1197 | return err; | |
1198 | } | |
1199 | ||
1200 | static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file) | |
1201 | { | |
1202 | int err; | |
1203 | aufs_bindex_t bdst; | |
1204 | struct au_dtime dt; | |
1205 | struct dentry *dentry, *parent, *h_parent, *wh_dentry; | |
1206 | struct au_branch *br; | |
1207 | struct path h_path; | |
1208 | ||
1209 | dentry = cpg->dentry; | |
1210 | bdst = cpg->bdst; | |
1211 | br = au_sbr(dentry->d_sb, bdst); | |
1212 | parent = dget_parent(dentry); | |
1213 | h_parent = au_h_dptr(parent, bdst); | |
1214 | wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); | |
1215 | err = PTR_ERR(wh_dentry); | |
1216 | if (IS_ERR(wh_dentry)) | |
1217 | goto out; | |
1218 | ||
1219 | h_path.dentry = h_parent; | |
1220 | h_path.mnt = au_br_mnt(br); | |
1221 | au_dtime_store(&dt, parent, &h_path); | |
1222 | err = au_do_cpup_wh(cpg, wh_dentry, file); | |
1223 | if (unlikely(err)) | |
1224 | goto out_wh; | |
1225 | ||
1226 | dget(wh_dentry); | |
1227 | h_path.dentry = wh_dentry; | |
1228 | if (!d_is_dir(wh_dentry)) { | |
1229 | /* no delegation since it is just created */ | |
1230 | err = vfsub_unlink(d_inode(h_parent), &h_path, | |
1231 | /*delegated*/NULL, /*force*/0); | |
1232 | } else | |
1233 | err = vfsub_rmdir(d_inode(h_parent), &h_path); | |
1234 | if (unlikely(err)) { | |
1235 | AuIOErr("failed remove copied-up tmp file %pd(%d)\n", | |
1236 | wh_dentry, err); | |
1237 | err = -EIO; | |
1238 | } | |
1239 | au_dtime_revert(&dt); | |
1240 | au_set_hi_wh(d_inode(dentry), bdst, wh_dentry); | |
1241 | ||
1242 | out_wh: | |
1243 | dput(wh_dentry); | |
1244 | out: | |
1245 | dput(parent); | |
1246 | return err; | |
1247 | } | |
1248 | ||
1249 | struct au_cpup_wh_args { | |
1250 | int *errp; | |
1251 | struct au_cp_generic *cpg; | |
1252 | struct file *file; | |
1253 | }; | |
1254 | ||
1255 | static void au_call_cpup_wh(void *args) | |
1256 | { | |
1257 | struct au_cpup_wh_args *a = args; | |
1258 | ||
1259 | au_pin_hdir_acquire_nest(a->cpg->pin); | |
1260 | *a->errp = au_cpup_wh(a->cpg, a->file); | |
1261 | au_pin_hdir_release(a->cpg->pin); | |
1262 | } | |
1263 | ||
1264 | int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file) | |
1265 | { | |
1266 | int err, wkq_err; | |
1267 | aufs_bindex_t bdst; | |
1268 | struct dentry *dentry, *parent, *h_orph, *h_parent; | |
1269 | struct inode *dir, *h_dir, *h_tmpdir; | |
1270 | struct au_wbr *wbr; | |
1271 | struct au_pin wh_pin, *pin_orig; | |
1272 | ||
1273 | dentry = cpg->dentry; | |
1274 | bdst = cpg->bdst; | |
1275 | parent = dget_parent(dentry); | |
1276 | dir = d_inode(parent); | |
1277 | h_orph = NULL; | |
1278 | h_parent = NULL; | |
1279 | h_dir = au_igrab(au_h_iptr(dir, bdst)); | |
1280 | h_tmpdir = h_dir; | |
1281 | pin_orig = NULL; | |
1282 | if (!h_dir->i_nlink) { | |
1283 | wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; | |
1284 | h_orph = wbr->wbr_orph; | |
1285 | ||
1286 | h_parent = dget(au_h_dptr(parent, bdst)); | |
1287 | au_set_h_dptr(parent, bdst, dget(h_orph)); | |
1288 | h_tmpdir = d_inode(h_orph); | |
1289 | au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); | |
1290 | ||
1291 | inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3); | |
1292 | /* todo: au_h_open_pre()? */ | |
1293 | ||
1294 | pin_orig = cpg->pin; | |
1295 | au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT, | |
1296 | AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED); | |
1297 | cpg->pin = &wh_pin; | |
1298 | } | |
1299 | ||
1300 | if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE) | |
1301 | && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) | |
1302 | err = au_cpup_wh(cpg, file); | |
1303 | else { | |
1304 | struct au_cpup_wh_args args = { | |
1305 | .errp = &err, | |
1306 | .cpg = cpg, | |
1307 | .file = file | |
1308 | }; | |
1309 | wkq_err = au_wkq_wait(au_call_cpup_wh, &args); | |
1310 | if (unlikely(wkq_err)) | |
1311 | err = wkq_err; | |
1312 | } | |
1313 | ||
1314 | if (h_orph) { | |
1315 | inode_unlock(h_tmpdir); | |
1316 | /* todo: au_h_open_post()? */ | |
1317 | au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); | |
1318 | au_set_h_dptr(parent, bdst, h_parent); | |
1319 | AuDebugOn(!pin_orig); | |
1320 | cpg->pin = pin_orig; | |
1321 | } | |
1322 | iput(h_dir); | |
1323 | dput(parent); | |
1324 | ||
1325 | return err; | |
1326 | } | |
1327 | ||
1328 | /* ---------------------------------------------------------------------- */ | |
1329 | ||
1330 | /* | |
1331 | * generic routine for both of copy-up and copy-down. | |
1332 | */ | |
1333 | /* cf. revalidate function in file.c */ | |
1334 | int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, | |
1335 | int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, | |
1336 | struct au_pin *pin, | |
1337 | struct dentry *h_parent, void *arg), | |
1338 | void *arg) | |
1339 | { | |
1340 | int err; | |
1341 | struct au_pin pin; | |
1342 | struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry; | |
1343 | ||
1344 | err = 0; | |
1345 | parent = dget_parent(dentry); | |
1346 | if (IS_ROOT(parent)) | |
1347 | goto out; | |
1348 | ||
1349 | au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2, | |
1350 | au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE); | |
1351 | ||
1352 | /* do not use au_dpage */ | |
1353 | real_parent = parent; | |
1354 | while (1) { | |
1355 | dput(parent); | |
1356 | parent = dget_parent(dentry); | |
1357 | h_parent = au_h_dptr(parent, bdst); | |
1358 | if (h_parent) | |
1359 | goto out; /* success */ | |
1360 | ||
1361 | /* find top dir which is necessary to cpup */ | |
1362 | do { | |
1363 | d = parent; | |
1364 | dput(parent); | |
1365 | parent = dget_parent(d); | |
1366 | di_read_lock_parent3(parent, !AuLock_IR); | |
1367 | h_parent = au_h_dptr(parent, bdst); | |
1368 | di_read_unlock(parent, !AuLock_IR); | |
1369 | } while (!h_parent); | |
1370 | ||
1371 | if (d != real_parent) | |
1372 | di_write_lock_child3(d); | |
1373 | ||
1374 | /* somebody else might create while we were sleeping */ | |
1375 | h_dentry = au_h_dptr(d, bdst); | |
1376 | if (!h_dentry || d_is_negative(h_dentry)) { | |
1377 | if (h_dentry) | |
1378 | au_update_dbtop(d); | |
1379 | ||
1380 | au_pin_set_dentry(&pin, d); | |
1381 | err = au_do_pin(&pin); | |
1382 | if (!err) { | |
1383 | err = cp(d, bdst, &pin, h_parent, arg); | |
1384 | au_unpin(&pin); | |
1385 | } | |
1386 | } | |
1387 | ||
1388 | if (d != real_parent) | |
1389 | di_write_unlock(d); | |
1390 | if (unlikely(err)) | |
1391 | break; | |
1392 | } | |
1393 | ||
1394 | out: | |
1395 | dput(parent); | |
1396 | return err; | |
1397 | } | |
1398 | ||
1399 | static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst, | |
1400 | struct au_pin *pin, | |
1401 | struct dentry *h_parent __maybe_unused, | |
1402 | void *arg __maybe_unused) | |
1403 | { | |
1404 | struct au_cp_generic cpg = { | |
1405 | .dentry = dentry, | |
1406 | .bdst = bdst, | |
1407 | .bsrc = -1, | |
1408 | .len = 0, | |
1409 | .pin = pin, | |
1410 | .flags = AuCpup_DTIME | |
1411 | }; | |
1412 | return au_sio_cpup_simple(&cpg); | |
1413 | } | |
1414 | ||
1415 | int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) | |
1416 | { | |
1417 | return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL); | |
1418 | } | |
1419 | ||
1420 | int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) | |
1421 | { | |
1422 | int err; | |
1423 | struct dentry *parent; | |
1424 | struct inode *dir; | |
1425 | ||
1426 | parent = dget_parent(dentry); | |
1427 | dir = d_inode(parent); | |
1428 | err = 0; | |
1429 | if (au_h_iptr(dir, bdst)) | |
1430 | goto out; | |
1431 | ||
1432 | di_read_unlock(parent, AuLock_IR); | |
1433 | di_write_lock_parent(parent); | |
1434 | /* someone else might change our inode while we were sleeping */ | |
1435 | if (!au_h_iptr(dir, bdst)) | |
1436 | err = au_cpup_dirs(dentry, bdst); | |
1437 | di_downgrade_lock(parent, AuLock_IR); | |
1438 | ||
1439 | out: | |
1440 | dput(parent); | |
1441 | return err; | |
1442 | } |