tmpfs fixes against 2.4.6-pre
Subsystems (2)
PATCH 1/1 tmpfs fixes against 2.4.6-pre
Hi Linus,
I split up my previous patch into two. Hopefully this is more acceptable for you or will trigger some comments.
This is the first part:
1) shmem_remount_fs garbles parameters which are not supplied
2) shmem_truncate should check the maximum size else we get ugly oopses
3) shmem_file_setup should give an error if the size is too big. So the application will fail early. I also cleaned up the error handling a bit.
4) We should recalculate the inode on page allocation. Else we get really weird sizes on sparse files.
Please apply
Christoph
mm/shmem.c +20 -8
@@ -3,7 +3,8 @@* * Copyright (C) 2000 Linus Torvalds. * 2000 Transmeta Corp. -* 2000 Christoph Rohland +* 2000-2001 Christoph Rohland +* 2000-2001 SAP AG * * This file is released under the GPL. */
@@ -33,7 +34,7 @@#define TMPFS_MAGIC 0x01021994#define ENTRIES_PER_PAGE (PAGE_SIZE/sizeof(unsigned long)) -#define NR_SINGLE (ENTRIES_PER_PAGE + SHMEM_NR_DIRECT) +#define SHMEM_MAX_BLOCKS (SHMEM_NR_DIRECT + ENTRIES_PER_PAGE*ENTRIES_PER_PAGE)static struct super_operations shmem_ops;static struct address_space_operations shmem_aops;
@@ -193,7 +194,14 @@ } out: - info->max_index = index; +/* +* We have no chance to give an error, so we limit it to max +* size here and the application will fail later +*/ +if (index >SHMEM_MAX_BLOCKS ) + info->max_index =SHMEM_MAX_BLOCKS ; +else + info->max_index = index; info->swapped -= freed;shmem_recalc_inode (inode);spin_unlock (&info->lock);
@@ -314,6 +322,7 @@return page; } +shmem_recalc_inode (inode);if (entry->val) {unsigned long flags;
@@ -1027,6 +1036,8 @@unsigned long max_inodes, inodes;struct shmem_sb_info *info = &sb->u.shmem_sb; + max_blocks = info->max_blocks; + max_inodes = info->max_inodes;if (shmem_parse_options (data,NULL , &max_blocks, &max_inodes))return -EINVAL ;
@@ -1074,7 +1085,7 @@ sb->u.shmem_sb.free_blocks = blocks; sb->u.shmem_sb.max_inodes = inodes; sb->u.shmem_sb.free_inodes = inodes; - sb->s_maxbytes = (unsigned long long )(SHMEM_NR_DIRECT + (ENTRIES_PER_PAGE *ENTRIES_PER_PAGE )) <<PAGE_CACHE_SHIFT ; + sb->s_maxbytes = (unsigned long long )SHMEM_MAX_BLOCKS <<PAGE_CACHE_SHIFT ; sb->s_blocksize =PAGE_CACHE_SIZE ; sb->s_blocksize_bits =PAGE_CACHE_SHIFT ; sb->s_magic =TMPFS_MAGIC ;
@@ -1282,9 +1293,11 @@struct qstr this;int vm_enough_memory (long pages); - error = -ENOMEM ; +if (size > (unsigned long long )SHMEM_MAX_BLOCKS <<PAGE_CACHE_SHIFT ) +return ERR_PTR (-EINVAL ); +if (!vm_enough_memory ((size) >>PAGE_SHIFT )) - goto out; +return ERR_PTR (-ENOMEM ); this.name = name; this.len =strlen (name);
@@ -1292,7 +1305,7 @@ root = tmpfs_fs_type.kern_mnt->mnt_root; dentry =d_alloc (root, &this);if (!dentry) - goto out; +return ERR_PTR (-ENOMEM ); error = -ENFILE ; file =get_empty_filp ();
@@ -1318,7 +1331,6 @@put_filp (file); put_dentry:dput (dentry); -out:return ERR_PTR (error); }/*