[ostree/wip/gs-dir-iter: 4/4] diriter



commit a755ce5a3dc1be4a5b4330657255d602f75c7eb8
Author: Colin Walters <walters verbum org>
Date:   Tue Dec 16 21:14:18 2014 -0500

    diriter

 src/libostree/ostree-repo-commit.c |  206 ++++++++++++++++++++++++++++++++----
 1 files changed, 184 insertions(+), 22 deletions(-)
---
diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c
index 6161f2b..7b516bc 100644
--- a/src/libostree/ostree-repo-commit.c
+++ b/src/libostree/ostree-repo-commit.c
@@ -1901,6 +1901,8 @@ get_modified_xattrs (OstreeRepo                       *self,
                      const char                       *relpath,
                      GFileInfo                        *file_info,
                      GFile                            *path,
+                     int                               dfd,
+                     const char                       *dfd_subpath,
                      GVariant                        **out_xattrs,
                      GCancellable                     *cancellable,
                      GError                          **error)
@@ -1915,8 +1917,18 @@ get_modified_xattrs (OstreeRepo                       *self,
     }
   else if (!(modifier && (modifier->flags & OSTREE_REPO_COMMIT_MODIFIER_FLAGS_SKIP_XATTRS) > 0))
     {
-      if (!gs_file_get_all_xattrs (path, &ret_xattrs, cancellable, error))
-        goto out;
+      if (path)
+        {
+          if (!gs_file_get_all_xattrs (path, &ret_xattrs, cancellable, error))
+            goto out;
+        }
+      else
+        {
+          g_assert (dfd != -1);
+          if (!gs_dfd_and_name_set_all_xattrs (dfd, dfd_subpath, &ret_xattrs,
+                                               cancellable, error))
+            goto out;
+        }
     }
 
   if (modifier && modifier->sepolicy)
@@ -1964,11 +1976,20 @@ write_directory_to_mtree_internal (OstreeRepo                  *self,
                                    GPtrArray                   *path,
                                    GCancellable                *cancellable,
                                    GError                     **error);
+static gboolean
+write_dfd_iter_to_mtree_internal (OstreeRepo                  *self,
+                                  GSDirFdIterator             *src_dfd_iter,
+                                  OstreeMutableTree           *mtree,
+                                  OstreeRepoCommitModifier    *modifier,
+                                  GPtrArray                   *path,
+                                  GCancellable                *cancellable,
+                                  GError                     **error);
 
 static gboolean
 write_directory_content_to_mtree_internal (OstreeRepo                  *self,
                                            OstreeRepoFile              *repo_dir,
                                            GFileEnumerator             *dir_enum,
+                                           GSDirFdIterator             *dfd_iter,
                                            GFileInfo                   *child_info,
                                            OstreeMutableTree           *mtree,
                                            OstreeRepoCommitModifier    *modifier,
@@ -1985,13 +2006,19 @@ write_directory_content_to_mtree_internal (OstreeRepo                  *self,
   GFileType file_type;
   OstreeRepoCommitFilterResult filter_result;
 
+  g_assert (dir_enum != NULL || dfd != -1);
+
   name = g_file_info_get_name (child_info);
   g_ptr_array_add (path, (char*)name);
 
   if (modifier != NULL)
-    child_relpath = ptrarray_path_join (path);
+    {
+      child_relpath = ptrarray_path_join (path);
 
-  filter_result = apply_commit_filter (self, modifier, child_relpath, child_info, &modified_info);
+      filter_result = apply_commit_filter (self, modifier, child_relpath, child_info, &modified_info);
+    }
+  else
+    filter_result = OSTREE_REPO_COMMIT_FILTER_ALLOW;
 
   if (filter_result != OSTREE_REPO_COMMIT_FILTER_ALLOW)
     {
@@ -2000,8 +2027,6 @@ write_directory_content_to_mtree_internal (OstreeRepo                  *self,
       goto out;
     }
 
-  child = g_file_enumerator_get_child (dir_enum, child_info);
-
   file_type = g_file_info_get_file_type (child_info);
   switch (file_type)
     {
@@ -2016,18 +2041,36 @@ write_directory_content_to_mtree_internal (OstreeRepo                  *self,
       goto out;
     }
 
+  if (dir_enum != NULL)
+    child = g_file_enumerator_get_child (dir_enum, child_info);
+
   if (file_type == G_FILE_TYPE_DIRECTORY)
     {
       if (!ostree_mutable_tree_ensure_dir (mtree, name, &child_mtree, error))
         goto out;
 
-      if (!write_directory_to_mtree_internal (self, child, child_mtree,
-                                              modifier, path,
-                                              cancellable, error))
-        goto out;
+      if (dir_enum != NULL)
+        {
+          if (!write_directory_to_mtree_internal (self, child, child_mtree,
+                                                  modifier, path,
+                                                  cancellable, error))
+            goto out;
+        }
+      else
+        {
+          GSDirFdIterator child_dfd_iter = { 0, };
+
+          if (!gs_dirfd_iterator_init_at (dfd_iter->fd, name, FALSE, &child_dfd_iter, error))
+            goto out;
+
+          if (!write_dfd_iter_to_mtree_internal (self, &child_dfd_iter, mtree, modifier, path,
+                                                 cancellable, error))
+            goto out;
+        }
     }
   else if (repo_dir)
     {
+      g_assert (dir_enum != NULL);
       g_debug ("Adding: %s", gs_file_get_path_cached (child));
       if (!ostree_mutable_tree_replace_file (mtree, name,
                                              ostree_repo_file_get_checksum ((OstreeRepoFile*) child),
@@ -2057,13 +2100,26 @@ write_directory_content_to_mtree_internal (OstreeRepo                  *self,
         {
           if (g_file_info_get_file_type (modified_info) == G_FILE_TYPE_REGULAR)
             {
-              file_input = (GInputStream*)g_file_read (child, cancellable, error);
-              if (!file_input)
-                goto out;
+              if (child != NULL)
+                {
+                  file_input = (GInputStream*)g_file_read (child, cancellable, error);
+                  if (!file_input)
+                    goto out;
+                }
+              else
+                {
+                  int filefd = openat (dfd_iter->fd, name, O_RDONLY, 0);
+                  if (filefd == -1)
+                    {
+                      ot_util_set_error_from_errno (error, errno);
+                      goto out;
+                    }
+                  file_input = (GInputStream*)g_unix_input_stream_new (filefd, TRUE);
+                }
             }
 
           if (!get_modified_xattrs (self, modifier,
-                                    child_relpath, child_info, child,
+                                    child_relpath, child_info, child, dfd_iter, name,
                                     &xattrs,
                                     cancellable, error))
             goto out;
@@ -2107,11 +2163,12 @@ write_directory_to_mtree_internal (OstreeRepo                  *self,
   gs_unref_object GFileEnumerator *dir_enum = NULL;
   gs_unref_object GFileInfo *child_info = NULL;
 
-  g_debug ("Examining: %s", gs_file_get_path_cached (dir));
+  if (dir)
+    g_debug ("Examining: %s", gs_file_get_path_cached (dir));
 
   /* If the directory is already in the repository, we can try to
    * reuse checksums to skip checksumming. */
-  if (OSTREE_IS_REPO_FILE (dir) && modifier == NULL)
+  if (dir && OSTREE_IS_REPO_FILE (dir) && modifier == NULL)
     repo_dir = (OstreeRepoFile *) dir;
 
   if (repo_dir)
@@ -2154,8 +2211,8 @@ write_directory_to_mtree_internal (OstreeRepo                  *self,
 
       if (filter_result == OSTREE_REPO_COMMIT_FILTER_ALLOW)
         {
-          g_debug ("Adding: %s", gs_file_get_path_cached (dir));
-          if (!get_modified_xattrs (self, modifier, relpath, child_info, dir,
+          if (!get_modified_xattrs (self, modifier, relpath, child_info,
+                                    dir, dfd, dfd_path,
                                     &xattrs,
                                     cancellable, error))
             goto out;
@@ -2193,7 +2250,8 @@ write_directory_to_mtree_internal (OstreeRepo                  *self,
           if (child_info == NULL)
             break;
 
-          if (!write_directory_content_to_mtree_internal (self, repo_dir, dir_enum, child_info,
+          if (!write_directory_content_to_mtree_internal (self, repo_dir, dir_enum, NULL,
+                                                          child_info,
                                                           mtree, modifier, path,
                                                           cancellable, error))
             goto out;
@@ -2205,6 +2263,96 @@ write_directory_to_mtree_internal (OstreeRepo                  *self,
   return ret;
 }
 
+static gboolean
+write_dfd_iter_to_mtree_internal (OstreeRepo                  *self,
+                                  GSDirFdIterator             *src_dfd_iter,
+                                  OstreeMutableTree           *mtree,
+                                  OstreeRepoCommitModifier    *modifier,
+                                  GPtrArray                   *path,
+                                  GCancellable                *cancellable,
+                                  GError                     **error)
+{
+  gboolean ret = FALSE;
+  gs_unref_object GFileInfo *modified_info = NULL;
+  gs_unref_variant GVariant *xattrs = NULL;
+  gs_free guchar *child_file_csum = NULL;
+  gs_free char *tmp_checksum = NULL;
+  gs_free char *relpath = NULL;
+  struct stat dir_stbuf;
+
+  if (fstat (src_dfd_iter->fd, &dir_stbuf) != 0)
+    {
+      ot_util_set_error_from_errno (error, errno);
+      goto out;
+    }
+
+  if (modifier != NULL)
+    {
+      gs_unref_object GFileInfo *child_info = NULL;
+
+      relpath = ptrarray_path_join (path);
+
+      child_info = ot_util_struct_stat_to_gfile_info (&dir_stbuf);
+      
+      filter_result = apply_commit_filter (self, modifier, relpath, child_info, &modified_info);
+    }
+  else
+    filter_result = OSTREE_REPO_COMMIT_FILTER_ALLOW;
+
+  if (filter_result == OSTREE_REPO_COMMIT_FILTER_ALLOW)
+    {
+      g_debug ("Adding: %s", gs_file_get_path_cached (dir));
+      if (!get_modified_xattrs (self, modifier, relpath, child_info,
+                                NULL, src_dfd_iter->fd, NULL,
+                                &xattrs,
+                                cancellable, error))
+        goto out;
+
+      if (!_ostree_repo_write_directory_meta (self, modified_info, xattrs, &child_file_csum,
+                                              cancellable, error))
+        goto out;
+
+      g_free (tmp_checksum);
+      tmp_checksum = ostree_checksum_from_bytes (child_file_csum);
+      ostree_mutable_tree_set_metadata_checksum (mtree, tmp_checksum);
+    }
+
+  g_clear_object (&child_info);
+
+  if (filter_result == OSTREE_REPO_COMMIT_FILTER_ALLOW)
+    {
+      struct dirent *dent;
+      struct stat stbuf;
+
+      if (!gs_dirfd_iterator_next_dent (dfd_iter, &dent, cancellable, error))
+        goto out;
+
+      if (dent == NULL)
+        break;
+
+      if (fstatat (dfd_iter->fd, dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW) == -1)
+        {
+          ot_util_set_error_from_errno (error, errno);
+          goto out;
+        }
+
+      child_info = ot_util_struct_stat_to_gfile_info (&dir_stbuf);
+      g_file_info_set_name (child_info, dent->d_name);
+
+      if (!write_directory_content_to_mtree_internal (self, NULL, NULL, dfd_iter,
+                                                      child_info,
+                                                      mtree, modifier, path,
+                                                      cancellable, error))
+        goto out;
+
+      g_clear_object (&child_info);
+    }
+
+  ret = TRUE;
+ out:
+  return ret;
+}
+
 /**
  * ostree_repo_write_directory_to_mtree:
  * @self: Repo
@@ -2234,9 +2382,23 @@ ostree_repo_write_directory_to_mtree (OstreeRepo                *self,
     }
 
   path = g_ptr_array_new ();
-  if (!write_directory_to_mtree_internal (self, dir, mtree, modifier, path,
-                                          cancellable, error))
-    goto out;
+  if (g_file_is_native (dir))
+    {
+      GSDirFdIterator dfd_iter = { 0, };
+
+      if (!gs_dirfd_iterator_init_at (AT_FDCWD, dir, FALSE, &dfd_iter, error))
+        goto out;
+
+      if (!write_dfd_iter_to_mtree_internal (self, &dfd_iter, mtree, modifier, path,
+                                             cancellable, error))
+        goto out;
+    }
+  else
+    {
+      if (!write_directory_to_mtree_internal (self, dir, mtree, modifier, path,
+                                              cancellable, error))
+        goto out;
+    }
 
   ret = TRUE;
  out:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]