containerfs: stat reports the underlying FS inode number

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano 2018-07-02 11:06:35 +02:00
parent b49ce8e958
commit c6ab8b7115
No known key found for this signature in database
GPG Key ID: E4730F97F60286ED

42
main.c
View File

@ -104,6 +104,7 @@ struct lo_node
char *path; char *path;
char *name; char *name;
int lookups; int lookups;
ino_t ino;
unsigned int dirty : 1; unsigned int dirty : 1;
unsigned int low : 1; unsigned int low : 1;
unsigned int do_unlink : 1; unsigned int do_unlink : 1;
@ -331,6 +332,15 @@ get_gid (struct lo_data *data, gid_t id)
return find_mapping (id, data->gid_mappings, false); return find_mapping (id, data->gid_mappings, false);
} }
static ino_t
get_inode_number (struct lo_node *node)
{
if (node->lowerdir)
return node->lowerdir->ino;
return node->ino;
}
static int static int
rpl_stat (fuse_req_t req, struct lo_node *node, struct stat *st) rpl_stat (fuse_req_t req, struct lo_node *node, struct stat *st)
{ {
@ -348,8 +358,7 @@ rpl_stat (fuse_req_t req, struct lo_node *node, struct stat *st)
st->st_uid = find_mapping (st->st_uid, data->uid_mappings, true); st->st_uid = find_mapping (st->st_uid, data->uid_mappings, true);
st->st_gid = find_mapping (st->st_gid, data->gid_mappings, true); st->st_gid = find_mapping (st->st_gid, data->gid_mappings, true);
st->st_ino = NODE_TO_INODE (node); st->st_ino = get_inode_number (node);
if (ret == 0 && node_dirp (node)) if (ret == 0 && node_dirp (node))
{ {
struct lo_node *it; struct lo_node *it;
@ -478,7 +487,7 @@ node_compare (const void *n1, const void *n2)
} }
static struct lo_node * static struct lo_node *
make_lo_node (const char *path, const char *name, bool dir_p) make_lo_node (const char *path, const char *name, ino_t ino, bool dir_p)
{ {
struct lo_node *ret = malloc (sizeof (*ret)); struct lo_node *ret = malloc (sizeof (*ret));
if (ret == NULL) if (ret == NULL)
@ -496,6 +505,13 @@ make_lo_node (const char *path, const char *name, bool dir_p)
ret->hidden = 0; ret->hidden = 0;
ret->do_rmdir = 0; ret->do_rmdir = 0;
ret->not_exists = 0; ret->not_exists = 0;
if (ino == 0)
{
struct stat st;
if (stat (path, &st) == 0)
ino = st.st_ino;
}
ret->ino = ino;
ret->name = strdup (name); ret->name = strdup (name);
if (ret->name == NULL) if (ret->name == NULL)
@ -601,14 +617,14 @@ traverse_dir (char * const dir, struct lo_node *lower, bool low)
case FTS_D: case FTS_D:
if (root == NULL) if (root == NULL)
{ {
root = make_lo_node (dir, "/", true); root = make_lo_node (dir, "/", ent->fts_statp->st_ino, true);
root->lowerdir = lower; root->lowerdir = lower;
root->low = low ? 1 : 0; root->low = low ? 1 : 0;
ent->fts_pointer = root; ent->fts_pointer = root;
} }
else else
{ {
n = make_lo_node (ent->fts_path, ent->fts_name, true); n = make_lo_node (ent->fts_path, ent->fts_name, ent->fts_statp->st_ino, true);
ent->fts_pointer = n; ent->fts_pointer = n;
if (n == NULL) if (n == NULL)
goto err; goto err;
@ -638,7 +654,7 @@ traverse_dir (char * const dir, struct lo_node *lower, bool low)
} }
} }
n = make_lo_node (ent->fts_path, name, false); n = make_lo_node (ent->fts_path, name, ent->fts_statp->st_ino, false);
if (n == NULL) if (n == NULL)
goto err; goto err;
n->low = low ? 1 : 0; n->low = low ? 1 : 0;
@ -767,7 +783,7 @@ reload_dir (struct lo_node *n, char *path, char *name, struct lo_node *lowerdir)
} }
else else
{ {
n = created = make_lo_node (path, name, true); n = created = make_lo_node (path, name, 0, true);
if (n == NULL) if (n == NULL)
return NULL; return NULL;
} }
@ -843,7 +859,7 @@ reload_dir (struct lo_node *n, char *path, char *name, struct lo_node *lowerdir)
continue; continue;
} }
child = make_lo_node (b, dent->d_name, dirp); child = make_lo_node (b, dent->d_name, dent->d_ino, dirp);
if (!child) if (!child)
goto err; goto err;
@ -987,7 +1003,7 @@ do_lookup_file (struct lo_data *lo, fuse_ino_t parent, const char *path)
return NULL; return NULL;
sprintf (b, "%s/%s", node->path, lowerdir->name); sprintf (b, "%s/%s", node->path, lowerdir->name);
next = make_lo_node (b, lowerdir->name, lowerdir->children != NULL); next = make_lo_node (b, lowerdir->name, 0, lowerdir->children != NULL);
if (!next) if (!next)
return NULL; return NULL;
@ -1917,7 +1933,7 @@ lo_do_open (fuse_req_t req, fuse_ino_t parent, const char *name, int flags, mode
return -1; return -1;
} }
n = make_lo_node (path, name, false); n = make_lo_node (path, name, 0, false);
if (n == NULL) if (n == NULL)
{ {
p->dirty = 1; p->dirty = 1;
@ -2267,7 +2283,7 @@ lo_link (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent, const char *newna
return; return;
} }
node = make_lo_node (path, newname, false); node = make_lo_node (path, newname, 0, false);
if (node == NULL) if (node == NULL)
{ {
fuse_reply_err (req, ENOMEM); fuse_reply_err (req, ENOMEM);
@ -2345,7 +2361,7 @@ lo_symlink (fuse_req_t req, const char *link, fuse_ino_t parent, const char *nam
return; return;
} }
node = make_lo_node (path, name, false); node = make_lo_node (path, name, 0, false);
if (node == NULL) if (node == NULL)
{ {
fuse_reply_err (req, ENOMEM); fuse_reply_err (req, ENOMEM);
@ -2729,7 +2745,7 @@ lo_mkdir (fuse_req_t req, fuse_ino_t parent, const char *name, mode_t mode)
return; return;
} }
node = make_lo_node (path, name, true); node = make_lo_node (path, name, 0, true);
if (node == NULL) if (node == NULL)
{ {
fuse_reply_err (req, ENOMEM); fuse_reply_err (req, ENOMEM);