From 92eb7a2f28d551acedeb5752263267a64b1f5ddf Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 10 Jul 2006 04:45:31 -0700 Subject: [PATCH] fix weird logic in alloc_fdtable() There's a fairly obvious infinite loop in there. Also, use roundup_pow_of_two() rather than open-coding stuff. Cc: Eric Dumazet Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/file.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'fs/file.c') diff --git a/fs/file.c b/fs/file.c index 55f4e702256..3f356086061 100644 --- a/fs/file.c +++ b/fs/file.c @@ -240,13 +240,9 @@ static struct fdtable *alloc_fdtable(int nr) if (!fdt) goto out; - nfds = 8 * L1_CACHE_BYTES; - /* Expand to the max in easy steps */ - while (nfds <= nr) { - nfds = nfds * 2; - if (nfds > NR_OPEN) - nfds = NR_OPEN; - } + nfds = max_t(int, 8 * L1_CACHE_BYTES, roundup_pow_of_two(nfds)); + if (nfds > NR_OPEN) + nfds = NR_OPEN; new_openset = alloc_fdset(nfds); new_execset = alloc_fdset(nfds); -- cgit v1.2.3 From d579091b4385e9386e244622d593fe064aa8e8e7 Mon Sep 17 00:00:00 2001 From: Kirill Korotaev Date: Wed, 12 Jul 2006 09:03:05 -0700 Subject: [PATCH] fix fdset leakage When found, it is obvious. nfds calculated when allocating fdsets is rewritten by calculation of size of fdtable, and when we are unlucky, we try to free fdsets of wrong size. Found due to OpenVZ resource management (User Beancounters). Signed-off-by: Alexey Kuznetsov Signed-off-by: Kirill Korotaev Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/file.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fs/file.c') diff --git a/fs/file.c b/fs/file.c index 3f356086061..c8f1b0af8e0 100644 --- a/fs/file.c +++ b/fs/file.c @@ -273,11 +273,13 @@ static struct fdtable *alloc_fdtable(int nr) } while (nfds <= nr); new_fds = alloc_fd_array(nfds); if (!new_fds) - goto out; + goto out2; fdt->fd = new_fds; fdt->max_fds = nfds; fdt->free_files = NULL; return fdt; +out2: + nfds = fdt->max_fdset; out: if (new_openset) free_fdset(new_openset, nfds); -- cgit v1.2.3 From a29b0b74e73b66674d20a170e463fe9032f2272a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 12 Jul 2006 09:03:08 -0700 Subject: [PATCH] alloc_fdtable() expansion fix We're supposed to go the next power of two if nfds==nr. Of `nr', not of `nfsd'. Spotted by Rene Scharfe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'fs/file.c') diff --git a/fs/file.c b/fs/file.c index c8f1b0af8e0..b3c6b82e6a9 100644 --- a/fs/file.c +++ b/fs/file.c @@ -240,7 +240,7 @@ static struct fdtable *alloc_fdtable(int nr) if (!fdt) goto out; - nfds = max_t(int, 8 * L1_CACHE_BYTES, roundup_pow_of_two(nfds)); + nfds = max_t(int, 8 * L1_CACHE_BYTES, roundup_pow_of_two(nr + 1)); if (nfds > NR_OPEN) nfds = NR_OPEN; -- cgit v1.2.3