Page MenuHomeFreeBSD

Fix zfs_copy_file_range() for handling of RLIMIT_FSIZE
Needs ReviewPublic

Authored by rmacklem on Sep 10 2023, 9:27 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Apr 7, 11:08 PM
Unknown Object (File)
Sun, Mar 31, 6:36 AM
Unknown Object (File)
Jan 12 2024, 9:05 AM
Unknown Object (File)
Dec 23 2023, 1:34 AM
Unknown Object (File)
Nov 18 2023, 11:16 AM
Unknown Object (File)
Oct 26 2023, 2:39 AM
Unknown Object (File)
Oct 18 2023, 5:25 AM
Unknown Object (File)
Oct 12 2023, 7:54 AM
Subscribers

Details

Summary

Commit 52360ca32ff9 fixed the handling of RLIMIT_FSIZE
for vn_generic_copy_file_range() and nfs_copy_file_range().
I think the same fix is needed for zfs_copy_file_range(),
which is what this patch does.

I have no way of testing this and have no idea how ZFS commits
are done so, hopefully, someone else will handle this.

Test Plan

Someone else needs to test this.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped

Event Timeline

Oh, and I didn't include it in the review, but the
comment for zfs_copy_file_range() should probably
be updated since it now gets calls for different mounts.
ie. The TODO has been done.

This isn't necessary. My test program passes on ZFS even without this change. Here's the program:

#include <sys/types.h>

#include <sys/resource.h>
#include <sys/time.h>

#include <assert.h>
#include <err.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>

size_t FSIZE = 65536;

int main(int argc, char **argv) {
	struct rlimit rl;
	int infd, outfd;
	char *buf;
	size_t nbytes = FSIZE;
	ssize_t r;
	off_t ioff = 0, ooff = 0;

	buf = calloc(FSIZE, 1);

	infd = open("copy_file_range_rlimit_fsize_infile", O_RDWR | O_CREAT,
		0644);
	if (infd < 0)
		err(1, "open");

	while (nbytes > 0) {
		int r;
		if ((r = write(infd, buf, nbytes)) < 0)
			err(1, "write");
		nbytes -= r;
	}

	if (getrlimit(RLIMIT_FSIZE, &rl) != 0)
		err(1, "getrlimit");

	rl.rlim_cur = FSIZE / 2;
	if (setrlimit(RLIMIT_FSIZE, &rl) != 0)
		err(1, "setrlimit");

	outfd = open("copy_file_range_rlimit_fsize_outfile", O_WRONLY | O_CREAT,
		0644);
	if (outfd < 0)
		err(1, "open");

	r = copy_file_range(infd, &ioff, outfd, &ooff, FSIZE, 0);
	if (r < 0)
		err(1, "copy_file_range");
	if (r > rl.rlim_cur)
		errx(1, "copy_file_range exceeded RLIMIT_FSIZE");

	return (0);
}