patch for 2.1.57 fs/file_table.c

Bill Hawes (whawes@star.net)
Fri, 03 Oct 1997 11:41:01 -0400


This is a multi-part message in MIME format.
--------------AA05A6C6A5FD59B14736982F
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I've attached a patch to fix a minor problem with reserved files. The
existing code checks for the root user when files are allocated, but
once the allocation limit has been reached, even root can't get any
more. The patch fixes this by keeping a count of the number of free
files, and only allowing root to use the reserved files. The reserved
file count is set at 10.

Since the number of free files is now available, I've added it to the
sysctl display. /proc/sys/kernel/file-nr now displays files, free
files, and max files in that order.

Regards,
Bill
--------------AA05A6C6A5FD59B14736982F
Content-Type: text/plain; charset=us-ascii; name="file_table57-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="file_table57-patch"

--- linux-2.1.57/fs/file_table.c.old Thu Sep 4 12:33:50 1997
+++ linux-2.1.57/fs/file_table.c Fri Oct 3 11:07:04 1997
@@ -18,8 +18,9 @@
static kmem_cache_t *filp_cache;

/* sysctl tunables... */
-int nr_files = 0;
-int max_files = NR_FILE;
+int nr_files = 0; /* read only */
+int nr_free_files = 0; /* read only */
+int max_files = NR_FILE;/* tunable */

/* Free list management, if you are here you must have f_count == 0 */
static struct file * free_filps = NULL;
@@ -30,6 +31,7 @@
free_filps->f_pprev = &file->f_next;
free_filps = file;
file->f_pprev = &free_filps;
+ nr_free_files++;
}

/* The list of in-use filp's must be exported (ugh...) */
@@ -43,6 +45,7 @@
file->f_pprev = &inuse_filps;
}

+/* N.B. This should be an __initfunc ... */
void file_table_init(void)
{
filp_cache = kmem_cache_create("filp", sizeof(struct file),
@@ -50,6 +53,11 @@
SLAB_HWCACHE_ALIGN, NULL, NULL);
if(!filp_cache)
panic("VFS: Cannot alloc filp SLAB cache.");
+ /*
+ * We could allocate the reserved files here, but really
+ * shouldn't need to: the normal boot process will create
+ * plenty of free files.
+ */
}

/* Find an unused file structure and return a pointer to it.
@@ -61,24 +69,31 @@
static int old_max = 0;
struct file * f;

- f = free_filps;
- if (!f)
- goto get_more;
- remove_filp(f);
-got_one:
- memset(f, 0, sizeof(*f));
- f->f_count = 1;
- f->f_version = ++event;
- put_inuse(f);
- return f;
-
-get_more:
- /* Reserve a few files for the super-user.. */
- if (nr_files < (current->euid ? max_files - 10 : max_files)) {
+ if (nr_free_files > NR_RESERVED_FILES) {
+ used_one:
+ f = free_filps;
+ remove_filp(f);
+ nr_free_files--;
+ new_one:
+ memset(f, 0, sizeof(*f));
+ f->f_count = 1;
+ f->f_version = ++event;
+ put_inuse(f);
+ return f;
+ }
+ /*
+ * Use a reserved one if we're the superuser
+ */
+ if (nr_free_files && !current->euid)
+ goto used_one;
+ /*
+ * Allocate a new one if we're below the limit.
+ */
+ if (nr_files < max_files) {
f = kmem_cache_alloc(filp_cache, SLAB_KERNEL);
if (f) {
nr_files++;
- goto got_one;
+ goto new_one;
}
/* Big problems... */
printk("VFS: filp allocation failed\n");
--- linux-2.1.57/kernel/sysctl.c.old Sat Jul 19 08:17:17 1997
+++ linux-2.1.57/kernel/sysctl.c Fri Oct 3 10:58:15 1997
@@ -147,7 +147,7 @@
0444, NULL, &proc_dointvec},
{KERN_MAXINODE, "inode-max", &max_inodes, sizeof(int),
0644, NULL, &proc_dointvec},
- {KERN_NRFILE, "file-nr", &nr_files, sizeof(int),
+ {KERN_NRFILE, "file-nr", &nr_files, 3*sizeof(int),
0444, NULL, &proc_dointvec},
{KERN_MAXFILE, "file-max", &max_files, sizeof(int),
0644, NULL, &proc_dointvec},
--- linux-2.1.57/include/linux/fs.h.old Sat Sep 27 15:11:08 1997
+++ linux-2.1.57/include/linux/fs.h Fri Oct 3 10:18:15 1997
@@ -42,9 +42,10 @@

/* And dynamically-tunable limits and defaults: */
extern int max_inodes;
-extern int max_files, nr_files;
+extern int max_files, nr_files, nr_free_files;
#define NR_INODE 4096 /* this should be bigger than NR_FILE */
#define NR_FILE 1024 /* this can well be larger on a larger system */
+#define NR_RESERVED_FILES 10 /* reserved for root */

#define MAY_EXEC 1
#define MAY_WRITE 2

--------------AA05A6C6A5FD59B14736982F--