patch-2.4.7 linux/mm/shmem.c
Next file: linux/mm/swap_state.c
Previous file: linux/mm/oom_kill.c
Back to the patch index
Back to the overall index
- Lines: 145
- Date:
Wed Jul 11 14:52:58 2001
- Orig file:
v2.4.6/linux/mm/shmem.c
- Orig date:
Tue May 22 09:31:25 2001
diff -u --recursive --new-file v2.4.6/linux/mm/shmem.c linux/mm/shmem.c
@@ -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);
@@ -223,7 +231,7 @@
*/
static int shmem_writepage(struct page * page)
{
- int error = 0;
+ int error;
struct shmem_inode_info *info;
swp_entry_t *entry, swap;
struct inode *inode;
@@ -231,17 +239,14 @@
if (!PageLocked(page))
BUG();
- /* Only move to the swap cache if there are no other users of
- * the page. */
- if (atomic_read(&page->count) > 2)
- goto out;
-
inode = page->mapping->host;
info = &inode->u.shmem_i;
swap = __get_swap_page(2);
error = -ENOMEM;
- if (!swap.val)
+ if (!swap.val) {
+ activate_page(page);
goto out;
+ }
spin_lock(&info->lock);
entry = shmem_swp_entry(info, page->index);
@@ -314,6 +319,7 @@
return page;
}
+ shmem_recalc_inode(inode);
if (entry->val) {
unsigned long flags;
@@ -393,22 +399,9 @@
static int shmem_getpage(struct inode * inode, unsigned long idx, struct page **ptr)
{
- struct address_space * mapping = inode->i_mapping;
int error;
- *ptr = NOPAGE_SIGBUS;
- if (inode->i_size <= (loff_t) idx * PAGE_CACHE_SIZE)
- return -EFAULT;
-
- *ptr = __find_get_page(mapping, idx, page_hash(mapping, idx));
- if (*ptr) {
- if (Page_Uptodate(*ptr))
- return 0;
- page_cache_release(*ptr);
- }
-
down (&inode->i_sem);
- /* retest we may have slept */
if (inode->i_size < (loff_t) idx * PAGE_CACHE_SIZE)
goto sigbus;
*ptr = shmem_getpage_locked(inode, idx);
@@ -1027,6 +1020,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 +1069,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 +1277,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 +1289,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 +1315,6 @@
put_filp(file);
put_dentry:
dput (dentry);
-out:
return ERR_PTR(error);
}
/*
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)