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.c69
1 files changed, 50 insertions, 19 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index a96fa07b3f3b..2beb2f401aa2 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -130,7 +130,7 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf,
130 memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); 130 memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size);
131 if (ip->i_di.di_size < offset + size) 131 if (ip->i_di.di_size < offset + size)
132 ip->i_di.di_size = offset + size; 132 ip->i_di.di_size = offset + size;
133 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; 133 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
134 gfs2_dinode_out(ip, dibh->b_data); 134 gfs2_dinode_out(ip, dibh->b_data);
135 135
136 brelse(dibh); 136 brelse(dibh);
@@ -228,7 +228,7 @@ out:
228 228
229 if (ip->i_di.di_size < offset + copied) 229 if (ip->i_di.di_size < offset + copied)
230 ip->i_di.di_size = offset + copied; 230 ip->i_di.di_size = offset + copied;
231 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; 231 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
232 232
233 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 233 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
234 gfs2_dinode_out(ip, dibh->b_data); 234 gfs2_dinode_out(ip, dibh->b_data);
@@ -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,55 @@ 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 be16_to_cpu(dent->de_type),
1503 be64_to_cpu(dent->de_inum.no_addr),
1504 be64_to_cpu(dent->de_inum.no_formal_ino));
1505 brelse(bh);
1506 return inode;
1507 }
1508 return ERR_PTR(-ENOENT);
1509}
1510
1511int gfs2_dir_check(struct inode *dir, const struct qstr *name,
1512 const struct gfs2_inode *ip)
1513{
1514 struct buffer_head *bh;
1515 struct gfs2_dirent *dent;
1516 int ret = -ENOENT;
1496 1517
1497 dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh); 1518 dent = gfs2_dirent_search(dir, name, gfs2_dirent_find, &bh);
1498 if (dent) { 1519 if (dent) {
1499 if (IS_ERR(dent)) 1520 if (IS_ERR(dent))
1500 return PTR_ERR(dent); 1521 return PTR_ERR(dent);
1501 if (inum) 1522 if (ip) {
1502 gfs2_inum_in(inum, (char *)&dent->de_inum); 1523 if (be64_to_cpu(dent->de_inum.no_addr) != ip->i_no_addr)
1503 if (type) 1524 goto out;
1504 *type = be16_to_cpu(dent->de_type); 1525 if (be64_to_cpu(dent->de_inum.no_formal_ino) !=
1526 ip->i_no_formal_ino)
1527 goto out;
1528 if (unlikely(IF2DT(ip->i_inode.i_mode) !=
1529 be16_to_cpu(dent->de_type))) {
1530 gfs2_consist_inode(GFS2_I(dir));
1531 ret = -EIO;
1532 goto out;
1533 }
1534 }
1535 ret = 0;
1536out:
1505 brelse(bh); 1537 brelse(bh);
1506 return 0;
1507 } 1538 }
1508 return -ENOENT; 1539 return ret;
1509} 1540}
1510 1541
1511static int dir_new_leaf(struct inode *inode, const struct qstr *name) 1542static int dir_new_leaf(struct inode *inode, const struct qstr *name)
@@ -1565,7 +1596,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name)
1565 */ 1596 */
1566 1597
1567int gfs2_dir_add(struct inode *inode, const struct qstr *name, 1598int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1568 const struct gfs2_inum_host *inum, unsigned type) 1599 const struct gfs2_inode *nip, unsigned type)
1569{ 1600{
1570 struct gfs2_inode *ip = GFS2_I(inode); 1601 struct gfs2_inode *ip = GFS2_I(inode);
1571 struct buffer_head *bh; 1602 struct buffer_head *bh;
@@ -1580,7 +1611,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1580 if (IS_ERR(dent)) 1611 if (IS_ERR(dent))
1581 return PTR_ERR(dent); 1612 return PTR_ERR(dent);
1582 dent = gfs2_init_dirent(inode, dent, name, bh); 1613 dent = gfs2_init_dirent(inode, dent, name, bh);
1583 gfs2_inum_out(inum, (char *)&dent->de_inum); 1614 gfs2_inum_out(nip, dent);
1584 dent->de_type = cpu_to_be16(type); 1615 dent->de_type = cpu_to_be16(type);
1585 if (ip->i_di.di_flags & GFS2_DIF_EXHASH) { 1616 if (ip->i_di.di_flags & GFS2_DIF_EXHASH) {
1586 leaf = (struct gfs2_leaf *)bh->b_data; 1617 leaf = (struct gfs2_leaf *)bh->b_data;
@@ -1592,7 +1623,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name,
1592 break; 1623 break;
1593 gfs2_trans_add_bh(ip->i_gl, bh, 1); 1624 gfs2_trans_add_bh(ip->i_gl, bh, 1);
1594 ip->i_di.di_entries++; 1625 ip->i_di.di_entries++;
1595 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME_SEC; 1626 ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
1596 gfs2_dinode_out(ip, bh->b_data); 1627 gfs2_dinode_out(ip, bh->b_data);
1597 brelse(bh); 1628 brelse(bh);
1598 error = 0; 1629 error = 0;
@@ -1678,7 +1709,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
1678 gfs2_consist_inode(dip); 1709 gfs2_consist_inode(dip);
1679 gfs2_trans_add_bh(dip->i_gl, bh, 1); 1710 gfs2_trans_add_bh(dip->i_gl, bh, 1);
1680 dip->i_di.di_entries--; 1711 dip->i_di.di_entries--;
1681 dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC; 1712 dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
1682 gfs2_dinode_out(dip, bh->b_data); 1713 gfs2_dinode_out(dip, bh->b_data);
1683 brelse(bh); 1714 brelse(bh);
1684 mark_inode_dirty(&dip->i_inode); 1715 mark_inode_dirty(&dip->i_inode);
@@ -1700,7 +1731,7 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
1700 */ 1731 */
1701 1732
1702int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, 1733int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1703 struct gfs2_inum_host *inum, unsigned int new_type) 1734 const struct gfs2_inode *nip, unsigned int new_type)
1704{ 1735{
1705 struct buffer_head *bh; 1736 struct buffer_head *bh;
1706 struct gfs2_dirent *dent; 1737 struct gfs2_dirent *dent;
@@ -1715,7 +1746,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1715 return PTR_ERR(dent); 1746 return PTR_ERR(dent);
1716 1747
1717 gfs2_trans_add_bh(dip->i_gl, bh, 1); 1748 gfs2_trans_add_bh(dip->i_gl, bh, 1);
1718 gfs2_inum_out(inum, (char *)&dent->de_inum); 1749 gfs2_inum_out(nip, dent);
1719 dent->de_type = cpu_to_be16(new_type); 1750 dent->de_type = cpu_to_be16(new_type);
1720 1751
1721 if (dip->i_di.di_flags & GFS2_DIF_EXHASH) { 1752 if (dip->i_di.di_flags & GFS2_DIF_EXHASH) {
@@ -1726,7 +1757,7 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1726 gfs2_trans_add_bh(dip->i_gl, bh, 1); 1757 gfs2_trans_add_bh(dip->i_gl, bh, 1);
1727 } 1758 }
1728 1759
1729 dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME_SEC; 1760 dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME;
1730 gfs2_dinode_out(dip, bh->b_data); 1761 gfs2_dinode_out(dip, bh->b_data);
1731 brelse(bh); 1762 brelse(bh);
1732 return 0; 1763 return 0;
@@ -1867,7 +1898,7 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len,
1867 for (x = 0; x < rlist.rl_rgrps; x++) { 1898 for (x = 0; x < rlist.rl_rgrps; x++) {
1868 struct gfs2_rgrpd *rgd; 1899 struct gfs2_rgrpd *rgd;
1869 rgd = rlist.rl_ghs[x].gh_gl->gl_object; 1900 rgd = rlist.rl_ghs[x].gh_gl->gl_object;
1870 rg_blocks += rgd->rd_ri.ri_length; 1901 rg_blocks += rgd->rd_length;
1871 } 1902 }
1872 1903
1873 error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs); 1904 error = gfs2_glock_nq_m(rlist.rl_rgrps, rlist.rl_ghs);