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.c63
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
229void gfs2_inode_min_init(struct gfs2_inode *ip, unsigned int type) 229void 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
701struct 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
718int gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root, 724struct 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,
768out: 775out:
769 gfs2_glock_dq_uninit(&d_gh); 776 gfs2_glock_dq_uninit(&d_gh);
770done: 777done:
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
780static int pick_formal_ino_1(struct gfs2_sbd *sdp, uint64_t *formal_ino) 790static 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;