diff options
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 72 |
1 files changed, 41 insertions, 31 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 37725ade3c51..3a9ef526c308 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. | 2 | * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3 | * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. | 3 | * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. |
4 | * | 4 | * |
5 | * This copyrighted material is made available to anyone wishing to use, | 5 | * This copyrighted material is made available to anyone wishing to use, |
6 | * modify, copy, or redistribute it subject to the terms and conditions | 6 | * modify, copy, or redistribute it subject to the terms and conditions |
@@ -149,7 +149,8 @@ void gfs2_set_iop(struct inode *inode) | |||
149 | } else if (S_ISLNK(mode)) { | 149 | } else if (S_ISLNK(mode)) { |
150 | inode->i_op = &gfs2_symlink_iops; | 150 | inode->i_op = &gfs2_symlink_iops; |
151 | } else { | 151 | } else { |
152 | inode->i_op = &gfs2_dev_iops; | 152 | inode->i_op = &gfs2_file_iops; |
153 | init_special_inode(inode, inode->i_mode, inode->i_rdev); | ||
153 | } | 154 | } |
154 | 155 | ||
155 | unlock_new_inode(inode); | 156 | unlock_new_inode(inode); |
@@ -248,12 +249,10 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
248 | { | 249 | { |
249 | struct gfs2_dinode_host *di = &ip->i_di; | 250 | struct gfs2_dinode_host *di = &ip->i_di; |
250 | const struct gfs2_dinode *str = buf; | 251 | const struct gfs2_dinode *str = buf; |
252 | u16 height, depth; | ||
251 | 253 | ||
252 | if (ip->i_no_addr != be64_to_cpu(str->di_num.no_addr)) { | 254 | if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) |
253 | if (gfs2_consist_inode(ip)) | 255 | goto corrupt; |
254 | gfs2_dinode_print(ip); | ||
255 | return -EIO; | ||
256 | } | ||
257 | ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); | 256 | ip->i_no_formal_ino = be64_to_cpu(str->di_num.no_formal_ino); |
258 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); | 257 | ip->i_inode.i_mode = be32_to_cpu(str->di_mode); |
259 | ip->i_inode.i_rdev = 0; | 258 | ip->i_inode.i_rdev = 0; |
@@ -275,8 +274,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
275 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); | 274 | ip->i_inode.i_nlink = be32_to_cpu(str->di_nlink); |
276 | di->di_size = be64_to_cpu(str->di_size); | 275 | di->di_size = be64_to_cpu(str->di_size); |
277 | i_size_write(&ip->i_inode, di->di_size); | 276 | i_size_write(&ip->i_inode, di->di_size); |
278 | di->di_blocks = be64_to_cpu(str->di_blocks); | 277 | gfs2_set_inode_blocks(&ip->i_inode, be64_to_cpu(str->di_blocks)); |
279 | gfs2_set_inode_blocks(&ip->i_inode); | ||
280 | ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); | 278 | ip->i_inode.i_atime.tv_sec = be64_to_cpu(str->di_atime); |
281 | ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); | 279 | ip->i_inode.i_atime.tv_nsec = be32_to_cpu(str->di_atime_nsec); |
282 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); | 280 | ip->i_inode.i_mtime.tv_sec = be64_to_cpu(str->di_mtime); |
@@ -284,15 +282,20 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
284 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); | 282 | ip->i_inode.i_ctime.tv_sec = be64_to_cpu(str->di_ctime); |
285 | ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); | 283 | ip->i_inode.i_ctime.tv_nsec = be32_to_cpu(str->di_ctime_nsec); |
286 | 284 | ||
287 | di->di_goal_meta = be64_to_cpu(str->di_goal_meta); | 285 | ip->i_goal = be64_to_cpu(str->di_goal_meta); |
288 | di->di_goal_data = be64_to_cpu(str->di_goal_data); | ||
289 | di->di_generation = be64_to_cpu(str->di_generation); | 286 | di->di_generation = be64_to_cpu(str->di_generation); |
290 | 287 | ||
291 | di->di_flags = be32_to_cpu(str->di_flags); | 288 | di->di_flags = be32_to_cpu(str->di_flags); |
292 | gfs2_set_inode_flags(&ip->i_inode); | 289 | gfs2_set_inode_flags(&ip->i_inode); |
293 | di->di_height = be16_to_cpu(str->di_height); | 290 | height = be16_to_cpu(str->di_height); |
294 | 291 | if (unlikely(height > GFS2_MAX_META_HEIGHT)) | |
295 | di->di_depth = be16_to_cpu(str->di_depth); | 292 | goto corrupt; |
293 | ip->i_height = (u8)height; | ||
294 | |||
295 | depth = be16_to_cpu(str->di_depth); | ||
296 | if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) | ||
297 | goto corrupt; | ||
298 | ip->i_depth = (u8)depth; | ||
296 | di->di_entries = be32_to_cpu(str->di_entries); | 299 | di->di_entries = be32_to_cpu(str->di_entries); |
297 | 300 | ||
298 | di->di_eattr = be64_to_cpu(str->di_eattr); | 301 | di->di_eattr = be64_to_cpu(str->di_eattr); |
@@ -300,6 +303,10 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) | |||
300 | gfs2_set_aops(&ip->i_inode); | 303 | gfs2_set_aops(&ip->i_inode); |
301 | 304 | ||
302 | return 0; | 305 | return 0; |
306 | corrupt: | ||
307 | if (gfs2_consist_inode(ip)) | ||
308 | gfs2_dinode_print(ip); | ||
309 | return -EIO; | ||
303 | } | 310 | } |
304 | 311 | ||
305 | /** | 312 | /** |
@@ -337,13 +344,15 @@ int gfs2_dinode_dealloc(struct gfs2_inode *ip) | |||
337 | struct gfs2_rgrpd *rgd; | 344 | struct gfs2_rgrpd *rgd; |
338 | int error; | 345 | int error; |
339 | 346 | ||
340 | if (ip->i_di.di_blocks != 1) { | 347 | if (gfs2_get_inode_blocks(&ip->i_inode) != 1) { |
341 | if (gfs2_consist_inode(ip)) | 348 | if (gfs2_consist_inode(ip)) |
342 | gfs2_dinode_print(ip); | 349 | gfs2_dinode_print(ip); |
343 | return -EIO; | 350 | return -EIO; |
344 | } | 351 | } |
345 | 352 | ||
346 | al = gfs2_alloc_get(ip); | 353 | al = gfs2_alloc_get(ip); |
354 | if (!al) | ||
355 | return -ENOMEM; | ||
347 | 356 | ||
348 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 357 | error = gfs2_quota_hold(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
349 | if (error) | 358 | if (error) |
@@ -487,7 +496,7 @@ struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, | |||
487 | return dir; | 496 | return dir; |
488 | } | 497 | } |
489 | 498 | ||
490 | if (gfs2_glock_is_locked_by_me(dip->i_gl) == 0) { | 499 | if (gfs2_glock_is_locked_by_me(dip->i_gl) == NULL) { |
491 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); | 500 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); |
492 | if (error) | 501 | if (error) |
493 | return ERR_PTR(error); | 502 | return ERR_PTR(error); |
@@ -818,7 +827,8 @@ static int make_dinode(struct gfs2_inode *dip, struct gfs2_glock *gl, | |||
818 | int error; | 827 | int error; |
819 | 828 | ||
820 | munge_mode_uid_gid(dip, &mode, &uid, &gid); | 829 | munge_mode_uid_gid(dip, &mode, &uid, &gid); |
821 | gfs2_alloc_get(dip); | 830 | if (!gfs2_alloc_get(dip)) |
831 | return -ENOMEM; | ||
822 | 832 | ||
823 | error = gfs2_quota_lock(dip, uid, gid); | 833 | error = gfs2_quota_lock(dip, uid, gid); |
824 | if (error) | 834 | if (error) |
@@ -853,6 +863,8 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name, | |||
853 | int error; | 863 | int error; |
854 | 864 | ||
855 | al = gfs2_alloc_get(dip); | 865 | al = gfs2_alloc_get(dip); |
866 | if (!al) | ||
867 | return -ENOMEM; | ||
856 | 868 | ||
857 | error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); | 869 | error = gfs2_quota_lock(dip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE); |
858 | if (error) | 870 | if (error) |
@@ -1219,7 +1231,7 @@ int gfs2_readlinki(struct gfs2_inode *ip, char **buf, unsigned int *len) | |||
1219 | 1231 | ||
1220 | x = ip->i_di.di_size + 1; | 1232 | x = ip->i_di.di_size + 1; |
1221 | if (x > *len) { | 1233 | if (x > *len) { |
1222 | *buf = kmalloc(x, GFP_KERNEL); | 1234 | *buf = kmalloc(x, GFP_NOFS); |
1223 | if (!*buf) { | 1235 | if (!*buf) { |
1224 | error = -ENOMEM; | 1236 | error = -ENOMEM; |
1225 | goto out_brelse; | 1237 | goto out_brelse; |
@@ -1391,21 +1403,21 @@ void gfs2_dinode_out(const struct gfs2_inode *ip, void *buf) | |||
1391 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); | 1403 | str->di_gid = cpu_to_be32(ip->i_inode.i_gid); |
1392 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); | 1404 | str->di_nlink = cpu_to_be32(ip->i_inode.i_nlink); |
1393 | str->di_size = cpu_to_be64(di->di_size); | 1405 | str->di_size = cpu_to_be64(di->di_size); |
1394 | str->di_blocks = cpu_to_be64(di->di_blocks); | 1406 | str->di_blocks = cpu_to_be64(gfs2_get_inode_blocks(&ip->i_inode)); |
1395 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); | 1407 | str->di_atime = cpu_to_be64(ip->i_inode.i_atime.tv_sec); |
1396 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); | 1408 | str->di_mtime = cpu_to_be64(ip->i_inode.i_mtime.tv_sec); |
1397 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); | 1409 | str->di_ctime = cpu_to_be64(ip->i_inode.i_ctime.tv_sec); |
1398 | 1410 | ||
1399 | str->di_goal_meta = cpu_to_be64(di->di_goal_meta); | 1411 | str->di_goal_meta = cpu_to_be64(ip->i_goal); |
1400 | str->di_goal_data = cpu_to_be64(di->di_goal_data); | 1412 | str->di_goal_data = cpu_to_be64(ip->i_goal); |
1401 | str->di_generation = cpu_to_be64(di->di_generation); | 1413 | str->di_generation = cpu_to_be64(di->di_generation); |
1402 | 1414 | ||
1403 | str->di_flags = cpu_to_be32(di->di_flags); | 1415 | str->di_flags = cpu_to_be32(di->di_flags); |
1404 | str->di_height = cpu_to_be16(di->di_height); | 1416 | str->di_height = cpu_to_be16(ip->i_height); |
1405 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && | 1417 | str->di_payload_format = cpu_to_be32(S_ISDIR(ip->i_inode.i_mode) && |
1406 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? | 1418 | !(ip->i_di.di_flags & GFS2_DIF_EXHASH) ? |
1407 | GFS2_FORMAT_DE : 0); | 1419 | GFS2_FORMAT_DE : 0); |
1408 | str->di_depth = cpu_to_be16(di->di_depth); | 1420 | str->di_depth = cpu_to_be16(ip->i_depth); |
1409 | str->di_entries = cpu_to_be32(di->di_entries); | 1421 | str->di_entries = cpu_to_be32(di->di_entries); |
1410 | 1422 | ||
1411 | str->di_eattr = cpu_to_be64(di->di_eattr); | 1423 | str->di_eattr = cpu_to_be64(di->di_eattr); |
@@ -1423,15 +1435,13 @@ void gfs2_dinode_print(const struct gfs2_inode *ip) | |||
1423 | printk(KERN_INFO " no_addr = %llu\n", | 1435 | printk(KERN_INFO " no_addr = %llu\n", |
1424 | (unsigned long long)ip->i_no_addr); | 1436 | (unsigned long long)ip->i_no_addr); |
1425 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); | 1437 | printk(KERN_INFO " di_size = %llu\n", (unsigned long long)di->di_size); |
1426 | printk(KERN_INFO " di_blocks = %llu\n", | 1438 | printk(KERN_INFO " blocks = %llu\n", |
1427 | (unsigned long long)di->di_blocks); | 1439 | (unsigned long long)gfs2_get_inode_blocks(&ip->i_inode)); |
1428 | printk(KERN_INFO " di_goal_meta = %llu\n", | 1440 | printk(KERN_INFO " i_goal = %llu\n", |
1429 | (unsigned long long)di->di_goal_meta); | 1441 | (unsigned long long)ip->i_goal); |
1430 | printk(KERN_INFO " di_goal_data = %llu\n", | ||
1431 | (unsigned long long)di->di_goal_data); | ||
1432 | printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags); | 1442 | printk(KERN_INFO " di_flags = 0x%.8X\n", di->di_flags); |
1433 | printk(KERN_INFO " di_height = %u\n", di->di_height); | 1443 | printk(KERN_INFO " i_height = %u\n", ip->i_height); |
1434 | printk(KERN_INFO " di_depth = %u\n", di->di_depth); | 1444 | printk(KERN_INFO " i_depth = %u\n", ip->i_depth); |
1435 | printk(KERN_INFO " di_entries = %u\n", di->di_entries); | 1445 | printk(KERN_INFO " di_entries = %u\n", di->di_entries); |
1436 | printk(KERN_INFO " di_eattr = %llu\n", | 1446 | printk(KERN_INFO " di_eattr = %llu\n", |
1437 | (unsigned long long)di->di_eattr); | 1447 | (unsigned long long)di->di_eattr); |