/*
- * Copyright (C) 2005-2012 Junjiro R. Okajima
+ * Copyright (C) 2005-2013 Junjiro R. Okajima
*
* This program, aufs is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
hdp = au_di(sb->s_root)->di_hdentry;
for (bindex = 0; !err && bindex <= bend; bindex++) {
br = au_sbr(sb, bindex);
- path.mnt = br->br_mnt;
+ path.mnt = au_br_mnt(br);
path.dentry = hdp[bindex].hd_dentry;
err = au_seq_path(seq, &path);
if (err > 0) {
AuRwMustAnyLock(&sbinfo->si_rwsem);
- seq_printf(m, ",create=");
+ seq_puts(m, ",create=");
pat = au_optstr_wbr_create(v);
switch (v) {
case AuWbrCreate_TDP:
case AuWbrCreate_RR:
case AuWbrCreate_MFS:
case AuWbrCreate_PMFS:
- seq_printf(m, pat);
+ seq_puts(m, pat);
break;
case AuWbrCreate_MFSV:
seq_printf(m, /*pat*/"mfs:%lu",
jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
/ MSEC_PER_SEC);
break;
+ case AuWbrCreate_PMFSRR:
+ seq_printf(m, /*pat*/"pmfsrr:%llu",
+ sbinfo->si_wbr_mfs.mfsrr_watermark);
+ break;
+ case AuWbrCreate_PMFSRRV:
+ seq_printf(m, /*pat*/"pmfsrr:%llu:%lu",
+ sbinfo->si_wbr_mfs.mfsrr_watermark,
+ jiffies_to_msecs(sbinfo->si_wbr_mfs.mfs_expire)
+ / MSEC_PER_SEC);
+ break;
}
}
old = a;
a += b;
- if (old < a)
+ if (old <= a)
+ return a;
+ return ULLONG_MAX;
+}
+
+static u64 au_mul_till_max(u64 a, long mul)
+{
+ u64 old;
+
+ old = a;
+ a *= mul;
+ if (old <= a)
return a;
return ULLONG_MAX;
}
static int au_statfs_sum(struct super_block *sb, struct kstatfs *buf)
{
int err;
+ long bsize, factor;
u64 blocks, bfree, bavail, files, ffree;
aufs_bindex_t bend, bindex, i;
unsigned char shared;
struct path h_path;
struct super_block *h_sb;
+ err = 0;
+ bsize = LONG_MAX;
+ files = 0;
+ ffree = 0;
blocks = 0;
bfree = 0;
bavail = 0;
- files = 0;
- ffree = 0;
-
- err = 0;
bend = au_sbend(sb);
- for (bindex = bend; bindex >= 0; bindex--) {
+ for (bindex = 0; bindex <= bend; bindex++) {
h_path.mnt = au_sbr_mnt(sb, bindex);
h_sb = h_path.mnt->mnt_sb;
shared = 0;
- for (i = bindex + 1; !shared && i <= bend; i++)
+ for (i = 0; !shared && i < bindex; i++)
shared = (au_sbr_sb(sb, i) == h_sb);
if (shared)
continue;
if (unlikely(err))
goto out;
- blocks = au_add_till_max(blocks, buf->f_blocks);
- bfree = au_add_till_max(bfree, buf->f_bfree);
- bavail = au_add_till_max(bavail, buf->f_bavail);
+ if (bsize > buf->f_bsize) {
+ /*
+ * we will reduce bsize, so we have to expand blocks
+ * etc. to match them again
+ */
+ factor = (bsize / buf->f_bsize);
+ blocks = au_mul_till_max(blocks, factor);
+ bfree = au_mul_till_max(bfree, factor);
+ bavail = au_mul_till_max(bavail, factor);
+ bsize = buf->f_bsize;
+ }
+
+ factor = (buf->f_bsize / bsize);
+ blocks = au_add_till_max(blocks,
+ au_mul_till_max(buf->f_blocks, factor));
+ bfree = au_add_till_max(bfree,
+ au_mul_till_max(buf->f_bfree, factor));
+ bavail = au_add_till_max(bavail,
+ au_mul_till_max(buf->f_bavail, factor));
files = au_add_till_max(files, buf->f_files);
ffree = au_add_till_max(ffree, buf->f_ffree);
}
+ buf->f_bsize = bsize;
buf->f_blocks = blocks;
buf->f_bfree = bfree;
buf->f_bavail = bavail;
buf->f_files = files;
buf->f_ffree = ffree;
+ buf->f_frsize = 0;
out:
return err;
/* ---------------------------------------------------------------------- */
+static int aufs_sync_fs(struct super_block *sb, int wait)
+{
+ int err, e;
+ aufs_bindex_t bend, bindex;
+ struct au_branch *br;
+ struct super_block *h_sb;
+
+ err = 0;
+ si_noflush_read_lock(sb);
+ bend = au_sbend(sb);
+ for (bindex = 0; bindex <= bend; bindex++) {
+ br = au_sbr(sb, bindex);
+ if (!au_br_writable(br->br_perm))
+ continue;
+
+ h_sb = au_sbr_sb(sb, bindex);
+ if (h_sb->s_op->sync_fs) {
+ e = h_sb->s_op->sync_fs(h_sb, wait);
+ if (unlikely(e && !err))
+ err = e;
+ /* go on even if an error happens */
+ }
+ }
+ si_read_unlock(sb);
+
+ return err;
+}
+
+/* ---------------------------------------------------------------------- */
+
/* final actions when unmounting a file system */
static void aufs_put_super(struct super_block *sb)
{
sigen = au_sigen(sb);
for (ull = 0; ull < max; ull++) {
inode = array[ull];
- if (au_iigen(inode) != sigen) {
+ if (au_iigen(inode, NULL) != sigen) {
ii_write_lock_child(inode);
e = au_refresh_hinode_self(inode);
ii_write_unlock(inode);
.show_options = aufs_show_options,
.statfs = aufs_statfs,
.put_super = aufs_put_super,
+ .sync_fs = aufs_sync_fs,
.remount_fs = aufs_remount_fs
};