Page MenuHomeFreeBSD

D61490.1794630660.diff
No OneTemporary

Authored By
Unknown
Size
2 KB
Referenced Files
None
Subscribers
None

D61490.1794630660.diff

diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -1956,9 +1956,10 @@
/*
* If there is a partial page at the beginning of the hole-punching
- * request, fill the partial page with zeroes.
+ * request or if we're only punching a hole within a single page, fill
+ * the partial page with zeroes.
*/
- if (startofs != 0) {
+ if (startofs != 0 || pistart == piend) {
end = pistart != piend ? PAGE_SIZE : endofs;
error = tmpfs_partial_page_invalidate(object, pistart, startofs,
end, FALSE);
@@ -1966,6 +1967,9 @@
goto out;
off += end - startofs;
len -= end - startofs;
+
+ if (pistart == piend)
+ goto out;
}
/*
@@ -1981,7 +1985,7 @@
* If there is a partial page at the end of the hole-punching request,
* fill the partial page with zeroes.
*/
- if (endofs != 0 && pistart != piend) {
+ if (endofs != 0) {
error = tmpfs_partial_page_invalidate(object, piend, 0, endofs,
FALSE);
if (error != 0)
diff --git a/tests/sys/file/fspacectl_test.c b/tests/sys/file/fspacectl_test.c
--- a/tests/sys/file/fspacectl_test.c
+++ b/tests/sys/file/fspacectl_test.c
@@ -325,6 +325,32 @@
ATF_REQUIRE(close(fd) == 0);
}
+/*
+ * Check deallocation of an aligned range that ends within its first block.
+ * tmpfs used to make no progress on such a range, leaving the caller
+ * spinning in vn_deallocate_impl() forever.
+ */
+ATF_TC_WITHOUT_HEAD(aligned_dealloc_partial);
+ATF_TC_BODY(aligned_dealloc_partial, tc)
+{
+ struct spacectl_range range;
+ off_t offset, length;
+ blksize_t blocksize;
+ int fd;
+
+ ATF_REQUIRE((blocksize = fd_get_blksize()) != -1);
+ range.r_offset = offset = blocksize;
+ range.r_len = length = blocksize / 2;
+
+ ATF_REQUIRE((fd = open("sys_fspacectl_testfile",
+ O_CREAT | O_RDWR | O_TRUNC, 0600)) != -1);
+ ATF_REQUIRE(fill(fd, 0, file_max_blocks * blocksize) == 0);
+ ATF_CHECK(fspacectl(fd, SPACECTL_DEALLOC, &range, 0, &range) == 0);
+ ATF_CHECK(check_content_dealloc(fd, offset, length,
+ file_max_blocks * blocksize) == 0);
+ ATF_REQUIRE(close(fd) == 0);
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, aligned_dealloc);
@@ -333,6 +359,7 @@
ATF_TP_ADD_TC(tp, unaligned_dealloc_eof);
ATF_TP_ADD_TC(tp, aligned_dealloc_offmax);
ATF_TP_ADD_TC(tp, unaligned_dealloc_offmax);
+ ATF_TP_ADD_TC(tp, aligned_dealloc_partial);
return atf_no_error();
}

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 14, 4:31 AM (19 m, 9 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41709840
Default Alt Text
D61490.1794630660.diff (2 KB)

Event Timeline