[CRIU] [PATCH 4/4] files: Cache special file IDs
Andrew Vagin
avagin at parallels.com
Tue Feb 4 10:50:19 PST 2014
On Tue, Feb 04, 2014 at 08:03:46PM +0400, Pavel Emelyanov wrote:
> We have tons of files with equal IDs, e.g. libraries mapped
> to different tasks. We can avoid writing all this duplicate
> stuff into images by caching the IDs with dev:ino keys.
>
> This looks _very_ similar to irmap cache, but the latter one
> caches dev:ino into paths. Need to think how to merge them.
>
> Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
> ---
> file-ids.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 63 insertions(+), 1 deletion(-)
>
> diff --git a/file-ids.c b/file-ids.c
> index 7cac60f..30f1bbc 100644
> --- a/file-ids.c
> +++ b/file-ids.c
> @@ -6,7 +6,7 @@
> #include <unistd.h>
> #include <errno.h>
> #include <string.h>
> -
> +#include <sys/stat.h>
> #include <sys/types.h>
>
> #include "asm/types.h"
> @@ -26,9 +26,68 @@ void fd_id_show_tree(void)
> kid_show_tree(&fd_tree);
> }
>
> +#define FDID_BITS 5
> +#define FDID_SIZE (1 << FDID_BITS)
> +#define FDID_MASK (FDID_SIZE - 1)
> +
> +static inline int fdid_hashfn(unsigned int s_dev, unsigned long i_ino)
> +{
> + return (s_dev + i_ino) & FDID_MASK;
> +}
> +
> +struct fd_id {
> + unsigned int dev;
> + unsigned long ino;
> + u32 id;
> + struct fd_id *n;
next is more obvious here
> +};
> +
> +static struct fd_id *fd_id_cache[FDID_SIZE];
> +
> +static void fd_id_cache_one(u32 id, struct stat *st)
> +{
> + struct fd_id *fi;
> + unsigned hv;
> +
> + fi = xmalloc(sizeof(*fi));
> + if (fi) {
> + fi->dev = st->st_dev;
> + fi->ino = st->st_ino;
> + fi->id = id;
> +
> + hv = fdid_hashfn(st->st_dev, st->st_ino);
> + fi->n = fd_id_cache[hv];
> + fd_id_cache[hv] = fi;
> + }
> +}
> +
> +static struct fd_id *fd_id_cache_lookup(struct stat *st)
> +{
> + struct fd_id *fi;
> +
> + for (fi = fd_id_cache[fdid_hashfn(st->st_dev, st->st_ino)];
> + fi; fi = fi->n)
> + if (fi->dev == st->st_dev && fi->ino == st->st_ino)
> + return fi;
For me the following code is bit more readable
fi = fd_id_cache[fdid_hashfn(st->st_dev, st->st_ino)];
while (fi) {
if (fi->dev == st->st_dev && fi->ino == st->st_ino)
return fi;
fi = fi->n;
}
> +
> + return NULL;
> +}
> +
> int fd_id_generate_special(struct stat *st, u32 *id)
> {
> + if (st) {
> + struct fd_id *fi;
> +
> + fi = fd_id_cache_lookup(st);
> + if (fi) {
> + *id = fi->id;
> + return 0;
> + }
> + }
> +
> *id = fd_tree.subid++;
> + if (st)
> + fd_id_cache_one(*id, st);
> return 1;
> }
>
> @@ -46,6 +105,9 @@ int fd_id_generate(pid_t pid, FdinfoEntry *fe, struct stat *st)
> if (!id)
> return -ENOMEM;
>
> + if (new_id)
> + fd_id_cache_one(id, st);
> +
> fe->id = id;
> return new_id;
> }
> --
> 1.8.4.2
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
More information about the CRIU
mailing list