[1/5] util: Add mkdirpat_precise helper

Submitted by Cyrill Gorcunov on Feb. 22, 2019, 4:02 p.m.

Details

Message ID 20190222160257.27697-2-gorcunov@gmail.com
State New
Series "Fix order problem in ghost files cleanup"
Headers show

Commit Message

Cyrill Gorcunov Feb. 22, 2019, 4:02 p.m.
To know where new dirents are created.

Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
---
 criu/include/util.h |  6 +++++-
 criu/util.c         | 26 ++++++++++++++++++++------
 2 files changed, 25 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/util.h b/criu/include/util.h
index 57192c5f273d..694b5358cf68 100644
--- a/criu/include/util.h
+++ b/criu/include/util.h
@@ -253,7 +253,11 @@  static inline bool issubpath(const char *path, const char *sub_path)
 /*
  * mkdir -p
  */
-int mkdirpat(int fd, const char *path, int mode);
+int mkdirpat_precise(int fd, const char *path, int mode, const char **new);
+static inline int mkdirpat(int fd, const char *path, int mode)
+{
+	return mkdirpat_precise(fd, path, mode, NULL);
+}
 
 /*
  * Tests whether a path is a prefix of another path. This is different than
diff --git a/criu/util.c b/criu/util.c
index 1cc4ecd4427e..8c1ee550983f 100644
--- a/criu/util.c
+++ b/criu/util.c
@@ -1001,10 +1001,15 @@  struct vma_area *alloc_vma_area(void)
 	return p;
 }
 
-int mkdirpat(int fd, const char *path, int mode)
+/*
+ * Make the whole @path to the specified directory, report
+ * the position of newly created directories via @new.
+ */
+int mkdirpat_precise(int fd, const char *path, int mode, const char **new)
 {
-	size_t i;
 	char made_path[PATH_MAX], *pos;
+	const char *where = path;
+	size_t i;
 
 	if (strlen(path) >= PATH_MAX) {
 		pr_err("path %s is longer than PATH_MAX\n", path);
@@ -1021,18 +1026,27 @@  int mkdirpat(int fd, const char *path, int mode)
 		pos = strchr(made_path + i, '/');
 		if (pos)
 			*pos = '\0';
-		if (mkdirat(fd, made_path, mode) < 0 && errno != EEXIST) {
-			int ret = -errno;
-			pr_perror("couldn't mkdirpat directory %s", made_path);
-			return ret;
+		if (mkdirat(fd, made_path, mode) < 0) {
+			if (errno == EEXIST) {
+				where = path;
+			} else {
+				int ret = -errno;
+				pr_perror("couldn't mkdirpat directory %s", made_path);
+				return ret;
+			}
 		}
 		if (pos) {
 			*pos = '/';
 			i = pos - made_path;
+			if (where == path)
+				where = &path[i+1];
 		} else
 			break;
 	}
 
+	if (new)
+		*new = where;
+
 	return 0;
 }
 

Comments

Pavel Tikhomirov Feb. 25, 2019, 2:22 p.m.
On 2/22/19 7:02 PM, Cyrill Gorcunov wrote:
> To know where new dirents are created.
> 
> Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
> ---
>   criu/include/util.h |  6 +++++-
>   criu/util.c         | 26 ++++++++++++++++++++------
>   2 files changed, 25 insertions(+), 7 deletions(-)
> 
> diff --git a/criu/include/util.h b/criu/include/util.h
> index 57192c5f273d..694b5358cf68 100644
> --- a/criu/include/util.h
> +++ b/criu/include/util.h
> @@ -253,7 +253,11 @@ static inline bool issubpath(const char *path, const char *sub_path)
>   /*
>    * mkdir -p
>    */
> -int mkdirpat(int fd, const char *path, int mode);
> +int mkdirpat_precise(int fd, const char *path, int mode, const char **new);
> +static inline int mkdirpat(int fd, const char *path, int mode)
> +{
> +	return mkdirpat_precise(fd, path, mode, NULL);
> +}
>   
>   /*
>    * Tests whether a path is a prefix of another path. This is different than
> diff --git a/criu/util.c b/criu/util.c
> index 1cc4ecd4427e..8c1ee550983f 100644
> --- a/criu/util.c
> +++ b/criu/util.c
> @@ -1001,10 +1001,15 @@ struct vma_area *alloc_vma_area(void)
>   	return p;
>   }
>   

"i" and "pos" looks duplicating the meaning of each other, maybe we can 
do something like 
https://github.com/Snorch/criu/commit/9e141789698210d5b5ac6f50d36d4657603968a0 
to simplify mkdirpat?

> -int mkdirpat(int fd, const char *path, int mode)
> +/*
> + * Make the whole @path to the specified directory, report
> + * the position of newly created directories via @new.
> + */
> +int mkdirpat_precise(int fd, const char *path, int mode, const char **new)
>   {
> -	size_t i;
>   	char made_path[PATH_MAX], *pos;
> +	const char *where = path;
> +	size_t i;
>   
>   	if (strlen(path) >= PATH_MAX) {
>   		pr_err("path %s is longer than PATH_MAX\n", path);
> @@ -1021,18 +1026,27 @@ int mkdirpat(int fd, const char *path, int mode)
>   		pos = strchr(made_path + i, '/');
>   		if (pos)
>   			*pos = '\0';
> -		if (mkdirat(fd, made_path, mode) < 0 && errno != EEXIST) {
> -			int ret = -errno;
> -			pr_perror("couldn't mkdirpat directory %s", made_path);
> -			return ret;
> +		if (mkdirat(fd, made_path, mode) < 0) {
> +			if (errno == EEXIST) {
> +				where = path;
> +			} else {
> +				int ret = -errno;
> +				pr_perror("couldn't mkdirpat directory %s", made_path);
> +				return ret;
> +			}
>   		}
>   		if (pos) {
>   			*pos = '/';
>   			i = pos - made_path;
> +			if (where == path)
> +				where = &path[i+1];
>   		} else
>   			break;
>   	}
>   
> +	if (new)
> +		*new = where;
> +
>   	return 0;
>   }
>   
>
Cyrill Gorcunov Feb. 25, 2019, 2:32 p.m.
On Mon, Feb 25, 2019 at 02:22:07PM +0000, Pavel Tikhomirov wrote:
> > --- a/criu/util.c
> > +++ b/criu/util.c
> > @@ -1001,10 +1001,15 @@ struct vma_area *alloc_vma_area(void)
> >   	return p;
> >   }
> >   
> 
> "i" and "pos" looks duplicating the meaning of each other, maybe we can 
> do something like 
> https://github.com/Snorch/criu/commit/9e141789698210d5b5ac6f50d36d4657603968a0 
> to simplify mkdirpat?

I wanted to make patch smaller. But since we're modifying the code
anyway will update, thanks!