lib/commit: don't query devino cache for modified files
We can't use the cache if the file we want to commit has been modified by the client through the file info or xattr modifiers. We would prematurely look into the cache in `write_dfd_iter_to_mtree_internal`, regardless of whether any filtering applied. We remove that path there, and make sure that we only use the cache if there were no modifications. We rename the `get_modified_xattrs` to `get_final_xattrs` to reflect the fact that the xattrs may not be modified. One tricky bit that took me some time was that we now need to store the st_dev & st_ino values in the GFileInfo because the cache lookup relies on it. I'm guessing we regressed on this at some point. This patch does slightly change the semantics of the xattr callback. Previously, returning NULL from the cb meant no xattrs at all. Now, it means to default to the on-disk state. We might want to consider putting that behind a flag instead. Though it seems like a more useful behaviour so that callers can only override the files they want to without losing original on-disk state (and if they don't want that, just return an empty GVariant). Closes: #1165 Closes: #1170 Approved by: cgwalters
This commit is contained in:
1 parent
e4a90caeb9
commit
8fe4536257
5 files changed
+246
-62
No files matched your search
@@ -1568,12 +1568,52 @@ _ostree_stbuf_to_gfileinfo (const struct stat *stbuf)
|
||||
g_file_info_set_attribute_uint32 (ret, "unix::uid", stbuf->st_uid);
|
||||
g_file_info_set_attribute_uint32 (ret, "unix::gid", stbuf->st_gid);
|
||||
g_file_info_set_attribute_uint32 (ret, "unix::mode", mode);
|
||||
|
||||
/* those aren't stored by ostree, but used by the devino cache */
|
||||
g_file_info_set_attribute_uint32 (ret, "unix::device", stbuf->st_dev);
|
||||
g_file_info_set_attribute_uint64 (ret, "unix::inode", stbuf->st_ino);
|
||||
|
||||
if (S_ISREG (mode))
|
||||
g_file_info_set_attribute_uint64 (ret, "standard::size", stbuf->st_size);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* _ostree_gfileinfo_equal:
|
||||
* @a: First file info
|
||||
* @b: Second file info
|
||||
*
|
||||
* OSTree only cares about a subset of file attributes. This function
|
||||
* checks whether two #GFileInfo objects are equal as far as OSTree is
|
||||
* concerned.
|
||||
*
|
||||
* Returns: TRUE if the #GFileInfo objects are OSTree-equivalent.
|
||||
*/
|
||||
gboolean
|
||||
_ostree_gfileinfo_equal (GFileInfo *a, GFileInfo *b)
|
||||
{
|
||||
/* trivial case */
|
||||
if (a == b)
|
||||
return TRUE;
|
||||
|
||||
#define CHECK_ONE_ATTR(type, attr, a, b) \
|
||||
do { if (g_file_info_get_attribute_##type(a, attr) != \
|
||||
g_file_info_get_attribute_##type(b, attr)) \
|
||||
return FALSE; \
|
||||
} while (0)
|
||||
|
||||
CHECK_ONE_ATTR (uint32, "unix::uid", a, b);
|
||||
CHECK_ONE_ATTR (uint32, "unix::gid", a, b);
|
||||
CHECK_ONE_ATTR (uint32, "unix::mode", a, b);
|
||||
CHECK_ONE_ATTR (uint32, "standard::type", a, b);
|
||||
CHECK_ONE_ATTR (uint64, "standard::size", a, b);
|
||||
|
||||
#undef CHECK_ONE_ATTR
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GFileInfo *
|
||||
_ostree_mode_uidgid_to_gfileinfo (mode_t mode, uid_t uid, gid_t gid)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user