diff mbox series

[RFC] RLIMIT_NOFILE: the maximum number of open files or the maximum fd index?

Message ID 4731d54723b841599882a24f7aa73aaa@huawei.com (mailing list archive)
State New
Headers show
Series [RFC] RLIMIT_NOFILE: the maximum number of open files or the maximum fd index? | expand

Commit Message

Nixiaoming Dec. 24, 2024, 1:20 a.m. UTC
I always thought that RLIMIT_NOFILE limits the number of open files, but when I
 read the code for alloc_fd(), I found that RLIMIT_NOFILE is the largest fd index?
Is this a mistake in my understanding, or is it a code implementation error?

-----

alloc_fd code:


-----

Test Procedure
1. ulimit -n 1024.
2. Create 1000 FDs.
3. ulimit -n 100.
4. Close all FDs less than 100 and continue to hold FDs greater than 100.
5. Open() and check whether the FD is successfully created,

If RLIMIT_NOFILE is the upper limit of the number of opened files, step 5 should fail, but step 5 returns success.

-----

test code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
#include <errno.h>

int main(int argc, char *argv[])
{
	int fd, i;
	struct rlimit rl;
	rl.rlim_cur = 1024;
	rl.rlim_max = 1024;

	if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
		perror("setrlimit");
		exit(EXIT_FAILURE);
	}

	for (i = 0; i < 1000; i++) {
		fd = open("/dev/null", O_RDWR | O_CLOEXEC);
		if (fd == -1) {
			perror("open");
			exit(EXIT_FAILURE);
		}
	}

	rl.rlim_cur = 100;
	rl.rlim_max = 100;
	if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
		perror("setrlimit");
		exit(EXIT_FAILURE);
	}

	for (i = 3; i < 100; i++) {
		close(i);
	}

	fd = open("/dev/null", O_RDWR | O_CLOEXEC);
	if (fd == -1) {
		if (errno == EMFILE) {
			printf("ok\n");
			return 0;
		} else {
			perror("open");
			exit(EXIT_FAILURE);
		}
	} else {
		printf("fail: {OPEN_MAX} file descriptors are currently open in the calling process, but open() still returns a success\n");
		return -1;
	}

	return 0;
}

----

Best regards,

Xiaoming Ni
diff mbox series

Patch

diff --git a/fs/file.c b/fs/file.c
index fb1011c..e47ddac 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -561,6 +561,7 @@  static int alloc_fd(unsigned start, unsigned end, unsigned flags)
 	 */
 	error = -EMFILE;
 	if (unlikely(fd >= end))
+		// There may be unclosed fd between [end, max]. the number of open files can be greater than RLIMIT_NOFILE.
 		goto out;
 
	if (unlikely(fd >= fdt->max_fds)) {