aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext2/super.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-09-16 15:15:37 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-16 15:54:30 -0400
commitecaff756ff540f3821e2b00b8fa19aca07c7c3e5 (patch)
tree80c40b24ad9228dcd7cf48c798250a9ccc74887a /fs/ext2/super.c
parent55ebcc38a5f6d40e4c41447e413ef842b803980f (diff)
[PATCH] knfsd: Have ext2 reject file handles with bad inode numbers early
This prevents bad inode numbers from triggering errors in ext2_get_inode. [akpm@osdl.org: speedup, cleanup] Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/ext2/super.c')
-rw-r--r--fs/ext2/super.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 681dea8f9532..ca5bfb6914d2 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -251,6 +251,44 @@ static struct super_operations ext2_sops = {
251#endif 251#endif
252}; 252};
253 253
254static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
255{
256 __u32 *objp = vobjp;
257 unsigned long ino = objp[0];
258 __u32 generation = objp[1];
259 struct inode *inode;
260 struct dentry *result;
261
262 if (ino < EXT2_FIRST_INO(sb) && ino != EXT2_ROOT_INO)
263 return ERR_PTR(-ESTALE);
264 if (ino > le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count))
265 return ERR_PTR(-ESTALE);
266
267 /* iget isn't really right if the inode is currently unallocated!!
268 * ext2_read_inode currently does appropriate checks, but
269 * it might be "neater" to call ext2_get_inode first and check
270 * if the inode is valid.....
271 */
272 inode = iget(sb, ino);
273 if (inode == NULL)
274 return ERR_PTR(-ENOMEM);
275 if (is_bad_inode(inode) ||
276 (generation && inode->i_generation != generation)) {
277 /* we didn't find the right inode.. */
278 iput(inode);
279 return ERR_PTR(-ESTALE);
280 }
281 /* now to find a dentry.
282 * If possible, get a well-connected one
283 */
284 result = d_alloc_anon(inode);
285 if (!result) {
286 iput(inode);
287 return ERR_PTR(-ENOMEM);
288 }
289 return result;
290}
291
254/* Yes, most of these are left as NULL!! 292/* Yes, most of these are left as NULL!!
255 * A NULL value implies the default, which works with ext2-like file 293 * A NULL value implies the default, which works with ext2-like file
256 * systems, but can be improved upon. 294 * systems, but can be improved upon.
@@ -258,6 +296,7 @@ static struct super_operations ext2_sops = {
258 */ 296 */
259static struct export_operations ext2_export_ops = { 297static struct export_operations ext2_export_ops = {
260 .get_parent = ext2_get_parent, 298 .get_parent = ext2_get_parent,
299 .get_dentry = ext2_get_dentry,
261}; 300};
262 301
263static unsigned long get_sb_block(void **data) 302static unsigned long get_sb_block(void **data)