GNU tar volume labels (by using `-V`) will be applied to EROFS.

Signed-off-by: Gao Xiang <[email protected]>
---
 lib/tar.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/lib/tar.c b/lib/tar.c
index 8e71f11..1cd820f 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -17,6 +17,9 @@
 #include "erofs/blobchunk.h"
 #include "erofs/rebuild.h"
 
+/* This file is a tape/volume header.  Ignore it on extraction.  */
+#define GNUTYPE_VOLHDR 'V'
+
 struct tar_header {
        char name[100];         /*   0-99 */
        char mode[8];           /* 100-107 */
@@ -632,12 +635,6 @@ restart:
                goto restart;
        }
 
-       if (memcmp(th->magic, "ustar", 5)) {
-               erofs_err("invalid tar magic @ %llu", tar_offset);
-               ret = -EIO;
-               goto out;
-       }
-
        /* chksum field itself treated as ' ' */
        csum = tarerofs_otoi(th->chksum, sizeof(th->chksum));
        if (errno) {
@@ -663,6 +660,21 @@ restart:
                goto out;
        }
 
+       if (th->typeflag == GNUTYPE_VOLHDR) {
+               if (th->size[0])
+                       erofs_warn("GNUTYPE_VOLHDR with non-zeroed size @ %llu",
+                                  tar_offset);
+               /* anyway, strncpy could cause some GCC warning here */
+               memcpy(sbi->volume_name, th->name, sizeof(sbi->volume_name));
+               goto restart;
+       }
+
+       if (memcmp(th->magic, "ustar", 5)) {
+               erofs_err("invalid tar magic @ %llu", tar_offset);
+               ret = -EIO;
+               goto out;
+       }
+
        st.st_mode = tarerofs_otoi(th->mode, sizeof(th->mode));
        if (errno)
                goto invalid_tar;
-- 
2.39.3

Reply via email to