aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/afs/mntpt.c2
-rw-r--r--fs/block_dev.c5
-rw-r--r--fs/buffer.c2
-rw-r--r--fs/cifs/cifs_dfs_ref.c2
-rw-r--r--fs/devpts/inode.c16
-rw-r--r--fs/dquot.c33
-rw-r--r--fs/ext3/super.c3
-rw-r--r--fs/ext4/super.c3
-rw-r--r--fs/fcntl.c140
-rw-r--r--fs/file.c61
-rw-r--r--fs/jffs2/summary.c40
-rw-r--r--fs/jffs2/summary.h6
-rw-r--r--fs/libfs.c4
-rw-r--r--fs/namei.c17
-rw-r--r--fs/namespace.c16
-rw-r--r--fs/nfs/namespace.c2
-rw-r--r--fs/omfs/bitmap.c6
-rw-r--r--fs/omfs/dir.c2
-rw-r--r--fs/omfs/file.c6
-rw-r--r--fs/open.c56
-rw-r--r--fs/proc/generic.c27
-rw-r--r--fs/reiserfs/super.c16
-rw-r--r--fs/romfs/inode.c37
23 files changed, 243 insertions, 259 deletions
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index 2f5503902c37..78db4953a800 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -232,7 +232,7 @@ static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
232 } 232 }
233 233
234 mntget(newmnt); 234 mntget(newmnt);
235 err = do_add_mount(newmnt, nd, MNT_SHRINKABLE, &afs_vfsmounts); 235 err = do_add_mount(newmnt, &nd->path, MNT_SHRINKABLE, &afs_vfsmounts);
236 switch (err) { 236 switch (err) {
237 case 0: 237 case 0:
238 path_put(&nd->path); 238 path_put(&nd->path);
diff --git a/fs/block_dev.c b/fs/block_dev.c
index dcf37cada369..aff54219e049 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -941,8 +941,10 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
941 * hooks: /n/, see "layering violations". 941 * hooks: /n/, see "layering violations".
942 */ 942 */
943 ret = devcgroup_inode_permission(bdev->bd_inode, perm); 943 ret = devcgroup_inode_permission(bdev->bd_inode, perm);
944 if (ret != 0) 944 if (ret != 0) {
945 bdput(bdev);
945 return ret; 946 return ret;
947 }
946 948
947 ret = -ENXIO; 949 ret = -ENXIO;
948 file->f_mapping = bdev->bd_inode->i_mapping; 950 file->f_mapping = bdev->bd_inode->i_mapping;
@@ -1234,6 +1236,7 @@ fail:
1234 bdev = ERR_PTR(error); 1236 bdev = ERR_PTR(error);
1235 goto out; 1237 goto out;
1236} 1238}
1239EXPORT_SYMBOL(lookup_bdev);
1237 1240
1238/** 1241/**
1239 * open_bdev_excl - open a block device by name and set it up for use 1242 * open_bdev_excl - open a block device by name and set it up for use
diff --git a/fs/buffer.c b/fs/buffer.c
index ca12a6bb82b1..4dbe52948e8f 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -580,7 +580,7 @@ EXPORT_SYMBOL(mark_buffer_async_write);
580/* 580/*
581 * The buffer's backing address_space's private_lock must be held 581 * The buffer's backing address_space's private_lock must be held
582 */ 582 */
583static inline void __remove_assoc_queue(struct buffer_head *bh) 583static void __remove_assoc_queue(struct buffer_head *bh)
584{ 584{
585 list_del_init(&bh->b_assoc_buffers); 585 list_del_init(&bh->b_assoc_buffers);
586 WARN_ON(!bh->b_assoc_map); 586 WARN_ON(!bh->b_assoc_map);
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index d82374c9e329..d2c8eef84f3c 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -226,7 +226,7 @@ static int add_mount_helper(struct vfsmount *newmnt, struct nameidata *nd,
226 int err; 226 int err;
227 227
228 mntget(newmnt); 228 mntget(newmnt);
229 err = do_add_mount(newmnt, nd, nd->path.mnt->mnt_flags, mntlist); 229 err = do_add_mount(newmnt, &nd->path, nd->path.mnt->mnt_flags, mntlist);
230 switch (err) { 230 switch (err) {
231 case 0: 231 case 0:
232 path_put(&nd->path); 232 path_put(&nd->path);
diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
index 285b64a8b06e..488eb424f662 100644
--- a/fs/devpts/inode.c
+++ b/fs/devpts/inode.c
@@ -29,7 +29,7 @@
29#define DEVPTS_DEFAULT_MODE 0600 29#define DEVPTS_DEFAULT_MODE 0600
30 30
31extern int pty_limit; /* Config limit on Unix98 ptys */ 31extern int pty_limit; /* Config limit on Unix98 ptys */
32static DEFINE_IDR(allocated_ptys); 32static DEFINE_IDA(allocated_ptys);
33static DEFINE_MUTEX(allocated_ptys_lock); 33static DEFINE_MUTEX(allocated_ptys_lock);
34 34
35static struct vfsmount *devpts_mnt; 35static struct vfsmount *devpts_mnt;
@@ -180,24 +180,24 @@ static struct dentry *get_node(int num)
180int devpts_new_index(void) 180int devpts_new_index(void)
181{ 181{
182 int index; 182 int index;
183 int idr_ret; 183 int ida_ret;
184 184
185retry: 185retry:
186 if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) { 186 if (!ida_pre_get(&allocated_ptys, GFP_KERNEL)) {
187 return -ENOMEM; 187 return -ENOMEM;
188 } 188 }
189 189
190 mutex_lock(&allocated_ptys_lock); 190 mutex_lock(&allocated_ptys_lock);
191 idr_ret = idr_get_new(&allocated_ptys, NULL, &index); 191 ida_ret = ida_get_new(&allocated_ptys, &index);
192 if (idr_ret < 0) { 192 if (ida_ret < 0) {
193 mutex_unlock(&allocated_ptys_lock); 193 mutex_unlock(&allocated_ptys_lock);
194 if (idr_ret == -EAGAIN) 194 if (ida_ret == -EAGAIN)
195 goto retry; 195 goto retry;
196 return -EIO; 196 return -EIO;
197 } 197 }
198 198
199 if (index >= pty_limit) { 199 if (index >= pty_limit) {
200 idr_remove(&allocated_ptys, index); 200 ida_remove(&allocated_ptys, index);
201 mutex_unlock(&allocated_ptys_lock); 201 mutex_unlock(&allocated_ptys_lock);
202 return -EIO; 202 return -EIO;
203 } 203 }
@@ -208,7 +208,7 @@ retry:
208void devpts_kill_index(int idx) 208void devpts_kill_index(int idx)
209{ 209{
210 mutex_lock(&allocated_ptys_lock); 210 mutex_lock(&allocated_ptys_lock);
211 idr_remove(&allocated_ptys, idx); 211 ida_remove(&allocated_ptys, idx);
212 mutex_unlock(&allocated_ptys_lock); 212 mutex_unlock(&allocated_ptys_lock);
213} 213}
214 214
diff --git a/fs/dquot.c b/fs/dquot.c
index 1346eebe74ce..8ec4d6cc7633 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -1793,6 +1793,21 @@ static int vfs_quota_on_remount(struct super_block *sb, int type)
1793 return ret; 1793 return ret;
1794} 1794}
1795 1795
1796int vfs_quota_on_path(struct super_block *sb, int type, int format_id,
1797 struct path *path)
1798{
1799 int error = security_quota_on(path->dentry);
1800 if (error)
1801 return error;
1802 /* Quota file not on the same filesystem? */
1803 if (path->mnt->mnt_sb != sb)
1804 error = -EXDEV;
1805 else
1806 error = vfs_quota_on_inode(path->dentry->d_inode, type,
1807 format_id);
1808 return error;
1809}
1810
1796/* Actual function called from quotactl() */ 1811/* Actual function called from quotactl() */
1797int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path, 1812int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path,
1798 int remount) 1813 int remount)
@@ -1804,19 +1819,10 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path,
1804 return vfs_quota_on_remount(sb, type); 1819 return vfs_quota_on_remount(sb, type);
1805 1820
1806 error = path_lookup(path, LOOKUP_FOLLOW, &nd); 1821 error = path_lookup(path, LOOKUP_FOLLOW, &nd);
1807 if (error < 0) 1822 if (!error) {
1808 return error; 1823 error = vfs_quota_on_path(sb, type, format_id, &nd.path);
1809 error = security_quota_on(nd.path.dentry); 1824 path_put(&nd.path);
1810 if (error) 1825 }
1811 goto out_path;
1812 /* Quota file not on the same filesystem? */
1813 if (nd.path.mnt->mnt_sb != sb)
1814 error = -EXDEV;
1815 else
1816 error = vfs_quota_on_inode(nd.path.dentry->d_inode, type,
1817 format_id);
1818out_path:
1819 path_put(&nd.path);
1820 return error; 1826 return error;
1821} 1827}
1822 1828
@@ -2185,6 +2191,7 @@ EXPORT_SYMBOL(unregister_quota_format);
2185EXPORT_SYMBOL(dqstats); 2191EXPORT_SYMBOL(dqstats);
2186EXPORT_SYMBOL(dq_data_lock); 2192EXPORT_SYMBOL(dq_data_lock);
2187EXPORT_SYMBOL(vfs_quota_on); 2193EXPORT_SYMBOL(vfs_quota_on);
2194EXPORT_SYMBOL(vfs_quota_on_path);
2188EXPORT_SYMBOL(vfs_quota_on_mount); 2195EXPORT_SYMBOL(vfs_quota_on_mount);
2189EXPORT_SYMBOL(vfs_quota_off); 2196EXPORT_SYMBOL(vfs_quota_off);
2190EXPORT_SYMBOL(vfs_quota_sync); 2197EXPORT_SYMBOL(vfs_quota_sync);
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 8ddced384674..f38a5afc39a1 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -2810,8 +2810,9 @@ static int ext3_quota_on(struct super_block *sb, int type, int format_id,
2810 journal_unlock_updates(EXT3_SB(sb)->s_journal); 2810 journal_unlock_updates(EXT3_SB(sb)->s_journal);
2811 } 2811 }
2812 2812
2813 err = vfs_quota_on_path(sb, type, format_id, &nd.path);
2813 path_put(&nd.path); 2814 path_put(&nd.path);
2814 return vfs_quota_on(sb, type, format_id, path, remount); 2815 return err;
2815} 2816}
2816 2817
2817/* Read data from quotafile - avoid pagecache and such because we cannot afford 2818/* Read data from quotafile - avoid pagecache and such because we cannot afford
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index b5479b1dff14..1e69f29a8c55 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -3352,8 +3352,9 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id,
3352 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 3352 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
3353 } 3353 }
3354 3354
3355 err = vfs_quota_on_path(sb, type, format_id, &nd.path);
3355 path_put(&nd.path); 3356 path_put(&nd.path);
3356 return vfs_quota_on(sb, type, format_id, path, remount); 3357 return err;
3357} 3358}
3358 3359
3359/* Read data from quotafile - avoid pagecache and such because we cannot afford 3360/* Read data from quotafile - avoid pagecache and such because we cannot afford
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 61d625136813..ac4f7db9f134 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -49,73 +49,6 @@ static int get_close_on_exec(unsigned int fd)
49 return res; 49 return res;
50} 50}
51 51
52/*
53 * locate_fd finds a free file descriptor in the open_fds fdset,
54 * expanding the fd arrays if necessary. Must be called with the
55 * file_lock held for write.
56 */
57
58static int locate_fd(unsigned int orig_start, int cloexec)
59{
60 struct files_struct *files = current->files;
61 unsigned int newfd;
62 unsigned int start;
63 int error;
64 struct fdtable *fdt;
65
66 spin_lock(&files->file_lock);
67repeat:
68 fdt = files_fdtable(files);
69 /*
70 * Someone might have closed fd's in the range
71 * orig_start..fdt->next_fd
72 */
73 start = orig_start;
74 if (start < files->next_fd)
75 start = files->next_fd;
76
77 newfd = start;
78 if (start < fdt->max_fds)
79 newfd = find_next_zero_bit(fdt->open_fds->fds_bits,
80 fdt->max_fds, start);
81
82 error = expand_files(files, newfd);
83 if (error < 0)
84 goto out;
85
86 /*
87 * If we needed to expand the fs array we
88 * might have blocked - try again.
89 */
90 if (error)
91 goto repeat;
92
93 if (start <= files->next_fd)
94 files->next_fd = newfd + 1;
95
96 FD_SET(newfd, fdt->open_fds);
97 if (cloexec)
98 FD_SET(newfd, fdt->close_on_exec);
99 else
100 FD_CLR(newfd, fdt->close_on_exec);
101 error = newfd;
102
103out:
104 spin_unlock(&files->file_lock);
105 return error;
106}
107
108static int dupfd(struct file *file, unsigned int start, int cloexec)
109{
110 int fd = locate_fd(start, cloexec);
111 if (fd >= 0)
112 fd_install(fd, file);
113 else
114 fput(file);
115
116 return fd;
117}
118
119asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags) 52asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
120{ 53{
121 int err = -EBADF; 54 int err = -EBADF;
@@ -130,31 +63,35 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
130 return -EINVAL; 63 return -EINVAL;
131 64
132 spin_lock(&files->file_lock); 65 spin_lock(&files->file_lock);
133 if (!(file = fcheck(oldfd)))
134 goto out_unlock;
135 get_file(file); /* We are now finished with oldfd */
136
137 err = expand_files(files, newfd); 66 err = expand_files(files, newfd);
67 file = fcheck(oldfd);
68 if (unlikely(!file))
69 goto Ebadf;
138 if (unlikely(err < 0)) { 70 if (unlikely(err < 0)) {
139 if (err == -EMFILE) 71 if (err == -EMFILE)
140 err = -EBADF; 72 goto Ebadf;
141 goto out_fput; 73 goto out_unlock;
142 } 74 }
143 75 /*
144 /* To avoid races with open() and dup(), we will mark the fd as 76 * We need to detect attempts to do dup2() over allocated but still
145 * in-use in the open-file bitmap throughout the entire dup2() 77 * not finished descriptor. NB: OpenBSD avoids that at the price of
146 * process. This is quite safe: do_close() uses the fd array 78 * extra work in their equivalent of fget() - they insert struct
147 * entry, not the bitmap, to decide what work needs to be 79 * file immediately after grabbing descriptor, mark it larval if
148 * done. --sct */ 80 * more work (e.g. actual opening) is needed and make sure that
149 /* Doesn't work. open() might be there first. --AV */ 81 * fget() treats larval files as absent. Potentially interesting,
150 82 * but while extra work in fget() is trivial, locking implications
151 /* Yes. It's a race. In user space. Nothing sane to do */ 83 * and amount of surgery on open()-related paths in VFS are not.
84 * FreeBSD fails with -EBADF in the same situation, NetBSD "solution"
85 * deadlocks in rather amusing ways, AFAICS. All of that is out of
86 * scope of POSIX or SUS, since neither considers shared descriptor
87 * tables and this condition does not arise without those.
88 */
152 err = -EBUSY; 89 err = -EBUSY;
153 fdt = files_fdtable(files); 90 fdt = files_fdtable(files);
154 tofree = fdt->fd[newfd]; 91 tofree = fdt->fd[newfd];
155 if (!tofree && FD_ISSET(newfd, fdt->open_fds)) 92 if (!tofree && FD_ISSET(newfd, fdt->open_fds))
156 goto out_fput; 93 goto out_unlock;
157 94 get_file(file);
158 rcu_assign_pointer(fdt->fd[newfd], file); 95 rcu_assign_pointer(fdt->fd[newfd], file);
159 FD_SET(newfd, fdt->open_fds); 96 FD_SET(newfd, fdt->open_fds);
160 if (flags & O_CLOEXEC) 97 if (flags & O_CLOEXEC)
@@ -165,17 +102,14 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
165 102
166 if (tofree) 103 if (tofree)
167 filp_close(tofree, files); 104 filp_close(tofree, files);
168 err = newfd;
169out:
170 return err;
171out_unlock:
172 spin_unlock(&files->file_lock);
173 goto out;
174 105
175out_fput: 106 return newfd;
107
108Ebadf:
109 err = -EBADF;
110out_unlock:
176 spin_unlock(&files->file_lock); 111 spin_unlock(&files->file_lock);
177 fput(file); 112 return err;
178 goto out;
179} 113}
180 114
181asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd) 115asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
@@ -194,10 +128,15 @@ asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
194asmlinkage long sys_dup(unsigned int fildes) 128asmlinkage long sys_dup(unsigned int fildes)
195{ 129{
196 int ret = -EBADF; 130 int ret = -EBADF;
197 struct file * file = fget(fildes); 131 struct file *file = fget(fildes);
198 132
199 if (file) 133 if (file) {
200 ret = dupfd(file, 0, 0); 134 ret = get_unused_fd();
135 if (ret >= 0)
136 fd_install(ret, file);
137 else
138 fput(file);
139 }
201 return ret; 140 return ret;
202} 141}
203 142
@@ -322,8 +261,11 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
322 case F_DUPFD_CLOEXEC: 261 case F_DUPFD_CLOEXEC:
323 if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur) 262 if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
324 break; 263 break;
325 get_file(filp); 264 err = alloc_fd(arg, cmd == F_DUPFD_CLOEXEC ? O_CLOEXEC : 0);
326 err = dupfd(filp, arg, cmd == F_DUPFD_CLOEXEC); 265 if (err >= 0) {
266 get_file(filp);
267 fd_install(err, filp);
268 }
327 break; 269 break;
328 case F_GETFD: 270 case F_GETFD:
329 err = get_close_on_exec(fd) ? FD_CLOEXEC : 0; 271 err = get_close_on_exec(fd) ? FD_CLOEXEC : 0;
diff --git a/fs/file.c b/fs/file.c
index d8773b19fe47..f313314f996f 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -6,6 +6,7 @@
6 * Manage the dynamic fd arrays in the process files_struct. 6 * Manage the dynamic fd arrays in the process files_struct.
7 */ 7 */
8 8
9#include <linux/module.h>
9#include <linux/fs.h> 10#include <linux/fs.h>
10#include <linux/mm.h> 11#include <linux/mm.h>
11#include <linux/time.h> 12#include <linux/time.h>
@@ -432,3 +433,63 @@ struct files_struct init_files = {
432 }, 433 },
433 .file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock), 434 .file_lock = __SPIN_LOCK_UNLOCKED(init_task.file_lock),
434}; 435};
436
437/*
438 * allocate a file descriptor, mark it busy.
439 */
440int alloc_fd(unsigned start, unsigned flags)
441{
442 struct files_struct *files = current->files;
443 unsigned int fd;
444 int error;
445 struct fdtable *fdt;
446
447 spin_lock(&files->file_lock);
448repeat:
449 fdt = files_fdtable(files);
450 fd = start;
451 if (fd < files->next_fd)
452 fd = files->next_fd;
453
454 if (fd < fdt->max_fds)
455 fd = find_next_zero_bit(fdt->open_fds->fds_bits,
456 fdt->max_fds, fd);
457
458 error = expand_files(files, fd);
459 if (error < 0)
460 goto out;
461
462 /*
463 * If we needed to expand the fs array we
464 * might have blocked - try again.
465 */
466 if (error)
467 goto repeat;
468
469 if (start <= files->next_fd)
470 files->next_fd = fd + 1;
471
472 FD_SET(fd, fdt->open_fds);
473 if (flags & O_CLOEXEC)
474 FD_SET(fd, fdt->close_on_exec);
475 else
476 FD_CLR(fd, fdt->close_on_exec);
477 error = fd;
478#if 1
479 /* Sanity check */
480 if (rcu_dereference(fdt->fd[fd]) != NULL) {
481 printk(KERN_WARNING "alloc_fd: slot %d not NULL!\n", fd);
482 rcu_assign_pointer(fdt->fd[fd], NULL);
483 }
484#endif
485
486out:
487 spin_unlock(&files->file_lock);
488 return error;
489}
490
491int get_unused_fd(void)
492{
493 return alloc_fd(0, 0);
494}
495EXPORT_SYMBOL(get_unused_fd);
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 629af01e5ade..6caf1e1ee26d 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -23,6 +23,8 @@
23 23
24int jffs2_sum_init(struct jffs2_sb_info *c) 24int jffs2_sum_init(struct jffs2_sb_info *c)
25{ 25{
26 uint32_t sum_size = max_t(uint32_t, c->sector_size, MAX_SUMMARY_SIZE);
27
26 c->summary = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL); 28 c->summary = kzalloc(sizeof(struct jffs2_summary), GFP_KERNEL);
27 29
28 if (!c->summary) { 30 if (!c->summary) {
@@ -30,7 +32,7 @@ int jffs2_sum_init(struct jffs2_sb_info *c)
30 return -ENOMEM; 32 return -ENOMEM;
31 } 33 }
32 34
33 c->summary->sum_buf = vmalloc(c->sector_size); 35 c->summary->sum_buf = kmalloc(sum_size, GFP_KERNEL);
34 36
35 if (!c->summary->sum_buf) { 37 if (!c->summary->sum_buf) {
36 JFFS2_WARNING("Can't allocate buffer for writing out summary information!\n"); 38 JFFS2_WARNING("Can't allocate buffer for writing out summary information!\n");
@@ -49,7 +51,7 @@ void jffs2_sum_exit(struct jffs2_sb_info *c)
49 51
50 jffs2_sum_disable_collecting(c->summary); 52 jffs2_sum_disable_collecting(c->summary);
51 53
52 vfree(c->summary->sum_buf); 54 kfree(c->summary->sum_buf);
53 c->summary->sum_buf = NULL; 55 c->summary->sum_buf = NULL;
54 56
55 kfree(c->summary); 57 kfree(c->summary);
@@ -665,7 +667,7 @@ crc_err:
665/* Write summary data to flash - helper function for jffs2_sum_write_sumnode() */ 667/* Write summary data to flash - helper function for jffs2_sum_write_sumnode() */
666 668
667static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, 669static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb,
668 uint32_t infosize, uint32_t datasize, int padsize) 670 uint32_t infosize, uint32_t datasize, int padsize)
669{ 671{
670 struct jffs2_raw_summary isum; 672 struct jffs2_raw_summary isum;
671 union jffs2_sum_mem *temp; 673 union jffs2_sum_mem *temp;
@@ -676,6 +678,26 @@ static int jffs2_sum_write_data(struct jffs2_sb_info *c, struct jffs2_eraseblock
676 int ret; 678 int ret;
677 size_t retlen; 679 size_t retlen;
678 680
681 if (padsize + datasize > MAX_SUMMARY_SIZE) {
682 /* It won't fit in the buffer. Abort summary for this jeb */
683 jffs2_sum_disable_collecting(c->summary);
684
685 JFFS2_WARNING("Summary too big (%d data, %d pad) in eraseblock at %08x\n",
686 datasize, padsize, jeb->offset);
687 /* Non-fatal */
688 return 0;
689 }
690 /* Is there enough space for summary? */
691 if (padsize < 0) {
692 /* don't try to write out summary for this jeb */
693 jffs2_sum_disable_collecting(c->summary);
694
695 JFFS2_WARNING("Not enough space for summary, padsize = %d\n",
696 padsize);
697 /* Non-fatal */
698 return 0;
699 }
700
679 memset(c->summary->sum_buf, 0xff, datasize); 701 memset(c->summary->sum_buf, 0xff, datasize);
680 memset(&isum, 0, sizeof(isum)); 702 memset(&isum, 0, sizeof(isum));
681 703
@@ -821,7 +843,7 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
821{ 843{
822 int datasize, infosize, padsize; 844 int datasize, infosize, padsize;
823 struct jffs2_eraseblock *jeb; 845 struct jffs2_eraseblock *jeb;
824 int ret; 846 int ret = 0;
825 847
826 dbg_summary("called\n"); 848 dbg_summary("called\n");
827 849
@@ -841,16 +863,6 @@ int jffs2_sum_write_sumnode(struct jffs2_sb_info *c)
841 infosize += padsize; 863 infosize += padsize;
842 datasize += padsize; 864 datasize += padsize;
843 865
844 /* Is there enough space for summary? */
845 if (padsize < 0) {
846 /* don't try to write out summary for this jeb */
847 jffs2_sum_disable_collecting(c->summary);
848
849 JFFS2_WARNING("Not enough space for summary, padsize = %d\n", padsize);
850 spin_lock(&c->erase_completion_lock);
851 return 0;
852 }
853
854 ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize); 866 ret = jffs2_sum_write_data(c, jeb, infosize, datasize, padsize);
855 spin_lock(&c->erase_completion_lock); 867 spin_lock(&c->erase_completion_lock);
856 return ret; 868 return ret;
diff --git a/fs/jffs2/summary.h b/fs/jffs2/summary.h
index 8bf34f2fa5ce..60207a2ae952 100644
--- a/fs/jffs2/summary.h
+++ b/fs/jffs2/summary.h
@@ -13,6 +13,12 @@
13#ifndef JFFS2_SUMMARY_H 13#ifndef JFFS2_SUMMARY_H
14#define JFFS2_SUMMARY_H 14#define JFFS2_SUMMARY_H
15 15
16/* Limit summary size to 64KiB so that we can kmalloc it. If the summary
17 is larger than that, we have to just ditch it and avoid using summary
18 for the eraseblock in question... and it probably doesn't hurt us much
19 anyway. */
20#define MAX_SUMMARY_SIZE 65536
21
16#include <linux/uio.h> 22#include <linux/uio.h>
17#include <linux/jffs2.h> 23#include <linux/jffs2.h>
18 24
diff --git a/fs/libfs.c b/fs/libfs.c
index baeb71ee1cde..1add676a19df 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -216,8 +216,8 @@ int get_sb_pseudo(struct file_system_type *fs_type, char *name,
216 216
217 s->s_flags = MS_NOUSER; 217 s->s_flags = MS_NOUSER;
218 s->s_maxbytes = ~0ULL; 218 s->s_maxbytes = ~0ULL;
219 s->s_blocksize = 1024; 219 s->s_blocksize = PAGE_SIZE;
220 s->s_blocksize_bits = 10; 220 s->s_blocksize_bits = PAGE_SHIFT;
221 s->s_magic = magic; 221 s->s_magic = magic;
222 s->s_op = ops ? ops : &simple_super_operations; 222 s->s_op = ops ? ops : &simple_super_operations;
223 s->s_time_gran = 1; 223 s->s_time_gran = 1;
diff --git a/fs/namei.c b/fs/namei.c
index a7b0a0b80128..4ea63ed5e791 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -274,7 +274,7 @@ int inode_permission(struct inode *inode, int mask)
274 return retval; 274 return retval;
275 275
276 return security_inode_permission(inode, 276 return security_inode_permission(inode,
277 mask & (MAY_READ|MAY_WRITE|MAY_EXEC)); 277 mask & (MAY_READ|MAY_WRITE|MAY_EXEC|MAY_APPEND));
278} 278}
279 279
280/** 280/**
@@ -1431,8 +1431,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
1431 * 3. We should have write and exec permissions on dir 1431 * 3. We should have write and exec permissions on dir
1432 * 4. We can't do it if dir is immutable (done in permission()) 1432 * 4. We can't do it if dir is immutable (done in permission())
1433 */ 1433 */
1434static inline int may_create(struct inode *dir, struct dentry *child, 1434static inline int may_create(struct inode *dir, struct dentry *child)
1435 struct nameidata *nd)
1436{ 1435{
1437 if (child->d_inode) 1436 if (child->d_inode)
1438 return -EEXIST; 1437 return -EEXIST;
@@ -1504,7 +1503,7 @@ void unlock_rename(struct dentry *p1, struct dentry *p2)
1504int vfs_create(struct inode *dir, struct dentry *dentry, int mode, 1503int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
1505 struct nameidata *nd) 1504 struct nameidata *nd)
1506{ 1505{
1507 int error = may_create(dir, dentry, nd); 1506 int error = may_create(dir, dentry);
1508 1507
1509 if (error) 1508 if (error)
1510 return error; 1509 return error;
@@ -1948,7 +1947,7 @@ EXPORT_SYMBOL_GPL(lookup_create);
1948 1947
1949int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) 1948int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1950{ 1949{
1951 int error = may_create(dir, dentry, NULL); 1950 int error = may_create(dir, dentry);
1952 1951
1953 if (error) 1952 if (error)
1954 return error; 1953 return error;
@@ -2049,7 +2048,7 @@ asmlinkage long sys_mknod(const char __user *filename, int mode, unsigned dev)
2049 2048
2050int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) 2049int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
2051{ 2050{
2052 int error = may_create(dir, dentry, NULL); 2051 int error = may_create(dir, dentry);
2053 2052
2054 if (error) 2053 if (error)
2055 return error; 2054 return error;
@@ -2316,7 +2315,7 @@ asmlinkage long sys_unlink(const char __user *pathname)
2316 2315
2317int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname) 2316int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
2318{ 2317{
2319 int error = may_create(dir, dentry, NULL); 2318 int error = may_create(dir, dentry);
2320 2319
2321 if (error) 2320 if (error)
2322 return error; 2321 return error;
@@ -2386,7 +2385,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
2386 if (!inode) 2385 if (!inode)
2387 return -ENOENT; 2386 return -ENOENT;
2388 2387
2389 error = may_create(dir, new_dentry, NULL); 2388 error = may_create(dir, new_dentry);
2390 if (error) 2389 if (error)
2391 return error; 2390 return error;
2392 2391
@@ -2595,7 +2594,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
2595 return error; 2594 return error;
2596 2595
2597 if (!new_dentry->d_inode) 2596 if (!new_dentry->d_inode)
2598 error = may_create(new_dir, new_dentry, NULL); 2597 error = may_create(new_dir, new_dentry);
2599 else 2598 else
2600 error = may_delete(new_dir, new_dentry, is_dir); 2599 error = may_delete(new_dir, new_dentry, is_dir);
2601 if (error) 2600 if (error)
diff --git a/fs/namespace.c b/fs/namespace.c
index 411728c0c8bb..6e283c93b50d 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1667,31 +1667,31 @@ static noinline int do_new_mount(struct nameidata *nd, char *type, int flags,
1667 if (IS_ERR(mnt)) 1667 if (IS_ERR(mnt))
1668 return PTR_ERR(mnt); 1668 return PTR_ERR(mnt);
1669 1669
1670 return do_add_mount(mnt, nd, mnt_flags, NULL); 1670 return do_add_mount(mnt, &nd->path, mnt_flags, NULL);
1671} 1671}
1672 1672
1673/* 1673/*
1674 * add a mount into a namespace's mount tree 1674 * add a mount into a namespace's mount tree
1675 * - provide the option of adding the new mount to an expiration list 1675 * - provide the option of adding the new mount to an expiration list
1676 */ 1676 */
1677int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd, 1677int do_add_mount(struct vfsmount *newmnt, struct path *path,
1678 int mnt_flags, struct list_head *fslist) 1678 int mnt_flags, struct list_head *fslist)
1679{ 1679{
1680 int err; 1680 int err;
1681 1681
1682 down_write(&namespace_sem); 1682 down_write(&namespace_sem);
1683 /* Something was mounted here while we slept */ 1683 /* Something was mounted here while we slept */
1684 while (d_mountpoint(nd->path.dentry) && 1684 while (d_mountpoint(path->dentry) &&
1685 follow_down(&nd->path.mnt, &nd->path.dentry)) 1685 follow_down(&path->mnt, &path->dentry))
1686 ; 1686 ;
1687 err = -EINVAL; 1687 err = -EINVAL;
1688 if (!check_mnt(nd->path.mnt)) 1688 if (!check_mnt(path->mnt))
1689 goto unlock; 1689 goto unlock;
1690 1690
1691 /* Refuse the same filesystem on the same mount point */ 1691 /* Refuse the same filesystem on the same mount point */
1692 err = -EBUSY; 1692 err = -EBUSY;
1693 if (nd->path.mnt->mnt_sb == newmnt->mnt_sb && 1693 if (path->mnt->mnt_sb == newmnt->mnt_sb &&
1694 nd->path.mnt->mnt_root == nd->path.dentry) 1694 path->mnt->mnt_root == path->dentry)
1695 goto unlock; 1695 goto unlock;
1696 1696
1697 err = -EINVAL; 1697 err = -EINVAL;
@@ -1699,7 +1699,7 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
1699 goto unlock; 1699 goto unlock;
1700 1700
1701 newmnt->mnt_flags = mnt_flags; 1701 newmnt->mnt_flags = mnt_flags;
1702 if ((err = graft_tree(newmnt, &nd->path))) 1702 if ((err = graft_tree(newmnt, path)))
1703 goto unlock; 1703 goto unlock;
1704 1704
1705 if (fslist) /* add to the specified expiration list */ 1705 if (fslist) /* add to the specified expiration list */
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 2f285ef76399..66df08dd1caf 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -129,7 +129,7 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd)
129 goto out_err; 129 goto out_err;
130 130
131 mntget(mnt); 131 mntget(mnt);
132 err = do_add_mount(mnt, nd, nd->path.mnt->mnt_flags|MNT_SHRINKABLE, 132 err = do_add_mount(mnt, &nd->path, nd->path.mnt->mnt_flags|MNT_SHRINKABLE,
133 &nfs_automount_list); 133 &nfs_automount_list);
134 if (err < 0) { 134 if (err < 0) {
135 mntput(mnt); 135 mntput(mnt);
diff --git a/fs/omfs/bitmap.c b/fs/omfs/bitmap.c
index dc75f22be3f2..697663b01bae 100644
--- a/fs/omfs/bitmap.c
+++ b/fs/omfs/bitmap.c
@@ -71,10 +71,10 @@ static int set_run(struct super_block *sb, int map,
71 } 71 }
72 if (set) { 72 if (set) {
73 set_bit(bit, sbi->s_imap[map]); 73 set_bit(bit, sbi->s_imap[map]);
74 set_bit(bit, (long *) bh->b_data); 74 set_bit(bit, (unsigned long *)bh->b_data);
75 } else { 75 } else {
76 clear_bit(bit, sbi->s_imap[map]); 76 clear_bit(bit, sbi->s_imap[map]);
77 clear_bit(bit, (long *) bh->b_data); 77 clear_bit(bit, (unsigned long *)bh->b_data);
78 } 78 }
79 } 79 }
80 mark_buffer_dirty(bh); 80 mark_buffer_dirty(bh);
@@ -109,7 +109,7 @@ int omfs_allocate_block(struct super_block *sb, u64 block)
109 if (!bh) 109 if (!bh)
110 goto out; 110 goto out;
111 111
112 set_bit(bit, (long *) bh->b_data); 112 set_bit(bit, (unsigned long *)bh->b_data);
113 mark_buffer_dirty(bh); 113 mark_buffer_dirty(bh);
114 brelse(bh); 114 brelse(bh);
115 } 115 }
diff --git a/fs/omfs/dir.c b/fs/omfs/dir.c
index 05a5bc31e4bd..c0757e998876 100644
--- a/fs/omfs/dir.c
+++ b/fs/omfs/dir.c
@@ -104,7 +104,7 @@ int omfs_make_empty(struct inode *inode, struct super_block *sb)
104 104
105 oi = (struct omfs_inode *) bh->b_data; 105 oi = (struct omfs_inode *) bh->b_data;
106 oi->i_head.h_self = cpu_to_be64(inode->i_ino); 106 oi->i_head.h_self = cpu_to_be64(inode->i_ino);
107 oi->i_sibling = ~0ULL; 107 oi->i_sibling = ~cpu_to_be64(0ULL);
108 108
109 mark_buffer_dirty(bh); 109 mark_buffer_dirty(bh);
110 brelse(bh); 110 brelse(bh);
diff --git a/fs/omfs/file.c b/fs/omfs/file.c
index 66e01fae4384..7e2499053e4d 100644
--- a/fs/omfs/file.c
+++ b/fs/omfs/file.c
@@ -30,11 +30,11 @@ void omfs_make_empty_table(struct buffer_head *bh, int offset)
30{ 30{
31 struct omfs_extent *oe = (struct omfs_extent *) &bh->b_data[offset]; 31 struct omfs_extent *oe = (struct omfs_extent *) &bh->b_data[offset];
32 32
33 oe->e_next = ~0ULL; 33 oe->e_next = ~cpu_to_be64(0ULL);
34 oe->e_extent_count = cpu_to_be32(1), 34 oe->e_extent_count = cpu_to_be32(1),
35 oe->e_fill = cpu_to_be32(0x22), 35 oe->e_fill = cpu_to_be32(0x22),
36 oe->e_entry.e_cluster = ~0ULL; 36 oe->e_entry.e_cluster = ~cpu_to_be64(0ULL);
37 oe->e_entry.e_blocks = ~0ULL; 37 oe->e_entry.e_blocks = ~cpu_to_be64(0ULL);
38} 38}
39 39
40int omfs_shrink_inode(struct inode *inode) 40int omfs_shrink_inode(struct inode *inode)
diff --git a/fs/open.c b/fs/open.c
index 52647be277a2..07da9359481c 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -963,62 +963,6 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
963} 963}
964EXPORT_SYMBOL(dentry_open); 964EXPORT_SYMBOL(dentry_open);
965 965
966/*
967 * Find an empty file descriptor entry, and mark it busy.
968 */
969int get_unused_fd_flags(int flags)
970{
971 struct files_struct * files = current->files;
972 int fd, error;
973 struct fdtable *fdt;
974
975 spin_lock(&files->file_lock);
976
977repeat:
978 fdt = files_fdtable(files);
979 fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds,
980 files->next_fd);
981
982 /* Do we need to expand the fd array or fd set? */
983 error = expand_files(files, fd);
984 if (error < 0)
985 goto out;
986
987 if (error) {
988 /*
989 * If we needed to expand the fs array we
990 * might have blocked - try again.
991 */
992 goto repeat;
993 }
994
995 FD_SET(fd, fdt->open_fds);
996 if (flags & O_CLOEXEC)
997 FD_SET(fd, fdt->close_on_exec);
998 else
999 FD_CLR(fd, fdt->close_on_exec);
1000 files->next_fd = fd + 1;
1001#if 1
1002 /* Sanity check */
1003 if (fdt->fd[fd] != NULL) {
1004 printk(KERN_WARNING "get_unused_fd: slot %d not NULL!\n", fd);
1005 fdt->fd[fd] = NULL;
1006 }
1007#endif
1008 error = fd;
1009
1010out:
1011 spin_unlock(&files->file_lock);
1012 return error;
1013}
1014
1015int get_unused_fd(void)
1016{
1017 return get_unused_fd_flags(0);
1018}
1019
1020EXPORT_SYMBOL(get_unused_fd);
1021
1022static void __put_unused_fd(struct files_struct *files, unsigned int fd) 966static void __put_unused_fd(struct files_struct *files, unsigned int fd)
1023{ 967{
1024 struct fdtable *fdt = files_fdtable(files); 968 struct fdtable *fdt = files_fdtable(files);
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index cb4096cc3fb7..4fb81e9c94e3 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -300,10 +300,10 @@ out:
300 return rtn; 300 return rtn;
301} 301}
302 302
303static DEFINE_IDR(proc_inum_idr); 303static DEFINE_IDA(proc_inum_ida);
304static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */ 304static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */
305 305
306#define PROC_DYNAMIC_FIRST 0xF0000000UL 306#define PROC_DYNAMIC_FIRST 0xF0000000U
307 307
308/* 308/*
309 * Return an inode number between PROC_DYNAMIC_FIRST and 309 * Return an inode number between PROC_DYNAMIC_FIRST and
@@ -311,36 +311,33 @@ static DEFINE_SPINLOCK(proc_inum_lock); /* protects the above */
311 */ 311 */
312static unsigned int get_inode_number(void) 312static unsigned int get_inode_number(void)
313{ 313{
314 int i, inum = 0; 314 unsigned int i;
315 int error; 315 int error;
316 316
317retry: 317retry:
318 if (idr_pre_get(&proc_inum_idr, GFP_KERNEL) == 0) 318 if (ida_pre_get(&proc_inum_ida, GFP_KERNEL) == 0)
319 return 0; 319 return 0;
320 320
321 spin_lock(&proc_inum_lock); 321 spin_lock(&proc_inum_lock);
322 error = idr_get_new(&proc_inum_idr, NULL, &i); 322 error = ida_get_new(&proc_inum_ida, &i);
323 spin_unlock(&proc_inum_lock); 323 spin_unlock(&proc_inum_lock);
324 if (error == -EAGAIN) 324 if (error == -EAGAIN)
325 goto retry; 325 goto retry;
326 else if (error) 326 else if (error)
327 return 0; 327 return 0;
328 328
329 inum = (i & MAX_ID_MASK) + PROC_DYNAMIC_FIRST; 329 if (i > UINT_MAX - PROC_DYNAMIC_FIRST) {
330 330 spin_lock(&proc_inum_lock);
331 /* inum will never be more than 0xf0ffffff, so no check 331 ida_remove(&proc_inum_ida, i);
332 * for overflow. 332 spin_unlock(&proc_inum_lock);
333 */ 333 }
334 334 return PROC_DYNAMIC_FIRST + i;
335 return inum;
336} 335}
337 336
338static void release_inode_number(unsigned int inum) 337static void release_inode_number(unsigned int inum)
339{ 338{
340 int id = (inum - PROC_DYNAMIC_FIRST) | ~MAX_ID_MASK;
341
342 spin_lock(&proc_inum_lock); 339 spin_lock(&proc_inum_lock);
343 idr_remove(&proc_inum_idr, id); 340 ida_remove(&proc_inum_ida, inum - PROC_DYNAMIC_FIRST);
344 spin_unlock(&proc_inum_lock); 341 spin_unlock(&proc_inum_lock);
345} 342}
346 343
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 879e54d35c2d..282a13596c70 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -2076,8 +2076,8 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
2076 return err; 2076 return err;
2077 /* Quotafile not on the same filesystem? */ 2077 /* Quotafile not on the same filesystem? */
2078 if (nd.path.mnt->mnt_sb != sb) { 2078 if (nd.path.mnt->mnt_sb != sb) {
2079 path_put(&nd.path); 2079 err = -EXDEV;
2080 return -EXDEV; 2080 goto out;
2081 } 2081 }
2082 inode = nd.path.dentry->d_inode; 2082 inode = nd.path.dentry->d_inode;
2083 /* We must not pack tails for quota files on reiserfs for quota IO to work */ 2083 /* We must not pack tails for quota files on reiserfs for quota IO to work */
@@ -2087,8 +2087,8 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
2087 reiserfs_warning(sb, 2087 reiserfs_warning(sb,
2088 "reiserfs: Unpacking tail of quota file failed" 2088 "reiserfs: Unpacking tail of quota file failed"
2089 " (%d). Cannot turn on quotas.", err); 2089 " (%d). Cannot turn on quotas.", err);
2090 path_put(&nd.path); 2090 err = -EINVAL;
2091 return -EINVAL; 2091 goto out;
2092 } 2092 }
2093 mark_inode_dirty(inode); 2093 mark_inode_dirty(inode);
2094 } 2094 }
@@ -2109,13 +2109,15 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,
2109 /* Just start temporary transaction and finish it */ 2109 /* Just start temporary transaction and finish it */
2110 err = journal_begin(&th, sb, 1); 2110 err = journal_begin(&th, sb, 1);
2111 if (err) 2111 if (err)
2112 return err; 2112 goto out;
2113 err = journal_end_sync(&th, sb, 1); 2113 err = journal_end_sync(&th, sb, 1);
2114 if (err) 2114 if (err)
2115 return err; 2115 goto out;
2116 } 2116 }
2117 err = vfs_quota_on_path(sb, type, format_id, &nd.path);
2118out:
2117 path_put(&nd.path); 2119 path_put(&nd.path);
2118 return vfs_quota_on(sb, type, format_id, path, 0); 2120 return err;
2119} 2121}
2120 2122
2121/* Read data from quotafile - avoid pagecache and such because we cannot afford 2123/* Read data from quotafile - avoid pagecache and such because we cannot afford
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index 8e51a2aaa977..60d2f822e87b 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -418,7 +418,8 @@ static int
418romfs_readpage(struct file *file, struct page * page) 418romfs_readpage(struct file *file, struct page * page)
419{ 419{
420 struct inode *inode = page->mapping->host; 420 struct inode *inode = page->mapping->host;
421 loff_t offset, avail, readlen; 421 loff_t offset, size;
422 unsigned long filled;
422 void *buf; 423 void *buf;
423 int result = -EIO; 424 int result = -EIO;
424 425
@@ -430,21 +431,29 @@ romfs_readpage(struct file *file, struct page * page)
430 431
431 /* 32 bit warning -- but not for us :) */ 432 /* 32 bit warning -- but not for us :) */
432 offset = page_offset(page); 433 offset = page_offset(page);
433 if (offset < i_size_read(inode)) { 434 size = i_size_read(inode);
434 avail = inode->i_size-offset; 435 filled = 0;
435 readlen = min_t(unsigned long, avail, PAGE_SIZE); 436 result = 0;
436 if (romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen) == readlen) { 437 if (offset < size) {
437 if (readlen < PAGE_SIZE) { 438 unsigned long readlen;
438 memset(buf + readlen,0,PAGE_SIZE-readlen); 439
439 } 440 size -= offset;
440 SetPageUptodate(page); 441 readlen = size > PAGE_SIZE ? PAGE_SIZE : size;
441 result = 0; 442
443 filled = romfs_copyfrom(inode, buf, ROMFS_I(inode)->i_dataoffset+offset, readlen);
444
445 if (filled != readlen) {
446 SetPageError(page);
447 filled = 0;
448 result = -EIO;
442 } 449 }
443 } 450 }
444 if (result) { 451
445 memset(buf, 0, PAGE_SIZE); 452 if (filled < PAGE_SIZE)
446 SetPageError(page); 453 memset(buf + filled, 0, PAGE_SIZE-filled);
447 } 454
455 if (!result)
456 SetPageUptodate(page);
448 flush_dcache_page(page); 457 flush_dcache_page(page);
449 458
450 unlock_page(page); 459 unlock_page(page);