repo: Ensure we set mode for bare-user files before xattrs

When trying to switch ostree to `O_TMPFILE`, I hit the fact that
by default it uses mode `000`.  It still works to write to the
open fd of course, but it *doesn't* work to set xattrs because
that code path for some reason in the kernel checks the mode bits.

This only broke for bare-user repos where we tried to set the xattr
before calling `fchmod()`, so just invert those two operations.

Closes: #391
Approved by: jlebon
This commit is contained in:
Colin Walters 2016-07-12 09:43:32 -04:00 committed by Atomic Bot
parent 87c9e227cb
commit f45eca948c
1 changed files with 5 additions and 4 deletions

View File

@ -240,15 +240,13 @@ commit_loose_object_trusted (OstreeRepo *self,
if (objtype == OSTREE_OBJECT_TYPE_FILE && self->mode == OSTREE_REPO_MODE_BARE_USER) if (objtype == OSTREE_OBJECT_TYPE_FILE && self->mode == OSTREE_REPO_MODE_BARE_USER)
{ {
if (!write_file_metadata_to_xattr (fd, uid, gid, mode, xattrs, error))
goto out;
if (!object_is_symlink) if (!object_is_symlink)
{ {
/* We need to apply at least some mode bits, because the repo file was created /* We need to apply at least some mode bits, because the repo file was created
with mode 644, and we need e.g. exec bits to be right when we do a user-mode with mode 644, and we need e.g. exec bits to be right when we do a user-mode
checkout. To make this work we apply all user bits and the read bits for checkout. To make this work we apply all user bits and the read bits for
group/other */ group/other. Furthermore, setting user xattrs requires write access, so
this makes sure it's at least writable by us. (O_TMPFILE uses mode 0 by default) */
do do
res = fchmod (fd, mode | 0744); res = fchmod (fd, mode | 0744);
while (G_UNLIKELY (res == -1 && errno == EINTR)); while (G_UNLIKELY (res == -1 && errno == EINTR));
@ -258,6 +256,9 @@ commit_loose_object_trusted (OstreeRepo *self,
goto out; goto out;
} }
} }
if (!write_file_metadata_to_xattr (fd, uid, gid, mode, xattrs, error))
goto out;
} }
if (objtype == OSTREE_OBJECT_TYPE_FILE && (self->mode == OSTREE_REPO_MODE_BARE || if (objtype == OSTREE_OBJECT_TYPE_FILE && (self->mode == OSTREE_REPO_MODE_BARE ||