From: Gao Xiang <gaoxiang25@huawei.com>
To: Li Guifu <bluce.lee@aliyun.com>
Cc: Miao Xie <miaoxie@huawei.com>, linux-erofs@lists.ozlabs.org
Subject: Re: [PATCH v6] erofs-utils: introduce exclude dirs and files
Date: Tue, 18 Feb 2020 10:32:17 +0800 [thread overview]
Message-ID: <20200218023214.GA215954@architecture4> (raw)
In-Reply-To: <20200217131653.54489-1-bluce.lee@aliyun.com>
On Mon, Feb 17, 2020 at 09:16:53PM +0800, Li Guifu wrote:
> From: Li GuiFu <bluce.lee@aliyun.com>
>
> Add excluded file feature "--exclude-path=" and '--exclude-regex=',
> which can be used to build EROFS image without some user specific
> files or dirs. Note that you may give multiple '--exclude-path'
> or '--exclude-regex' options.
>
> Signed-off-by: Gao Xiang <gaoxiang25@huawei.com>
> Signed-off-by: Li Guifu <bluce.lee@aliyun.com>
> ---
> change since v6, fix as comments suggested by Gao Xiang
> - update a new email address
> - refact regex and pattern match
>
> include/erofs/exclude.h | 26 ++++++++
> lib/Makefile.am | 2 +-
> lib/exclude.c | 136 ++++++++++++++++++++++++++++++++++++++++
> lib/inode.c | 5 ++
> man/mkfs.erofs.1 | 8 +++
> mkfs/main.c | 36 +++++++++--
> 6 files changed, 206 insertions(+), 7 deletions(-)
> create mode 100644 include/erofs/exclude.h
> create mode 100644 lib/exclude.c
>
> diff --git a/include/erofs/exclude.h b/include/erofs/exclude.h
> new file mode 100644
> index 0000000..0a82dbe
> --- /dev/null
> +++ b/include/erofs/exclude.h
> @@ -0,0 +1,26 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * erofs-utils/include/erofs/exclude.h
> + *
> + * Created by Li Guifu <bluce.lee@aliyun.com>
> + */
> +#ifndef __EROFS_EXCLUDE_H
> +#define __EROFS_EXCLUDE_H
> +#include <sys/types.h>
> +#include <regex.h>
> +
> +struct erofs_exclude_rule {
> + struct list_head list;
> +
> + char *pattern; /* save original pattern for exact or regex match */
> + regex_t reg;
> +};
> +
> +void erofs_exclude_set_root(const char *rootdir);
> +void erofs_cleanup_exclude_rules(void);
> +
> +int erofs_parse_exclude_path(const char *args, bool is_regex);
> +struct erofs_exclude_rule *erofs_is_exclude_path(const char *dir,
> + const char *name);
> +#endif
> +
> diff --git a/lib/Makefile.am b/lib/Makefile.am
> index 1ff81f9..e4b51e6 100644
> --- a/lib/Makefile.am
> +++ b/lib/Makefile.am
> @@ -3,7 +3,7 @@
>
> noinst_LTLIBRARIES = liberofs.la
> liberofs_la_SOURCES = config.c io.c cache.c inode.c xattr.c \
> - compress.c compressor.c
> + compress.c compressor.c exclude.c
> liberofs_la_CFLAGS = -Wall -Werror -I$(top_srcdir)/include
> if ENABLE_LZ4
> liberofs_la_CFLAGS += ${LZ4_CFLAGS}
> diff --git a/lib/exclude.c b/lib/exclude.c
> new file mode 100644
> index 0000000..6dae67e
> --- /dev/null
> +++ b/lib/exclude.c
> @@ -0,0 +1,136 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * erofs-utils/lib/exclude.c
> + *
> + * Created by Li Guifu <bluce.lee@aliyun.com>
> + */
> +#include <string.h>
> +#include <stdlib.h>
> +#include "erofs/err.h"
> +#include "erofs/list.h"
> +#include "erofs/print.h"
> +#include "erofs/exclude.h"
> +
> +#define EXCLUDE_RULE_EXACT_SIZE offsetof(struct erofs_exclude_rule, reg)
> +#define EXCLUDE_RULE_REGEX_SIZE sizeof(struct erofs_exclude_rule)
> +
> +static LIST_HEAD(exclude_head);
> +static LIST_HEAD(regex_exclude_head);
> +
> +static unsigned int rpathlen; /* root directory prefix length */
> +
> +void erofs_exclude_set_root(const char *rootdir)
> +{
> + rpathlen = strlen(rootdir);
> +}
> +
> +static void dump_regerror(int errcode, const char *s, const regex_t *preg)
> +{
> + char str[1024]; /* overflow safe */
> +
> + regerror(errcode, preg, str, 1024);
Still some minor issues here.
You could send the new version or I will fix them myself later.
Maybe it's better to "
char msg[1024];
regerror(errcode, preg, msg, sizeof(msg));
"
> + erofs_err("invalid regex %s,because %s\n", s, str);
> +}
> +
> +static struct erofs_exclude_rule *erofs_insert_exclude(const char *s,
> + bool is_regex)
> +{
> + int ret = -ENOMEM;
> + struct erofs_exclude_rule *r;
> + struct list_head *h;
> + unsigned int size;
> +
> + size = is_regex ? EXCLUDE_RULE_REGEX_SIZE : EXCLUDE_RULE_EXACT_SIZE;
> + r = malloc(size);
> + if (!r)
> + return ERR_PTR(-ENOMEM);
> +
> + r->pattern = strdup(s);
> + if (!r->pattern)
> + goto err_rule;
> +
> + if (is_regex) {
> + ret = regcomp(&r->reg, s, REG_EXTENDED|REG_NOSUB);
> + if(ret) {
> + dump_regerror(ret, s, &r->reg);
> + goto err_rule;
> + }
> + h = ®ex_exclude_head;
> + } else {
> + h = &exclude_head;
> + }
> +
> + list_add_tail(&r->list, h);
> + erofs_info("Insert exclude:[%s]\n", s);
> + return r;
> +
> +err_rule:
> + free(r);
> + return ERR_PTR(ret);
> +}
> +
> +static inline void erofs_free_exclude_rules(struct list_head *h)
> +{
> + struct erofs_exclude_rule *r, *n;
> +
> + list_for_each_entry_safe(r, n, h, list) {
> + list_del(&r->list);
> + free(r->pattern);
> + free(r);
> + }
> +}
> +
> +void erofs_cleanup_exclude_rules(void)
> +{
> + erofs_free_exclude_rules(&exclude_head);
> + erofs_free_exclude_rules(®ex_exclude_head);
For regular expression, it needs to regfree(&r->reg) anyway.
> +}
> +
> +int erofs_parse_exclude_path(const char *args, bool is_regex)
> +{
> + struct erofs_exclude_rule *r = erofs_insert_exclude(args, is_regex);
> +
> + if (IS_ERR(r)) {
> + erofs_cleanup_exclude_rules();
> + return PTR_ERR(r);
> + }
> + return 0;
> +}
> +
> +struct erofs_exclude_rule *erofs_is_exclude_path(const char *dir,
> + const char *name)
> +{
> + char buf[PATH_MAX];
> + const char *s;
> + struct erofs_exclude_rule *r;
> +
> + if (!dir) {
> + /* no prefix */
> + s = name;
> + } else {
> + sprintf(buf, "%s/%s", dir, name);
> + s = buf;
> + }
> +
> + s += rpathlen;
> + while (*s == '/')
> + s++;
> +
> + list_for_each_entry(r, &exclude_head, list) {
> + if (!strcmp(r->pattern, s))
> + return r;
> + }
> +
> + list_for_each_entry(r, ®ex_exclude_head, list) {
> + int ret = regexec(&r->reg, s, (size_t)0, NULL, 0);
> +
> + if(!ret)
> + return r;
> + else if (ret != REG_NOMATCH)
> + dump_regerror(ret, s, &r->reg);
> +
> + }
> +
> + return NULL;
> +}
> +
> diff --git a/lib/inode.c b/lib/inode.c
> index bd0652b..7114023 100644
> --- a/lib/inode.c
> +++ b/lib/inode.c
> @@ -20,6 +20,7 @@
> #include "erofs/io.h"
> #include "erofs/compress.h"
> #include "erofs/xattr.h"
> +#include "erofs/exclude.h"
>
> struct erofs_sb_info sbi;
>
> @@ -877,6 +878,10 @@ struct erofs_inode *erofs_mkfs_build_tree(struct erofs_inode *dir)
> !strncmp(dp->d_name, "lost+found", strlen("lost+found")))
> continue;
>
> + /* skip if it's a exclude file */
> + if (erofs_is_exclude_path(dir->i_srcpath, dp->d_name))
> + continue;
> +
> d = erofs_d_alloc(dir, dp->d_name);
> if (IS_ERR(d)) {
> ret = PTR_ERR(d);
> diff --git a/man/mkfs.erofs.1 b/man/mkfs.erofs.1
> index d6bf828..ab19927 100644
> --- a/man/mkfs.erofs.1
> +++ b/man/mkfs.erofs.1
> @@ -52,6 +52,14 @@ Forcely generate extended inodes (64-byte inodes) to output.
> Set all files to the given UNIX timestamp. Reproducible builds requires setting
> all to a specific one.
> .TP
> +.BI "\-\-exclude-path=" path
> +Ignore file that matches the exact literal path.
> +You may give multiple `--exclude-path' options.
> +.TP
> +.BI "\-\-exclude-regex=" path
> +Ignore file that matches the exact literal path given by a regex expression
> +You may give multiple `--exclude-regex` options
Didn't handle the previous comment of this.
(Regular expression is not a exact literal path.)
> +.TP
> .B \-\-help
> Display this help and exit.
> .SH AUTHOR
> diff --git a/mkfs/main.c b/mkfs/main.c
> index 817a6c1..d0c9869 100644
> --- a/mkfs/main.c
> +++ b/mkfs/main.c
> @@ -21,6 +21,7 @@
> #include "erofs/io.h"
> #include "erofs/compress.h"
> #include "erofs/xattr.h"
> +#include "erofs/exclude.h"
>
> #ifdef HAVE_LIBUUID
> #include <uuid/uuid.h>
> @@ -30,6 +31,8 @@
>
> static struct option long_options[] = {
> {"help", no_argument, 0, 1},
> + {"exclude-path", required_argument, NULL, 2},
> + {"exclude-regex", required_argument, NULL, 3},
> {0, 0, 0, 0},
> };
>
> @@ -50,12 +53,14 @@ static void usage(void)
> {
> fputs("usage: [options] FILE DIRECTORY\n\n"
> "Generate erofs image from DIRECTORY to FILE, and [options] are:\n"
> - " -zX[,Y] X=compressor (Y=compression level, optional)\n"
> - " -d# set output message level to # (maximum 9)\n"
> - " -x# set xattr tolerance to # (< 0, disable xattrs; default 2)\n"
> - " -EX[,...] X=extended options\n"
> - " -T# set a fixed UNIX timestamp # to all files\n"
> - " --help display this help and exit\n"
> + " -zX[,Y] X=compressor (Y=compression level, optional)\n"
> + " -d# set output message level to # (maximum 9)\n"
> + " -x# set xattr tolerance to # (< 0, disable xattrs; default 2)\n"
> + " -EX[,...] X=extended options\n"
> + " -T# set a fixed UNIX timestamp # to all files\n"
> + " --exclude-path=X avoid including file X (X = exact literal path)\n"
> + " --exclude-regex=X avoid including file X (X = exact literal path of a regex)\n"
Didn't handle this as well.
Thanks,
Gao Xiang
next prev parent reply other threads:[~2020-02-18 2:34 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-17 13:16 [PATCH v6] erofs-utils: introduce exclude dirs and files Li Guifu via Linux-erofs
2020-02-18 2:32 ` Gao Xiang [this message]
2020-02-18 14:04 ` Li GuiFu via Linux-erofs
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200218023214.GA215954@architecture4 \
--to=gaoxiang25@huawei.com \
--cc=bluce.lee@aliyun.com \
--cc=linux-erofs@lists.ozlabs.org \
--cc=miaoxie@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.