]>
Commit | Line | Data |
---|---|---|
e14748e8 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 | * 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 | au_delayed_kfree(buf); | |
361 | else | |
362 | au_delayed_free_page((unsigned long)buf); | |
363 | ||
364 | out: | |
365 | return err; | |
366 | } | |
367 | ||
368 | /* | |
369 | * to support a sparse file which is opened with O_APPEND, | |
370 | * we need to close the file. | |
371 | */ | |
372 | static int au_cp_regular(struct au_cp_generic *cpg) | |
373 | { | |
374 | int err, i; | |
375 | enum { SRC, DST }; | |
376 | struct { | |
377 | aufs_bindex_t bindex; | |
378 | unsigned int flags; | |
379 | struct dentry *dentry; | |
380 | int force_wr; | |
381 | struct file *file; | |
382 | void *label; | |
383 | } *f, file[] = { | |
384 | { | |
385 | .bindex = cpg->bsrc, | |
386 | .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, | |
387 | .label = &&out | |
388 | }, | |
389 | { | |
390 | .bindex = cpg->bdst, | |
391 | .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, | |
392 | .force_wr = !!au_ftest_cpup(cpg->flags, RWDST), | |
393 | .label = &&out_src | |
394 | } | |
395 | }; | |
396 | struct super_block *sb; | |
397 | struct inode *h_src_inode; | |
398 | struct task_struct *tsk = current; | |
399 | ||
400 | /* bsrc branch can be ro/rw. */ | |
401 | sb = cpg->dentry->d_sb; | |
402 | f = file; | |
403 | for (i = 0; i < 2; i++, f++) { | |
404 | f->dentry = au_h_dptr(cpg->dentry, f->bindex); | |
405 | f->file = au_h_open(cpg->dentry, f->bindex, f->flags, | |
406 | /*file*/NULL, f->force_wr); | |
407 | err = PTR_ERR(f->file); | |
408 | if (IS_ERR(f->file)) | |
409 | goto *f->label; | |
410 | } | |
411 | ||
412 | /* try stopping to update while we copyup */ | |
413 | h_src_inode = d_inode(file[SRC].dentry); | |
414 | if (!au_test_nfs(h_src_inode->i_sb)) | |
415 | IMustLock(h_src_inode); | |
416 | err = au_copy_file(file[DST].file, file[SRC].file, cpg->len); | |
417 | ||
418 | /* i wonder if we had O_NO_DELAY_FPUT flag */ | |
419 | if (tsk->flags & PF_KTHREAD) | |
420 | __fput_sync(file[DST].file); | |
421 | else { | |
422 | WARN(1, "%pD\nPlease report this warning to aufs-users ML", | |
423 | file[DST].file); | |
424 | fput(file[DST].file); | |
425 | /* | |
426 | * too bad. | |
427 | * we have to call both since we don't know which place the file | |
428 | * was added to. | |
429 | */ | |
430 | task_work_run(); | |
431 | flush_delayed_fput(); | |
432 | } | |
433 | au_sbr_put(sb, file[DST].bindex); | |
434 | ||
435 | out_src: | |
436 | fput(file[SRC].file); | |
437 | au_sbr_put(sb, file[SRC].bindex); | |
438 | out: | |
439 | return err; | |
440 | } | |
441 | ||
442 | static int au_do_cpup_regular(struct au_cp_generic *cpg, | |
443 | struct au_cpup_reg_attr *h_src_attr) | |
444 | { | |
445 | int err, rerr; | |
446 | loff_t l; | |
447 | struct path h_path; | |
448 | struct inode *h_src_inode, *h_dst_inode; | |
449 | ||
450 | err = 0; | |
451 | h_src_inode = au_h_iptr(d_inode(cpg->dentry), cpg->bsrc); | |
452 | l = i_size_read(h_src_inode); | |
453 | if (cpg->len == -1 || l < cpg->len) | |
454 | cpg->len = l; | |
455 | if (cpg->len) { | |
456 | /* try stopping to update while we are referencing */ | |
457 | inode_lock_nested(h_src_inode, AuLsc_I_CHILD); | |
458 | au_pin_hdir_unlock(cpg->pin); | |
459 | ||
460 | h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc); | |
461 | h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc); | |
462 | h_src_attr->iflags = h_src_inode->i_flags; | |
463 | if (!au_test_nfs(h_src_inode->i_sb)) | |
464 | err = vfs_getattr(&h_path, &h_src_attr->st); | |
465 | else { | |
466 | inode_unlock(h_src_inode); | |
467 | err = vfs_getattr(&h_path, &h_src_attr->st); | |
468 | inode_lock_nested(h_src_inode, AuLsc_I_CHILD); | |
469 | } | |
470 | if (unlikely(err)) { | |
471 | inode_unlock(h_src_inode); | |
472 | goto out; | |
473 | } | |
474 | h_src_attr->valid = 1; | |
475 | if (!au_test_nfs(h_src_inode->i_sb)) { | |
476 | err = au_cp_regular(cpg); | |
477 | inode_unlock(h_src_inode); | |
478 | } else { | |
479 | inode_unlock(h_src_inode); | |
480 | err = au_cp_regular(cpg); | |
481 | } | |
482 | rerr = au_pin_hdir_relock(cpg->pin); | |
483 | if (!err && rerr) | |
484 | err = rerr; | |
485 | } | |
486 | if (!err && (h_src_inode->i_state & I_LINKABLE)) { | |
487 | h_path.dentry = au_h_dptr(cpg->dentry, cpg->bdst); | |
488 | h_dst_inode = d_inode(h_path.dentry); | |
489 | spin_lock(&h_dst_inode->i_lock); | |
490 | h_dst_inode->i_state |= I_LINKABLE; | |
491 | spin_unlock(&h_dst_inode->i_lock); | |
492 | } | |
493 | ||
494 | out: | |
495 | return err; | |
496 | } | |
497 | ||
498 | static int au_do_cpup_symlink(struct path *h_path, struct dentry *h_src, | |
499 | struct inode *h_dir) | |
500 | { | |
501 | int err, symlen; | |
502 | mm_segment_t old_fs; | |
503 | union { | |
504 | char *k; | |
505 | char __user *u; | |
506 | } sym; | |
507 | ||
508 | err = -ENOMEM; | |
509 | sym.k = (void *)__get_free_page(GFP_NOFS); | |
510 | if (unlikely(!sym.k)) | |
511 | goto out; | |
512 | ||
513 | /* unnecessary to support mmap_sem since symlink is not mmap-able */ | |
514 | old_fs = get_fs(); | |
515 | set_fs(KERNEL_DS); | |
516 | symlen = vfs_readlink(h_src, sym.u, PATH_MAX); | |
517 | err = symlen; | |
518 | set_fs(old_fs); | |
519 | ||
520 | if (symlen > 0) { | |
521 | sym.k[symlen] = 0; | |
522 | err = vfsub_symlink(h_dir, h_path, sym.k); | |
523 | } | |
524 | au_delayed_free_page((unsigned long)sym.k); | |
525 | ||
526 | out: | |
527 | return err; | |
528 | } | |
529 | ||
530 | /* | |
531 | * regardless 'acl' option, reset all ACL. | |
532 | * All ACL will be copied up later from the original entry on the lower branch. | |
533 | */ | |
534 | static int au_reset_acl(struct inode *h_dir, struct path *h_path, umode_t mode) | |
535 | { | |
536 | int err; | |
537 | struct dentry *h_dentry; | |
538 | struct inode *h_inode; | |
539 | ||
540 | h_dentry = h_path->dentry; | |
541 | h_inode = d_inode(h_dentry); | |
542 | /* forget_all_cached_acls(h_inode)); */ | |
543 | err = vfsub_removexattr(h_dentry, XATTR_NAME_POSIX_ACL_ACCESS); | |
544 | AuTraceErr(err); | |
545 | if (err == -EOPNOTSUPP) | |
546 | err = 0; | |
547 | if (!err) | |
548 | err = vfsub_acl_chmod(h_inode, mode); | |
549 | ||
550 | AuTraceErr(err); | |
551 | return err; | |
552 | } | |
553 | ||
554 | static int au_do_cpup_dir(struct au_cp_generic *cpg, struct dentry *dst_parent, | |
555 | struct inode *h_dir, struct path *h_path) | |
556 | { | |
557 | int err; | |
558 | struct inode *dir, *inode; | |
559 | ||
560 | err = vfsub_removexattr(h_path->dentry, XATTR_NAME_POSIX_ACL_DEFAULT); | |
561 | AuTraceErr(err); | |
562 | if (err == -EOPNOTSUPP) | |
563 | err = 0; | |
564 | if (unlikely(err)) | |
565 | goto out; | |
566 | ||
567 | /* | |
568 | * strange behaviour from the users view, | |
569 | * particularry setattr case | |
570 | */ | |
571 | dir = d_inode(dst_parent); | |
572 | if (au_ibtop(dir) == cpg->bdst) | |
573 | au_cpup_attr_nlink(dir, /*force*/1); | |
574 | inode = d_inode(cpg->dentry); | |
575 | au_cpup_attr_nlink(inode, /*force*/1); | |
576 | ||
577 | out: | |
578 | return err; | |
579 | } | |
580 | ||
581 | static noinline_for_stack | |
582 | int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent, | |
583 | struct au_cpup_reg_attr *h_src_attr) | |
584 | { | |
585 | int err; | |
586 | umode_t mode; | |
587 | unsigned int mnt_flags; | |
588 | unsigned char isdir, isreg, force; | |
589 | const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME); | |
590 | struct au_dtime dt; | |
591 | struct path h_path; | |
592 | struct dentry *h_src, *h_dst, *h_parent; | |
593 | struct inode *h_inode, *h_dir; | |
594 | struct super_block *sb; | |
595 | ||
596 | /* bsrc branch can be ro/rw. */ | |
597 | h_src = au_h_dptr(cpg->dentry, cpg->bsrc); | |
598 | h_inode = d_inode(h_src); | |
599 | AuDebugOn(h_inode != au_h_iptr(d_inode(cpg->dentry), cpg->bsrc)); | |
600 | ||
601 | /* try stopping to be referenced while we are creating */ | |
602 | h_dst = au_h_dptr(cpg->dentry, cpg->bdst); | |
603 | if (au_ftest_cpup(cpg->flags, RENAME)) | |
604 | AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX, | |
605 | AUFS_WH_PFX_LEN)); | |
606 | h_parent = h_dst->d_parent; /* dir inode is locked */ | |
607 | h_dir = d_inode(h_parent); | |
608 | IMustLock(h_dir); | |
609 | AuDebugOn(h_parent != h_dst->d_parent); | |
610 | ||
611 | sb = cpg->dentry->d_sb; | |
612 | h_path.mnt = au_sbr_mnt(sb, cpg->bdst); | |
613 | if (do_dt) { | |
614 | h_path.dentry = h_parent; | |
615 | au_dtime_store(&dt, dst_parent, &h_path); | |
616 | } | |
617 | h_path.dentry = h_dst; | |
618 | ||
619 | isreg = 0; | |
620 | isdir = 0; | |
621 | mode = h_inode->i_mode; | |
622 | switch (mode & S_IFMT) { | |
623 | case S_IFREG: | |
624 | isreg = 1; | |
625 | err = vfsub_create(h_dir, &h_path, S_IRUSR | S_IWUSR, | |
626 | /*want_excl*/true); | |
627 | if (!err) | |
628 | err = au_do_cpup_regular(cpg, h_src_attr); | |
629 | break; | |
630 | case S_IFDIR: | |
631 | isdir = 1; | |
632 | err = vfsub_mkdir(h_dir, &h_path, mode); | |
633 | if (!err) | |
634 | err = au_do_cpup_dir(cpg, dst_parent, h_dir, &h_path); | |
635 | break; | |
636 | case S_IFLNK: | |
637 | err = au_do_cpup_symlink(&h_path, h_src, h_dir); | |
638 | break; | |
639 | case S_IFCHR: | |
640 | case S_IFBLK: | |
641 | AuDebugOn(!capable(CAP_MKNOD)); | |
642 | /*FALLTHROUGH*/ | |
643 | case S_IFIFO: | |
644 | case S_IFSOCK: | |
645 | err = vfsub_mknod(h_dir, &h_path, mode, h_inode->i_rdev); | |
646 | break; | |
647 | default: | |
648 | AuIOErr("Unknown inode type 0%o\n", mode); | |
649 | err = -EIO; | |
650 | } | |
651 | if (!err) | |
652 | err = au_reset_acl(h_dir, &h_path, mode); | |
653 | ||
654 | mnt_flags = au_mntflags(sb); | |
655 | if (!au_opt_test(mnt_flags, UDBA_NONE) | |
656 | && !isdir | |
657 | && au_opt_test(mnt_flags, XINO) | |
658 | && (h_inode->i_nlink == 1 | |
659 | || (h_inode->i_state & I_LINKABLE)) | |
660 | /* todo: unnecessary? */ | |
661 | /* && d_inode(cpg->dentry)->i_nlink == 1 */ | |
662 | && cpg->bdst < cpg->bsrc | |
663 | && !au_ftest_cpup(cpg->flags, KEEPLINO)) | |
664 | au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0); | |
665 | /* ignore this error */ | |
666 | ||
667 | if (!err) { | |
668 | force = 0; | |
669 | if (isreg) { | |
670 | force = !!cpg->len; | |
671 | if (cpg->len == -1) | |
672 | force = !!i_size_read(h_inode); | |
673 | } | |
674 | au_fhsm_wrote(sb, cpg->bdst, force); | |
675 | } | |
676 | ||
677 | if (do_dt) | |
678 | au_dtime_revert(&dt); | |
679 | return err; | |
680 | } | |
681 | ||
682 | static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path) | |
683 | { | |
684 | int err; | |
685 | struct dentry *dentry, *h_dentry, *h_parent, *parent; | |
686 | struct inode *h_dir; | |
687 | aufs_bindex_t bdst; | |
688 | ||
689 | dentry = cpg->dentry; | |
690 | bdst = cpg->bdst; | |
691 | h_dentry = au_h_dptr(dentry, bdst); | |
692 | if (!au_ftest_cpup(cpg->flags, OVERWRITE)) { | |
693 | dget(h_dentry); | |
694 | au_set_h_dptr(dentry, bdst, NULL); | |
695 | err = au_lkup_neg(dentry, bdst, /*wh*/0); | |
696 | if (!err) | |
697 | h_path->dentry = dget(au_h_dptr(dentry, bdst)); | |
698 | au_set_h_dptr(dentry, bdst, h_dentry); | |
699 | } else { | |
700 | err = 0; | |
701 | parent = dget_parent(dentry); | |
702 | h_parent = au_h_dptr(parent, bdst); | |
703 | dput(parent); | |
704 | h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent); | |
705 | if (IS_ERR(h_path->dentry)) | |
706 | err = PTR_ERR(h_path->dentry); | |
707 | } | |
708 | if (unlikely(err)) | |
709 | goto out; | |
710 | ||
711 | h_parent = h_dentry->d_parent; /* dir inode is locked */ | |
712 | h_dir = d_inode(h_parent); | |
713 | IMustLock(h_dir); | |
714 | AuDbg("%pd %pd\n", h_dentry, h_path->dentry); | |
715 | /* no delegation since it is just created */ | |
716 | err = vfsub_rename(h_dir, h_dentry, h_dir, h_path, /*delegated*/NULL, | |
717 | /*flags*/0); | |
718 | dput(h_path->dentry); | |
719 | ||
720 | out: | |
721 | return err; | |
722 | } | |
723 | ||
724 | /* | |
725 | * copyup the @dentry from @bsrc to @bdst. | |
726 | * the caller must set the both of lower dentries. | |
727 | * @len is for truncating when it is -1 copyup the entire file. | |
728 | * in link/rename cases, @dst_parent may be different from the real one. | |
729 | * basic->bsrc can be larger than basic->bdst. | |
730 | * aufs doesn't touch the credential so | |
731 | * security_inode_copy_up{,_xattr}() are unnecrssary. | |
732 | */ | |
733 | static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) | |
734 | { | |
735 | int err, rerr; | |
736 | aufs_bindex_t old_ibtop; | |
737 | unsigned char isdir, plink; | |
738 | struct dentry *h_src, *h_dst, *h_parent; | |
739 | struct inode *dst_inode, *h_dir, *inode, *delegated, *src_inode; | |
740 | struct super_block *sb; | |
741 | struct au_branch *br; | |
742 | /* to reuduce stack size */ | |
743 | struct { | |
744 | struct au_dtime dt; | |
745 | struct path h_path; | |
746 | struct au_cpup_reg_attr h_src_attr; | |
747 | } *a; | |
748 | ||
749 | err = -ENOMEM; | |
750 | a = kmalloc(sizeof(*a), GFP_NOFS); | |
751 | if (unlikely(!a)) | |
752 | goto out; | |
753 | a->h_src_attr.valid = 0; | |
754 | ||
755 | sb = cpg->dentry->d_sb; | |
756 | br = au_sbr(sb, cpg->bdst); | |
757 | a->h_path.mnt = au_br_mnt(br); | |
758 | h_dst = au_h_dptr(cpg->dentry, cpg->bdst); | |
759 | h_parent = h_dst->d_parent; /* dir inode is locked */ | |
760 | h_dir = d_inode(h_parent); | |
761 | IMustLock(h_dir); | |
762 | ||
763 | h_src = au_h_dptr(cpg->dentry, cpg->bsrc); | |
764 | inode = d_inode(cpg->dentry); | |
765 | ||
766 | if (!dst_parent) | |
767 | dst_parent = dget_parent(cpg->dentry); | |
768 | else | |
769 | dget(dst_parent); | |
770 | ||
771 | plink = !!au_opt_test(au_mntflags(sb), PLINK); | |
772 | dst_inode = au_h_iptr(inode, cpg->bdst); | |
773 | if (dst_inode) { | |
774 | if (unlikely(!plink)) { | |
775 | err = -EIO; | |
776 | AuIOErr("hi%lu(i%lu) exists on b%d " | |
777 | "but plink is disabled\n", | |
778 | dst_inode->i_ino, inode->i_ino, cpg->bdst); | |
779 | goto out_parent; | |
780 | } | |
781 | ||
782 | if (dst_inode->i_nlink) { | |
783 | const int do_dt = au_ftest_cpup(cpg->flags, DTIME); | |
784 | ||
785 | h_src = au_plink_lkup(inode, cpg->bdst); | |
786 | err = PTR_ERR(h_src); | |
787 | if (IS_ERR(h_src)) | |
788 | goto out_parent; | |
789 | if (unlikely(d_is_negative(h_src))) { | |
790 | err = -EIO; | |
791 | AuIOErr("i%lu exists on b%d " | |
792 | "but not pseudo-linked\n", | |
793 | inode->i_ino, cpg->bdst); | |
794 | dput(h_src); | |
795 | goto out_parent; | |
796 | } | |
797 | ||
798 | if (do_dt) { | |
799 | a->h_path.dentry = h_parent; | |
800 | au_dtime_store(&a->dt, dst_parent, &a->h_path); | |
801 | } | |
802 | ||
803 | a->h_path.dentry = h_dst; | |
804 | delegated = NULL; | |
805 | err = vfsub_link(h_src, h_dir, &a->h_path, &delegated); | |
806 | if (!err && au_ftest_cpup(cpg->flags, RENAME)) | |
807 | err = au_do_ren_after_cpup(cpg, &a->h_path); | |
808 | if (do_dt) | |
809 | au_dtime_revert(&a->dt); | |
810 | if (unlikely(err == -EWOULDBLOCK)) { | |
811 | pr_warn("cannot retry for NFSv4 delegation" | |
812 | " for an internal link\n"); | |
813 | iput(delegated); | |
814 | } | |
815 | dput(h_src); | |
816 | goto out_parent; | |
817 | } else | |
818 | /* todo: cpup_wh_file? */ | |
819 | /* udba work */ | |
820 | au_update_ibrange(inode, /*do_put_zero*/1); | |
821 | } | |
822 | ||
823 | isdir = S_ISDIR(inode->i_mode); | |
824 | old_ibtop = au_ibtop(inode); | |
825 | err = cpup_entry(cpg, dst_parent, &a->h_src_attr); | |
826 | if (unlikely(err)) | |
827 | goto out_rev; | |
828 | dst_inode = d_inode(h_dst); | |
829 | inode_lock_nested(dst_inode, AuLsc_I_CHILD2); | |
830 | /* todo: necessary? */ | |
831 | /* au_pin_hdir_unlock(cpg->pin); */ | |
832 | ||
833 | err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr); | |
834 | if (unlikely(err)) { | |
835 | /* todo: necessary? */ | |
836 | /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */ | |
837 | inode_unlock(dst_inode); | |
838 | goto out_rev; | |
839 | } | |
840 | ||
841 | if (cpg->bdst < old_ibtop) { | |
842 | if (S_ISREG(inode->i_mode)) { | |
843 | err = au_dy_iaop(inode, cpg->bdst, dst_inode); | |
844 | if (unlikely(err)) { | |
845 | /* ignore an error */ | |
846 | /* au_pin_hdir_relock(cpg->pin); */ | |
847 | inode_unlock(dst_inode); | |
848 | goto out_rev; | |
849 | } | |
850 | } | |
851 | au_set_ibtop(inode, cpg->bdst); | |
852 | } else | |
853 | au_set_ibbot(inode, cpg->bdst); | |
854 | au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode), | |
855 | au_hi_flags(inode, isdir)); | |
856 | ||
857 | /* todo: necessary? */ | |
858 | /* err = au_pin_hdir_relock(cpg->pin); */ | |
859 | inode_unlock(dst_inode); | |
860 | if (unlikely(err)) | |
861 | goto out_rev; | |
862 | ||
863 | src_inode = d_inode(h_src); | |
864 | if (!isdir | |
865 | && (src_inode->i_nlink > 1 | |
866 | || src_inode->i_state & I_LINKABLE) | |
867 | && plink) | |
868 | au_plink_append(inode, cpg->bdst, h_dst); | |
869 | ||
870 | if (au_ftest_cpup(cpg->flags, RENAME)) { | |
871 | a->h_path.dentry = h_dst; | |
872 | err = au_do_ren_after_cpup(cpg, &a->h_path); | |
873 | } | |
874 | if (!err) | |
875 | goto out_parent; /* success */ | |
876 | ||
877 | /* revert */ | |
878 | out_rev: | |
879 | a->h_path.dentry = h_parent; | |
880 | au_dtime_store(&a->dt, dst_parent, &a->h_path); | |
881 | a->h_path.dentry = h_dst; | |
882 | rerr = 0; | |
883 | if (d_is_positive(h_dst)) { | |
884 | if (!isdir) { | |
885 | /* no delegation since it is just created */ | |
886 | rerr = vfsub_unlink(h_dir, &a->h_path, | |
887 | /*delegated*/NULL, /*force*/0); | |
888 | } else | |
889 | rerr = vfsub_rmdir(h_dir, &a->h_path); | |
890 | } | |
891 | au_dtime_revert(&a->dt); | |
892 | if (rerr) { | |
893 | AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); | |
894 | err = -EIO; | |
895 | } | |
896 | out_parent: | |
897 | dput(dst_parent); | |
898 | au_delayed_kfree(a); | |
899 | out: | |
900 | return err; | |
901 | } | |
902 | ||
903 | #if 0 /* reserved */ | |
904 | struct au_cpup_single_args { | |
905 | int *errp; | |
906 | struct au_cp_generic *cpg; | |
907 | struct dentry *dst_parent; | |
908 | }; | |
909 | ||
910 | static void au_call_cpup_single(void *args) | |
911 | { | |
912 | struct au_cpup_single_args *a = args; | |
913 | ||
914 | au_pin_hdir_acquire_nest(a->cpg->pin); | |
915 | *a->errp = au_cpup_single(a->cpg, a->dst_parent); | |
916 | au_pin_hdir_release(a->cpg->pin); | |
917 | } | |
918 | #endif | |
919 | ||
920 | /* | |
921 | * prevent SIGXFSZ in copy-up. | |
922 | * testing CAP_MKNOD is for generic fs, | |
923 | * but CAP_FSETID is for xfs only, currently. | |
924 | */ | |
925 | static int au_cpup_sio_test(struct au_pin *pin, umode_t mode) | |
926 | { | |
927 | int do_sio; | |
928 | struct super_block *sb; | |
929 | struct inode *h_dir; | |
930 | ||
931 | do_sio = 0; | |
932 | sb = au_pinned_parent(pin)->d_sb; | |
933 | if (!au_wkq_test() | |
934 | && (!au_sbi(sb)->si_plink_maint_pid | |
935 | || au_plink_maint(sb, AuLock_NOPLM))) { | |
936 | switch (mode & S_IFMT) { | |
937 | case S_IFREG: | |
938 | /* no condition about RLIMIT_FSIZE and the file size */ | |
939 | do_sio = 1; | |
940 | break; | |
941 | case S_IFCHR: | |
942 | case S_IFBLK: | |
943 | do_sio = !capable(CAP_MKNOD); | |
944 | break; | |
945 | } | |
946 | if (!do_sio) | |
947 | do_sio = ((mode & (S_ISUID | S_ISGID)) | |
948 | && !capable(CAP_FSETID)); | |
949 | /* this workaround may be removed in the future */ | |
950 | if (!do_sio) { | |
951 | h_dir = au_pinned_h_dir(pin); | |
952 | do_sio = h_dir->i_mode & S_ISVTX; | |
953 | } | |
954 | } | |
955 | ||
956 | return do_sio; | |
957 | } | |
958 | ||
959 | #if 0 /* reserved */ | |
960 | int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) | |
961 | { | |
962 | int err, wkq_err; | |
963 | struct dentry *h_dentry; | |
964 | ||
965 | h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc); | |
966 | if (!au_cpup_sio_test(pin, d_inode(h_dentry)->i_mode)) | |
967 | err = au_cpup_single(cpg, dst_parent); | |
968 | else { | |
969 | struct au_cpup_single_args args = { | |
970 | .errp = &err, | |
971 | .cpg = cpg, | |
972 | .dst_parent = dst_parent | |
973 | }; | |
974 | wkq_err = au_wkq_wait(au_call_cpup_single, &args); | |
975 | if (unlikely(wkq_err)) | |
976 | err = wkq_err; | |
977 | } | |
978 | ||
979 | return err; | |
980 | } | |
981 | #endif | |
982 | ||
983 | /* | |
984 | * copyup the @dentry from the first active lower branch to @bdst, | |
985 | * using au_cpup_single(). | |
986 | */ | |
987 | static int au_cpup_simple(struct au_cp_generic *cpg) | |
988 | { | |
989 | int err; | |
990 | unsigned int flags_orig; | |
991 | struct dentry *dentry; | |
992 | ||
993 | AuDebugOn(cpg->bsrc < 0); | |
994 | ||
995 | dentry = cpg->dentry; | |
996 | DiMustWriteLock(dentry); | |
997 | ||
998 | err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1); | |
999 | if (!err) { | |
1000 | flags_orig = cpg->flags; | |
1001 | au_fset_cpup(cpg->flags, RENAME); | |
1002 | err = au_cpup_single(cpg, NULL); | |
1003 | cpg->flags = flags_orig; | |
1004 | if (!err) | |
1005 | return 0; /* success */ | |
1006 | ||
1007 | /* revert */ | |
1008 | au_set_h_dptr(dentry, cpg->bdst, NULL); | |
1009 | au_set_dbtop(dentry, cpg->bsrc); | |
1010 | } | |
1011 | ||
1012 | return err; | |
1013 | } | |
1014 | ||
1015 | struct au_cpup_simple_args { | |
1016 | int *errp; | |
1017 | struct au_cp_generic *cpg; | |
1018 | }; | |
1019 | ||
1020 | static void au_call_cpup_simple(void *args) | |
1021 | { | |
1022 | struct au_cpup_simple_args *a = args; | |
1023 | ||
1024 | au_pin_hdir_acquire_nest(a->cpg->pin); | |
1025 | *a->errp = au_cpup_simple(a->cpg); | |
1026 | au_pin_hdir_release(a->cpg->pin); | |
1027 | } | |
1028 | ||
1029 | static int au_do_sio_cpup_simple(struct au_cp_generic *cpg) | |
1030 | { | |
1031 | int err, wkq_err; | |
1032 | struct dentry *dentry, *parent; | |
1033 | struct file *h_file; | |
1034 | struct inode *h_dir; | |
1035 | ||
1036 | dentry = cpg->dentry; | |
1037 | h_file = NULL; | |
1038 | if (au_ftest_cpup(cpg->flags, HOPEN)) { | |
1039 | AuDebugOn(cpg->bsrc < 0); | |
1040 | h_file = au_h_open_pre(dentry, cpg->bsrc, /*force_wr*/0); | |
1041 | err = PTR_ERR(h_file); | |
1042 | if (IS_ERR(h_file)) | |
1043 | goto out; | |
1044 | } | |
1045 | ||
1046 | parent = dget_parent(dentry); | |
1047 | h_dir = au_h_iptr(d_inode(parent), cpg->bdst); | |
1048 | if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE) | |
1049 | && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) | |
1050 | err = au_cpup_simple(cpg); | |
1051 | else { | |
1052 | struct au_cpup_simple_args args = { | |
1053 | .errp = &err, | |
1054 | .cpg = cpg | |
1055 | }; | |
1056 | wkq_err = au_wkq_wait(au_call_cpup_simple, &args); | |
1057 | if (unlikely(wkq_err)) | |
1058 | err = wkq_err; | |
1059 | } | |
1060 | ||
1061 | dput(parent); | |
1062 | if (h_file) | |
1063 | au_h_open_post(dentry, cpg->bsrc, h_file); | |
1064 | ||
1065 | out: | |
1066 | return err; | |
1067 | } | |
1068 | ||
1069 | int au_sio_cpup_simple(struct au_cp_generic *cpg) | |
1070 | { | |
1071 | aufs_bindex_t bsrc, bbot; | |
1072 | struct dentry *dentry, *h_dentry; | |
1073 | ||
1074 | if (cpg->bsrc < 0) { | |
1075 | dentry = cpg->dentry; | |
1076 | bbot = au_dbbot(dentry); | |
1077 | for (bsrc = cpg->bdst + 1; bsrc <= bbot; bsrc++) { | |
1078 | h_dentry = au_h_dptr(dentry, bsrc); | |
1079 | if (h_dentry) { | |
1080 | AuDebugOn(d_is_negative(h_dentry)); | |
1081 | break; | |
1082 | } | |
1083 | } | |
1084 | AuDebugOn(bsrc > bbot); | |
1085 | cpg->bsrc = bsrc; | |
1086 | } | |
1087 | AuDebugOn(cpg->bsrc <= cpg->bdst); | |
1088 | return au_do_sio_cpup_simple(cpg); | |
1089 | } | |
1090 | ||
1091 | int au_sio_cpdown_simple(struct au_cp_generic *cpg) | |
1092 | { | |
1093 | AuDebugOn(cpg->bdst <= cpg->bsrc); | |
1094 | return au_do_sio_cpup_simple(cpg); | |
1095 | } | |
1096 | ||
1097 | /* ---------------------------------------------------------------------- */ | |
1098 | ||
1099 | /* | |
1100 | * copyup the deleted file for writing. | |
1101 | */ | |
1102 | static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry, | |
1103 | struct file *file) | |
1104 | { | |
1105 | int err; | |
1106 | unsigned int flags_orig; | |
1107 | aufs_bindex_t bsrc_orig; | |
1108 | struct au_dinfo *dinfo; | |
1109 | struct { | |
1110 | struct au_hdentry *hd; | |
1111 | struct dentry *h_dentry; | |
1112 | } hdst, hsrc; | |
1113 | ||
1114 | dinfo = au_di(cpg->dentry); | |
1115 | AuRwMustWriteLock(&dinfo->di_rwsem); | |
1116 | ||
1117 | bsrc_orig = cpg->bsrc; | |
1118 | cpg->bsrc = dinfo->di_btop; | |
1119 | hdst.hd = au_hdentry(dinfo, cpg->bdst); | |
1120 | hdst.h_dentry = hdst.hd->hd_dentry; | |
1121 | hdst.hd->hd_dentry = wh_dentry; | |
1122 | dinfo->di_btop = cpg->bdst; | |
1123 | ||
1124 | hsrc.h_dentry = NULL; | |
1125 | if (file) { | |
1126 | hsrc.hd = au_hdentry(dinfo, cpg->bsrc); | |
1127 | hsrc.h_dentry = hsrc.hd->hd_dentry; | |
1128 | hsrc.hd->hd_dentry = au_hf_top(file)->f_path.dentry; | |
1129 | } | |
1130 | flags_orig = cpg->flags; | |
1131 | cpg->flags = !AuCpup_DTIME; | |
1132 | err = au_cpup_single(cpg, /*h_parent*/NULL); | |
1133 | cpg->flags = flags_orig; | |
1134 | if (file) { | |
1135 | if (!err) | |
1136 | err = au_reopen_nondir(file); | |
1137 | hsrc.hd->hd_dentry = hsrc.h_dentry; | |
1138 | } | |
1139 | hdst.hd->hd_dentry = hdst.h_dentry; | |
1140 | dinfo->di_btop = cpg->bsrc; | |
1141 | cpg->bsrc = bsrc_orig; | |
1142 | ||
1143 | return err; | |
1144 | } | |
1145 | ||
1146 | static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file) | |
1147 | { | |
1148 | int err; | |
1149 | aufs_bindex_t bdst; | |
1150 | struct au_dtime dt; | |
1151 | struct dentry *dentry, *parent, *h_parent, *wh_dentry; | |
1152 | struct au_branch *br; | |
1153 | struct path h_path; | |
1154 | ||
1155 | dentry = cpg->dentry; | |
1156 | bdst = cpg->bdst; | |
1157 | br = au_sbr(dentry->d_sb, bdst); | |
1158 | parent = dget_parent(dentry); | |
1159 | h_parent = au_h_dptr(parent, bdst); | |
1160 | wh_dentry = au_whtmp_lkup(h_parent, br, &dentry->d_name); | |
1161 | err = PTR_ERR(wh_dentry); | |
1162 | if (IS_ERR(wh_dentry)) | |
1163 | goto out; | |
1164 | ||
1165 | h_path.dentry = h_parent; | |
1166 | h_path.mnt = au_br_mnt(br); | |
1167 | au_dtime_store(&dt, parent, &h_path); | |
1168 | err = au_do_cpup_wh(cpg, wh_dentry, file); | |
1169 | if (unlikely(err)) | |
1170 | goto out_wh; | |
1171 | ||
1172 | dget(wh_dentry); | |
1173 | h_path.dentry = wh_dentry; | |
1174 | if (!d_is_dir(wh_dentry)) { | |
1175 | /* no delegation since it is just created */ | |
1176 | err = vfsub_unlink(d_inode(h_parent), &h_path, | |
1177 | /*delegated*/NULL, /*force*/0); | |
1178 | } else | |
1179 | err = vfsub_rmdir(d_inode(h_parent), &h_path); | |
1180 | if (unlikely(err)) { | |
1181 | AuIOErr("failed remove copied-up tmp file %pd(%d)\n", | |
1182 | wh_dentry, err); | |
1183 | err = -EIO; | |
1184 | } | |
1185 | au_dtime_revert(&dt); | |
1186 | au_set_hi_wh(d_inode(dentry), bdst, wh_dentry); | |
1187 | ||
1188 | out_wh: | |
1189 | dput(wh_dentry); | |
1190 | out: | |
1191 | dput(parent); | |
1192 | return err; | |
1193 | } | |
1194 | ||
1195 | struct au_cpup_wh_args { | |
1196 | int *errp; | |
1197 | struct au_cp_generic *cpg; | |
1198 | struct file *file; | |
1199 | }; | |
1200 | ||
1201 | static void au_call_cpup_wh(void *args) | |
1202 | { | |
1203 | struct au_cpup_wh_args *a = args; | |
1204 | ||
1205 | au_pin_hdir_acquire_nest(a->cpg->pin); | |
1206 | *a->errp = au_cpup_wh(a->cpg, a->file); | |
1207 | au_pin_hdir_release(a->cpg->pin); | |
1208 | } | |
1209 | ||
1210 | int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file) | |
1211 | { | |
1212 | int err, wkq_err; | |
1213 | aufs_bindex_t bdst; | |
1214 | struct dentry *dentry, *parent, *h_orph, *h_parent; | |
1215 | struct inode *dir, *h_dir, *h_tmpdir; | |
1216 | struct au_wbr *wbr; | |
1217 | struct au_pin wh_pin, *pin_orig; | |
1218 | ||
1219 | dentry = cpg->dentry; | |
1220 | bdst = cpg->bdst; | |
1221 | parent = dget_parent(dentry); | |
1222 | dir = d_inode(parent); | |
1223 | h_orph = NULL; | |
1224 | h_parent = NULL; | |
1225 | h_dir = au_igrab(au_h_iptr(dir, bdst)); | |
1226 | h_tmpdir = h_dir; | |
1227 | pin_orig = NULL; | |
1228 | if (!h_dir->i_nlink) { | |
1229 | wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; | |
1230 | h_orph = wbr->wbr_orph; | |
1231 | ||
1232 | h_parent = dget(au_h_dptr(parent, bdst)); | |
1233 | au_set_h_dptr(parent, bdst, dget(h_orph)); | |
1234 | h_tmpdir = d_inode(h_orph); | |
1235 | au_set_h_iptr(dir, bdst, au_igrab(h_tmpdir), /*flags*/0); | |
1236 | ||
1237 | inode_lock_nested(h_tmpdir, AuLsc_I_PARENT3); | |
1238 | /* todo: au_h_open_pre()? */ | |
1239 | ||
1240 | pin_orig = cpg->pin; | |
1241 | au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT, | |
1242 | AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED); | |
1243 | cpg->pin = &wh_pin; | |
1244 | } | |
1245 | ||
1246 | if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE) | |
1247 | && !au_cpup_sio_test(cpg->pin, d_inode(dentry)->i_mode)) | |
1248 | err = au_cpup_wh(cpg, file); | |
1249 | else { | |
1250 | struct au_cpup_wh_args args = { | |
1251 | .errp = &err, | |
1252 | .cpg = cpg, | |
1253 | .file = file | |
1254 | }; | |
1255 | wkq_err = au_wkq_wait(au_call_cpup_wh, &args); | |
1256 | if (unlikely(wkq_err)) | |
1257 | err = wkq_err; | |
1258 | } | |
1259 | ||
1260 | if (h_orph) { | |
1261 | inode_unlock(h_tmpdir); | |
1262 | /* todo: au_h_open_post()? */ | |
1263 | au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); | |
1264 | au_set_h_dptr(parent, bdst, h_parent); | |
1265 | AuDebugOn(!pin_orig); | |
1266 | cpg->pin = pin_orig; | |
1267 | } | |
1268 | iput(h_dir); | |
1269 | dput(parent); | |
1270 | ||
1271 | return err; | |
1272 | } | |
1273 | ||
1274 | /* ---------------------------------------------------------------------- */ | |
1275 | ||
1276 | /* | |
1277 | * generic routine for both of copy-up and copy-down. | |
1278 | */ | |
1279 | /* cf. revalidate function in file.c */ | |
1280 | int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, | |
1281 | int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, | |
1282 | struct au_pin *pin, | |
1283 | struct dentry *h_parent, void *arg), | |
1284 | void *arg) | |
1285 | { | |
1286 | int err; | |
1287 | struct au_pin pin; | |
1288 | struct dentry *d, *parent, *h_parent, *real_parent, *h_dentry; | |
1289 | ||
1290 | err = 0; | |
1291 | parent = dget_parent(dentry); | |
1292 | if (IS_ROOT(parent)) | |
1293 | goto out; | |
1294 | ||
1295 | au_pin_init(&pin, dentry, bdst, AuLsc_DI_PARENT2, AuLsc_I_PARENT2, | |
1296 | au_opt_udba(dentry->d_sb), AuPin_MNT_WRITE); | |
1297 | ||
1298 | /* do not use au_dpage */ | |
1299 | real_parent = parent; | |
1300 | while (1) { | |
1301 | dput(parent); | |
1302 | parent = dget_parent(dentry); | |
1303 | h_parent = au_h_dptr(parent, bdst); | |
1304 | if (h_parent) | |
1305 | goto out; /* success */ | |
1306 | ||
1307 | /* find top dir which is necessary to cpup */ | |
1308 | do { | |
1309 | d = parent; | |
1310 | dput(parent); | |
1311 | parent = dget_parent(d); | |
1312 | di_read_lock_parent3(parent, !AuLock_IR); | |
1313 | h_parent = au_h_dptr(parent, bdst); | |
1314 | di_read_unlock(parent, !AuLock_IR); | |
1315 | } while (!h_parent); | |
1316 | ||
1317 | if (d != real_parent) | |
1318 | di_write_lock_child3(d); | |
1319 | ||
1320 | /* somebody else might create while we were sleeping */ | |
1321 | h_dentry = au_h_dptr(d, bdst); | |
1322 | if (!h_dentry || d_is_negative(h_dentry)) { | |
1323 | if (h_dentry) | |
1324 | au_update_dbtop(d); | |
1325 | ||
1326 | au_pin_set_dentry(&pin, d); | |
1327 | err = au_do_pin(&pin); | |
1328 | if (!err) { | |
1329 | err = cp(d, bdst, &pin, h_parent, arg); | |
1330 | au_unpin(&pin); | |
1331 | } | |
1332 | } | |
1333 | ||
1334 | if (d != real_parent) | |
1335 | di_write_unlock(d); | |
1336 | if (unlikely(err)) | |
1337 | break; | |
1338 | } | |
1339 | ||
1340 | out: | |
1341 | dput(parent); | |
1342 | return err; | |
1343 | } | |
1344 | ||
1345 | static int au_cpup_dir(struct dentry *dentry, aufs_bindex_t bdst, | |
1346 | struct au_pin *pin, | |
1347 | struct dentry *h_parent __maybe_unused, | |
1348 | void *arg __maybe_unused) | |
1349 | { | |
1350 | struct au_cp_generic cpg = { | |
1351 | .dentry = dentry, | |
1352 | .bdst = bdst, | |
1353 | .bsrc = -1, | |
1354 | .len = 0, | |
1355 | .pin = pin, | |
1356 | .flags = AuCpup_DTIME | |
1357 | }; | |
1358 | return au_sio_cpup_simple(&cpg); | |
1359 | } | |
1360 | ||
1361 | int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) | |
1362 | { | |
1363 | return au_cp_dirs(dentry, bdst, au_cpup_dir, NULL); | |
1364 | } | |
1365 | ||
1366 | int au_test_and_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) | |
1367 | { | |
1368 | int err; | |
1369 | struct dentry *parent; | |
1370 | struct inode *dir; | |
1371 | ||
1372 | parent = dget_parent(dentry); | |
1373 | dir = d_inode(parent); | |
1374 | err = 0; | |
1375 | if (au_h_iptr(dir, bdst)) | |
1376 | goto out; | |
1377 | ||
1378 | di_read_unlock(parent, AuLock_IR); | |
1379 | di_write_lock_parent(parent); | |
1380 | /* someone else might change our inode while we were sleeping */ | |
1381 | if (!au_h_iptr(dir, bdst)) | |
1382 | err = au_cpup_dirs(dentry, bdst); | |
1383 | di_downgrade_lock(parent, AuLock_IR); | |
1384 | ||
1385 | out: | |
1386 | dput(parent); | |
1387 | return err; | |
1388 | } |