diff options
Diffstat (limited to 'fs/gfs2/inode.c')
-rw-r--r-- | fs/gfs2/inode.c | 70 |
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 | ||
714 | int gfs2_lookupi(struct gfs2_inode *dip, struct qstr *name, int is_root, | 714 | int 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: | 763 | out: |
760 | gfs2_glock_dq_uninit(&d_gh); | 764 | gfs2_glock_dq_uninit(&d_gh); |
761 | 765 | done: | |
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 | ||
1181 | int gfs2_createi(struct gfs2_holder *ghs, struct qstr *name, unsigned int mode) | 1191 | struct 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, | |||
1445 | int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to) | 1460 | int 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 | } |