]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - fs/aufs/plink.c
UBUNTU: Ubuntu-4.13.0-45.50
[mirror_ubuntu-artful-kernel.git] / fs / aufs / plink.c
CommitLineData
b6450630
SF
1/*
2 * Copyright (C) 2005-2017 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, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * pseudo-link
20 */
21
22#include "aufs.h"
23
24/*
25 * the pseudo-link maintenance mode.
26 * during a user process maintains the pseudo-links,
27 * prohibit adding a new plink and branch manipulation.
28 *
29 * Flags
30 * NOPLM:
31 * For entry functions which will handle plink, and i_mutex is already held
32 * in VFS.
33 * They cannot wait and should return an error at once.
34 * Callers has to check the error.
35 * NOPLMW:
36 * For entry functions which will handle plink, but i_mutex is not held
37 * in VFS.
38 * They can wait the plink maintenance mode to finish.
39 *
40 * They behave like F_SETLK and F_SETLKW.
41 * If the caller never handle plink, then both flags are unnecessary.
42 */
43
44int au_plink_maint(struct super_block *sb, int flags)
45{
46 int err;
47 pid_t pid, ppid;
48 struct task_struct *parent, *prev;
49 struct au_sbinfo *sbi;
50
51 SiMustAnyLock(sb);
52
53 err = 0;
54 if (!au_opt_test(au_mntflags(sb), PLINK))
55 goto out;
56
57 sbi = au_sbi(sb);
58 pid = sbi->si_plink_maint_pid;
59 if (!pid || pid == current->pid)
60 goto out;
61
62 /* todo: it highly depends upon /sbin/mount.aufs */
63 prev = NULL;
64 parent = current;
65 ppid = 0;
66 rcu_read_lock();
67 while (1) {
68 parent = rcu_dereference(parent->real_parent);
69 if (parent == prev)
70 break;
71 ppid = task_pid_vnr(parent);
72 if (pid == ppid) {
73 rcu_read_unlock();
74 goto out;
75 }
76 prev = parent;
77 }
78 rcu_read_unlock();
79
80 if (au_ftest_lock(flags, NOPLMW)) {
81 /* if there is no i_mutex lock in VFS, we don't need to wait */
82 /* AuDebugOn(!lockdep_depth(current)); */
83 while (sbi->si_plink_maint_pid) {
84 si_read_unlock(sb);
85 /* gave up wake_up_bit() */
86 wait_event(sbi->si_plink_wq, !sbi->si_plink_maint_pid);
87
88 if (au_ftest_lock(flags, FLUSH))
89 au_nwt_flush(&sbi->si_nowait);
90 si_noflush_read_lock(sb);
91 }
92 } else if (au_ftest_lock(flags, NOPLM)) {
93 AuDbg("ppid %d, pid %d\n", ppid, pid);
94 err = -EAGAIN;
95 }
96
97out:
98 return err;
99}
100
101void au_plink_maint_leave(struct au_sbinfo *sbinfo)
102{
103 spin_lock(&sbinfo->si_plink_maint_lock);
104 sbinfo->si_plink_maint_pid = 0;
105 spin_unlock(&sbinfo->si_plink_maint_lock);
106 wake_up_all(&sbinfo->si_plink_wq);
107}
108
109int au_plink_maint_enter(struct super_block *sb)
110{
111 int err;
112 struct au_sbinfo *sbinfo;
113
114 err = 0;
115 sbinfo = au_sbi(sb);
116 /* make sure i am the only one in this fs */
117 si_write_lock(sb, AuLock_FLUSH);
118 if (au_opt_test(au_mntflags(sb), PLINK)) {
119 spin_lock(&sbinfo->si_plink_maint_lock);
120 if (!sbinfo->si_plink_maint_pid)
121 sbinfo->si_plink_maint_pid = current->pid;
122 else
123 err = -EBUSY;
124 spin_unlock(&sbinfo->si_plink_maint_lock);
125 }
126 si_write_unlock(sb);
127
128 return err;
129}
130
131/* ---------------------------------------------------------------------- */
132
133#ifdef CONFIG_AUFS_DEBUG
134void au_plink_list(struct super_block *sb)
135{
136 int i;
137 struct au_sbinfo *sbinfo;
138 struct hlist_head *plink_hlist;
139 struct au_icntnr *icntnr;
140
141 SiMustAnyLock(sb);
142
143 sbinfo = au_sbi(sb);
144 AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
145 AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
146
147 for (i = 0; i < AuPlink_NHASH; i++) {
148 plink_hlist = &sbinfo->si_plink[i].head;
149 rcu_read_lock();
150 hlist_for_each_entry_rcu(icntnr, plink_hlist, plink)
151 AuDbg("%lu\n", icntnr->vfs_inode.i_ino);
152 rcu_read_unlock();
153 }
154}
155#endif
156
157/* is the inode pseudo-linked? */
158int au_plink_test(struct inode *inode)
159{
160 int found, i;
161 struct au_sbinfo *sbinfo;
162 struct hlist_head *plink_hlist;
163 struct au_icntnr *icntnr;
164
165 sbinfo = au_sbi(inode->i_sb);
166 AuRwMustAnyLock(&sbinfo->si_rwsem);
167 AuDebugOn(!au_opt_test(au_mntflags(inode->i_sb), PLINK));
168 AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
169
170 found = 0;
171 i = au_plink_hash(inode->i_ino);
172 plink_hlist = &sbinfo->si_plink[i].head;
173 rcu_read_lock();
174 hlist_for_each_entry_rcu(icntnr, plink_hlist, plink)
175 if (&icntnr->vfs_inode == inode) {
176 found = 1;
177 break;
178 }
179 rcu_read_unlock();
180 return found;
181}
182
183/* ---------------------------------------------------------------------- */
184
185/*
186 * generate a name for plink.
187 * the file will be stored under AUFS_WH_PLINKDIR.
188 */
189/* 20 is max digits length of ulong 64 */
190#define PLINK_NAME_LEN ((20 + 1) * 2)
191
192static int plink_name(char *name, int len, struct inode *inode,
193 aufs_bindex_t bindex)
194{
195 int rlen;
196 struct inode *h_inode;
197
198 h_inode = au_h_iptr(inode, bindex);
199 rlen = snprintf(name, len, "%lu.%lu", inode->i_ino, h_inode->i_ino);
200 return rlen;
201}
202
203struct au_do_plink_lkup_args {
204 struct dentry **errp;
205 struct qstr *tgtname;
206 struct dentry *h_parent;
207 struct au_branch *br;
208};
209
210static struct dentry *au_do_plink_lkup(struct qstr *tgtname,
211 struct dentry *h_parent,
212 struct au_branch *br)
213{
214 struct dentry *h_dentry;
215 struct inode *h_inode;
216
217 h_inode = d_inode(h_parent);
218 vfsub_inode_lock_shared_nested(h_inode, AuLsc_I_CHILD2);
219 h_dentry = vfsub_lkup_one(tgtname, h_parent);
220 inode_unlock_shared(h_inode);
221 return h_dentry;
222}
223
224static void au_call_do_plink_lkup(void *args)
225{
226 struct au_do_plink_lkup_args *a = args;
227 *a->errp = au_do_plink_lkup(a->tgtname, a->h_parent, a->br);
228}
229
230/* lookup the plink-ed @inode under the branch at @bindex */
231struct dentry *au_plink_lkup(struct inode *inode, aufs_bindex_t bindex)
232{
233 struct dentry *h_dentry, *h_parent;
234 struct au_branch *br;
235 int wkq_err;
236 char a[PLINK_NAME_LEN];
237 struct qstr tgtname = QSTR_INIT(a, 0);
238
239 AuDebugOn(au_plink_maint(inode->i_sb, AuLock_NOPLM));
240
241 br = au_sbr(inode->i_sb, bindex);
242 h_parent = br->br_wbr->wbr_plink;
243 tgtname.len = plink_name(a, sizeof(a), inode, bindex);
244
245 if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
246 struct au_do_plink_lkup_args args = {
247 .errp = &h_dentry,
248 .tgtname = &tgtname,
249 .h_parent = h_parent,
250 .br = br
251 };
252
253 wkq_err = au_wkq_wait(au_call_do_plink_lkup, &args);
254 if (unlikely(wkq_err))
255 h_dentry = ERR_PTR(wkq_err);
256 } else
257 h_dentry = au_do_plink_lkup(&tgtname, h_parent, br);
258
259 return h_dentry;
260}
261
262/* create a pseudo-link */
263static int do_whplink(struct qstr *tgt, struct dentry *h_parent,
264 struct dentry *h_dentry, struct au_branch *br)
265{
266 int err;
267 struct path h_path = {
268 .mnt = au_br_mnt(br)
269 };
270 struct inode *h_dir, *delegated;
271
272 h_dir = d_inode(h_parent);
273 inode_lock_nested(h_dir, AuLsc_I_CHILD2);
274again:
275 h_path.dentry = vfsub_lkup_one(tgt, h_parent);
276 err = PTR_ERR(h_path.dentry);
277 if (IS_ERR(h_path.dentry))
278 goto out;
279
280 err = 0;
281 /* wh.plink dir is not monitored */
282 /* todo: is it really safe? */
283 if (d_is_positive(h_path.dentry)
284 && d_inode(h_path.dentry) != d_inode(h_dentry)) {
285 delegated = NULL;
286 err = vfsub_unlink(h_dir, &h_path, &delegated, /*force*/0);
287 if (unlikely(err == -EWOULDBLOCK)) {
288 pr_warn("cannot retry for NFSv4 delegation"
289 " for an internal unlink\n");
290 iput(delegated);
291 }
292 dput(h_path.dentry);
293 h_path.dentry = NULL;
294 if (!err)
295 goto again;
296 }
297 if (!err && d_is_negative(h_path.dentry)) {
298 delegated = NULL;
299 err = vfsub_link(h_dentry, h_dir, &h_path, &delegated);
300 if (unlikely(err == -EWOULDBLOCK)) {
301 pr_warn("cannot retry for NFSv4 delegation"
302 " for an internal link\n");
303 iput(delegated);
304 }
305 }
306 dput(h_path.dentry);
307
308out:
309 inode_unlock(h_dir);
310 return err;
311}
312
313struct do_whplink_args {
314 int *errp;
315 struct qstr *tgt;
316 struct dentry *h_parent;
317 struct dentry *h_dentry;
318 struct au_branch *br;
319};
320
321static void call_do_whplink(void *args)
322{
323 struct do_whplink_args *a = args;
324 *a->errp = do_whplink(a->tgt, a->h_parent, a->h_dentry, a->br);
325}
326
327static int whplink(struct dentry *h_dentry, struct inode *inode,
328 aufs_bindex_t bindex, struct au_branch *br)
329{
330 int err, wkq_err;
331 struct au_wbr *wbr;
332 struct dentry *h_parent;
333 char a[PLINK_NAME_LEN];
334 struct qstr tgtname = QSTR_INIT(a, 0);
335
336 wbr = au_sbr(inode->i_sb, bindex)->br_wbr;
337 h_parent = wbr->wbr_plink;
338 tgtname.len = plink_name(a, sizeof(a), inode, bindex);
339
340 /* always superio. */
341 if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID)) {
342 struct do_whplink_args args = {
343 .errp = &err,
344 .tgt = &tgtname,
345 .h_parent = h_parent,
346 .h_dentry = h_dentry,
347 .br = br
348 };
349 wkq_err = au_wkq_wait(call_do_whplink, &args);
350 if (unlikely(wkq_err))
351 err = wkq_err;
352 } else
353 err = do_whplink(&tgtname, h_parent, h_dentry, br);
354
355 return err;
356}
357
358/*
359 * create a new pseudo-link for @h_dentry on @bindex.
360 * the linked inode is held in aufs @inode.
361 */
362void au_plink_append(struct inode *inode, aufs_bindex_t bindex,
363 struct dentry *h_dentry)
364{
365 struct super_block *sb;
366 struct au_sbinfo *sbinfo;
367 struct hlist_head *plink_hlist;
368 struct au_icntnr *icntnr;
369 struct au_sphlhead *sphl;
370 int found, err, cnt, i;
371
372 sb = inode->i_sb;
373 sbinfo = au_sbi(sb);
374 AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
375 AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
376
377 found = au_plink_test(inode);
378 if (found)
379 return;
380
381 i = au_plink_hash(inode->i_ino);
382 sphl = sbinfo->si_plink + i;
383 plink_hlist = &sphl->head;
384 au_igrab(inode);
385
386 spin_lock(&sphl->spin);
387 hlist_for_each_entry(icntnr, plink_hlist, plink) {
388 if (&icntnr->vfs_inode == inode) {
389 found = 1;
390 break;
391 }
392 }
393 if (!found) {
394 icntnr = container_of(inode, struct au_icntnr, vfs_inode);
395 hlist_add_head_rcu(&icntnr->plink, plink_hlist);
396 }
397 spin_unlock(&sphl->spin);
398 if (!found) {
399 cnt = au_sphl_count(sphl);
400#define msg "unexpectedly unblanced or too many pseudo-links"
401 if (cnt > AUFS_PLINK_WARN)
402 AuWarn1(msg ", %d\n", cnt);
403#undef msg
404 err = whplink(h_dentry, inode, bindex, au_sbr(sb, bindex));
405 if (unlikely(err)) {
406 pr_warn("err %d, damaged pseudo link.\n", err);
407 au_sphl_del_rcu(&icntnr->plink, sphl);
408 iput(&icntnr->vfs_inode);
409 }
410 } else
411 iput(&icntnr->vfs_inode);
412}
413
414/* free all plinks */
415void au_plink_put(struct super_block *sb, int verbose)
416{
417 int i, warned;
418 struct au_sbinfo *sbinfo;
419 struct hlist_head *plink_hlist;
420 struct hlist_node *tmp;
421 struct au_icntnr *icntnr;
422
423 SiMustWriteLock(sb);
424
425 sbinfo = au_sbi(sb);
426 AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
427 AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
428
429 /* no spin_lock since sbinfo is write-locked */
430 warned = 0;
431 for (i = 0; i < AuPlink_NHASH; i++) {
432 plink_hlist = &sbinfo->si_plink[i].head;
433 if (!warned && verbose && !hlist_empty(plink_hlist)) {
434 pr_warn("pseudo-link is not flushed");
435 warned = 1;
436 }
437 hlist_for_each_entry_safe(icntnr, tmp, plink_hlist, plink)
438 iput(&icntnr->vfs_inode);
439 INIT_HLIST_HEAD(plink_hlist);
440 }
441}
442
443void au_plink_clean(struct super_block *sb, int verbose)
444{
445 struct dentry *root;
446
447 root = sb->s_root;
448 aufs_write_lock(root);
449 if (au_opt_test(au_mntflags(sb), PLINK))
450 au_plink_put(sb, verbose);
451 aufs_write_unlock(root);
452}
453
454static int au_plink_do_half_refresh(struct inode *inode, aufs_bindex_t br_id)
455{
456 int do_put;
457 aufs_bindex_t btop, bbot, bindex;
458
459 do_put = 0;
460 btop = au_ibtop(inode);
461 bbot = au_ibbot(inode);
462 if (btop >= 0) {
463 for (bindex = btop; bindex <= bbot; bindex++) {
464 if (!au_h_iptr(inode, bindex)
465 || au_ii_br_id(inode, bindex) != br_id)
466 continue;
467 au_set_h_iptr(inode, bindex, NULL, 0);
468 do_put = 1;
469 break;
470 }
471 if (do_put)
472 for (bindex = btop; bindex <= bbot; bindex++)
473 if (au_h_iptr(inode, bindex)) {
474 do_put = 0;
475 break;
476 }
477 } else
478 do_put = 1;
479
480 return do_put;
481}
482
483/* free the plinks on a branch specified by @br_id */
484void au_plink_half_refresh(struct super_block *sb, aufs_bindex_t br_id)
485{
486 struct au_sbinfo *sbinfo;
487 struct hlist_head *plink_hlist;
488 struct hlist_node *tmp;
489 struct au_icntnr *icntnr;
490 struct inode *inode;
491 int i, do_put;
492
493 SiMustWriteLock(sb);
494
495 sbinfo = au_sbi(sb);
496 AuDebugOn(!au_opt_test(au_mntflags(sb), PLINK));
497 AuDebugOn(au_plink_maint(sb, AuLock_NOPLM));
498
499 /* no spin_lock since sbinfo is write-locked */
500 for (i = 0; i < AuPlink_NHASH; i++) {
501 plink_hlist = &sbinfo->si_plink[i].head;
502 hlist_for_each_entry_safe(icntnr, tmp, plink_hlist, plink) {
503 inode = au_igrab(&icntnr->vfs_inode);
504 ii_write_lock_child(inode);
505 do_put = au_plink_do_half_refresh(inode, br_id);
506 if (do_put) {
507 hlist_del(&icntnr->plink);
508 iput(inode);
509 }
510 ii_write_unlock(inode);
511 iput(inode);
512 }
513 }
514}