aufs: debug, from aufs2.2-3.0
[zen-stable.git] / fs / aufs / plink.c
blobb1888f30c7199b0fef3dd36d22886a07e3f8fcf7
1 /*
2 * Copyright (C) 2005-2011 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 * pseudo-link
23 #include "aufs.h"
26 * the pseudo-link maintenance mode.
27 * during a user process maintains the pseudo-links,
28 * prohibit adding a new plink and branch manipulation.
30 * Flags
31 * NOPLM:
32 * For entry functions which will handle plink, and i_mutex is already held
33 * in VFS.
34 * They cannot wait and should return an error at once.
35 * Callers has to check the error.
36 * NOPLMW:
37 * For entry functions which will handle plink, but i_mutex is not held
38 * in VFS.
39 * They can wait the plink maintenance mode to finish.
41 * They behave like F_SETLK and F_SETLKW.
42 * If the caller never handle plink, then both flags are unnecessary.
45 int au_plink_maint(struct super_block *sb, int flags)
47 int err;
48 pid_t pid, ppid;
49 struct au_sbinfo *sbi;
51 SiMustAnyLock(sb);
53 err = 0;
54 if (!au_opt_test(au_mntflags(sb), PLINK))
55 goto out;
57 sbi = au_sbi(sb);
58 pid = sbi->si_plink_maint_pid;
59 if (!pid || pid == current->pid)
60 goto out;
62 /* todo: it highly depends upon /sbin/mount.aufs */
63 rcu_read_lock();
64 ppid = task_pid_vnr(rcu_dereference(current->real_parent));
65 rcu_read_unlock();
66 if (pid == ppid)
67 goto out;
69 if (au_ftest_lock(flags, NOPLMW)) {
70 /* if there is no i_mutex lock in VFS, we don't need to wait */
71 /* AuDebugOn(!lockdep_depth(current)); */
72 while (sbi->si_plink_maint_pid) {
73 si_read_unlock(sb);
74 /* gave up wake_up_bit() */
75 wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
77 if (au_ftest_lock(flags, FLUSH))
78 au_nwt_flush(&sbi->si_nowait);
79 si_noflush_read_lock(sb);
81 } else if (au_ftest_lock(flags, NOPLM)) {
82 AuDbg("ppid %d, pid %d\n", ppid, pid);
83 err = -EAGAIN;
86 out:
87 return err;
90 void au_plink_maint_leave(struct au_sbinfo *sbinfo)
92 spin_lock(&sbinfo->si_plink_maint_lock);
93 sbinfo->si_plink_maint_pid = 0;
94 spin_unlock(&sbinfo->si_plink_maint_lock);
95 wake_up_all(&sbinfo->si_plink_wq);
98 int au_plink_maint_enter(struct super_block *sb)
100 int err;
101 struct au_sbinfo *sbinfo;
103 err = 0;
104 sbinfo = au_sbi(sb);
105 /* make sure i am the only one in this fs */
106 si_write_lock(sb, AuLock_FLUSH);
107 if (au_opt_test(au_mntflags(sb), PLINK)) {
108 spin_lock(&sbinfo->si_plink_maint_lock);
109 if (!sbinfo->si_plink_maint_pid)
110 sbinfo->si_plink_maint_pid = current->pid;
111 else
112 err = -EBUSY;
113 spin_unlock(&sbinfo->si_plink_maint_lock);
115 si_write_unlock(sb);
117 return err;
120 /* ---------------------------------------------------------------------- */
122 struct pseudo_link {
123 union {
124 struct list_head list;
125 struct rcu_head rcu;
127 struct inode *inode;
130 #ifdef CONFIG_AUFS_DEBUG
131 void au_plink_list(struct super_block *sb)
133 struct au_sbinfo *sbinfo;
134 struct list_head *plink_list;
135 struct pseudo_link *plink;
137 SiMustAnyLock(sb);
139 sbinfo = au_sbi(sb);
140 AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
141 AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
143 plink_list = &sbinfo->si_plink.head;
144 rcu_read_lock();
145 list_for_each_entry_rcu(plink, plink_list, list)
146 AuDbg("%lu\n", plink->inode->i_ino);
147 rcu_read_unlock();
149 #endif
151 /* is the inode pseudo-linked? */
152 int au_plink_test(struct inode *inode)
154 int found;
155 struct au_sbinfo *sbinfo;
156 struct list_head *plink_list;
157 struct pseudo_link *plink;
159 sbinfo = au_sbi(inode->i_sb);
160 AuRwMustAnyLock(&sbinfo->si_rwsem);
161 AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
162 AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
164 found = 0;
165 plink_list = &sbinfo->si_plink.head;
166 rcu_read_lock();
167 list_for_each_entry_rcu(plink, plink_list, list)
168 if (plink->inode == inode) {
169 found = 1;
170 break;
172 rcu_read_unlock();
173 return found;
176 /* ---------------------------------------------------------------------- */
179 * generate a name for plink.
180 * the file will be stored under AUFS_WH_PLINKDIR.
182 /* 20 is max digits length of ulong 64 */
183 #define PLINK_NAME_LEN ((20 + 1) * 2)
185 static int plink_name(char *name, int len, struct inode *inode,
186 aufs_bindex_t bindex)
188 int rlen;
189 struct inode *h_inode;
191 h_inode = au_h_iptr(inode, bindex);
192 rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
193 return rlen;
196 struct au_do_plink_lkup_args {
197 struct dentry **errp;
198 struct qstr *tgtname;
199 struct dentry *h_parent;
200 struct au_branch *br;
203 static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
204 struct dentry *h_parent,
205 struct au_branch *br)
207 struct dentry *h_dentry;
208 struct mutex *h_mtx;
210 h_mtx = &h_parent->d_inode->i_mutex;
211 mutex_lock_nested(h_mtx, AuLsc_I_CHILD2);
212 h_dentry = au_lkup_one(tgtname, h_parent, br, /*nd*/NULL);
213 mutex_unlock(h_mtx);
214 return h_dentry;
217 static void au_call_do_plink_lkup(void *args)
219 struct au_do_plink_lkup_args *a = args;
220 *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
223 /* lookup the plink-ed @inode under the branch at @bindex */
224 struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
226 struct dentry *h_dentry, *h_parent;
227 struct au_branch *br;
228 struct inode *h_dir;
229 int wkq_err;
230 char a[PLINK_NAME_LEN];
231 struct qstr tgtname = {
232 .name = a
235 AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
237 br = au_sbr(inode->i_sb, bindex);
238 h_parent = br->br_wbr->wbr_plink;
239 h_dir = h_parent->d_inode;
240 tgtname.len = plink_name(a, sizeof(a), inode, bindex);
242 if (current_fsuid()) {
243 struct au_do_plink_lkup_args args = {
244 .errp = &h_dentry,
245 .tgtname = &tgtname,
246 .h_parent = h_parent,
247 .br = br
250 wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
251 if (unlikely(wkq_err))
252 h_dentry = ERR_PTR(wkq_err);
253 } else
254 h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
256 return h_dentry;
259 /* create a pseudo-link */
260 static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
261 struct dentry *h_dentry, struct au_branch *br)
263 int err;
264 struct path h_path = {
265 .mnt = br->br_mnt
267 struct inode *h_dir;
269 h_dir = h_parent->d_inode;
270 mutex_lock_nested(&h_dir->i_mutex, AuLsc_I_CHILD2);
271 again:
272 h_path.dentry = au_lkup_one(tgt, h_parent, br, /*nd*/NULL);
273 err = PTR_ERR(h_path.dentry);
274 if (IS_ERR(h_path.dentry))
275 goto out;
277 err = 0;
278 /* wh.plink dir is not monitored */
279 /* todo: is it really safe? */
280 if (h_path.dentry->d_inode
281 && h_path.dentry->d_inode != h_dentry->d_inode) {
282 err = vfsub_unlink(h_dir, &h_path, /*force*/0);
283 dput(h_path.dentry);
284 h_path.dentry = NULL;
285 if (!err)
286 goto again;
288 if (!err && !h_path.dentry->d_inode)
289 err = vfsub_link(h_dentry, h_dir, &h_path);
290 dput(h_path.dentry);
292 out:
293 mutex_unlock(&h_dir->i_mutex);
294 return err;
297 struct do_whplink_args {
298 int *errp;
299 struct qstr *tgt;
300 struct dentry *h_parent;
301 struct dentry *h_dentry;
302 struct au_branch *br;
305 static void call_do_whplink(void *args)
307 struct do_whplink_args *a = args;
308 *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
311 static int whplink(struct dentry *h_dentry, struct inode *inode,
312 aufs_bindex_t bindex, struct au_branch *br)
314 int err, wkq_err;
315 struct au_wbr *wbr;
316 struct dentry *h_parent;
317 struct inode *h_dir;
318 char a[PLINK_NAME_LEN];
319 struct qstr tgtname = {
320 .name = a
323 wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
324 h_parent = wbr->wbr_plink;
325 h_dir = h_parent->d_inode;
326 tgtname.len = plink_name(a, sizeof(a), inode, bindex);
328 /* always superio. */
329 if (current_fsuid()) {
330 struct do_whplink_args args = {
331 .errp = &err,
332 .tgt = &tgtname,
333 .h_parent = h_parent,
334 .h_dentry = h_dentry,
335 .br = br
337 wkq_err = au_wkq_wait(call_do_whplink, &args);
338 if (unlikely(wkq_err))
339 err = wkq_err;
340 } else
341 err = do_whplink(&tgtname, h_parent, h_dentry, br);
343 return err;
346 /* free a single plink */
347 static void do_put_plink(struct pseudo_link *plink, int do_del)
349 if (do_del)
350 list_del(&plink->list);
351 iput(plink->inode);
352 kfree(plink);
355 static void do_put_plink_rcu(struct rcu_head *rcu)
357 struct pseudo_link *plink;
359 plink = container_of(rcu, struct pseudo_link, rcu);
360 iput(plink->inode);
361 kfree(plink);
365 * create a new pseudo-link for @h_dentry on @bindex.
366 * the linked inode is held in aufs @inode.
368 void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
369 struct dentry *h_dentry)
371 struct super_block *sb;
372 struct au_sbinfo *sbinfo;
373 struct list_head *plink_list;
374 struct pseudo_link *plink, *tmp;
375 int found, err, cnt;
377 sb = inode->i_sb;
378 sbinfo = au_sbi(sb);
379 AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
380 AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
382 cnt = 0;
383 found = 0;
384 plink_list = &sbinfo->si_plink.head;
385 rcu_read_lock();
386 list_for_each_entry_rcu(plink, plink_list, list) {
387 cnt++;
388 if (plink->inode == inode) {
389 found = 1;
390 break;
393 rcu_read_unlock();
394 if (found)
395 return;
397 tmp = kmalloc(sizeof(*plink), GFP_NOFS);
398 if (tmp)
399 tmp->inode = au_igrab(inode);
400 else {
401 err = -ENOMEM;
402 goto out;
405 spin_lock(&sbinfo->si_plink.spin);
406 list_for_each_entry(plink, plink_list, list) {
407 if (plink->inode == inode) {
408 found = 1;
409 break;
412 if (!found)
413 list_add_rcu(&tmp->list, plink_list);
414 spin_unlock(&sbinfo->si_plink.spin);
415 if (!found) {
416 cnt++;
417 WARN_ONCE(cnt > AUFS_PLINK_WARN,
418 "unexpectedly many pseudo links, %d\n", cnt);
419 err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
420 } else {
421 do_put_plink(tmp, 0);
422 return;
425 out:
426 if (unlikely(err)) {
427 pr_warning("err %d, damaged pseudo link.\n", err);
428 if (tmp) {
429 au_spl_del_rcu(&tmp->list, &sbinfo->si_plink);
430 call_rcu(&tmp->rcu, do_put_plink_rcu);
435 /* free all plinks */
436 void au_plink_put(struct super_block *sb, int verbose)
438 struct au_sbinfo *sbinfo;
439 struct list_head *plink_list;
440 struct pseudo_link *plink, *tmp;
442 SiMustWriteLock(sb);
444 sbinfo = au_sbi(sb);
445 AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
446 AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
448 plink_list = &sbinfo->si_plink.head;
449 /* no spin_lock since sbinfo is write-locked */
450 WARN(verbose && !list_empty(plink_list), "pseudo-link is not flushed");
451 list_for_each_entry_safe(plink, tmp, plink_list, list)
452 do_put_plink(plink, 0);
453 INIT_LIST_HEAD(plink_list);
456 void au_plink_clean(struct super_block *sb, int verbose)
458 struct dentry *root;
460 root = sb->s_root;
461 aufs_write_lock(root);
462 if (au_opt_test(au_mntflags(sb), PLINK))
463 au_plink_put(sb, verbose);
464 aufs_write_unlock(root);
467 /* free the plinks on a branch specified by @br_id */
468 void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
470 struct au_sbinfo *sbinfo;
471 struct list_head *plink_list;
472 struct pseudo_link *plink, *tmp;
473 struct inode *inode;
474 aufs_bindex_t bstart, bend, bindex;
475 unsigned char do_put;
477 SiMustWriteLock(sb);
479 sbinfo = au_sbi(sb);
480 AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
481 AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
483 plink_list = &sbinfo->si_plink.head;
484 /* no spin_lock since sbinfo is write-locked */
485 list_for_each_entry_safe(plink, tmp, plink_list, list) {
486 do_put = 0;
487 inode = au_igrab(plink->inode);
488 ii_write_lock_child(inode);
489 bstart = au_ibstart(inode);
490 bend = au_ibend(inode);
491 if (bstart >= 0) {
492 for (bindex = bstart; bindex <= bend; bindex++) {
493 if (!au_h_iptr(inode, bindex)
494 || au_ii_br_id(inode, bindex) != br_id)
495 continue;
496 au_set_h_iptr(inode, bindex, NULL, 0);
497 do_put = 1;
498 break;
500 } else
501 do_put_plink(plink, 1);
503 if (do_put) {
504 for (bindex = bstart; bindex <= bend; bindex++)
505 if (au_h_iptr(inode, bindex)) {
506 do_put = 0;
507 break;
509 if (do_put)
510 do_put_plink(plink, 1);
512 ii_write_unlock(inode);
513 iput(inode);