Commit f371c057 authored by J. R. Okajima's avatar J. R. Okajima
Browse files

aufs: dirren 2/6, branch id as a filename of the info



DIRREN gives an identifier to every branch, and it is used as a part of
the filename of the detailed info file.
Signed-off-by: default avatarJ. R. Okajima <hooanon05g@gmail.com>
parent 53c63b41
......@@ -318,6 +318,40 @@ out:
return err;
}
/* ---------------------------------------------------------------------- */
static int au_dr_brid_init(struct au_dr_brid *brid, const struct path *path)
{
int err;
struct kstatfs kstfs;
dev_t dev;
struct dentry *dentry;
struct super_block *sb;
err = vfs_statfs((void *)path, &kstfs);
AuTraceErr(err);
if (unlikely(err))
goto out;
/* todo: support for UUID */
if (kstfs.f_fsid.val[0] || kstfs.f_fsid.val[1]) {
brid->type = AuBrid_FSID;
brid->fsid = kstfs.f_fsid;
} else {
dentry = path->dentry;
sb = dentry->d_sb;
dev = sb->s_dev;
if (dev) {
brid->type = AuBrid_DEV;
brid->dev = dev;
}
}
out:
return err;
}
int au_dr_br_init(struct super_block *sb, struct au_branch *br,
const struct path *path)
{
......@@ -330,10 +364,14 @@ int au_dr_br_init(struct super_block *sb, struct au_branch *br,
for (i = 0; i < AuDirren_NHASH; i++, hbl++)
INIT_HLIST_BL_HEAD(hbl);
err = 0;
err = au_dr_brid_init(&dr->dr_brid, path);
if (unlikely(err))
goto out;
if (au_opt_test(au_mntflags(sb), DIRREN))
err = au_dr_hino(sb, /*bindex*/-1, br, path);
out:
AuTraceErr(err);
return err;
}
......@@ -350,3 +388,48 @@ int au_dr_br_fin(struct super_block *sb, struct au_branch *br)
return err;
}
/* ---------------------------------------------------------------------- */
/* re-commit later */ __maybe_unused
static int au_brid_str(struct au_dr_brid *brid, struct inode *h_inode,
char *buf, size_t sz)
{
int err;
unsigned int major, minor;
char *p;
p = buf;
err = snprintf(p, sz, "%d_", brid->type);
AuDebugOn(err > sz);
p += err;
sz -= err;
switch (brid->type) {
case AuBrid_Unset:
return -EINVAL;
case AuBrid_UUID:
err = snprintf(p, sz, "%pU", brid->uuid.b);
break;
case AuBrid_FSID:
err = snprintf(p, sz, "%08x-%08x",
brid->fsid.val[0], brid->fsid.val[1]);
break;
case AuBrid_DEV:
major = MAJOR(brid->dev);
minor = MINOR(brid->dev);
if (major <= 0xff && minor <= 0xff)
err = snprintf(p, sz, "%02x%02x", major, minor);
else
err = snprintf(p, sz, "%03x:%05x", major, minor);
break;
}
AuDebugOn(err > sz);
p += err;
sz -= err;
err = snprintf(p, sz, "_%llu", (unsigned long long)h_inode->i_ino);
AuDebugOn(err > sz);
p += err;
sz -= err;
return p - buf;
}
......@@ -12,11 +12,34 @@
#ifdef __KERNEL__
#include <linux/statfs.h>
#include <linux/uuid.h>
#include "hbl.h"
#define AuDirren_NHASH 100
#ifdef CONFIG_AUFS_DIRREN
enum au_brid_type {
AuBrid_Unset,
AuBrid_UUID,
AuBrid_FSID,
AuBrid_DEV
};
struct au_dr_brid {
enum au_brid_type type;
union {
uuid_t uuid; /* unimplemented yet */
fsid_t fsid;
dev_t dev;
};
};
/* 20 is the max digits length of ulong 64 */
/* brid-type "_" uuid "_" inum */
#define AUFS_DIRREN_FNAME_SZ (1 + 1 + UUID_STRING_LEN + 20)
#define AUFS_DIRREN_ENV_VAL_SZ (AUFS_DIRREN_FNAME_SZ + 1 + 20)
struct au_dr_hino {
struct hlist_bl_node dr_hnode;
ino_t dr_h_ino;
......@@ -24,6 +47,7 @@ struct au_dr_hino {
struct au_dr_br {
struct hlist_bl_head dr_h_ino[AuDirren_NHASH];
struct au_dr_brid dr_brid;
};
#else
struct au_dr_hino;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment