aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r--fs/gfs2/dir.c56
1 files changed, 43 insertions, 13 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index a96fa07b3f3b..9cdd71cef59c 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -1456,7 +1456,7 @@ int gfs2_dir_read(struct inode *inode, u64 *offset, void *opaque,
1456 if (dip->i_di.di_entries != g.offset) { 1456 if (dip->i_di.di_entries != g.offset) {
1457 fs_warn(sdp, "Number of entries corrupt in dir %llu, " 1457 fs_warn(sdp, "Number of entries corrupt in dir %llu, "
1458 "ip->i_di.di_entries (%u) != g.offset (%u)\n", 1458 "ip->i_di.di_entries (%u) != g.offset (%u)\n",
1459 (unsigned long long)dip->i_num.no_addr, 1459 (unsigned long long)dip->i_no_addr,
1460 dip->i_di.di_entries, 1460 dip->i_di.di_entries,
1461 g.offset); 1461 g.offset);
1462 error = -EIO; 1462 error = -EIO;
@@ -1488,24 +1488,54 @@ out:
1488 * Returns: errno 1488 * Returns: errno
1489 */ 1489 */
1490 1490
1491int gfs2_dir_search(struct inode *dir, const struct qstr *name, 1491struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name)
1492 struct gfs2_inum_host *inum, unsigned int *type)
1493{ 1492{
1494 struct buffer_head *bh; 1493 struct buffer_head *bh;
1495 struct gfs2_dirent *dent; 1494 struct gfs2_dirent *dent;
1495 struct inode *inode;
1496
1497 dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
1498 if (dent) {
1499 if (IS_ERR(dent))
1500 return ERR_PTR(PTR_ERR(dent));
1501 inode = gfs2_inode_lookup(dir->i_sb,
1502 be64_to_cpu(dent->de_inum.no_addr),
1503 be16_to_cpu(dent->de_type));
1504 brelse(bh);
1505 return inode;
1506 }
1507 return ERR_PTR(-ENOENT);
1508}
1509
1510int gfs2_dir_check(struct inode *dir, const struct qstr *name,
1511 const struct gfs2_inode *ip)
1512{
1513 struct buffer_head *bh;
1514 struct gfs2_dirent *dent;
1515 int ret = -ENOENT;
1496 1516
1497 dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); 1517 dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
1498 if (dent) { 1518 if (dent) {
1499 if (IS_ERR(dent)) 1519 if (IS_ERR(dent))
1500 return PTR_ERR(dent); 1520 return PTR_ERR(dent);
1501 if (inum) 1521 if (ip) {
1502 gfs2_inum_in(inum, (char *)&dent->de_inum); 1522 if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr)
1503 if (type) 1523 goto out;
1504 *type = be16_to_cpu(dent->de_type); 1524 if (be64_to_cpu(dent->de_inum.no_formal_ino) !=
1525 ip->i_no_formal_ino)
1526 goto out;
1527 if (unlikely(IF2DT(ip->i_inode.i_mode) !=
1528 be16_to_cpu(dent->de_type))) {
1529 gfs2_consist_inode(GFS2_I(dir));
1530 ret = -EIO;
1531 goto out;
1532 }
1533 }
1534 ret = 0;
1535out:
1505 brelse(bh); 1536 brelse(bh);
1506 return 0;
1507 } 1537 }
1508 return -ENOENT; 1538 return ret;
1509} 1539}
1510 1540
1511static int dir_new_leaf(struct inode *inode, const struct qstr *name) 1541static int dir_new_leaf(struct inode *inode, const struct qstr *name)
@@ -1565,7 +1595,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
1565 */ 1595 */
1566 1596
1567int gfs2_dir_add(struct inode *inode, const struct qstr *name, 1597int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1568 const struct gfs2_inum_host *inum, unsigned type) 1598 const struct gfs2_inode *nip, unsigned type)
1569{ 1599{
1570 struct gfs2_inode *ip = GFS2_I(inode); 1600 struct gfs2_inode *ip = GFS2_I(inode);
1571 struct buffer_head *bh; 1601 struct buffer_head *bh;
@@ -1580,7 +1610,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1580 if (IS_ERR(dent)) 1610 if (IS_ERR(dent))
1581 return PTR_ERR(dent); 1611 return PTR_ERR(dent);
1582 dent = gfs2_init_dirent(inode, dent, name, bh); 1612 dent = gfs2_init_dirent(inode, dent, name, bh);
1583 gfs2_inum_out(inum, (char *)&dent->de_inum); 1613 gfs2_inum_out(nip, dent);
1584 dent->de_type = cpu_to_be16(type); 1614 dent->de_type = cpu_to_be16(type);
1585 if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { 1615 if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
1586 leaf = (struct gfs2_leaf *)bh->b_data; 1616 leaf = (struct gfs2_leaf *)bh->b_data;
@@ -1700,7 +1730,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
1700 */ 1730 */
1701 1731
1702int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, 1732int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1703 struct gfs2_inum_host *inum, unsigned int new_type) 1733 const struct gfs2_inode *nip, unsigned int new_type)
1704{ 1734{
1705 struct buffer_head *bh; 1735 struct buffer_head *bh;
1706 struct gfs2_dirent *dent; 1736 struct gfs2_dirent *dent;
@@ -1715,7 +1745,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1715 return PTR_ERR(dent); 1745 return PTR_ERR(dent);
1716 1746
1717 gfs2_trans_add_bh(dip->i_gl, bh, 1); 1747 gfs2_trans_add_bh(dip->i_gl, bh, 1);
1718 gfs2_inum_out(inum, (char *)&dent->de_inum); 1748 gfs2_inum_out(nip, dent);
1719 dent->de_type = cpu_to_be16(new_type); 1749 dent->de_type = cpu_to_be16(new_type);
1720 1750
1721 if (dip->i_di.di_flags & GFS2_DIF_EXHASH) { 1751 if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {