rofiles: Fix --copyup when creating a new file
This tripped up the `docbook-dtds` `%post` in my experiments with doing rpm-ostree for buildroots. I cloned and built [xfstests](https://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git) but haven't yet investigated actually running it. In the meantime let's do the obvious fix here; we need to distinguish between "copyup enabled" and "actually did a copyup" in the open path at least, since if we didn't do a copyup we don't need to re-open. Closes: #1396 Approved by: jlebon
This commit is contained in:
parent
46a841a062
commit
3b9304b5d7
|
|
@ -247,10 +247,14 @@ gioerror_to_errno (GIOErrorEnum e)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
verify_write_or_copyup (const char *path, const struct stat *stbuf)
|
verify_write_or_copyup (const char *path, const struct stat *stbuf,
|
||||||
|
gboolean *out_did_copyup)
|
||||||
{
|
{
|
||||||
struct stat stbuf_local;
|
struct stat stbuf_local;
|
||||||
|
|
||||||
|
if (out_did_copyup)
|
||||||
|
*out_did_copyup = FALSE;
|
||||||
|
|
||||||
/* If a stbuf wasn't provided, gather it now */
|
/* If a stbuf wasn't provided, gather it now */
|
||||||
if (!stbuf)
|
if (!stbuf)
|
||||||
{
|
{
|
||||||
|
|
@ -272,6 +276,8 @@ verify_write_or_copyup (const char *path, const struct stat *stbuf)
|
||||||
g_autoptr(GError) tmp_error = NULL;
|
g_autoptr(GError) tmp_error = NULL;
|
||||||
if (!ostree_break_hardlink (basefd, path, FALSE, NULL, &tmp_error))
|
if (!ostree_break_hardlink (basefd, path, FALSE, NULL, &tmp_error))
|
||||||
return -gioerror_to_errno ((GIOErrorEnum)tmp_error->code);
|
return -gioerror_to_errno ((GIOErrorEnum)tmp_error->code);
|
||||||
|
if (out_did_copyup)
|
||||||
|
*out_did_copyup = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return -EROFS;
|
return -EROFS;
|
||||||
|
|
@ -286,7 +292,7 @@ verify_write_or_copyup (const char *path, const struct stat *stbuf)
|
||||||
*/
|
*/
|
||||||
#define PATH_WRITE_ENTRYPOINT(path) do { \
|
#define PATH_WRITE_ENTRYPOINT(path) do { \
|
||||||
path = ENSURE_RELPATH (path); \
|
path = ENSURE_RELPATH (path); \
|
||||||
int r = verify_write_or_copyup (path, NULL); \
|
int r = verify_write_or_copyup (path, NULL, NULL); \
|
||||||
if (r != 0) \
|
if (r != 0) \
|
||||||
return r; \
|
return r; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
@ -374,7 +380,8 @@ do_open (const char *path, mode_t mode, struct fuse_file_info *finfo)
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
int r = verify_write_or_copyup (path, &stbuf);
|
gboolean did_copyup;
|
||||||
|
int r = verify_write_or_copyup (path, &stbuf, &did_copyup);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
{
|
{
|
||||||
(void) close (fd);
|
(void) close (fd);
|
||||||
|
|
@ -382,7 +389,7 @@ do_open (const char *path, mode_t mode, struct fuse_file_info *finfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In the copyup case, we need to re-open */
|
/* In the copyup case, we need to re-open */
|
||||||
if (opt_copyup)
|
if (did_copyup)
|
||||||
{
|
{
|
||||||
(void) close (fd);
|
(void) close (fd);
|
||||||
/* Note that unlike the initial open, we will pass through
|
/* Note that unlike the initial open, we will pass through
|
||||||
|
|
|
||||||
|
|
@ -121,19 +121,54 @@ echo "ok flock"
|
||||||
|
|
||||||
# And now with --copyup enabled
|
# And now with --copyup enabled
|
||||||
|
|
||||||
fusermount -u ${test_tmpdir}/mnt
|
copyup_reset() {
|
||||||
assert_not_has_file mnt/firstfile
|
cd ${test_tmpdir}
|
||||||
rofiles-fuse --copyup checkout-test2 mnt
|
fusermount -u mnt
|
||||||
|
rm checkout-test2 -rf
|
||||||
|
$OSTREE checkout -H test2 checkout-test2
|
||||||
|
rofiles-fuse --copyup checkout-test2 mnt
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_test_file() {
|
||||||
|
t=$1
|
||||||
|
f=$2
|
||||||
|
if ! test ${t} "${f}"; then
|
||||||
|
ls -al "${f}"
|
||||||
|
fatal "Failed test ${t} ${f}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
copyup_reset
|
||||||
assert_file_has_content mnt/firstfile first
|
assert_file_has_content mnt/firstfile first
|
||||||
echo "ok copyup mount"
|
echo "ok copyup mount"
|
||||||
|
|
||||||
|
# Test O_TRUNC directly
|
||||||
firstfile_orig_inode=$(stat -c %i checkout-test2/firstfile)
|
firstfile_orig_inode=$(stat -c %i checkout-test2/firstfile)
|
||||||
for path in firstfile{,-link}; do
|
echo -n truncating > mnt/firstfile
|
||||||
echo truncating > mnt/${path}
|
assert_streq "$(cat mnt/firstfile)" truncating
|
||||||
assert_file_has_content mnt/${path} truncating
|
|
||||||
assert_not_file_has_content mnt/${path} first
|
|
||||||
done
|
|
||||||
firstfile_new_inode=$(stat -c %i checkout-test2/firstfile)
|
firstfile_new_inode=$(stat -c %i checkout-test2/firstfile)
|
||||||
assert_not_streq "${firstfile_orig_inode}" "${firstfile_new_inode}"
|
assert_not_streq "${firstfile_orig_inode}" "${firstfile_new_inode}"
|
||||||
|
assert_test_file -f checkout-test2/firstfile
|
||||||
|
|
||||||
|
copyup_reset
|
||||||
|
firstfile_link_orig_inode=$(stat -c %i checkout-test2/firstfile-link)
|
||||||
|
firstfile_orig_inode=$(stat -c %i checkout-test2/firstfile)
|
||||||
|
# Now write via the symlink
|
||||||
|
echo -n truncating > mnt/firstfile-link
|
||||||
|
assert_streq "$(cat mnt/firstfile)" truncating
|
||||||
|
firstfile_new_inode=$(stat -c %i checkout-test2/firstfile)
|
||||||
|
firstfile_link_new_inode=$(stat -c %i checkout-test2/firstfile-link)
|
||||||
|
assert_not_streq "${firstfile_orig_inode}" "${firstfile_new_inode}"
|
||||||
|
assert_streq "${firstfile_link_orig_inode}" "${firstfile_link_new_inode}"
|
||||||
|
assert_test_file -f checkout-test2/firstfile
|
||||||
|
# Verify we didn't replace the link with a regfile somehow
|
||||||
|
assert_test_file -L checkout-test2/firstfile-link
|
||||||
|
|
||||||
|
# These both end up creating new files; in the sed case we'll then do a rename()
|
||||||
|
copyup_reset
|
||||||
|
echo "hello new file" > mnt/a-new-non-copyup-file
|
||||||
|
assert_file_has_content_literal mnt/a-new-non-copyup-file "hello new file"
|
||||||
|
sed -i -e s,first,second, mnt/firstfile
|
||||||
|
assert_file_has_content_literal mnt/firstfile "second"
|
||||||
|
|
||||||
echo "ok copyup"
|
echo "ok copyup"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue