Merge branch 'stable-3.2' into pandora-3.2
[pandora-kernel.git] / fs / aufs / export.c
1 /*
2  * Copyright (C) 2005-2012 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  * export via nfs
21  */
22
23 #include <linux/exportfs.h>
24 #include <linux/mnt_namespace.h>
25 #include <linux/namei.h>
26 #include <linux/nsproxy.h>
27 #include <linux/random.h>
28 #include <linux/writeback.h>
29 #include "aufs.h"
30
31 union conv {
32 #ifdef CONFIG_AUFS_INO_T_64
33         __u32 a[2];
34 #else
35         __u32 a[1];
36 #endif
37         ino_t ino;
38 };
39
40 static ino_t decode_ino(__u32 *a)
41 {
42         union conv u;
43
44         BUILD_BUG_ON(sizeof(u.ino) != sizeof(u.a));
45         u.a[0] = a[0];
46 #ifdef CONFIG_AUFS_INO_T_64
47         u.a[1] = a[1];
48 #endif
49         return u.ino;
50 }
51
52 static void encode_ino(__u32 *a, ino_t ino)
53 {
54         union conv u;
55
56         u.ino = ino;
57         a[0] = u.a[0];
58 #ifdef CONFIG_AUFS_INO_T_64
59         a[1] = u.a[1];
60 #endif
61 }
62
63 /* NFS file handle */
64 enum {
65         Fh_br_id,
66         Fh_sigen,
67 #ifdef CONFIG_AUFS_INO_T_64
68         /* support 64bit inode number */
69         Fh_ino1,
70         Fh_ino2,
71         Fh_dir_ino1,
72         Fh_dir_ino2,
73 #else
74         Fh_ino1,
75         Fh_dir_ino1,
76 #endif
77         Fh_igen,
78         Fh_h_type,
79         Fh_tail,
80
81         Fh_ino = Fh_ino1,
82         Fh_dir_ino = Fh_dir_ino1
83 };
84
85 static int au_test_anon(struct dentry *dentry)
86 {
87         /* note: read d_flags without d_lock */
88         return !!(dentry->d_flags & DCACHE_DISCONNECTED);
89 }
90
91 /* ---------------------------------------------------------------------- */
92 /* inode generation external table */
93
94 void au_xigen_inc(struct inode *inode)
95 {
96         loff_t pos;
97         ssize_t sz;
98         __u32 igen;
99         struct super_block *sb;
100         struct au_sbinfo *sbinfo;
101
102         sb = inode->i_sb;
103         AuDebugOn(!au_opt_test(au_mntflags(sb), XINO));
104
105         sbinfo = au_sbi(sb);
106         pos = inode->i_ino;
107         pos *= sizeof(igen);
108         igen = inode->i_generation + 1;
109         sz = xino_fwrite(sbinfo->si_xwrite, sbinfo->si_xigen, &igen,
110                          sizeof(igen), &pos);
111         if (sz == sizeof(igen))
112                 return; /* success */
113
114         if (unlikely(sz >= 0))
115                 AuIOErr("xigen error (%zd)\n", sz);
116 }
117
118 int au_xigen_new(struct inode *inode)
119 {
120         int err;
121         loff_t pos;
122         ssize_t sz;
123         struct super_block *sb;
124         struct au_sbinfo *sbinfo;
125         struct file *file;
126
127         err = 0;
128         /* todo: dirty, at mount time */
129         if (inode->i_ino == AUFS_ROOT_INO)
130                 goto out;
131         sb = inode->i_sb;
132         SiMustAnyLock(sb);
133         if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
134                 goto out;
135
136         err = -EFBIG;
137         pos = inode->i_ino;
138         if (unlikely(au_loff_max / sizeof(inode->i_generation) - 1 < pos)) {
139                 AuIOErr1("too large i%lld\n", pos);
140                 goto out;
141         }
142         pos *= sizeof(inode->i_generation);
143
144         err = 0;
145         sbinfo = au_sbi(sb);
146         file = sbinfo->si_xigen;
147         BUG_ON(!file);
148
149         if (i_size_read(file->f_dentry->d_inode)
150             < pos + sizeof(inode->i_generation)) {
151                 inode->i_generation = atomic_inc_return(&sbinfo->si_xigen_next);
152                 sz = xino_fwrite(sbinfo->si_xwrite, file, &inode->i_generation,
153                                  sizeof(inode->i_generation), &pos);
154         } else
155                 sz = xino_fread(sbinfo->si_xread, file, &inode->i_generation,
156                                 sizeof(inode->i_generation), &pos);
157         if (sz == sizeof(inode->i_generation))
158                 goto out; /* success */
159
160         err = sz;
161         if (unlikely(sz >= 0)) {
162                 err = -EIO;
163                 AuIOErr("xigen error (%zd)\n", sz);
164         }
165
166 out:
167         return err;
168 }
169
170 int au_xigen_set(struct super_block *sb, struct file *base)
171 {
172         int err;
173         struct au_sbinfo *sbinfo;
174         struct file *file;
175
176         SiMustWriteLock(sb);
177
178         sbinfo = au_sbi(sb);
179         file = au_xino_create2(base, sbinfo->si_xigen);
180         err = PTR_ERR(file);
181         if (IS_ERR(file))
182                 goto out;
183         err = 0;
184         if (sbinfo->si_xigen)
185                 fput(sbinfo->si_xigen);
186         sbinfo->si_xigen = file;
187
188 out:
189         return err;
190 }
191
192 void au_xigen_clr(struct super_block *sb)
193 {
194         struct au_sbinfo *sbinfo;
195
196         SiMustWriteLock(sb);
197
198         sbinfo = au_sbi(sb);
199         if (sbinfo->si_xigen) {
200                 fput(sbinfo->si_xigen);
201                 sbinfo->si_xigen = NULL;
202         }
203 }
204
205 /* ---------------------------------------------------------------------- */
206
207 static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
208                                     ino_t dir_ino)
209 {
210         struct dentry *dentry, *d;
211         struct inode *inode;
212         unsigned int sigen;
213
214         dentry = NULL;
215         inode = ilookup(sb, ino);
216         if (!inode)
217                 goto out;
218
219         dentry = ERR_PTR(-ESTALE);
220         sigen = au_sigen(sb);
221         if (unlikely(is_bad_inode(inode)
222                      || IS_DEADDIR(inode)
223                      || sigen != au_iigen(inode)))
224                 goto out_iput;
225
226         dentry = NULL;
227         if (!dir_ino || S_ISDIR(inode->i_mode))
228                 dentry = d_find_alias(inode);
229         else {
230                 spin_lock(&inode->i_lock);
231                 list_for_each_entry(d, &inode->i_dentry, d_alias) {
232                         spin_lock(&d->d_lock);
233                         if (!au_test_anon(d)
234                             && d->d_parent->d_inode->i_ino == dir_ino) {
235                                 dentry = dget_dlock(d);
236                                 spin_unlock(&d->d_lock);
237                                 break;
238                         }
239                         spin_unlock(&d->d_lock);
240                 }
241                 spin_unlock(&inode->i_lock);
242         }
243         if (unlikely(dentry && au_digen_test(dentry, sigen))) {
244                 /* need to refresh */
245                 dput(dentry);
246                 dentry = NULL;
247         }
248
249 out_iput:
250         iput(inode);
251 out:
252         AuTraceErrPtr(dentry);
253         return dentry;
254 }
255
256 /* ---------------------------------------------------------------------- */
257
258 /* todo: dirty? */
259 /* if exportfs_decode_fh() passed vfsmount*, we could be happy */
260
261 struct au_compare_mnt_args {
262         /* input */
263         struct super_block *sb;
264
265         /* output */
266         struct vfsmount *mnt;
267 };
268
269 static int au_compare_mnt(struct vfsmount *mnt, void *arg)
270 {
271         struct au_compare_mnt_args *a = arg;
272
273         if (mnt->mnt_sb != a->sb)
274                 return 0;
275         a->mnt = mntget(mnt);
276         return 1;
277 }
278
279 static struct vfsmount *au_mnt_get(struct super_block *sb)
280 {
281         int err;
282         struct au_compare_mnt_args args = {
283                 .sb = sb
284         };
285         struct mnt_namespace *ns;
286
287         br_read_lock(vfsmount_lock);
288         /* no get/put ?? */
289         AuDebugOn(!current->nsproxy);
290         ns = current->nsproxy->mnt_ns;
291         AuDebugOn(!ns);
292         err = iterate_mounts(au_compare_mnt, &args, ns->root);
293         br_read_unlock(vfsmount_lock);
294         AuDebugOn(!err);
295         AuDebugOn(!args.mnt);
296         return args.mnt;
297 }
298
299 struct au_nfsd_si_lock {
300         unsigned int sigen;
301         aufs_bindex_t bindex, br_id;
302         unsigned char force_lock;
303 };
304
305 static int si_nfsd_read_lock(struct super_block *sb,
306                              struct au_nfsd_si_lock *nsi_lock)
307 {
308         int err;
309         aufs_bindex_t bindex;
310
311         si_read_lock(sb, AuLock_FLUSH);
312
313         /* branch id may be wrapped around */
314         err = 0;
315         bindex = au_br_index(sb, nsi_lock->br_id);
316         if (bindex >= 0 && nsi_lock->sigen + AUFS_BRANCH_MAX > au_sigen(sb))
317                 goto out; /* success */
318
319         err = -ESTALE;
320         bindex = -1;
321         if (!nsi_lock->force_lock)
322                 si_read_unlock(sb);
323
324 out:
325         nsi_lock->bindex = bindex;
326         return err;
327 }
328
329 struct find_name_by_ino {
330         int called, found;
331         ino_t ino;
332         char *name;
333         int namelen;
334 };
335
336 static int
337 find_name_by_ino(void *arg, const char *name, int namelen, loff_t offset,
338                  u64 ino, unsigned int d_type)
339 {
340         struct find_name_by_ino *a = arg;
341
342         a->called++;
343         if (a->ino != ino)
344                 return 0;
345
346         memcpy(a->name, name, namelen);
347         a->namelen = namelen;
348         a->found = 1;
349         return 1;
350 }
351
352 static struct dentry *au_lkup_by_ino(struct path *path, ino_t ino,
353                                      struct au_nfsd_si_lock *nsi_lock)
354 {
355         struct dentry *dentry, *parent;
356         struct file *file;
357         struct inode *dir;
358         struct find_name_by_ino arg;
359         int err;
360
361         parent = path->dentry;
362         if (nsi_lock)
363                 si_read_unlock(parent->d_sb);
364         file = vfsub_dentry_open(path, au_dir_roflags);
365         dentry = (void *)file;
366         if (IS_ERR(file))
367                 goto out;
368
369         dentry = ERR_PTR(-ENOMEM);
370         arg.name = __getname_gfp(GFP_NOFS);
371         if (unlikely(!arg.name))
372                 goto out_file;
373         arg.ino = ino;
374         arg.found = 0;
375         do {
376                 arg.called = 0;
377                 /* smp_mb(); */
378                 err = vfsub_readdir(file, find_name_by_ino, &arg);
379         } while (!err && !arg.found && arg.called);
380         dentry = ERR_PTR(err);
381         if (unlikely(err))
382                 goto out_name;
383         dentry = ERR_PTR(-ENOENT);
384         if (!arg.found)
385                 goto out_name;
386
387         /* do not call au_lkup_one() */
388         dir = parent->d_inode;
389         mutex_lock(&dir->i_mutex);
390         dentry = vfsub_lookup_one_len(arg.name, parent, arg.namelen);
391         mutex_unlock(&dir->i_mutex);
392         AuTraceErrPtr(dentry);
393         if (IS_ERR(dentry))
394                 goto out_name;
395         AuDebugOn(au_test_anon(dentry));
396         if (unlikely(!dentry->d_inode)) {
397                 dput(dentry);
398                 dentry = ERR_PTR(-ENOENT);
399         }
400
401 out_name:
402         __putname(arg.name);
403 out_file:
404         fput(file);
405 out:
406         if (unlikely(nsi_lock
407                      && si_nfsd_read_lock(parent->d_sb, nsi_lock) < 0))
408                 if (!IS_ERR(dentry)) {
409                         dput(dentry);
410                         dentry = ERR_PTR(-ESTALE);
411                 }
412         AuTraceErrPtr(dentry);
413         return dentry;
414 }
415
416 static struct dentry *decode_by_dir_ino(struct super_block *sb, ino_t ino,
417                                         ino_t dir_ino,
418                                         struct au_nfsd_si_lock *nsi_lock)
419 {
420         struct dentry *dentry;
421         struct path path;
422
423         if (dir_ino != AUFS_ROOT_INO) {
424                 path.dentry = decode_by_ino(sb, dir_ino, 0);
425                 dentry = path.dentry;
426                 if (!path.dentry || IS_ERR(path.dentry))
427                         goto out;
428                 AuDebugOn(au_test_anon(path.dentry));
429         } else
430                 path.dentry = dget(sb->s_root);
431
432         path.mnt = au_mnt_get(sb);
433         dentry = au_lkup_by_ino(&path, ino, nsi_lock);
434         path_put(&path);
435
436 out:
437         AuTraceErrPtr(dentry);
438         return dentry;
439 }
440
441 /* ---------------------------------------------------------------------- */
442
443 static int h_acceptable(void *expv, struct dentry *dentry)
444 {
445         return 1;
446 }
447
448 static char *au_build_path(struct dentry *h_parent, struct path *h_rootpath,
449                            char *buf, int len, struct super_block *sb)
450 {
451         char *p;
452         int n;
453         struct path path;
454
455         p = d_path(h_rootpath, buf, len);
456         if (IS_ERR(p))
457                 goto out;
458         n = strlen(p);
459
460         path.mnt = h_rootpath->mnt;
461         path.dentry = h_parent;
462         p = d_path(&path, buf, len);
463         if (IS_ERR(p))
464                 goto out;
465         if (n != 1)
466                 p += n;
467
468         path.mnt = au_mnt_get(sb);
469         path.dentry = sb->s_root;
470         p = d_path(&path, buf, len - strlen(p));
471         mntput(path.mnt);
472         if (IS_ERR(p))
473                 goto out;
474         if (n != 1)
475                 p[strlen(p)] = '/';
476
477 out:
478         AuTraceErrPtr(p);
479         return p;
480 }
481
482 static
483 struct dentry *decode_by_path(struct super_block *sb, ino_t ino, __u32 *fh,
484                               int fh_len, struct au_nfsd_si_lock *nsi_lock)
485 {
486         struct dentry *dentry, *h_parent, *root;
487         struct super_block *h_sb;
488         char *pathname, *p;
489         struct vfsmount *h_mnt;
490         struct au_branch *br;
491         int err;
492         struct path path;
493
494         br = au_sbr(sb, nsi_lock->bindex);
495         h_mnt = br->br_mnt;
496         h_sb = h_mnt->mnt_sb;
497         /* todo: call lower fh_to_dentry()? fh_to_parent()? */
498         h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
499                                       fh_len - Fh_tail, fh[Fh_h_type],
500                                       h_acceptable, /*context*/NULL);
501         dentry = h_parent;
502         if (unlikely(!h_parent || IS_ERR(h_parent))) {
503                 AuWarn1("%s decode_fh failed, %ld\n",
504                         au_sbtype(h_sb), PTR_ERR(h_parent));
505                 goto out;
506         }
507         dentry = NULL;
508         if (unlikely(au_test_anon(h_parent))) {
509                 AuWarn1("%s decode_fh returned a disconnected dentry\n",
510                         au_sbtype(h_sb));
511                 goto out_h_parent;
512         }
513
514         dentry = ERR_PTR(-ENOMEM);
515         pathname = (void *)__get_free_page(GFP_NOFS);
516         if (unlikely(!pathname))
517                 goto out_h_parent;
518
519         root = sb->s_root;
520         path.mnt = h_mnt;
521         di_read_lock_parent(root, !AuLock_IR);
522         path.dentry = au_h_dptr(root, nsi_lock->bindex);
523         di_read_unlock(root, !AuLock_IR);
524         p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
525         dentry = (void *)p;
526         if (IS_ERR(p))
527                 goto out_pathname;
528
529         si_read_unlock(sb);
530         err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
531         dentry = ERR_PTR(err);
532         if (unlikely(err))
533                 goto out_relock;
534
535         dentry = ERR_PTR(-ENOENT);
536         AuDebugOn(au_test_anon(path.dentry));
537         if (unlikely(!path.dentry->d_inode))
538                 goto out_path;
539
540         if (ino != path.dentry->d_inode->i_ino)
541                 dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
542         else
543                 dentry = dget(path.dentry);
544
545 out_path:
546         path_put(&path);
547 out_relock:
548         if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
549                 if (!IS_ERR(dentry)) {
550                         dput(dentry);
551                         dentry = ERR_PTR(-ESTALE);
552                 }
553 out_pathname:
554         free_page((unsigned long)pathname);
555 out_h_parent:
556         dput(h_parent);
557 out:
558         AuTraceErrPtr(dentry);
559         return dentry;
560 }
561
562 /* ---------------------------------------------------------------------- */
563
564 static struct dentry *
565 aufs_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len,
566                   int fh_type)
567 {
568         struct dentry *dentry;
569         __u32 *fh = fid->raw;
570         struct au_branch *br;
571         ino_t ino, dir_ino;
572         struct au_nfsd_si_lock nsi_lock = {
573                 .force_lock     = 0
574         };
575
576         dentry = ERR_PTR(-ESTALE);
577         /* it should never happen, but the file handle is unreliable */
578         if (unlikely(fh_len < Fh_tail))
579                 goto out;
580         nsi_lock.sigen = fh[Fh_sigen];
581         nsi_lock.br_id = fh[Fh_br_id];
582
583         /* branch id may be wrapped around */
584         br = NULL;
585         if (unlikely(si_nfsd_read_lock(sb, &nsi_lock)))
586                 goto out;
587         nsi_lock.force_lock = 1;
588
589         /* is this inode still cached? */
590         ino = decode_ino(fh + Fh_ino);
591         /* it should never happen */
592         if (unlikely(ino == AUFS_ROOT_INO))
593                 goto out;
594
595         dir_ino = decode_ino(fh + Fh_dir_ino);
596         dentry = decode_by_ino(sb, ino, dir_ino);
597         if (IS_ERR(dentry))
598                 goto out_unlock;
599         if (dentry)
600                 goto accept;
601
602         /* is the parent dir cached? */
603         br = au_sbr(sb, nsi_lock.bindex);
604         atomic_inc(&br->br_count);
605         dentry = decode_by_dir_ino(sb, ino, dir_ino, &nsi_lock);
606         if (IS_ERR(dentry))
607                 goto out_unlock;
608         if (dentry)
609                 goto accept;
610
611         /* lookup path */
612         dentry = decode_by_path(sb, ino, fh, fh_len, &nsi_lock);
613         if (IS_ERR(dentry))
614                 goto out_unlock;
615         if (unlikely(!dentry))
616                 /* todo?: make it ESTALE */
617                 goto out_unlock;
618
619 accept:
620         if (!au_digen_test(dentry, au_sigen(sb))
621             && dentry->d_inode->i_generation == fh[Fh_igen])
622                 goto out_unlock; /* success */
623
624         dput(dentry);
625         dentry = ERR_PTR(-ESTALE);
626 out_unlock:
627         if (br)
628                 atomic_dec(&br->br_count);
629         si_read_unlock(sb);
630 out:
631         AuTraceErrPtr(dentry);
632         return dentry;
633 }
634
635 #if 0 /* reserved for future use */
636 /* support subtreecheck option */
637 static struct dentry *aufs_fh_to_parent(struct super_block *sb, struct fid *fid,
638                                         int fh_len, int fh_type)
639 {
640         struct dentry *parent;
641         __u32 *fh = fid->raw;
642         ino_t dir_ino;
643
644         dir_ino = decode_ino(fh + Fh_dir_ino);
645         parent = decode_by_ino(sb, dir_ino, 0);
646         if (IS_ERR(parent))
647                 goto out;
648         if (!parent)
649                 parent = decode_by_path(sb, au_br_index(sb, fh[Fh_br_id]),
650                                         dir_ino, fh, fh_len);
651
652 out:
653         AuTraceErrPtr(parent);
654         return parent;
655 }
656 #endif
657
658 /* ---------------------------------------------------------------------- */
659
660 static int aufs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
661                           int connectable)
662 {
663         int err;
664         aufs_bindex_t bindex, bend;
665         struct super_block *sb, *h_sb;
666         struct inode *inode;
667         struct dentry *parent, *h_parent;
668         struct au_branch *br;
669
670         AuDebugOn(au_test_anon(dentry));
671
672         parent = NULL;
673         err = -ENOSPC;
674         if (unlikely(*max_len <= Fh_tail)) {
675                 AuWarn1("NFSv2 client (max_len %d)?\n", *max_len);
676                 goto out;
677         }
678
679         err = FILEID_ROOT;
680         if (IS_ROOT(dentry)) {
681                 AuDebugOn(dentry->d_inode->i_ino != AUFS_ROOT_INO);
682                 goto out;
683         }
684
685         h_parent = NULL;
686         err = aufs_read_lock(dentry, AuLock_FLUSH | AuLock_IR | AuLock_GEN);
687         if (unlikely(err))
688                 goto out;
689
690         inode = dentry->d_inode;
691         AuDebugOn(!inode);
692         sb = dentry->d_sb;
693 #ifdef CONFIG_AUFS_DEBUG
694         if (unlikely(!au_opt_test(au_mntflags(sb), XINO)))
695                 AuWarn1("NFS-exporting requires xino\n");
696 #endif
697         err = -EIO;
698         parent = dget_parent(dentry);
699         di_read_lock_parent(parent, !AuLock_IR);
700         bend = au_dbtaildir(parent);
701         for (bindex = au_dbstart(parent); bindex <= bend; bindex++) {
702                 h_parent = au_h_dptr(parent, bindex);
703                 if (h_parent) {
704                         dget(h_parent);
705                         break;
706                 }
707         }
708         if (unlikely(!h_parent))
709                 goto out_unlock;
710
711         err = -EPERM;
712         br = au_sbr(sb, bindex);
713         h_sb = br->br_mnt->mnt_sb;
714         if (unlikely(!h_sb->s_export_op)) {
715                 AuErr1("%s branch is not exportable\n", au_sbtype(h_sb));
716                 goto out_dput;
717         }
718
719         fh[Fh_br_id] = br->br_id;
720         fh[Fh_sigen] = au_sigen(sb);
721         encode_ino(fh + Fh_ino, inode->i_ino);
722         encode_ino(fh + Fh_dir_ino, parent->d_inode->i_ino);
723         fh[Fh_igen] = inode->i_generation;
724
725         *max_len -= Fh_tail;
726         fh[Fh_h_type] = exportfs_encode_fh(h_parent, (void *)(fh + Fh_tail),
727                                            max_len,
728                                            /*connectable or subtreecheck*/0);
729         err = fh[Fh_h_type];
730         *max_len += Fh_tail;
731         /* todo: macros? */
732         if (err != 255)
733                 err = 99;
734         else
735                 AuWarn1("%s encode_fh failed\n", au_sbtype(h_sb));
736
737 out_dput:
738         dput(h_parent);
739 out_unlock:
740         di_read_unlock(parent, !AuLock_IR);
741         dput(parent);
742         aufs_read_unlock(dentry, AuLock_IR);
743 out:
744         if (unlikely(err < 0))
745                 err = 255;
746         return err;
747 }
748
749 /* ---------------------------------------------------------------------- */
750
751 static int aufs_commit_metadata(struct inode *inode)
752 {
753         int err;
754         aufs_bindex_t bindex;
755         struct super_block *sb;
756         struct inode *h_inode;
757         int (*f)(struct inode *inode);
758
759         sb = inode->i_sb;
760         si_read_lock(sb, AuLock_FLUSH | AuLock_NOPLMW);
761         ii_write_lock_child(inode);
762         bindex = au_ibstart(inode);
763         AuDebugOn(bindex < 0);
764         h_inode = au_h_iptr(inode, bindex);
765
766         f = h_inode->i_sb->s_export_op->commit_metadata;
767         if (f)
768                 err = f(h_inode);
769         else {
770                 struct writeback_control wbc = {
771                         .sync_mode      = WB_SYNC_ALL,
772                         .nr_to_write    = 0 /* metadata only */
773                 };
774
775                 err = sync_inode(h_inode, &wbc);
776         }
777
778         au_cpup_attr_timesizes(inode);
779         ii_write_unlock(inode);
780         si_read_unlock(sb);
781         return err;
782 }
783
784 /* ---------------------------------------------------------------------- */
785
786 static struct export_operations aufs_export_op = {
787         .fh_to_dentry           = aufs_fh_to_dentry,
788         /* .fh_to_parent        = aufs_fh_to_parent, */
789         .encode_fh              = aufs_encode_fh,
790         .commit_metadata        = aufs_commit_metadata
791 };
792
793 void au_export_init(struct super_block *sb)
794 {
795         struct au_sbinfo *sbinfo;
796         __u32 u;
797
798         sb->s_export_op = &aufs_export_op;
799         sbinfo = au_sbi(sb);
800         sbinfo->si_xigen = NULL;
801         get_random_bytes(&u, sizeof(u));
802         BUILD_BUG_ON(sizeof(u) != sizeof(int));
803         atomic_set(&sbinfo->si_xigen_next, u);
804 }