Whamcloud - gitweb
misc: copy extended attributes in populate_fs
authorRoss Burton <ross.burton@intel.com>
Thu, 10 Jul 2014 16:44:38 +0000 (17:44 +0100)
committerTheodore Ts'o <tytso@mit.edu>
Mon, 28 Jul 2014 01:19:24 +0000 (21:19 -0400)
When creating a file system using a source directory, also copy any extended
attributes that have been set.

[ Add configure tests for Linux-specific xattr syscalls and add fallback
  when compiling on non-Linux systems. --tytso ]

Signed-off-by: Ross Burton <ross.burton@intel.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
configure
configure.in
lib/config.h.in
misc/create_inode.c

index d8f6deb..6c503aa 100755 (executable)
--- a/configure
+++ b/configure
@@ -12404,7 +12404,7 @@ fi
 done
 
 fi
-for ac_header in       dirent.h        errno.h         execinfo.h      getopt.h        malloc.h        mntent.h        paths.h         semaphore.h     setjmp.h        signal.h        stdarg.h        stdint.h        stdlib.h        termios.h       termio.h        unistd.h        utime.h         linux/falloc.h  linux/fd.h      linux/major.h   linux/loop.h    net/if_dl.h     netinet/in.h    sys/disklabel.h         sys/disk.h      sys/file.h      sys/ioctl.h     sys/mkdev.h     sys/mman.h      sys/mount.h     sys/prctl.h     sys/resource.h  sys/select.h    sys/socket.h    sys/sockio.h    sys/stat.h      sys/syscall.h   sys/sysmacros.h         sys/time.h      sys/types.h     sys/un.h        sys/wait.h
+for ac_header in       dirent.h        errno.h         execinfo.h      getopt.h        malloc.h        mntent.h        paths.h         semaphore.h     setjmp.h        signal.h        stdarg.h        stdint.h        stdlib.h        termios.h       termio.h        unistd.h        utime.h         attr/xattr.h    linux/falloc.h  linux/fd.h      linux/major.h   linux/loop.h    net/if_dl.h     netinet/in.h    sys/disklabel.h         sys/disk.h      sys/file.h      sys/ioctl.h     sys/mkdev.h     sys/mman.h      sys/mount.h     sys/prctl.h     sys/resource.h  sys/select.h    sys/socket.h    sys/sockio.h    sys/stat.h      sys/syscall.h   sys/sysmacros.h         sys/time.h      sys/types.h     sys/un.h        sys/wait.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -13071,7 +13071,7 @@ if test "$ac_res" != no; then :
 fi
 
 fi
-for ac_func in         __secure_getenv         backtrace       blkid_probe_get_topology        blkid_probe_enable_partitions   chflags         fadvise64       fallocate       fallocate64     fchown  fdatasync       fstat64         ftruncate64     futimes         getcwd  getdtablesize   getmntinfo      getpwuid_r      getrlimit       getrusage       jrand48         llseek  lseek64         mallinfo        mbstowcs        memalign        mempcpy         mmap    msync   nanosleep       open64  pathconf        posix_fadvise   posix_fadvise64         posix_memalign  prctl   secure_getenv   setmntent       setresgid       setresuid       snprintf        srandom         stpcpy  strcasecmp      strdup  strnlen         strptime        strtoull        sync_file_range         sysconf         usleep  utime   valloc
+for ac_func in         __secure_getenv         backtrace       blkid_probe_get_topology        blkid_probe_enable_partitions   chflags         fadvise64       fallocate       fallocate64     fchown  fdatasync       fstat64         ftruncate64     futimes         getcwd  getdtablesize   getmntinfo      getpwuid_r      getrlimit       getrusage       jrand48         llistxattr      llseek  lseek64         mallinfo        mbstowcs        memalign        mempcpy         mmap    msync   nanosleep       open64  pathconf        posix_fadvise   posix_fadvise64         posix_memalign  prctl   secure_getenv   setmntent       setresgid       setresuid       snprintf        srandom         stpcpy  strcasecmp      strdup  strnlen         strptime        strtoull        sync_file_range         sysconf         usleep  utime   valloc
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
index 79c8dc2..67e5453 100644 (file)
@@ -920,6 +920,7 @@ AC_CHECK_HEADERS(m4_flatten([
        termio.h
        unistd.h
        utime.h
+       attr/xattr.h
        linux/falloc.h
        linux/fd.h
        linux/major.h
@@ -1098,6 +1099,7 @@ AC_CHECK_FUNCS(m4_flatten([
        getrlimit
        getrusage
        jrand48
+       llistxattr
        llseek
        lseek64
        mallinfo
index 3ed71fa..12a609a 100644 (file)
@@ -70,6 +70,9 @@
 /* Define to 1 if you have the `asprintf' function. */
 #undef HAVE_ASPRINTF
 
+/* Define to 1 if you have the <attr/xattr.h> header file. */
+#undef HAVE_ATTR_XATTR_H
+
 /* Define to 1 if you have the `backtrace' function. */
 #undef HAVE_BACKTRACE
 
 /* Define to 1 if you have the <linux/major.h> header file. */
 #undef HAVE_LINUX_MAJOR_H
 
+/* Define to 1 if you have the `llistxattr' function. */
+#undef HAVE_LLISTXATTR
+
 /* Define to 1 if you have the `llseek' function. */
 #undef HAVE_LLSEEK
 
index 92086d2..4d56719 100644 (file)
@@ -12,6 +12,9 @@
 #include <time.h>
 #include <unistd.h>
 #include <limits.h> /* for PATH_MAX */
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
 
 #include "create_inode.h"
 
@@ -103,6 +106,94 @@ static errcode_t set_inode_extra(ext2_filsys fs, ext2_ino_t cwd,
        return retval;
 }
 
+static errcode_t set_inode_xattr(ext2_filsys fs, ext2_ino_t ino, const char *filename)
+{
+#ifdef HAVE_LLISTXATTR
+       errcode_t                       retval, close_retval;
+       struct ext2_inode               inode;
+       struct ext2_xattr_handle        *handle;
+       ssize_t                         size, value_size;
+       char                            *list;
+       int                             i;
+
+       size = llistxattr(filename, NULL, 0);
+       if (size == -1) {
+               com_err(__func__, errno, "llistxattr failed on %s", filename);
+               return errno;
+       } else if (size == 0) {
+               return 0;
+       }
+
+       retval = ext2fs_xattrs_open(fs, ino, &handle);
+       if (retval) {
+               if (retval == EXT2_ET_MISSING_EA_FEATURE)
+                       return 0;
+               com_err(__func__, retval, "while opening inode %u", ino);
+               return retval;
+       }
+
+       retval = ext2fs_get_mem(size, &list);
+       if (retval) {
+               com_err(__func__, retval, "whilst allocating memory");
+               goto out;
+       }
+
+       size = llistxattr(filename, list, size);
+       if (size == -1) {
+               com_err(__func__, errno, "llistxattr failed on %s", filename);
+               retval = errno;
+               goto out;
+        }
+
+       for (i = 0; i < size; i += strlen(&list[i]) + 1) {
+               const char *name = &list[i];
+               char *value;
+
+               value_size = getxattr(filename, name, NULL, 0);
+               if (value_size == -1) {
+                       com_err(__func__, errno, "getxattr failed on %s",
+                               filename);
+                       retval = errno;
+                       break;
+               }
+
+               retval = ext2fs_get_mem(value_size, &value);
+               if (retval) {
+                       com_err(__func__, retval, "whilst allocating memory");
+                       break;
+               }
+
+               value_size = getxattr(filename, name, value, value_size);
+               if (value_size == -1) {
+                       ext2fs_free_mem(&value);
+                       com_err(__func__, errno, "getxattr failed on %s",
+                               filename);
+                       retval = errno;
+                       break;
+               }
+
+               retval = ext2fs_xattr_set(handle, name, value, value_size);
+               ext2fs_free_mem(&value);
+               if (retval) {
+                       com_err(__func__, retval,
+                               "while writing xattr %u", ino);
+                       break;
+               }
+
+       }
+ out:
+       ext2fs_free_mem(&list);
+       close_retval = ext2fs_xattrs_close(&handle);
+       if (close_retval) {
+               com_err(__func__, retval, "while closing inode %u", ino);
+               retval = retval ? retval : close_retval;
+       }
+       return retval;
+#else /* HAVE_LLISTXATTR */
+       return 0;
+#endif  /* HAVE_LLISTXATTR */
+}
+
 /* Make a special files (block and character devices), fifo's, and sockets  */
 errcode_t do_mknod_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
                            struct stat *st)
@@ -620,6 +711,13 @@ static errcode_t __populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
                        goto out;
                }
 
+               retval = set_inode_xattr(fs, ino, name);
+               if (retval) {
+                       com_err(__func__, retval,
+                               _("while setting xattrs for \"%s\""), name);
+                       goto out;
+               }
+
                /* Save the hardlink ino */
                if (save_inode) {
                        /*