Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GIT PULL] Add ftruncate #1004

Merged
merged 4 commits into from
Feb 9, 2024
Merged

[GIT PULL] Add ftruncate #1004

merged 4 commits into from
Feb 9, 2024

Conversation

tontinton
Copy link
Contributor

@tontinton tontinton commented Nov 24, 2023

To accompany the patches I sent for adding ftruncate, here are the changes for usermode.


git request-pull output:

The following changes since commit 63342497bec87b72d4b415c8bed930c15ff83b0d:

  test/read-mshot: check that IORING_CQE_F_MORE isn't set on error (2024-01-22 14:56:08 -0700)

are available in the Git repository at:

  git@github.com:tontinton/liburing.git truncate

for you to fetch changes up to c023393f3a3b960e3df77e5bcfd1b2e93e3b5e0f:

  man/io_uring_prep_ftruncate: Add the new ftruncate command (2024-01-31 17:52:13 +0200)

----------------------------------------------------------------
Tony Solomonik (4):
      Add ftruncate helpers
      test/truncate: Add test for ftruncate
      test/truncate: Add test for failure on truncate path
      man/io_uring_prep_ftruncate: Add the new ftruncate command

 man/io_uring_prep_ftruncate.3   |  48 ++++++++++++++++++++++++++++++++
 src/include/liburing.h          |   6 ++++
 src/include/liburing/io_uring.h |   1 +
 src/liburing-ffi.map            |   1 +
 test/Makefile                   |   1 +
 test/truncate.c                 | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 236 insertions(+)
 create mode 100644 man/io_uring_prep_ftruncate.3
 create mode 100644 test/truncate.c

Click to show/hide pull request guidelines

Pull Request Guidelines

  1. To make everyone easily filter pull request from the email
    notification, use [GIT PULL] as a prefix in your PR title.
[GIT PULL] Your Pull Request Title
  1. Follow the commit message format rules below.
  2. Follow the Linux kernel coding style (see: https://github.com/torvalds/linux/blob/master/Documentation/process/coding-style.rst).

Commit message format rules:

  1. The first line is title (don't be more than 72 chars if possible).
  2. Then an empty line.
  3. Then a description (may be omitted for truly trivial changes).
  4. Then an empty line again (if it has a description).
  5. Then a Signed-off-by tag with your real name and email. For example:
Signed-off-by: Foo Bar <foo.bar@gmail.com>

The description should be word-wrapped at 72 chars. Some things should
not be word-wrapped. They may be some kind of quoted text - long
compiler error messages, oops reports, Link, etc. (things that have a
certain specific format).

Note that all of this goes in the commit message, not in the pull
request text. The pull request text should introduce what this pull
request does, and each commit message should explain the rationale for
why that particular change was made. The git tree is canonical source
of truth, not github.

Each patch should do one thing, and one thing only. If you find yourself
writing an explanation for why a patch is fixing multiple issues, that's
a good indication that the change should be split into separate patches.

If the commit is a fix for an issue, add a Fixes tag with the issue
URL.

Don't use GitHub anonymous email like this as the commit author:

123456789+username@users.noreply.github.com

Use a real email address!

Commit message example:

src/queue: don't flush SQ ring for new wait interface

If we have IORING_FEAT_EXT_ARG, then timeouts are done through the
syscall instead of by posting an internal timeout. This was done
to be both more efficient, but also to enable multi-threaded use
the wait side. If we touch the SQ state by flushing it, that isn't
safe without synchronization.

Fixes: https://github.com/axboe/liburing/issues/402
Signed-off-by: Jens Axboe <axboe@kernel.dk>

By submitting this pull request, I acknowledge that:

  1. I have followed the above pull request guidelines.
  2. I have the rights to submit this work under the same license.
  3. I agree to a Developer Certificate of Origin (see https://developercertificate.org for more information).

@tontinton tontinton force-pushed the truncate branch 2 times, most recently from a098ef9 to 627c71e Compare November 24, 2023 10:06
@tontinton tontinton changed the title Add truncate + ftruncate [GIT PULL] Add truncate + ftruncate Nov 24, 2023
@tontinton tontinton force-pushed the truncate branch 2 times, most recently from d4f6968 to aed55d3 Compare January 23, 2024 13:19
@tontinton tontinton changed the title [GIT PULL] Add truncate + ftruncate [GIT PULL] Add ftruncate Jan 23, 2024
@tontinton tontinton force-pushed the truncate branch 2 times, most recently from d555e2f to 8f0c5c6 Compare January 23, 2024 13:31
@axboe
Copy link
Owner

axboe commented Jan 23, 2024

Two minor things:

  1. The prep helper should go into the ffi as well, and the ffi map (in the 2.6 section). See src/liburing-ffi.map.
  2. The test case tests functionality, which is great, but it should also the failure case. Since we're potentially adding truncate support later where we'll put the path in sqe->addr, add a test case that issues an sqe where addr is set to a filename and verify that it fails with EINVAL.

@tontinton tontinton force-pushed the truncate branch 2 times, most recently from f51b164 to fd1bd0e Compare January 23, 2024 21:12
@axboe
Copy link
Owner

axboe commented Jan 25, 2024

I think this looks fine, but one problem is that if you run this test case on an older kernel, then the test will fail. If you get -EINVAL for the first ftruncate you try, just assume the kernel doesn't support it and return T_EXIT_SKIP for that and skip the other tests. That way it'll just skip the test case on older kernels, but test it on newer kernels.

See other test cases that do this very thing, usually with a static int no_ftruncate global that can be set by the first test invocation, and then checked again for non-zero when that first test case returns. If true, then it should return T_EXIT_SKIP.

@tontinton
Copy link
Contributor Author

It already runs goto out which returns 0, when ftruncate is not supported.

test/truncate.c Outdated
if (ret < 0) {
if (ret == -EBADF || ret == -EINVAL) {
fprintf(stdout, "Ftruncate not supported, skipping\n");
goto out;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be a break?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is a break, it will go to test truncate with path failing, no reason to test that if ftruncate is unsupported I think

}
}

out:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should return T_EXIT_PASS for success, T_EXIT_SKIP if the test is skipped, and T_EXIT_FAIL if the test case failed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

@axboe
Copy link
Owner

axboe commented Jan 26, 2024

It already runs goto out which returns 0, when ftruncate is not supported.

It does, but it doesn't return T_EXIT_SKIPPED. I think you should also distinguish between "we got EBADF/EINVAL on the first test, it's probably not supported, T_EXIT_SKIPPED" rather than just have any of the test cases returning EINVAL leading to a skipped test where it probably should've been a failure.

Copy link
Contributor

@ammarfaizi2 ammarfaizi2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing Signed-off-by tag.

@@ -191,4 +191,5 @@ LIBURING_2.6 {
global:
io_uring_prep_fixed_fd_install;
io_uring_buf_ring_available;
io_uring_prep_ftruncate;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use tabs as indentation; don't use spaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

test/truncate.c Outdated
goto err;
}

return 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same indentation issue.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

test/truncate.c Outdated
Comment on lines 49 to 56
ret = cqe->res;
io_uring_cqe_seen(ring, cqe);
if (cqe->res != -EINVAL) {
fprintf(stderr, "unexpected truncate res %d\n", cqe->res);
goto err;
}

return 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After this assignment, ret = cqe->res, the ret value is not used. Shouldn't it be returned?

Also, goto err is return 1 while your caller checking is:

	ret = test_truncate(&ring, fd);
	if (ret < 0)
		goto err;

So test_truncate() will always be assumed as a success because it never returns a negative value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Signed-off-by: Tony Solomonik <tony.solomonik@gmail.com>
test/truncate.c Outdated
}
ret = cqe->res;
io_uring_cqe_seen(ring, cqe);
if (cqe->res != -EINVAL) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't matter too much here, but you cannot use the cqe after calling io_uring_cqe_seen() as it could've been overwritten by a new cqe. You assign 'ret' here anyway, so please just use ret. Would be a shame if people copied an error like that for their app.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed!

Signed-off-by: Tony Solomonik <tony.solomonik@gmail.com>
Signed-off-by: Tony Solomonik <tony.solomonik@gmail.com>
Signed-off-by: Tony Solomonik <tony.solomonik@gmail.com>
Comment on lines +28 to +32
sqe = io_uring_get_sqe(ring);
if (!sqe) {
fprintf(stderr, "get sqe failed\n");
goto err;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

goto err; contains return ret, but ret is uninitialized; stop using goto if you don't have any cleanup. Just return -1;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake, it turns out return 1; Not return ret.

Comment on lines +38 to +42
ret = io_uring_submit(ring);
if (ret <= 0) {
fprintf(stderr, "sqe submit failed: %d\n", ret);
goto err;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we assume io_uring_submit() returns 0 is failed, then you must override it with return -1 because return 0 is okay from the caller prespective.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the noise, I probably read the old code before you force pushed.

Comment on lines +52 to +54
err:
return 1;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return 1 is not an error as you have this in the caller:

	ret = test_ftruncate(&ring, fd, test_sizes[i]);
	if (ret < 0) {
		// fail
	}

Must be return -1?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah no, it has an else if, my mistake again...

@axboe axboe merged commit 5909e17 into axboe:master Feb 9, 2024
vmingchen added a commit to vmingchen/io-uring that referenced this pull request Dec 5, 2024
Introduces `opcode::Ftruncate` to support the ftruncate which got
supported since Linux 6.9.

Also updates the libc to the latest version to get the new
sys::IORING_OP_FTRUNCATE flag from libc.

See

- `IORING_OP_FTRUNCATE` commit: torvalds/linux@b4bb190
- liburing PR: axboe/liburing#1004
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants