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