diff options
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index cd1de61bff2f..d403d51d5b0f 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -228,12 +228,10 @@ struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum *inum) | |||
228 | 228 | ||
229 | void gfs2_inode_min_init(struct gfs2_inode *ip, unsigned int type) | 229 | void gfs2_inode_min_init(struct gfs2_inode *ip, unsigned int type) |
230 | { | 230 | { |
231 | spin_lock(&ip->i_spin); | ||
232 | if (!test_and_set_bit(GIF_MIN_INIT, &ip->i_flags)) { | 231 | if (!test_and_set_bit(GIF_MIN_INIT, &ip->i_flags)) { |
233 | ip->i_di.di_nlink = 1; | 232 | ip->i_di.di_nlink = 1; |
234 | ip->i_di.di_mode = DT2IF(type); | 233 | ip->i_di.di_mode = DT2IF(type); |
235 | } | 234 | } |
236 | spin_unlock(&ip->i_spin); | ||
237 | } | 235 | } |
238 | 236 | ||
239 | /** | 237 | /** |
@@ -257,10 +255,8 @@ int gfs2_inode_refresh(struct gfs2_inode *ip) | |||
257 | return -EIO; | 255 | return -EIO; |
258 | } | 256 | } |
259 | 257 | ||
260 | spin_lock(&ip->i_spin); | ||
261 | gfs2_dinode_in(&ip->i_di, dibh->b_data); | 258 | gfs2_dinode_in(&ip->i_di, dibh->b_data); |
262 | set_bit(GIF_MIN_INIT, &ip->i_flags); | 259 | set_bit(GIF_MIN_INIT, &ip->i_flags); |
263 | spin_unlock(&ip->i_spin); | ||
264 | 260 | ||
265 | brelse(dibh); | 261 | brelse(dibh); |
266 | 262 | ||
@@ -702,6 +698,16 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
702 | return 0; | 698 | return 0; |
703 | } | 699 | } |
704 | 700 | ||
701 | struct inode *gfs2_lookup_simple(struct inode *dip, const char *name) | ||
702 | { | ||
703 | struct qstr qstr; | ||
704 | qstr.name = name; | ||
705 | qstr.len = strlen(name); | ||
706 | qstr.hash = gfs2_disk_hash(qstr.name, qstr.len); | ||
707 | return gfs2_lookupi(dip, &qstr, 1, NULL); | ||
708 | } | ||
709 | |||
710 | |||
705 | /** | 711 | /** |
706 | * gfs2_lookupi - Look up a filename in a directory and return its inode | 712 | * gfs2_lookupi - Look up a filename in a directory and return its inode |
707 | * @d_gh: An initialized holder for the directory glock | 713 | * @d_gh: An initialized holder for the directory glock |
@@ -715,8 +721,9 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff) | |||
715 | * Returns: errno | 721 | * Returns: errno |
716 | */ | 722 | */ |
717 | 723 | ||
718 | int gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root, | 724 | struct inode *gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root, |
719 | struct inode **inodep) | 725 | struct nameidata *nd) |
726 | |||
720 | { | 727 | { |
721 | struct super_block *sb = dir->i_sb; | 728 | struct super_block *sb = dir->i_sb; |
722 | struct gfs2_inode *ipp; | 729 | struct gfs2_inode *ipp; |
@@ -727,14 +734,14 @@ int gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root, | |||
727 | unsigned int type; | 734 | unsigned int type; |
728 | struct gfs2_glock *gl; | 735 | struct gfs2_glock *gl; |
729 | int error = 0; | 736 | int error = 0; |
730 | 737 | struct inode *inode = NULL; | |
731 | *inodep = NULL; | ||
732 | 738 | ||
733 | if (!name->len || name->len > GFS2_FNAMESIZE) | 739 | if (!name->len || name->len > GFS2_FNAMESIZE) |
734 | return -ENAMETOOLONG; | 740 | return ERR_PTR(-ENAMETOOLONG); |
735 | 741 | ||
736 | if (gfs2_filecmp(name, ".", 1) || | 742 | if ((name->len == 1 && memcmp(name->name, ".", 1) == 0) || |
737 | (gfs2_filecmp(name, "..", 2) && dir == sb->s_root->d_inode)) { | 743 | (name->len == 2 && memcmp(name->name, "..", 2) == 0 && |
744 | dir == sb->s_root->d_inode)) { | ||
738 | gfs2_inode_hold(dip); | 745 | gfs2_inode_hold(dip); |
739 | ipp = dip; | 746 | ipp = dip; |
740 | goto done; | 747 | goto done; |
@@ -742,7 +749,7 @@ int gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root, | |||
742 | 749 | ||
743 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); | 750 | error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); |
744 | if (error) | 751 | if (error) |
745 | return error; | 752 | return ERR_PTR(error); |
746 | 753 | ||
747 | if (!is_root) { | 754 | if (!is_root) { |
748 | error = gfs2_repermission(dip->i_vnode, MAY_EXEC, NULL); | 755 | error = gfs2_repermission(dip->i_vnode, MAY_EXEC, NULL); |
@@ -750,7 +757,7 @@ int gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root, | |||
750 | goto out; | 757 | goto out; |
751 | } | 758 | } |
752 | 759 | ||
753 | error = gfs2_dir_search(dip, name, &inum, &type); | 760 | error = gfs2_dir_search(dir, name, &inum, &type); |
754 | if (error) | 761 | if (error) |
755 | goto out; | 762 | goto out; |
756 | 763 | ||
@@ -768,13 +775,16 @@ int gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root, | |||
768 | out: | 775 | out: |
769 | gfs2_glock_dq_uninit(&d_gh); | 776 | gfs2_glock_dq_uninit(&d_gh); |
770 | done: | 777 | done: |
778 | if (error == -ENOENT) | ||
779 | return NULL; | ||
771 | if (error == 0) { | 780 | if (error == 0) { |
772 | *inodep = gfs2_ip2v(ipp); | 781 | inode = gfs2_ip2v(ipp); |
773 | if (!*inodep) | ||
774 | error = -ENOMEM; | ||
775 | gfs2_inode_put(ipp); | 782 | gfs2_inode_put(ipp); |
783 | if (!inode) | ||
784 | return ERR_PTR(-ENOMEM); | ||
785 | return inode; | ||
776 | } | 786 | } |
777 | return error; | 787 | return ERR_PTR(error); |
778 | } | 788 | } |
779 | 789 | ||
780 | static int pick_formal_ino_1(struct gfs2_sbd *sdp, uint64_t *formal_ino) | 790 | static int pick_formal_ino_1(struct gfs2_sbd *sdp, uint64_t *formal_ino) |
@@ -918,7 +928,7 @@ static int create_ok(struct gfs2_inode *dip, struct qstr *name, | |||
918 | if (!dip->i_di.di_nlink) | 928 | if (!dip->i_di.di_nlink) |
919 | return -EPERM; | 929 | return -EPERM; |
920 | 930 | ||
921 | error = gfs2_dir_search(dip, name, NULL, NULL); | 931 | error = gfs2_dir_search(dip->i_vnode, name, NULL, NULL); |
922 | switch (error) { | 932 | switch (error) { |
923 | case -ENOENT: | 933 | case -ENOENT: |
924 | error = 0; | 934 | error = 0; |
@@ -1116,7 +1126,9 @@ static int link_dinode(struct gfs2_inode *dip, struct qstr *name, | |||
1116 | if (error) | 1126 | if (error) |
1117 | goto fail; | 1127 | goto fail; |
1118 | 1128 | ||
1119 | error = gfs2_diradd_alloc_required(dip, name, &alloc_required); | 1129 | error = alloc_required = gfs2_diradd_alloc_required(dip->i_vnode, name); |
1130 | if (alloc_required < 0) | ||
1131 | goto fail; | ||
1120 | if (alloc_required) { | 1132 | if (alloc_required) { |
1121 | error = gfs2_quota_check(dip, dip->i_di.di_uid, | 1133 | error = gfs2_quota_check(dip, dip->i_di.di_uid, |
1122 | dip->i_di.di_gid); | 1134 | dip->i_di.di_gid); |
@@ -1145,7 +1157,7 @@ static int link_dinode(struct gfs2_inode *dip, struct qstr *name, | |||
1145 | goto fail_quota_locks; | 1157 | goto fail_quota_locks; |
1146 | } | 1158 | } |
1147 | 1159 | ||
1148 | error = gfs2_dir_add(dip, name, &ip->i_num, IF2DT(ip->i_di.di_mode)); | 1160 | error = gfs2_dir_add(dip->i_vnode, name, &ip->i_num, IF2DT(ip->i_di.di_mode)); |
1149 | if (error) | 1161 | if (error) |
1150 | goto fail_end_trans; | 1162 | goto fail_end_trans; |
1151 | 1163 | ||
@@ -1379,12 +1391,14 @@ int gfs2_rmdiri(struct gfs2_inode *dip, struct qstr *name, | |||
1379 | 1391 | ||
1380 | dotname.len = 1; | 1392 | dotname.len = 1; |
1381 | dotname.name = "."; | 1393 | dotname.name = "."; |
1394 | dotname.hash = gfs2_disk_hash(dotname.name, dotname.len); | ||
1382 | error = gfs2_dir_del(ip, &dotname); | 1395 | error = gfs2_dir_del(ip, &dotname); |
1383 | if (error) | 1396 | if (error) |
1384 | return error; | 1397 | return error; |
1385 | 1398 | ||
1386 | dotname.len = 2; | 1399 | dotname.len = 2; |
1387 | dotname.name = ".."; | 1400 | dotname.name = ".."; |
1401 | dotname.hash = gfs2_disk_hash(dotname.name, dotname.len); | ||
1388 | error = gfs2_dir_del(ip, &dotname); | 1402 | error = gfs2_dir_del(ip, &dotname); |
1389 | if (error) | 1403 | if (error) |
1390 | return error; | 1404 | return error; |
@@ -1439,7 +1453,7 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, struct qstr *name, | |||
1439 | if (error) | 1453 | if (error) |
1440 | return error; | 1454 | return error; |
1441 | 1455 | ||
1442 | error = gfs2_dir_search(dip, name, &inum, &type); | 1456 | error = gfs2_dir_search(dip->i_vnode, name, &inum, &type); |
1443 | if (error) | 1457 | if (error) |
1444 | return error; | 1458 | return error; |
1445 | 1459 | ||
@@ -1476,6 +1490,7 @@ int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) | |||
1476 | memset(&dotdot, 0, sizeof(struct qstr)); | 1490 | memset(&dotdot, 0, sizeof(struct qstr)); |
1477 | dotdot.name = ".."; | 1491 | dotdot.name = ".."; |
1478 | dotdot.len = 2; | 1492 | dotdot.len = 2; |
1493 | dotdot.hash = gfs2_disk_hash(dotdot.name, dotdot.len); | ||
1479 | 1494 | ||
1480 | igrab(dir); | 1495 | igrab(dir); |
1481 | 1496 | ||
@@ -1489,9 +1504,11 @@ int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) | |||
1489 | break; | 1504 | break; |
1490 | } | 1505 | } |
1491 | 1506 | ||
1492 | error = gfs2_lookupi(dir, &dotdot, 1, &tmp); | 1507 | tmp = gfs2_lookupi(dir, &dotdot, 1, NULL); |
1493 | if (error) | 1508 | if (IS_ERR(tmp)) { |
1509 | error = PTR_ERR(tmp); | ||
1494 | break; | 1510 | break; |
1511 | } | ||
1495 | 1512 | ||
1496 | iput(dir); | 1513 | iput(dir); |
1497 | dir = tmp; | 1514 | dir = tmp; |