[ostree] repo: Port hardlink-scanning code to fd-relative calls



commit 488efac728d660d56e44c88242d0be63a473dea2
Author: Colin Walters <walters verbum org>
Date:   Tue Mar 3 09:13:47 2015 -0500

    repo: Port hardlink-scanning code to fd-relative calls
    
    Continuing the migration.

 libglnx                             |    2 +-
 src/libostree/ostree-repo-commit.c  |  126 ++++++++++++++++++++++-------------
 src/libostree/ostree-repo-private.h |    6 --
 src/libostree/ostree-repo.c         |   83 -----------------------
 4 files changed, 81 insertions(+), 136 deletions(-)
---
diff --git a/libglnx b/libglnx
index c1ae7ce..162d1f6 160000
--- a/libglnx
+++ b/libglnx
@@ -1 +1 @@
-Subproject commit c1ae7ce1bf9c9175b26d1d933757503a0cc368e3
+Subproject commit 162d1f6b58c9b501f47080e99aa1fd36864a89f9
diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c
index 4cab2f4..3aa7270 100644
--- a/src/libostree/ostree-repo-commit.c
+++ b/src/libostree/ostree-repo-commit.c
@@ -842,65 +842,58 @@ devino_equal (gconstpointer   a,
 }
 
 static gboolean
-scan_loose_devino (OstreeRepo                     *self,
-                   GHashTable                     *devino_cache,
-                   GCancellable                   *cancellable,
-                   GError                        **error)
+scan_one_loose_devino (OstreeRepo                     *self,
+                       int                             object_dir_fd,
+                       GHashTable                     *devino_cache,
+                       GCancellable                   *cancellable,
+                       GError                        **error)
 {
   gboolean ret = FALSE;
-  guint i;
-  OstreeRepoMode repo_mode;
-  gs_unref_ptrarray GPtrArray *object_dirs = NULL;
+  int res;
+  g_auto(GLnxDirFdIterator) dfd_iter = { 0, };
 
-  if (self->parent_repo)
+  if (!glnx_dirfd_iterator_init_at (object_dir_fd, ".", FALSE,
+                                    &dfd_iter, error))
+    goto out;
+  
+  while (TRUE)
     {
-      if (!scan_loose_devino (self->parent_repo, devino_cache, cancellable, error))
-        goto out;
-    }
+      struct dirent *dent;
+      g_auto(GLnxDirFdIterator) child_dfd_iter = { 0, };
 
-  repo_mode = ostree_repo_get_mode (self);
+      if (!glnx_dirfd_iterator_next_dent (&dfd_iter, &dent, cancellable, error))
+        goto out;
+          
+      if (dent == NULL)
+        break;
 
-  if (!_ostree_repo_get_loose_object_dirs (self, &object_dirs, cancellable, error))
-    goto out;
+      /* All object directories only have two character entries */
+      if (strlen (dent->d_name) != 2)
+        continue;
 
-  for (i = 0; i < object_dirs->len; i++)
-    {
-      GFile *objdir = object_dirs->pdata[i];
-      gs_unref_object GFileEnumerator *enumerator = NULL;
-      gs_unref_object GFileInfo *file_info = NULL;
-      const char *dirname;
-
-      enumerator = g_file_enumerate_children (objdir, OSTREE_GIO_FAST_QUERYINFO,
-                                              G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-                                              cancellable,
-                                              error);
-      if (!enumerator)
+      if (!glnx_dirfd_iterator_init_at (dfd_iter.fd, dent->d_name, FALSE,
+                                        &child_dfd_iter, error))
         goto out;
 
-      dirname = gs_file_get_basename_cached (objdir);
-
       while (TRUE)
         {
-          const char *name;
-          const char *dot;
-          guint32 type;
+          struct stat stbuf;
           OstreeDevIno *key;
+          struct dirent *child_dent;
+          const char *dot;
           GString *checksum;
           gboolean skip;
+          const char *name;
 
-          if (!gs_file_enumerator_iterate (enumerator, &file_info, NULL,
-                                           NULL, error))
+          if (!glnx_dirfd_iterator_next_dent (&child_dfd_iter, &child_dent, cancellable, error))
             goto out;
-          if (file_info == NULL)
+          
+          if (child_dent == NULL)
             break;
 
-          name = g_file_info_get_attribute_byte_string (file_info, "standard::name");
-          type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
+          name = child_dent->d_name;
 
-          if (type == G_FILE_TYPE_DIRECTORY)
-            continue;
-
-          switch (repo_mode)
+          switch (self->mode)
             {
             case OSTREE_REPO_MODE_ARCHIVE_Z2:
             case OSTREE_REPO_MODE_BARE:
@@ -915,17 +908,27 @@ scan_loose_devino (OstreeRepo                     *self,
 
           dot = strrchr (name, '.');
           g_assert (dot);
-
+          
+          /* Skip anything that doesn't look like a 64 character checksum */
           if ((dot - name) != 62)
             continue;
 
-          checksum = g_string_new (dirname);
-          g_string_append_len (checksum, name, 62);
+          do
+            res = fstatat (child_dfd_iter.fd, child_dent->d_name, &stbuf, AT_SYMLINK_NOFOLLOW);
+          while (G_UNLIKELY (res == -1 && errno == EINTR));
+          if (res == -1)
+            {
+              glnx_set_error_from_errno (error);
+              goto out;
+            }
 
+          checksum = g_string_new (dent->d_name);
+          g_string_append_len (checksum, name, 62);
+          
           key = g_new (OstreeDevIno, 1);
-          key->dev = g_file_info_get_attribute_uint32 (file_info, "unix::device");
-          key->ino = g_file_info_get_attribute_uint64 (file_info, "unix::inode");
-
+          key->dev = stbuf.st_dev;
+          key->ino = stbuf.st_ino;
+          
           g_hash_table_replace (devino_cache, key, g_string_free (checksum, FALSE));
         }
     }
@@ -935,6 +938,36 @@ scan_loose_devino (OstreeRepo                     *self,
   return ret;
 }
 
+static gboolean
+scan_loose_devino (OstreeRepo                     *self,
+                   GHashTable                     *devino_cache,
+                   GCancellable                   *cancellable,
+                   GError                        **error)
+{
+  gboolean ret = FALSE;
+
+  if (self->parent_repo)
+    {
+      if (!scan_loose_devino (self->parent_repo, devino_cache, cancellable, error))
+        goto out;
+    }
+
+  if (self->mode == OSTREE_REPO_MODE_ARCHIVE_Z2)
+    {
+      if (!scan_one_loose_devino (self, self->uncompressed_objects_dir_fd, devino_cache,
+                                  cancellable, error))
+        goto out;
+    }
+
+  if (!scan_one_loose_devino (self, self->objects_dir_fd,
+                              devino_cache, cancellable, error))
+    goto out;
+    
+  ret = TRUE;
+ out:
+  return ret;
+}
+
 static const char *
 devino_cache_lookup (OstreeRepo           *self,
                      guint32               device,
@@ -1096,6 +1129,7 @@ rename_pending_loose_objects (OstreeRepo        *self,
       if (!S_ISDIR (stbuf.st_mode))
         continue;
 
+      /* All object directories only have two character entries */
       if (strlen (dent->d_name) != 2)
         continue;
 
diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h
index a96d9d6..3bb4576 100644
--- a/src/libostree/ostree-repo-private.h
+++ b/src/libostree/ostree-repo-private.h
@@ -113,12 +113,6 @@ _ostree_repo_has_loose_object (OstreeRepo           *self,
                                GError             **error);
 
 gboolean
-_ostree_repo_get_loose_object_dirs (OstreeRepo       *self,
-                                    GPtrArray       **out_object_dirs,
-                                    GCancellable     *cancellable,
-                                    GError          **error);
-
-gboolean
 _ostree_repo_write_directory_meta (OstreeRepo   *self,
                                    GFileInfo    *file_info,
                                    GVariant     *xattrs,
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index d8e5ab7..5702825 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -1512,89 +1512,6 @@ ostree_repo_get_parent (OstreeRepo  *self)
 }
 
 static gboolean
-append_object_dirs_from (OstreeRepo          *self,
-                         GFile               *dir,
-                         GPtrArray           *object_dirs,
-                         GCancellable        *cancellable,
-                         GError             **error)
-{
-  gboolean ret = FALSE;
-  GError *temp_error = NULL;
-  gs_unref_object GFileEnumerator *enumerator = NULL;
-
-  enumerator = g_file_enumerate_children (dir, OSTREE_GIO_FAST_QUERYINFO,
-                                          G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
-                                          cancellable,
-                                          &temp_error);
-  if (!enumerator)
-    {
-      if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
-        {
-          g_clear_error (&temp_error);
-          ret = TRUE;
-        }
-      else
-        g_propagate_error (error, temp_error);
-
-      goto out;
-    }
-
-  while (TRUE)
-    {
-      GFileInfo *file_info;
-      const char *name;
-      guint32 type;
-
-      if (!gs_file_enumerator_iterate (enumerator, &file_info, NULL,
-                                       NULL, error))
-        goto out;
-      if (file_info == NULL)
-        break;
-
-      name = g_file_info_get_attribute_byte_string (file_info, "standard::name");
-      type = g_file_info_get_attribute_uint32 (file_info, "standard::type");
-
-      if (strlen (name) == 2 && type == G_FILE_TYPE_DIRECTORY)
-        {
-          GFile *objdir = g_file_get_child (g_file_enumerator_get_container (enumerator), name);
-          g_ptr_array_add (object_dirs, objdir);  /* transfer ownership */
-        }
-    }
-
-  ret = TRUE;
- out:
-  return ret;
-}
-
-gboolean
-_ostree_repo_get_loose_object_dirs (OstreeRepo       *self,
-                                    GPtrArray       **out_object_dirs,
-                                    GCancellable     *cancellable,
-                                    GError          **error)
-{
-  gboolean ret = FALSE;
-  gs_unref_ptrarray GPtrArray *ret_object_dirs = NULL;
-
-  ret_object_dirs = g_ptr_array_new_with_free_func ((GDestroyNotify)g_object_unref);
-
-  if (ostree_repo_get_mode (self) == OSTREE_REPO_MODE_ARCHIVE_Z2)
-    {
-      if (!append_object_dirs_from (self, self->uncompressed_objects_dir, ret_object_dirs,
-                                    cancellable, error))
-        goto out;
-    }
-
-  if (!append_object_dirs_from (self, self->objects_dir, ret_object_dirs,
-                                cancellable, error))
-    goto out;
-
-  ret = TRUE;
-  ot_transfer_out_value (out_object_dirs, &ret_object_dirs);
- out:
-  return ret;
-}
-
-static gboolean
 list_loose_objects_at (OstreeRepo             *self,
                        GHashTable             *inout_objects,
                        const char             *prefix,


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