]>
git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - fs/aufs/i_op_del.c
2 * Copyright (C) 2005-2016 Junjiro R. Okajima
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.
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.
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/>.
19 * inode operations (del entry)
25 * decide if a new whiteout for @dentry is necessary or not.
26 * when it is necessary, prepare the parent dir for the upper branch whose
27 * branch index is @bcpup for creation. the actual creation of the whiteout will
30 * 0: wh is unnecessary
31 * plus: wh is necessary
34 int au_wr_dir_need_wh(struct dentry
*dentry
, int isdir
, aufs_bindex_t
*bcpup
)
38 struct super_block
*sb
;
41 btop
= au_dbtop(dentry
);
44 if (au_test_ro(sb
, btop
, d_inode(dentry
))) {
45 err
= AuWbrCopyup(au_sbi(sb
), dentry
);
47 if (unlikely(err
< 0))
51 AuDebugOn(btop
< *bcpup
52 || au_test_ro(sb
, *bcpup
, d_inode(dentry
)));
53 AuDbg("bcpup %d, btop %d\n", *bcpup
, btop
);
56 err
= au_cpup_dirs(dentry
, *bcpup
);
61 struct au_dinfo
*dinfo
, *tmp
;
64 dinfo
= au_di(dentry
);
65 tmp
= au_di_alloc(sb
, AuLsc_DI_TMP
);
68 au_di_swap(tmp
, dinfo
);
69 /* returns the number of positive dentries */
70 need_wh
= au_lkup_dentry(dentry
, btop
+ 1,
71 /* AuLkup_IGNORE_PERM */ 0);
72 au_di_swap(tmp
, dinfo
);
73 au_rw_write_unlock(&tmp
->di_rwsem
);
77 AuDbg("need_wh %d\n", need_wh
);
85 * simple tests for the del-entry operations.
86 * following the checks in vfs, plus the parent-child relationship.
88 int au_may_del(struct dentry
*dentry
, aufs_bindex_t bindex
,
89 struct dentry
*h_parent
, int isdir
)
93 struct dentry
*h_dentry
, *h_latest
;
94 struct inode
*h_inode
;
96 h_dentry
= au_h_dptr(dentry
, bindex
);
97 if (d_really_is_positive(dentry
)) {
99 if (unlikely(d_is_negative(h_dentry
)))
101 h_inode
= d_inode(h_dentry
);
102 if (unlikely(!h_inode
->i_nlink
))
105 h_mode
= h_inode
->i_mode
;
108 if (unlikely(S_ISDIR(h_mode
)))
110 } else if (unlikely(!S_ISDIR(h_mode
))) {
117 if (unlikely(d_is_positive(h_dentry
)))
122 /* expected parent dir is locked */
123 if (unlikely(h_parent
!= h_dentry
->d_parent
))
128 * rmdir a dir may break the consistency on some filesystem.
129 * let's try heavy test.
132 if (unlikely(!au_opt_test(au_mntflags(dentry
->d_sb
), DIRPERM1
)
133 && au_test_h_perm(d_inode(h_parent
),
134 MAY_EXEC
| MAY_WRITE
)))
137 h_latest
= au_sio_lkup_one(&dentry
->d_name
, h_parent
);
139 if (IS_ERR(h_latest
))
141 if (h_latest
== h_dentry
)
150 * decide the branch where we operate for @dentry. the branch index will be set
151 * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
153 * when a new whiteout is necessary, create it.
155 static struct dentry
*
156 lock_hdir_create_wh(struct dentry
*dentry
, int isdir
, aufs_bindex_t
*rbcpup
,
157 struct au_dtime
*dt
, struct au_pin
*pin
)
159 struct dentry
*wh_dentry
;
160 struct super_block
*sb
;
166 need_wh
= au_wr_dir_need_wh(dentry
, isdir
, rbcpup
);
167 wh_dentry
= ERR_PTR(need_wh
);
168 if (unlikely(need_wh
< 0))
172 udba
= au_opt_udba(sb
);
174 err
= au_pin(pin
, dentry
, bcpup
, udba
,
175 AuPin_DI_LOCKED
| AuPin_MNT_WRITE
);
176 wh_dentry
= ERR_PTR(err
);
180 h_path
.dentry
= au_pinned_h_parent(pin
);
181 if (udba
!= AuOpt_UDBA_NONE
182 && au_dbtop(dentry
) == bcpup
) {
183 err
= au_may_del(dentry
, bcpup
, h_path
.dentry
, isdir
);
184 wh_dentry
= ERR_PTR(err
);
189 h_path
.mnt
= au_sbr_mnt(sb
, bcpup
);
190 au_dtime_store(dt
, au_pinned_parent(pin
), &h_path
);
193 goto out
; /* success, no need to create whiteout */
195 wh_dentry
= au_wh_create(dentry
, bcpup
, h_path
.dentry
);
196 if (IS_ERR(wh_dentry
))
199 /* returns with the parent is locked and wh_dentry is dget-ed */
200 goto out
; /* success */
209 * when removing a dir, rename it to a unique temporary whiteout-ed name first
210 * in order to be revertible and save time for removing many child whiteouts
212 * returns 1 when there are too many child whiteout and caller should remove
213 * them asynchronously. returns 0 when the number of children is enough small to
214 * remove now or the branch fs is a remote fs.
215 * otherwise return an error.
217 static int renwh_and_rmdir(struct dentry
*dentry
, aufs_bindex_t bindex
,
218 struct au_nhash
*whlist
, struct inode
*dir
)
220 int rmdir_later
, err
, dirwh
;
221 struct dentry
*h_dentry
;
222 struct super_block
*sb
;
227 h_dentry
= au_h_dptr(dentry
, bindex
);
228 err
= au_whtmp_ren(h_dentry
, au_sbr(sb
, bindex
));
232 /* stop monitoring */
233 inode
= d_inode(dentry
);
234 au_hn_free(au_hi(inode
, bindex
));
236 if (!au_test_fs_remote(h_dentry
->d_sb
)) {
237 dirwh
= au_sbi(sb
)->si_dirwh
;
238 rmdir_later
= (dirwh
<= 1);
240 rmdir_later
= au_nhash_test_longer_wh(whlist
, bindex
,
246 err
= au_whtmp_rmdir(dir
, bindex
, h_dentry
, whlist
);
248 AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
249 h_dentry
, bindex
, err
);
259 * final procedure for deleting a entry.
260 * maintain dentry and iattr.
262 static void epilog(struct inode
*dir
, struct dentry
*dentry
,
263 aufs_bindex_t bindex
)
267 inode
= d_inode(dentry
);
269 inode
->i_ctime
= dir
->i_ctime
;
271 au_dir_ts(dir
, bindex
);
276 * when an error happened, remove the created whiteout and revert everything.
278 static int do_revert(int err
, struct inode
*dir
, aufs_bindex_t bindex
,
279 aufs_bindex_t bwh
, struct dentry
*wh_dentry
,
280 struct dentry
*dentry
, struct au_dtime
*dt
)
283 struct path h_path
= {
285 .mnt
= au_sbr_mnt(dir
->i_sb
, bindex
)
288 rerr
= au_wh_unlink_dentry(au_h_iptr(dir
, bindex
), &h_path
, dentry
);
290 au_set_dbwh(dentry
, bwh
);
295 AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry
, err
, rerr
);
299 /* ---------------------------------------------------------------------- */
301 int aufs_unlink(struct inode
*dir
, struct dentry
*dentry
)
304 aufs_bindex_t bwh
, bindex
, btop
;
305 struct inode
*inode
, *h_dir
, *delegated
;
306 struct dentry
*parent
, *wh_dentry
;
307 /* to reuduce stack size */
317 a
= kmalloc(sizeof(*a
), GFP_NOFS
);
321 err
= aufs_read_lock(dentry
, AuLock_DW
| AuLock_GEN
);
324 err
= au_d_hashed_positive(dentry
);
327 inode
= d_inode(dentry
);
330 if (unlikely(d_is_dir(dentry
)))
331 goto out_unlock
; /* possible? */
333 btop
= au_dbtop(dentry
);
334 bwh
= au_dbwh(dentry
);
336 parent
= dentry
->d_parent
; /* dir inode is locked */
337 di_write_lock_parent(parent
);
338 wh_dentry
= lock_hdir_create_wh(dentry
, /*isdir*/0, &bindex
, &a
->dt
,
340 err
= PTR_ERR(wh_dentry
);
341 if (IS_ERR(wh_dentry
))
344 a
->h_path
.mnt
= au_sbr_mnt(dentry
->d_sb
, btop
);
345 a
->h_path
.dentry
= au_h_dptr(dentry
, btop
);
346 dget(a
->h_path
.dentry
);
347 if (bindex
== btop
) {
348 h_dir
= au_pinned_h_dir(&a
->pin
);
350 err
= vfsub_unlink(h_dir
, &a
->h_path
, &delegated
, /*force*/0);
351 if (unlikely(err
== -EWOULDBLOCK
)) {
352 pr_warn("cannot retry for NFSv4 delegation"
353 " for an internal unlink\n");
357 /* dir inode is locked */
358 h_dir
= d_inode(wh_dentry
->d_parent
);
364 vfsub_drop_nlink(inode
);
365 epilog(dir
, dentry
, bindex
);
367 /* update target timestamps */
368 if (bindex
== btop
) {
369 vfsub_update_h_iattr(&a
->h_path
, /*did*/NULL
);
371 inode
->i_ctime
= d_inode(a
->h_path
.dentry
)->i_ctime
;
373 /* todo: this timestamp may be reverted later */
374 inode
->i_ctime
= h_dir
->i_ctime
;
375 goto out_unpin
; /* success */
382 rerr
= do_revert(err
, dir
, bindex
, bwh
, wh_dentry
, dentry
,
391 dput(a
->h_path
.dentry
);
393 di_write_unlock(parent
);
395 aufs_read_unlock(dentry
, AuLock_DW
);
402 int aufs_rmdir(struct inode
*dir
, struct dentry
*dentry
)
404 int err
, rmdir_later
;
405 aufs_bindex_t bwh
, bindex
, btop
;
407 struct dentry
*parent
, *wh_dentry
, *h_dentry
;
408 struct au_whtmp_rmdir
*args
;
409 /* to reuduce stack size */
418 a
= kmalloc(sizeof(*a
), GFP_NOFS
);
422 err
= aufs_read_lock(dentry
, AuLock_DW
| AuLock_FLUSH
| AuLock_GEN
);
425 err
= au_alive_dir(dentry
);
428 inode
= d_inode(dentry
);
431 if (unlikely(!d_is_dir(dentry
)))
432 goto out_unlock
; /* possible? */
435 args
= au_whtmp_rmdir_alloc(dir
->i_sb
, GFP_NOFS
);
439 parent
= dentry
->d_parent
; /* dir inode is locked */
440 di_write_lock_parent(parent
);
441 err
= au_test_empty(dentry
, &args
->whlist
);
445 btop
= au_dbtop(dentry
);
446 bwh
= au_dbwh(dentry
);
448 wh_dentry
= lock_hdir_create_wh(dentry
, /*isdir*/1, &bindex
, &a
->dt
,
450 err
= PTR_ERR(wh_dentry
);
451 if (IS_ERR(wh_dentry
))
454 h_dentry
= au_h_dptr(dentry
, btop
);
457 if (bindex
== btop
) {
458 err
= renwh_and_rmdir(dentry
, btop
, &args
->whlist
, dir
);
464 /* stop monitoring */
465 au_hn_free(au_hi(inode
, btop
));
467 /* dir inode is locked */
468 IMustLock(d_inode(wh_dentry
->d_parent
));
473 vfsub_dead_dir(inode
);
474 au_set_dbdiropq(dentry
, -1);
475 epilog(dir
, dentry
, bindex
);
478 au_whtmp_kick_rmdir(dir
, btop
, h_dentry
, args
);
482 goto out_unpin
; /* success */
490 rerr
= do_revert(err
, dir
, bindex
, bwh
, wh_dentry
, dentry
,
501 di_write_unlock(parent
);
503 au_whtmp_rmdir_free(args
);
505 aufs_read_unlock(dentry
, AuLock_DW
);