diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2007-05-15 10:37:50 -0400 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2007-07-09 03:22:24 -0400 |
commit | dbb7cae2a36170cd17ffbe286ec0c91a998740ff (patch) | |
tree | 1f4da65b07ac31648fe9b72f2742075486a86008 /fs/gfs2/dir.c | |
parent | 41d7db0ab437bc84f8a6e77cccc626ce937605ac (diff) |
[GFS2] Clean up inode number handling
This patch cleans up the inode number handling code. The main difference
is that instead of looking up the inodes using a struct gfs2_inum_host
we now use just the no_addr member of this structure. The tests relating
to no_formal_ino can then be done by the calling code. This has
advantages in that we want to do different things in different code
paths if the no_formal_ino doesn't match. In the NFS patch we want to
return -ESTALE, but in the ->lookup() path, its a bug in the fs if the
no_formal_ino doesn't match and thus we can withdraw in this case.
In order to later fix bz #201012, we need to be able to look up an inode
without knowing no_formal_ino, as the only information that is known to
us is the on-disk location of the inode in question.
This patch will also help us to fix bz #236099 at a later date by
cleaning up a lot of the code in that area.
There are no user visible changes as a result of this patch and there
are no changes to the on-disk format either.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r-- | fs/gfs2/dir.c | 56 |
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 | ||
1491 | int gfs2_dir_search(struct inode *dir, const struct qstr *name, | 1491 | struct 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 | |||
1510 | int 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; | ||
1535 | out: | ||
1505 | brelse(bh); | 1536 | brelse(bh); |
1506 | return 0; | ||
1507 | } | 1537 | } |
1508 | return -ENOENT; | 1538 | return ret; |
1509 | } | 1539 | } |
1510 | 1540 | ||
1511 | static int dir_new_leaf(struct inode *inode, const struct qstr *name) | 1541 | static 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 | ||
1567 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, | 1597 | int 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 | ||
1702 | int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | 1732 | int 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) { |