Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / fs / aufs / i_op_del.c
1 /*
2  * Copyright (C) 2005-2013 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, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18
19 /*
20  * inode operations (del entry)
21  */
22
23 #include "aufs.h"
24
25 /*
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
29  * be done by caller.
30  * return value:
31  * 0: wh is unnecessary
32  * plus: wh is necessary
33  * minus: error
34  */
35 int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup)
36 {
37         int need_wh, err;
38         aufs_bindex_t bstart;
39         struct super_block *sb;
40
41         sb = dentry->d_sb;
42         bstart = au_dbstart(dentry);
43         if (*bcpup < 0) {
44                 *bcpup = bstart;
45                 if (au_test_ro(sb, bstart, dentry->d_inode)) {
46                         err = AuWbrCopyup(au_sbi(sb), dentry);
47                         *bcpup = err;
48                         if (unlikely(err < 0))
49                                 goto out;
50                 }
51         } else
52                 AuDebugOn(bstart < *bcpup
53                           || au_test_ro(sb, *bcpup, dentry->d_inode));
54         AuDbg("bcpup %d, bstart %d\n", *bcpup, bstart);
55
56         if (*bcpup != bstart) {
57                 err = au_cpup_dirs(dentry, *bcpup);
58                 if (unlikely(err))
59                         goto out;
60                 need_wh = 1;
61         } else {
62                 struct au_dinfo *dinfo, *tmp;
63
64                 need_wh = -ENOMEM;
65                 dinfo = au_di(dentry);
66                 tmp = au_di_alloc(sb, AuLsc_DI_TMP);
67                 if (tmp) {
68                         au_di_cp(tmp, dinfo);
69                         au_di_swap(tmp, dinfo);
70                         /* returns the number of positive dentries */
71                         need_wh = au_lkup_dentry(dentry, bstart + 1, /*type*/0,
72                                                  /*nd*/NULL);
73                         au_di_swap(tmp, dinfo);
74                         au_rw_write_unlock(&tmp->di_rwsem);
75                         au_di_free(tmp);
76                 }
77         }
78         AuDbg("need_wh %d\n", need_wh);
79         err = need_wh;
80
81 out:
82         return err;
83 }
84
85 /*
86  * simple tests for the del-entry operations.
87  * following the checks in vfs, plus the parent-child relationship.
88  */
89 int au_may_del(struct dentry *dentry, aufs_bindex_t bindex,
90                struct dentry *h_parent, int isdir)
91 {
92         int err;
93         umode_t h_mode;
94         struct dentry *h_dentry, *h_latest;
95         struct inode *h_inode;
96
97         h_dentry = au_h_dptr(dentry, bindex);
98         h_inode = h_dentry->d_inode;
99         if (dentry->d_inode) {
100                 err = -ENOENT;
101                 if (unlikely(!h_inode || !h_inode->i_nlink))
102                         goto out;
103
104                 h_mode = h_inode->i_mode;
105                 if (!isdir) {
106                         err = -EISDIR;
107                         if (unlikely(S_ISDIR(h_mode)))
108                                 goto out;
109                 } else if (unlikely(!S_ISDIR(h_mode))) {
110                         err = -ENOTDIR;
111                         goto out;
112                 }
113         } else {
114                 /* rename(2) case */
115                 err = -EIO;
116                 if (unlikely(h_inode))
117                         goto out;
118         }
119
120         err = -ENOENT;
121         /* expected parent dir is locked */
122         if (unlikely(h_parent != h_dentry->d_parent))
123                 goto out;
124         err = 0;
125
126         /*
127          * rmdir a dir may break the consistency on some filesystem.
128          * let's try heavy test.
129          */
130         err = -EACCES;
131         if (unlikely(au_test_h_perm(h_parent->d_inode, MAY_EXEC | MAY_WRITE)))
132                 goto out;
133
134         h_latest = au_sio_lkup_one(&dentry->d_name, h_parent,
135                                    au_sbr(dentry->d_sb, bindex));
136         err = -EIO;
137         if (IS_ERR(h_latest))
138                 goto out;
139         if (h_latest == h_dentry)
140                 err = 0;
141         dput(h_latest);
142
143 out:
144         return err;
145 }
146
147 /*
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
150  * dir for reverting.
151  * when a new whiteout is necessary, create it.
152  */
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)
156 {
157         struct dentry *wh_dentry;
158         struct super_block *sb;
159         struct path h_path;
160         int err, need_wh;
161         unsigned int udba;
162         aufs_bindex_t bcpup;
163
164         need_wh = au_wr_dir_need_wh(dentry, isdir, rbcpup);
165         wh_dentry = ERR_PTR(need_wh);
166         if (unlikely(need_wh < 0))
167                 goto out;
168
169         sb = dentry->d_sb;
170         udba = au_opt_udba(sb);
171         bcpup = *rbcpup;
172         err = au_pin(pin, dentry, bcpup, udba,
173                      AuPin_DI_LOCKED | AuPin_MNT_WRITE);
174         wh_dentry = ERR_PTR(err);
175         if (unlikely(err))
176                 goto out;
177
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);
183                 if (unlikely(err))
184                         goto out_unpin;
185         }
186
187         h_path.mnt = au_sbr_mnt(sb, bcpup);
188         au_dtime_store(dt, au_pinned_parent(pin), &h_path);
189         wh_dentry = NULL;
190         if (!need_wh)
191                 goto out; /* success, no need to create whiteout */
192
193         wh_dentry = au_wh_create(dentry, bcpup, h_path.dentry);
194         if (IS_ERR(wh_dentry))
195                 goto out_unpin;
196
197         /* returns with the parent is locked and wh_dentry is dget-ed */
198         goto out; /* success */
199
200 out_unpin:
201         au_unpin(pin);
202 out:
203         return wh_dentry;
204 }
205
206 /*
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
209  * under the dir.
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.
214  */
215 static int renwh_and_rmdir(struct dentry *dentry, aufs_bindex_t bindex,
216                            struct au_nhash *whlist, struct inode *dir)
217 {
218         int rmdir_later, err, dirwh;
219         struct dentry *h_dentry;
220         struct super_block *sb;
221
222         sb = dentry->d_sb;
223         SiMustAnyLock(sb);
224         h_dentry = au_h_dptr(dentry, bindex);
225         err = au_whtmp_ren(h_dentry, au_sbr(sb, bindex));
226         if (unlikely(err))
227                 goto out;
228
229         /* stop monitoring */
230         au_hn_free(au_hi(dentry->d_inode, bindex));
231
232         if (!au_test_fs_remote(h_dentry->d_sb)) {
233                 dirwh = au_sbi(sb)->si_dirwh;
234                 rmdir_later = (dirwh <= 1);
235                 if (!rmdir_later)
236                         rmdir_later = au_nhash_test_longer_wh(whlist, bindex,
237                                                               dirwh);
238                 if (rmdir_later)
239                         return rmdir_later;
240         }
241
242         err = au_whtmp_rmdir(dir, bindex, h_dentry, whlist);
243         if (unlikely(err)) {
244                 AuIOErr("rmdir %.*s, b%d failed, %d. ignored\n",
245                         AuDLNPair(h_dentry), bindex, err);
246                 err = 0;
247         }
248
249 out:
250         AuTraceErr(err);
251         return err;
252 }
253
254 /*
255  * final procedure for deleting a entry.
256  * maintain dentry and iattr.
257  */
258 static void epilog(struct inode *dir, struct dentry *dentry,
259                    aufs_bindex_t bindex)
260 {
261         struct inode *inode;
262
263         inode = dentry->d_inode;
264         d_drop(dentry);
265         inode->i_ctime = dir->i_ctime;
266
267         if (au_ibstart(dir) == bindex)
268                 au_cpup_attr_timesizes(dir);
269         dir->i_version++;
270 }
271
272 /*
273  * when an error happened, remove the created whiteout and revert everything.
274  */
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)
278 {
279         int rerr;
280         struct path h_path = {
281                 .dentry = wh_dentry,
282                 .mnt    = au_sbr_mnt(dir->i_sb, bindex)
283         };
284
285         rerr = au_wh_unlink_dentry(au_h_iptr(dir, bindex), &h_path, dentry);
286         if (!rerr) {
287                 au_set_dbwh(dentry, bwh);
288                 au_dtime_revert(dt);
289                 return 0;
290         }
291
292         AuIOErr("%.*s reverting whiteout failed(%d, %d)\n",
293                 AuDLNPair(dentry), err, rerr);
294         return -EIO;
295 }
296
297 /* ---------------------------------------------------------------------- */
298
299 int aufs_unlink(struct inode *dir, struct dentry *dentry)
300 {
301         int err;
302         aufs_bindex_t bwh, bindex, bstart;
303         struct inode *inode, *h_dir;
304         struct dentry *parent, *wh_dentry;
305         /* to reuduce stack size */
306         struct {
307                 struct au_dtime dt;
308                 struct au_pin pin;
309                 struct path h_path;
310         } *a;
311
312         IMustLock(dir);
313
314         err = -ENOMEM;
315         a = kmalloc(sizeof(*a), GFP_NOFS);
316         if (unlikely(!a))
317                 goto out;
318
319         err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN);
320         if (unlikely(err))
321                 goto out_free;
322         err = au_d_hashed_positive(dentry);
323         if (unlikely(err))
324                 goto out_unlock;
325         inode = dentry->d_inode;
326         IMustLock(inode);
327         err = -EISDIR;
328         if (unlikely(S_ISDIR(inode->i_mode)))
329                 goto out_unlock; /* possible? */
330
331         bstart = au_dbstart(dentry);
332         bwh = au_dbwh(dentry);
333         bindex = -1;
334         parent = dentry->d_parent; /* dir inode is locked */
335         di_write_lock_parent(parent);
336         wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt,
337                                         &a->pin);
338         err = PTR_ERR(wh_dentry);
339         if (IS_ERR(wh_dentry))
340                 goto out_parent;
341
342         a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart);
343         a->h_path.dentry = au_h_dptr(dentry, bstart);
344         dget(a->h_path.dentry);
345         if (bindex == bstart) {
346                 h_dir = au_pinned_h_dir(&a->pin);
347                 err = vfsub_unlink(h_dir, &a->h_path, /*force*/0);
348         } else {
349                 /* dir inode is locked */
350                 h_dir = wh_dentry->d_parent->d_inode;
351                 IMustLock(h_dir);
352                 err = 0;
353         }
354
355         if (!err) {
356                 vfsub_drop_nlink(inode);
357                 epilog(dir, dentry, bindex);
358
359                 /* update target timestamps */
360                 if (bindex == bstart) {
361                         vfsub_update_h_iattr(&a->h_path, /*did*/NULL);
362                         /*ignore*/
363                         inode->i_ctime = a->h_path.dentry->d_inode->i_ctime;
364                 } else
365                         /* todo: this timestamp may be reverted later */
366                         inode->i_ctime = h_dir->i_ctime;
367                 goto out_unpin; /* success */
368         }
369
370         /* revert */
371         if (wh_dentry) {
372                 int rerr;
373
374                 rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
375                                  &a->dt);
376                 if (rerr)
377                         err = rerr;
378         }
379
380 out_unpin:
381         au_unpin(&a->pin);
382         dput(wh_dentry);
383         dput(a->h_path.dentry);
384 out_parent:
385         di_write_unlock(parent);
386 out_unlock:
387         aufs_read_unlock(dentry, AuLock_DW);
388 out_free:
389         kfree(a);
390 out:
391         return err;
392 }
393
394 int aufs_rmdir(struct inode *dir, struct dentry *dentry)
395 {
396         int err, rmdir_later;
397         aufs_bindex_t bwh, bindex, bstart;
398         struct inode *inode;
399         struct dentry *parent, *wh_dentry, *h_dentry;
400         struct au_whtmp_rmdir *args;
401         /* to reuduce stack size */
402         struct {
403                 struct au_dtime dt;
404                 struct au_pin pin;
405         } *a;
406
407         IMustLock(dir);
408
409         err = -ENOMEM;
410         a = kmalloc(sizeof(*a), GFP_NOFS);
411         if (unlikely(!a))
412                 goto out;
413
414         err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN);
415         if (unlikely(err))
416                 goto out_free;
417         err = au_alive_dir(dentry);
418         if (unlikely(err))
419                 goto out_unlock;
420         inode = dentry->d_inode;
421         IMustLock(inode);
422         err = -ENOTDIR;
423         if (unlikely(!S_ISDIR(inode->i_mode)))
424                 goto out_unlock; /* possible? */
425
426         err = -ENOMEM;
427         args = au_whtmp_rmdir_alloc(dir->i_sb, GFP_NOFS);
428         if (unlikely(!args))
429                 goto out_unlock;
430
431         parent = dentry->d_parent; /* dir inode is locked */
432         di_write_lock_parent(parent);
433         err = au_test_empty(dentry, &args->whlist);
434         if (unlikely(err))
435                 goto out_parent;
436
437         bstart = au_dbstart(dentry);
438         bwh = au_dbwh(dentry);
439         bindex = -1;
440         wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt,
441                                         &a->pin);
442         err = PTR_ERR(wh_dentry);
443         if (IS_ERR(wh_dentry))
444                 goto out_parent;
445
446         h_dentry = au_h_dptr(dentry, bstart);
447         dget(h_dentry);
448         rmdir_later = 0;
449         if (bindex == bstart) {
450                 err = renwh_and_rmdir(dentry, bstart, &args->whlist, dir);
451                 if (err > 0) {
452                         rmdir_later = err;
453                         err = 0;
454                 }
455         } else {
456                 /* stop monitoring */
457                 au_hn_free(au_hi(inode, bstart));
458
459                 /* dir inode is locked */
460                 IMustLock(wh_dentry->d_parent->d_inode);
461                 err = 0;
462         }
463
464         if (!err) {
465                 vfsub_dead_dir(inode);
466                 au_set_dbdiropq(dentry, -1);
467                 epilog(dir, dentry, bindex);
468
469                 if (rmdir_later) {
470                         au_whtmp_kick_rmdir(dir, bstart, h_dentry, args);
471                         args = NULL;
472                 }
473
474                 goto out_unpin; /* success */
475         }
476
477         /* revert */
478         AuLabel(revert);
479         if (wh_dentry) {
480                 int rerr;
481
482                 rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry,
483                                  &a->dt);
484                 if (rerr)
485                         err = rerr;
486         }
487
488 out_unpin:
489         au_unpin(&a->pin);
490         dput(wh_dentry);
491         dput(h_dentry);
492 out_parent:
493         di_write_unlock(parent);
494         if (args)
495                 au_whtmp_rmdir_free(args);
496 out_unlock:
497         aufs_read_unlock(dentry, AuLock_DW);
498 out_free:
499         kfree(a);
500 out:
501         AuTraceErr(err);
502         return err;
503 }