2 * Copyright (C) 2005-2012 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, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * inode operations (del entry)
26 * decide if a new whiteout for @dentry is necessary or not.
27 * when it is necessary, prepare the parent dir for the upper branch whose
28 * branch index is @bcpup for creation. the actual creation of the whiteout will
31 * 0: wh is unnecessary
32 * plus: wh is necessary
35 int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
39 struct super_block *sb;
42 bstart = au_dbstart(dentry);
45 if (au_test_ro(sb, bstart, dentry->d_inode)) {
46 err = AuWbrCopyup(au_sbi(sb), dentry);
48 if (unlikely(err < 0))
52 AuDebugOn(bstart < *bcpup
53 || au_test_ro(sb, *bcpup, dentry->d_inode));
54 AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
56 if (*bcpup != bstart) {
57 err = au_cpup_dirs(dentry, *bcpup);
62 struct au_dinfo *dinfo, *tmp;
65 dinfo = au_di(dentry);
66 tmp = au_di_alloc(sb, AuLsc_DI_TMP);
69 au_di_swap(tmp, dinfo);
70 /* returns the number of positive dentries */
71 need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0,
73 au_di_swap(tmp, dinfo);
74 au_rw_write_unlock(&tmp->di_rwsem);
78 AuDbg("need_wh %d\n", need_wh);
86 * simple tests for the del-entry operations.
87 * following the checks in vfs, plus the parent-child relationship.
89 int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
90 struct dentry *h_parent, int isdir)
94 struct dentry *h_dentry, *h_latest;
95 struct inode *h_inode;
97 h_dentry = au_h_dptr(dentry, bindex);
98 h_inode = h_dentry->d_inode;
99 if (dentry->d_inode) {
101 if (unlikely(!h_inode || !h_inode->i_nlink))
104 h_mode = h_inode->i_mode;
107 if (unlikely(S_ISDIR(h_mode)))
109 } else if (unlikely(!S_ISDIR(h_mode))) {
116 if (unlikely(h_inode))
121 /* expected parent dir is locked */
122 if (unlikely(h_parent != h_dentry->d_parent))
127 * rmdir a dir may break the consistency on some filesystem.
128 * let's try heavy test.
131 if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
134 h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
135 au_sbr(dentry->d_sb, bindex));
137 if (IS_ERR(h_latest))
139 if (h_latest == h_dentry)
148 * decide the branch where we operate for @dentry. the branch index will be set
149 * @rbcpup. after diciding it, 'pin' it and store the timestamps of the parent
151 * when a new whiteout is necessary, create it.
153 static struct dentry*
154 lock_hdir_create_wh(struct dentry *dentry, int isdir, aufs_bindex_t *rbcpup,
155 struct au_dtime *dt, struct au_pin *pin)
157 struct dentry *wh_dentry;
158 struct super_block *sb;
164 need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
165 wh_dentry = ERR_PTR(need_wh);
166 if (unlikely(need_wh < 0))
170 udba = au_opt_udba(sb);
172 err = au_pin(pin, dentry, bcpup, udba,
173 AuPin_DI_LOCKED | AuPin_MNT_WRITE);
174 wh_dentry = ERR_PTR(err);
178 h_path.dentry = au_pinned_h_parent(pin);
179 if (udba != AuOpt_UDBA_NONE
180 && au_dbstart(dentry) == bcpup) {
181 err = au_may_del(dentry, bcpup, h_path.dentry, isdir);
182 wh_dentry = ERR_PTR(err);
187 h_path.mnt = au_sbr_mnt(sb, bcpup);
188 au_dtime_store(dt, au_pinned_parent(pin), &h_path);
191 goto out; /* success, no need to create whiteout */
193 wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
194 if (IS_ERR(wh_dentry))
197 /* returns with the parent is locked and wh_dentry is dget-ed */
198 goto out; /* success */
207 * when removing a dir, rename it to a unique temporary whiteout-ed name first
208 * in order to be revertible and save time for removing many child whiteouts
210 * returns 1 when there are too many child whiteout and caller should remove
211 * them asynchronously. returns 0 when the number of children is enough small to
212 * remove now or the branch fs is a remote fs.
213 * otherwise return an error.
215 static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
216 struct au_nhash *whlist, struct inode *dir)
218 int rmdir_later, err, dirwh;
219 struct dentry *h_dentry;
220 struct super_block *sb;
224 h_dentry = au_h_dptr(dentry, bindex);
225 err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
229 /* stop monitoring */
230 au_hn_free(au_hi(dentry->d_inode, bindex));
232 if (!au_test_fs_remote(h_dentry->d_sb)) {
233 dirwh = au_sbi(sb)->si_dirwh;
234 rmdir_later = (dirwh <= 1);
236 rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
242 err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
244 AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
245 AuDLNPair(h_dentry), bindex, err);
255 * final procedure for deleting a entry.
256 * maintain dentry and iattr.
258 static void epilog(struct inode *dir, struct dentry *dentry,
259 aufs_bindex_t bindex)
263 inode = dentry->d_inode;
265 inode->i_ctime = dir->i_ctime;
267 if (au_ibstart(dir) == bindex)
268 au_cpup_attr_timesizes(dir);
273 * when an error happened, remove the created whiteout and revert everything.
275 static int do_revert(int err, struct inode *dir, aufs_bindex_t bindex,
276 aufs_bindex_t bwh, struct dentry *wh_dentry,
277 struct dentry *dentry, struct au_dtime *dt)
280 struct path h_path = {
282 .mnt = au_sbr_mnt(dir->i_sb, bindex)
285 rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
287 au_set_dbwh(dentry, bwh);
292 AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
293 AuDLNPair(dentry), err, rerr);
297 /* ---------------------------------------------------------------------- */
299 int aufs_unlink(struct inode *dir, struct dentry *dentry)
302 aufs_bindex_t bwh, bindex, bstart;
306 struct inode *inode, *h_dir;
307 struct dentry *parent, *wh_dentry;
311 err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
314 err = au_d_hashed_positive(dentry);
317 inode = dentry->d_inode;
320 if (unlikely(S_ISDIR(inode->i_mode)))
321 goto out_unlock; /* possible? */
323 bstart = au_dbstart(dentry);
324 bwh = au_dbwh(dentry);
326 parent = dentry->d_parent; /* dir inode is locked */
327 di_write_lock_parent(parent);
328 wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin);
329 err = PTR_ERR(wh_dentry);
330 if (IS_ERR(wh_dentry))
333 h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
334 h_path.dentry = au_h_dptr(dentry, bstart);
336 if (bindex == bstart) {
337 h_dir = au_pinned_h_dir(&pin);
338 err = vfsub_unlink(h_dir, &h_path, /*force*/0);
340 /* dir inode is locked */
341 h_dir = wh_dentry->d_parent->d_inode;
347 vfsub_drop_nlink(inode);
348 epilog(dir, dentry, bindex);
350 /* update target timestamps */
351 if (bindex == bstart) {
352 vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/
353 inode->i_ctime = h_path.dentry->d_inode->i_ctime;
355 /* todo: this timestamp may be reverted later */
356 inode->i_ctime = h_dir->i_ctime;
357 goto out_unpin; /* success */
364 rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
374 di_write_unlock(parent);
376 aufs_read_unlock(dentry, AuLock_DW);
381 int aufs_rmdir(struct inode *dir, struct dentry *dentry)
383 int err, rmdir_later;
384 aufs_bindex_t bwh, bindex, bstart;
388 struct dentry *parent, *wh_dentry, *h_dentry;
389 struct au_whtmp_rmdir *args;
393 err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
396 err = au_alive_dir(dentry);
399 inode = dentry->d_inode;
402 if (unlikely(!S_ISDIR(inode->i_mode)))
403 goto out_unlock; /* possible? */
406 args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
410 parent = dentry->d_parent; /* dir inode is locked */
411 di_write_lock_parent(parent);
412 err = au_test_empty(dentry, &args->whlist);
416 bstart = au_dbstart(dentry);
417 bwh = au_dbwh(dentry);
419 wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin);
420 err = PTR_ERR(wh_dentry);
421 if (IS_ERR(wh_dentry))
424 h_dentry = au_h_dptr(dentry, bstart);
427 if (bindex == bstart) {
428 err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
434 /* stop monitoring */
435 au_hn_free(au_hi(inode, bstart));
437 /* dir inode is locked */
438 IMustLock(wh_dentry->d_parent->d_inode);
443 vfsub_dead_dir(inode);
444 au_set_dbdiropq(dentry, -1);
445 epilog(dir, dentry, bindex);
448 au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
452 goto out_unpin; /* success */
460 rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt);
470 di_write_unlock(parent);
472 au_whtmp_rmdir_free(args);
474 aufs_read_unlock(dentry, AuLock_DW);