[patch-2.4.0-test2]Re: Linux-2.4.0-test2

From: Tigran Aivazian (tigran@veritas.com)
Date: Sat Jun 24 2000 - 07:12:29 EST


On Fri, 23 Jun 2000, Linus Torvalds wrote:
> ... and said "It is Good. It is Bugfree".

he (the Penguin) was wrong. It is not Bugfree yet :)

Seriously, here is my fix that went into Alan Cox's tree but not in
2.4.0-test2:

> The assumption that C code:
>
>int x;
>int y;
>int z;
>
>allocates x,y,z at consecutive virtual addresses is wrong. Yet it is
>assumed when passing &nr_files in kernel/sysctl.c and saying "give me, I
>pray thee, 3 sizeof(int)". This results in garbage displayed in
>/proc/sys/fs/file-nr.
>
>To fix this, I followed (almost) the same technique as inodes_stat in
>fs/inode.c, i.e. gathered variables in a structure called files_stat.
>
>Tested under 2.3.99-pre10-3 (aka 2.4.0-test1)

Now, tested under 2.4.0-test2.

Thanks,
Tigran

PS. 2.4.0-test2 has a much more serious bug than this - xterm coredumps
when trying to:

open("/lib/libc.so.6", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0755, st_size=4101324, ...}) = 0
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\210\212"...,
4096) = 4096
old_mmap(NULL, 1001564, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) =
0x4001f000
mprotect(0x4010c000, 30812, PROT_NONE) = 0
old_mmap(0x4010c000, 16384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED,
3, 0xec000) = 0x4010c000
old_mmap(0x40110000, 14428, PROT_READ|PROT_WRITE,
MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x40110000
close(3) = 0
mprotect(0x4001f000, 970752, PROT_READ|PROT_WRITE) = 0
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++

so I quickly typed this email in rxvt and now back to 2.4.0-test1-ac18
which worked faithfully for me for ages...

-----------------------------------------------------------------------------

diff -urN -X dontdiff linux/fs/file_table.c work/fs/file_table.c
--- linux/fs/file_table.c Sat Jun 24 12:44:28 2000
+++ work/fs/file_table.c Sat Jun 24 12:57:25 2000
@@ -16,9 +16,7 @@
 static kmem_cache_t *filp_cache;
 
 /* sysctl tunables... */
-int nr_files; /* read only */
-int nr_free_files; /* read only */
-int max_files = NR_FILE;/* tunable */
+struct files_stat_struct files_stat = {0, 0, NR_FILE};
 
 /* Here the new files go */
 static LIST_HEAD(anon_list);
@@ -53,11 +51,11 @@
         struct file * f;
 
         file_list_lock();
- if (nr_free_files > NR_RESERVED_FILES) {
+ if (files_stat.nr_free_files > NR_RESERVED_FILES) {
         used_one:
                 f = list_entry(free_list.next, struct file, f_list);
                 list_del(&f->f_list);
- nr_free_files--;
+ files_stat.nr_free_files--;
         new_one:
                 file_list_unlock();
                 memset(f, 0, sizeof(*f));
@@ -73,25 +71,25 @@
         /*
          * Use a reserved one if we're the superuser
          */
- if (nr_free_files && !current->euid)
+ if (files_stat.nr_free_files && !current->euid)
                 goto used_one;
         /*
          * Allocate a new one if we're below the limit.
          */
- if (nr_files < max_files) {
+ if (files_stat.nr_files < files_stat.max_files) {
                 file_list_unlock();
                 f = kmem_cache_alloc(filp_cache, SLAB_KERNEL);
                 file_list_lock();
                 if (f) {
- nr_files++;
+ files_stat.nr_files++;
                         goto new_one;
                 }
                 /* Big problems... */
                 printk("VFS: filp allocation failed\n");
 
- } else if (max_files > old_max) {
- printk("VFS: file-max limit %d reached\n", max_files);
- old_max = max_files;
+ } else if (files_stat.max_files > old_max) {
+ printk("VFS: file-max limit %d reached\n", files_stat.max_files);
+ old_max = files_stat.max_files;
         }
         file_list_unlock();
         return NULL;
@@ -148,7 +146,7 @@
         file_list_lock();
         list_del(&file->f_list);
         list_add(&file->f_list, &free_list);
- nr_free_files++;
+ files_stat.nr_free_files++;
         file_list_unlock();
 }
 
@@ -160,7 +158,7 @@
                 file_list_lock();
                 list_del(&file->f_list);
                 list_add(&file->f_list, &free_list);
- nr_free_files++;
+ files_stat.nr_free_files++;
                 file_list_unlock();
         }
 }
diff -urN -X dontdiff linux/include/linux/fs.h work/include/linux/fs.h
--- linux/include/linux/fs.h Sat Jun 24 12:44:28 2000
+++ work/include/linux/fs.h Sat Jun 24 12:57:25 2000
@@ -47,7 +47,12 @@
 #define BLOCK_SIZE (1<<BLOCK_SIZE_BITS)
 
 /* And dynamically-tunable limits and defaults: */
-extern int max_files, nr_files, nr_free_files;
+struct files_stat_struct {
+ int nr_files; /* read only */
+ int nr_free_files; /* read only */
+ int max_files; /* tunable */
+};
+extern struct files_stat_struct files_stat;
 extern int max_super_blocks, nr_super_blocks;
 
 #define NR_FILE 8192 /* this can well be larger on a larger system */
diff -urN -X dontdiff linux/kernel/sysctl.c work/kernel/sysctl.c
--- linux/kernel/sysctl.c Sat Jun 24 12:44:28 2000
+++ work/kernel/sysctl.c Sat Jun 24 12:57:25 2000
@@ -255,9 +255,9 @@
          0444, NULL, &proc_dointvec},
         {FS_STATINODE, "inode-state", &inodes_stat, 7*sizeof(int),
          0444, NULL, &proc_dointvec},
- {FS_NRFILE, "file-nr", &nr_files, 3*sizeof(int),
+ {FS_NRFILE, "file-nr", &files_stat, 3*sizeof(int),
          0444, NULL, &proc_dointvec},
- {FS_MAXFILE, "file-max", &max_files, sizeof(int),
+ {FS_MAXFILE, "file-max", &files_stat.max_files, sizeof(int),
          0644, NULL, &proc_dointvec},
         {FS_NRSUPER, "super-nr", &nr_super_blocks, sizeof(int),
          0444, NULL, &proc_dointvec},
diff -urN -X dontdiff linux/net/netsyms.c work/net/netsyms.c
--- linux/net/netsyms.c Sat Jun 24 12:44:28 2000
+++ work/net/netsyms.c Sat Jun 24 12:57:25 2000
@@ -196,7 +196,7 @@
 
 /* Needed by unix.o */
 EXPORT_SYMBOL(scm_fp_dup);
-EXPORT_SYMBOL(max_files);
+EXPORT_SYMBOL(files_stat);
 EXPORT_SYMBOL(memcpy_toiovec);
 EXPORT_SYMBOL(csum_partial);
 
diff -urN -X dontdiff linux/net/unix/af_unix.c work/net/unix/af_unix.c
--- linux/net/unix/af_unix.c Sat Jun 24 12:44:28 2000
+++ work/net/unix/af_unix.c Sat Jun 24 12:57:25 2000
@@ -445,7 +445,7 @@
 {
         struct sock *sk;
 
- if (atomic_read(&unix_nr_socks) >= 2*max_files)
+ if (atomic_read(&unix_nr_socks) >= 2*files_stat.max_files)
                 return NULL;
 
         MOD_INC_USE_COUNT;

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Jun 26 2000 - 21:00:04 EST