2.4.0-test9: minixfs causing oopsen when out of inodes

From: Russell King (rmk@arm.linux.org.uk)
Date: Sun Oct 08 2000 - 09:17:43 EST


Hi,

There appears to be a nasty problem when a minix filesystem runs out of
inodes 2.4.0-test9. I've spotted this because I'm using a small ramdisk
(about 128k with 42 inodes) which contains the contents of /var/run and
/var/lock on a NFS rooted machine. I've recently changed the user-space
binaries, and the ramdisk needs enlarging, but before I did this, I was
getting lots of oopsen from fetchmail.

I can cause them by doing the following:

1. Create a small minix ramdisk
2. mount it
3. fill it up touching lots of files until it complains about
   "No space left on device"
4. touch another file - it still complains about no space, and no oops.
5. touch *the same file* again as you did in (4), and receive an oops
   for your efforts.

Note that you can repeat (4) as many times as you like, and it will always
complain with the same error, but no oops. Also note that in step 5, if
you stat the file, you also get an oops.

It appears that the above is caused by an uninitialised return value:

        minix_create()
        {
                int error;
                inode = minix_new_inode(dir, &error);
                if (error)
                        return error;
        }

        minix_new_inode(... int *error)
        {
                inode = get_empty_inode();
                if (!inode)
                        return NULL;
        }

The only time that minix_new_inode sets *error is if it succeeds! The
same applies to minix_mknod, minix_mkdir, and minix_symlink. With this
fixed, the above oops no longer happens. Here is a patch to fix this.
This makes minix follow the same "method" as ext2fs towards returning
errors from *_new_inode:

diff -u orig/fs/minix/bitmap.c linux/fs/minix/bitmap.c
--- orig/fs/minix/bitmap.c Mon Oct 2 10:06:36 2000
+++ linux/fs/minix/bitmap.c Sun Oct 8 14:56:55 2000
@@ -225,13 +225,16 @@
         int i,j;
 
         inode = get_empty_inode();
- if (!inode)
+ if (!inode) {
+ *error = -ENOMEM;
                 return NULL;
+ }
         sb = dir->i_sb;
         inode->i_sb = sb;
         inode->i_flags = 0;
         j = 8192;
         bh = NULL;
+ *error = -ENOSPC;
         lock_super(sb);
         for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++) {
                 bh = inode->i_sb->u.minix_sb.s_imap[i];
diff -u orig/fs/minix/namei.c linux/fs/minix/namei.c
--- orig/fs/minix/namei.c Mon Oct 2 10:06:36 2000
+++ linux/fs/minix/namei.c Sun Oct 8 14:55:06 2000
@@ -210,10 +210,8 @@
         struct minix_dir_entry * de;
 
         inode = minix_new_inode(dir, &error);
- if (error)
- return error;
         if (!inode)
- return -ENOSPC;
+ return error;
         inode->i_op = &minix_file_inode_operations;
         inode->i_fop = &minix_file_operations;
         inode->i_mapping->a_ops = &minix_aops;
@@ -242,10 +240,8 @@
         struct minix_dir_entry * de;
 
         inode = minix_new_inode(dir, &error);
- if (error)
- return error;
         if (!inode)
- return -ENOSPC;
+ return error;
         inode->i_uid = current->fsuid;
         init_special_inode(inode, mode, rdev);
         mark_inode_dirty(inode);
@@ -275,10 +271,8 @@
         if (dir->i_nlink >= info->s_link_max)
                 return -EMLINK;
         inode = minix_new_inode(dir, &error);
- if (error)
- return error;
         if (!inode)
- return -ENOSPC;
+ return error;
         inode->i_op = &minix_dir_inode_operations;
         inode->i_fop = &minix_dir_operations;
         inode->i_size = 2 * info->s_dirsize;
@@ -461,9 +455,6 @@
         if (i>1024)
                 goto out;
         inode = minix_new_inode(dir, &err);
- if (err)
- goto out;
- err = -ENOSPC;
         if (!inode)
                 goto out;
 
   _____
  |_____| ------------------------------------------------- ---+---+-
  | | Russell King rmk@arm.linux.org.uk --- ---
  | | | | http://www.arm.linux.org.uk/personal/aboutme.html / / |
  | +-+-+ --- -+-
  / | THE developer of ARM Linux |+| /|\
 / | | | --- |
    +-+-+ ------------------------------------------------- /\\\ |
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sun Oct 15 2000 - 21:00:10 EST