From c8d3c6f470e287e6712272fd03490c8b7b5e5208 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Mon, 19 Feb 2007 15:48:02 +0000 Subject: [PATCH] Implemented get/setrlimit(RLIMIT_NOVMON). Note the kernel calls don't set errno... but they're called by user versions. Might want to split them if needed. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20165 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/system/kernel/fs/vfs.cpp | 48 ++++++++++++++++++- src/system/kernel/thread.c | 2 + .../libroot/os/arch/x86/compatibility.c | 2 + 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 64de63ff9d..fcdf1846a5 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -3263,7 +3263,7 @@ vfs_new_io_context(void *_parentContext) context->table_size = tableSize; list_init(&context->node_monitors); - context->max_monitors = MAX_NODE_MONITORS; + context->max_monitors = DEFAULT_NODE_MONITORS; return context; } @@ -3352,6 +3352,29 @@ out: } +static status_t +vfs_resize_monitor_table(struct io_context *context, const int newSize) +{ + void *fds; + int status = B_OK; + + if (newSize <= 0 || newSize > MAX_NODE_MONITORS) + return EINVAL; + + mutex_lock(&context->io_mutex); + + if ((size_t)newSize < context->num_monitors) { + status = EBUSY; + goto out; + } + context->max_monitors = newSize; + +out: + mutex_unlock(&context->io_mutex); + return status; +} + + int vfs_getrlimit(int resource, struct rlimit * rlp) { @@ -3373,6 +3396,20 @@ vfs_getrlimit(int resource, struct rlimit * rlp) return 0; } + case RLIMIT_NOVMON: + { + struct io_context *ioctx = get_current_io_context(false); + + mutex_lock(&ioctx->io_mutex); + + rlp->rlim_cur = ioctx->max_monitors; + rlp->rlim_max = MAX_NODE_MONITORS; + + mutex_unlock(&ioctx->io_mutex); + + return 0; + } + default: return -1; } @@ -3387,8 +3424,17 @@ vfs_setrlimit(int resource, const struct rlimit * rlp) switch (resource) { case RLIMIT_NOFILE: + if (rlp->rlim_max != RLIM_SAVED_MAX && + rlp->rlim_max != MAX_FD_TABLE_SIZE) + return EINVAL; return vfs_resize_fd_table(get_current_io_context(false), rlp->rlim_cur); + case RLIMIT_NOVMON: + if (rlp->rlim_max != RLIM_SAVED_MAX && + rlp->rlim_max != MAX_NODE_MONITORS) + return EINVAL; + return vfs_resize_monitor_table(get_current_io_context(false), rlp->rlim_cur); + default: return -1; } diff --git a/src/system/kernel/thread.c b/src/system/kernel/thread.c index 101380e61d..375abaf197 100644 --- a/src/system/kernel/thread.c +++ b/src/system/kernel/thread.c @@ -2016,6 +2016,7 @@ getrlimit(int resource, struct rlimit * rlp) switch (resource) { case RLIMIT_NOFILE: + case RLIMIT_NOVMON: return vfs_getrlimit(resource, rlp); default: @@ -2034,6 +2035,7 @@ setrlimit(int resource, const struct rlimit * rlp) switch (resource) { case RLIMIT_NOFILE: + case RLIMIT_NOVMON: return vfs_setrlimit(resource, rlp); default: diff --git a/src/system/libroot/os/arch/x86/compatibility.c b/src/system/libroot/os/arch/x86/compatibility.c index 6192917243..976411ceb9 100644 --- a/src/system/libroot/os/arch/x86/compatibility.c +++ b/src/system/libroot/os/arch/x86/compatibility.c @@ -36,6 +36,7 @@ _kset_mon_limit_(int num) if (num < 1) return EINVAL; rl.rlim_cur = num; + rl.rlim_max = RLIM_SAVED_MAX; if (setrlimit(RLIMIT_NOVMON, &rl) < 0) return errno; return B_OK; @@ -49,6 +50,7 @@ _kset_fd_limit_(int num) if (num < 1) return EINVAL; rl.rlim_cur = num; + rl.rlim_max = RLIM_SAVED_MAX; if (setrlimit(RLIMIT_NOFILE, &rl) < 0) return errno; return B_OK;