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.c70
1 files changed, 43 insertions, 27 deletions
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 4c193e38f8e4..2a00b96eac01 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -711,24 +711,28 @@ int gfs2_change_nlink(struct gfs2_inode *ip, int diff)
711 * Returns: errno 711 * Returns: errno
712 */ 712 */
713 713
714int gfs2_lookupi(struct gfs2_inode *dip, struct qstr *name, int is_root, 714int gfs2_lookupi(struct inode *dir, struct qstr *name, int is_root,
715 struct gfs2_inode **ipp) 715 struct inode **inodep)
716{ 716{
717 struct gfs2_inode *ipp;
718 struct gfs2_inode *dip = get_v2ip(dir);
717 struct gfs2_sbd *sdp = dip->i_sbd; 719 struct gfs2_sbd *sdp = dip->i_sbd;
718 struct gfs2_holder d_gh; 720 struct gfs2_holder d_gh;
719 struct gfs2_inum inum; 721 struct gfs2_inum inum;
720 unsigned int type; 722 unsigned int type;
721 struct gfs2_glock *gl; 723 struct gfs2_glock *gl;
722 int error; 724 int error = 0;
725
726 *inodep = NULL;
723 727
724 if (!name->len || name->len > GFS2_FNAMESIZE) 728 if (!name->len || name->len > GFS2_FNAMESIZE)
725 return -ENAMETOOLONG; 729 return -ENAMETOOLONG;
726 730
727 if (gfs2_filecmp(name, ".", 1) || 731 if (gfs2_filecmp(name, ".", 1) ||
728 (gfs2_filecmp(name, "..", 2) && dip == get_v2ip(sdp->sd_root_dir))) { 732 (gfs2_filecmp(name, "..", 2) && dir == sdp->sd_root_dir)) {
729 gfs2_inode_hold(dip); 733 gfs2_inode_hold(dip);
730 *ipp = dip; 734 ipp = dip;
731 return 0; 735 goto done;
732 } 736 }
733 737
734 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh); 738 error = gfs2_glock_nq_init(dip->i_gl, LM_ST_SHARED, 0, &d_gh);
@@ -750,15 +754,21 @@ int gfs2_lookupi(struct gfs2_inode *dip, struct qstr *name, int is_root,
750 if (error) 754 if (error)
751 goto out; 755 goto out;
752 756
753 error = gfs2_inode_get(gl, &inum, CREATE, ipp); 757 error = gfs2_inode_get(gl, &inum, CREATE, &ipp);
754 if (!error) 758 if (!error)
755 gfs2_inode_min_init(*ipp, type); 759 gfs2_inode_min_init(ipp, type);
756 760
757 gfs2_glock_put(gl); 761 gfs2_glock_put(gl);
758 762
759 out: 763out:
760 gfs2_glock_dq_uninit(&d_gh); 764 gfs2_glock_dq_uninit(&d_gh);
761 765done:
766 if (error == 0) {
767 *inodep = gfs2_ip2v(ipp);
768 if (!*inodep)
769 error = -ENOMEM;
770 gfs2_inode_put(ipp);
771 }
762 return error; 772 return error;
763} 773}
764 774
@@ -1171,15 +1181,16 @@ static int link_dinode(struct gfs2_inode *dip, struct qstr *name,
1171 * @ghs[0] is an initialized holder for the directory 1181 * @ghs[0] is an initialized holder for the directory
1172 * @ghs[1] is the holder for the inode lock 1182 * @ghs[1] is the holder for the inode lock
1173 * 1183 *
1174 * If the return value is 0, the glocks on both the directory and the new 1184 * If the return value is not NULL, the glocks on both the directory and the new
1175 * file are held. A transaction has been started and an inplace reservation 1185 * file are held. A transaction has been started and an inplace reservation
1176 * is held, as well. 1186 * is held, as well.
1177 * 1187 *
1178 * Returns: errno 1188 * Returns: An inode
1179 */ 1189 */
1180 1190
1181int gfs2_createi(struct gfs2_holder *ghs, struct qstr *name, unsigned int mode) 1191struct inode *gfs2_createi(struct gfs2_holder *ghs, struct qstr *name, unsigned int mode)
1182{ 1192{
1193 struct inode *inode;
1183 struct gfs2_inode *dip = get_gl2ip(ghs->gh_gl); 1194 struct gfs2_inode *dip = get_gl2ip(ghs->gh_gl);
1184 struct gfs2_sbd *sdp = dip->i_sbd; 1195 struct gfs2_sbd *sdp = dip->i_sbd;
1185 struct gfs2_unlinked *ul; 1196 struct gfs2_unlinked *ul;
@@ -1187,11 +1198,11 @@ int gfs2_createi(struct gfs2_holder *ghs, struct qstr *name, unsigned int mode)
1187 int error; 1198 int error;
1188 1199
1189 if (!name->len || name->len > GFS2_FNAMESIZE) 1200 if (!name->len || name->len > GFS2_FNAMESIZE)
1190 return -ENAMETOOLONG; 1201 return ERR_PTR(-ENAMETOOLONG);
1191 1202
1192 error = gfs2_unlinked_get(sdp, &ul); 1203 error = gfs2_unlinked_get(sdp, &ul);
1193 if (error) 1204 if (error)
1194 return error; 1205 return ERR_PTR(error);
1195 1206
1196 gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); 1207 gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs);
1197 error = gfs2_glock_nq(ghs); 1208 error = gfs2_glock_nq(ghs);
@@ -1220,7 +1231,7 @@ int gfs2_createi(struct gfs2_holder *ghs, struct qstr *name, unsigned int mode)
1220 ghs + 1); 1231 ghs + 1);
1221 if (error) { 1232 if (error) {
1222 gfs2_unlinked_put(sdp, ul); 1233 gfs2_unlinked_put(sdp, ul);
1223 return error; 1234 return ERR_PTR(error);
1224 } 1235 }
1225 1236
1226 gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs); 1237 gfs2_holder_reinit(LM_ST_EXCLUSIVE, 0, ghs);
@@ -1228,7 +1239,7 @@ int gfs2_createi(struct gfs2_holder *ghs, struct qstr *name, unsigned int mode)
1228 if (error) { 1239 if (error) {
1229 gfs2_glock_dq_uninit(ghs + 1); 1240 gfs2_glock_dq_uninit(ghs + 1);
1230 gfs2_unlinked_put(sdp, ul); 1241 gfs2_unlinked_put(sdp, ul);
1231 return error; 1242 return ERR_PTR(error);
1232 } 1243 }
1233 1244
1234 error = create_ok(dip, name, mode); 1245 error = create_ok(dip, name, mode);
@@ -1266,7 +1277,11 @@ int gfs2_createi(struct gfs2_holder *ghs, struct qstr *name, unsigned int mode)
1266 1277
1267 gfs2_unlinked_put(sdp, ul); 1278 gfs2_unlinked_put(sdp, ul);
1268 1279
1269 return 0; 1280 inode = gfs2_ip2v(ip);
1281 gfs2_inode_put(ip);
1282 if (!inode)
1283 return ERR_PTR(-ENOMEM);
1284 return inode;
1270 1285
1271 fail_iput: 1286 fail_iput:
1272 gfs2_inode_put(ip); 1287 gfs2_inode_put(ip);
@@ -1280,7 +1295,7 @@ int gfs2_createi(struct gfs2_holder *ghs, struct qstr *name, unsigned int mode)
1280 fail: 1295 fail:
1281 gfs2_unlinked_put(sdp, ul); 1296 gfs2_unlinked_put(sdp, ul);
1282 1297
1283 return error; 1298 return ERR_PTR(error);
1284} 1299}
1285 1300
1286/** 1301/**
@@ -1445,7 +1460,8 @@ int gfs2_unlink_ok(struct gfs2_inode *dip, struct qstr *name,
1445int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) 1460int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
1446{ 1461{
1447 struct gfs2_sbd *sdp = this->i_sbd; 1462 struct gfs2_sbd *sdp = this->i_sbd;
1448 struct gfs2_inode *tmp; 1463 struct inode *dir = to->i_vnode;
1464 struct inode *tmp;
1449 struct qstr dotdot; 1465 struct qstr dotdot;
1450 int error = 0; 1466 int error = 0;
1451 1467
@@ -1453,27 +1469,27 @@ int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
1453 dotdot.name = ".."; 1469 dotdot.name = "..";
1454 dotdot.len = 2; 1470 dotdot.len = 2;
1455 1471
1456 gfs2_inode_hold(to); 1472 igrab(dir);
1457 1473
1458 for (;;) { 1474 for (;;) {
1459 if (to == this) { 1475 if (dir == this->i_vnode) {
1460 error = -EINVAL; 1476 error = -EINVAL;
1461 break; 1477 break;
1462 } 1478 }
1463 if (to == get_v2ip(sdp->sd_root_dir)) { 1479 if (dir == sdp->sd_root_dir) {
1464 error = 0; 1480 error = 0;
1465 break; 1481 break;
1466 } 1482 }
1467 1483
1468 error = gfs2_lookupi(to, &dotdot, 1, &tmp); 1484 error = gfs2_lookupi(dir, &dotdot, 1, &tmp);
1469 if (error) 1485 if (error)
1470 break; 1486 break;
1471 1487
1472 gfs2_inode_put(to); 1488 iput(dir);
1473 to = tmp; 1489 dir = tmp;
1474 } 1490 }
1475 1491
1476 gfs2_inode_put(to); 1492 iput(dir);
1477 1493
1478 return error; 1494 return error;
1479} 1495}