]>
git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blob - fs/aufs/i_op_del.c
1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2005-2020 Junjiro R. Okajima
5 * This program, aufs is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * inode operations (del entry)
23 #include <linux/iversion.h>
27 * decide if a new whiteout for @dentry is necessary or not.
28 * when it is necessary, prepare the parent dir for the upper branch whose
29 * branch index is @bcpup for creation. the actual creation of the whiteout will
32 * 0: wh is unnecessary
33 * plus: wh is necessary
36 int au_wr_dir_need_wh(struct dentry
*dentry
, int isdir
, aufs_bindex_t
*bcpup
)
40 struct super_block
*sb
;
43 btop
= au_dbtop(dentry
);
46 if (au_test_ro(sb
, btop
, d_inode(dentry
))) {
47 err
= AuWbrCopyup(au_sbi(sb
), dentry
);
49 if (unlikely(err
< 0))
53 AuDebugOn(btop
< *bcpup
54 || au_test_ro(sb
, *bcpup
, d_inode(dentry
)));
55 AuDbg("bcpup %d, btop %d\n", *bcpup
, btop
);
58 err
= au_cpup_dirs(dentry
, *bcpup
);
63 struct au_dinfo
*dinfo
, *tmp
;
66 dinfo
= au_di(dentry
);
67 tmp
= au_di_alloc(sb
, AuLsc_DI_TMP
);
70 au_di_swap(tmp
, dinfo
);
71 /* returns the number of positive dentries */
72 need_wh
= au_lkup_dentry(dentry
, btop
+ 1,
73 /* AuLkup_IGNORE_PERM */ 0);
74 au_di_swap(tmp
, dinfo
);
75 au_rw_write_unlock(&tmp
->di_rwsem
);
79 AuDbg("need_wh %d\n", need_wh
);
87 * simple tests for the del-entry operations.
88 * following the checks in vfs, plus the parent-child relationship.
90 int au_may_del(struct dentry
*dentry
, aufs_bindex_t bindex
,
91 struct dentry
*h_parent
, int isdir
)
95 struct dentry
*h_dentry
, *h_latest
;
96 struct inode
*h_inode
;
98 h_dentry
= au_h_dptr(dentry
, bindex
);
99 if (d_really_is_positive(dentry
)) {
101 if (unlikely(d_is_negative(h_dentry
)))
103 h_inode
= d_inode(h_dentry
);
104 if (unlikely(!h_inode
->i_nlink
))
107 h_mode
= h_inode
->i_mode
;
110 if (unlikely(S_ISDIR(h_mode
)))
112 } else if (unlikely(!S_ISDIR(h_mode
))) {
119 if (unlikely(d_is_positive(h_dentry
)))
124 /* expected parent dir is locked */
125 if (unlikely(h_parent
!= h_dentry
->d_parent
))
130 * rmdir a dir may break the consistency on some filesystem.
131 * let's try heavy test.
134 if (unlikely(!au_opt_test(au_mntflags(dentry
->d_sb
), DIRPERM1
)
135 && au_test_h_perm(d_inode(h_parent
),
136 MAY_EXEC
| MAY_WRITE
)))
139 h_latest
= au_sio_lkup_one(&dentry
->d_name
, h_parent
);
141 if (IS_ERR(h_latest
))
143 if (h_latest
== h_dentry
)
152 * decide the branch where we operate for @dentry. the branch index will be set
153 * @rbcpup. after deciding it, 'pin' it and store the timestamps of the parent
155 * when a new whiteout is necessary, create it.
157 static struct dentry
*
158 lock_hdir_create_wh(struct dentry
*dentry
, int isdir
, aufs_bindex_t
*rbcpup
,
159 struct au_dtime
*dt
, struct au_pin
*pin
)
161 struct dentry
*wh_dentry
;
162 struct super_block
*sb
;
168 need_wh
= au_wr_dir_need_wh(dentry
, isdir
, rbcpup
);
169 wh_dentry
= ERR_PTR(need_wh
);
170 if (unlikely(need_wh
< 0))
174 udba
= au_opt_udba(sb
);
176 err
= au_pin(pin
, dentry
, bcpup
, udba
,
177 AuPin_DI_LOCKED
| AuPin_MNT_WRITE
);
178 wh_dentry
= ERR_PTR(err
);
182 h_path
.dentry
= au_pinned_h_parent(pin
);
183 if (udba
!= AuOpt_UDBA_NONE
184 && au_dbtop(dentry
) == bcpup
) {
185 err
= au_may_del(dentry
, bcpup
, h_path
.dentry
, isdir
);
186 wh_dentry
= ERR_PTR(err
);
191 h_path
.mnt
= au_sbr_mnt(sb
, bcpup
);
192 au_dtime_store(dt
, au_pinned_parent(pin
), &h_path
);
195 goto out
; /* success, no need to create whiteout */
197 wh_dentry
= au_wh_create(dentry
, bcpup
, h_path
.dentry
);
198 if (IS_ERR(wh_dentry
))
201 /* returns with the parent is locked and wh_dentry is dget-ed */
202 goto out
; /* success */
211 * when removing a dir, rename it to a unique temporary whiteout-ed name first
212 * in order to be revertible and save time for removing many child whiteouts
214 * returns 1 when there are too many child whiteout and caller should remove
215 * them asynchronously. returns 0 when the number of children is enough small to
216 * remove now or the branch fs is a remote fs.
217 * otherwise return an error.
219 static int renwh_and_rmdir(struct dentry
*dentry
, aufs_bindex_t bindex
,
220 struct au_nhash
*whlist
, struct inode
*dir
)
222 int rmdir_later
, err
, dirwh
;
223 struct dentry
*h_dentry
;
224 struct super_block
*sb
;
229 h_dentry
= au_h_dptr(dentry
, bindex
);
230 err
= au_whtmp_ren(h_dentry
, au_sbr(sb
, bindex
));
234 /* stop monitoring */
235 inode
= d_inode(dentry
);
236 au_hn_free(au_hi(inode
, bindex
));
238 if (!au_test_fs_remote(h_dentry
->d_sb
)) {
239 dirwh
= au_sbi(sb
)->si_dirwh
;
240 rmdir_later
= (dirwh
<= 1);
242 rmdir_later
= au_nhash_test_longer_wh(whlist
, bindex
,
248 err
= au_whtmp_rmdir(dir
, bindex
, h_dentry
, whlist
);
250 AuIOErr("rmdir %pd, b%d failed, %d. ignored\n",
251 h_dentry
, bindex
, err
);
261 * final procedure for deleting a entry.
262 * maintain dentry and iattr.
264 static void epilog(struct inode
*dir
, struct dentry
*dentry
,
265 aufs_bindex_t bindex
)
269 inode
= d_inode(dentry
);
271 inode
->i_ctime
= dir
->i_ctime
;
273 au_dir_ts(dir
, bindex
);
274 inode_inc_iversion(dir
);
278 * when an error happened, remove the created whiteout and revert everything.
280 static int do_revert(int err
, struct inode
*dir
, aufs_bindex_t bindex
,
281 aufs_bindex_t bwh
, struct dentry
*wh_dentry
,
282 struct dentry
*dentry
, struct au_dtime
*dt
)
285 struct path h_path
= {
287 .mnt
= au_sbr_mnt(dir
->i_sb
, bindex
)
290 rerr
= au_wh_unlink_dentry(au_h_iptr(dir
, bindex
), &h_path
, dentry
);
292 au_set_dbwh(dentry
, bwh
);
297 AuIOErr("%pd reverting whiteout failed(%d, %d)\n", dentry
, err
, rerr
);
301 /* ---------------------------------------------------------------------- */
303 int aufs_unlink(struct inode
*dir
, struct dentry
*dentry
)
306 aufs_bindex_t bwh
, bindex
, btop
;
307 struct inode
*inode
, *h_dir
, *delegated
;
308 struct dentry
*parent
, *wh_dentry
;
309 /* to reduce stack size */
319 a
= kmalloc(sizeof(*a
), GFP_NOFS
);
323 err
= aufs_read_lock(dentry
, AuLock_DW
| AuLock_GEN
);
326 err
= au_d_hashed_positive(dentry
);
329 inode
= d_inode(dentry
);
332 if (unlikely(d_is_dir(dentry
)))
333 goto out_unlock
; /* possible? */
335 btop
= au_dbtop(dentry
);
336 bwh
= au_dbwh(dentry
);
338 parent
= dentry
->d_parent
; /* dir inode is locked */
339 di_write_lock_parent(parent
);
340 wh_dentry
= lock_hdir_create_wh(dentry
, /*isdir*/0, &bindex
, &a
->dt
,
342 err
= PTR_ERR(wh_dentry
);
343 if (IS_ERR(wh_dentry
))
346 a
->h_path
.mnt
= au_sbr_mnt(dentry
->d_sb
, btop
);
347 a
->h_path
.dentry
= au_h_dptr(dentry
, btop
);
348 dget(a
->h_path
.dentry
);
349 if (bindex
== btop
) {
350 h_dir
= au_pinned_h_dir(&a
->pin
);
352 err
= vfsub_unlink(h_dir
, &a
->h_path
, &delegated
, /*force*/0);
353 if (unlikely(err
== -EWOULDBLOCK
)) {
354 pr_warn("cannot retry for NFSv4 delegation"
355 " for an internal unlink\n");
359 /* dir inode is locked */
360 h_dir
= d_inode(wh_dentry
->d_parent
);
366 vfsub_drop_nlink(inode
);
367 epilog(dir
, dentry
, bindex
);
369 /* update target timestamps */
370 if (bindex
== btop
) {
371 vfsub_update_h_iattr(&a
->h_path
, /*did*/NULL
);
373 inode
->i_ctime
= d_inode(a
->h_path
.dentry
)->i_ctime
;
375 /* todo: this timestamp may be reverted later */
376 inode
->i_ctime
= h_dir
->i_ctime
;
377 goto out_unpin
; /* success */
384 rerr
= do_revert(err
, dir
, bindex
, bwh
, wh_dentry
, dentry
,
393 dput(a
->h_path
.dentry
);
395 di_write_unlock(parent
);
397 aufs_read_unlock(dentry
, AuLock_DW
);
404 int aufs_rmdir(struct inode
*dir
, struct dentry
*dentry
)
406 int err
, rmdir_later
;
407 aufs_bindex_t bwh
, bindex
, btop
;
409 struct dentry
*parent
, *wh_dentry
, *h_dentry
;
410 struct au_whtmp_rmdir
*args
;
411 /* to reduce stack size */
420 a
= kmalloc(sizeof(*a
), GFP_NOFS
);
424 err
= aufs_read_lock(dentry
, AuLock_DW
| AuLock_FLUSH
| AuLock_GEN
);
427 err
= au_alive_dir(dentry
);
430 inode
= d_inode(dentry
);
433 if (unlikely(!d_is_dir(dentry
)))
434 goto out_unlock
; /* possible? */
437 args
= au_whtmp_rmdir_alloc(dir
->i_sb
, GFP_NOFS
);
441 parent
= dentry
->d_parent
; /* dir inode is locked */
442 di_write_lock_parent(parent
);
443 err
= au_test_empty(dentry
, &args
->whlist
);
447 btop
= au_dbtop(dentry
);
448 bwh
= au_dbwh(dentry
);
450 wh_dentry
= lock_hdir_create_wh(dentry
, /*isdir*/1, &bindex
, &a
->dt
,
452 err
= PTR_ERR(wh_dentry
);
453 if (IS_ERR(wh_dentry
))
456 h_dentry
= au_h_dptr(dentry
, btop
);
459 if (bindex
== btop
) {
460 err
= renwh_and_rmdir(dentry
, btop
, &args
->whlist
, dir
);
466 /* stop monitoring */
467 au_hn_free(au_hi(inode
, btop
));
469 /* dir inode is locked */
470 IMustLock(d_inode(wh_dentry
->d_parent
));
475 vfsub_dead_dir(inode
);
476 au_set_dbdiropq(dentry
, -1);
477 epilog(dir
, dentry
, bindex
);
480 au_whtmp_kick_rmdir(dir
, btop
, h_dentry
, args
);
484 goto out_unpin
; /* success */
492 rerr
= do_revert(err
, dir
, bindex
, bwh
, wh_dentry
, dentry
,
503 di_write_unlock(parent
);
505 au_whtmp_rmdir_free(args
);
507 aufs_read_unlock(dentry
, AuLock_DW
);