aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r--fs/gfs2/inode.c72
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;
306corrupt:
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);