diff options
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r-- | fs/gfs2/dir.c | 228 |
1 files changed, 106 insertions, 122 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index b9dd88a78dd4..091ee4779538 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -79,12 +79,12 @@ | |||
79 | #define gfs2_disk_hash2offset(h) (((u64)(h)) >> 1) | 79 | #define gfs2_disk_hash2offset(h) (((u64)(h)) >> 1) |
80 | #define gfs2_dir_offset2hash(p) ((u32)(((u64)(p)) << 1)) | 80 | #define gfs2_dir_offset2hash(p) ((u32)(((u64)(p)) << 1)) |
81 | 81 | ||
82 | typedef int (*leaf_call_t) (struct gfs2_inode *dip, u32 index, u32 len, | 82 | struct qstr gfs2_qdot __read_mostly; |
83 | u64 leaf_no, void *data); | 83 | struct qstr gfs2_qdotdot __read_mostly; |
84 | |||
84 | typedef int (*gfs2_dscan_t)(const struct gfs2_dirent *dent, | 85 | typedef int (*gfs2_dscan_t)(const struct gfs2_dirent *dent, |
85 | const struct qstr *name, void *opaque); | 86 | const struct qstr *name, void *opaque); |
86 | 87 | ||
87 | |||
88 | int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block, | 88 | int gfs2_dir_get_new_buffer(struct gfs2_inode *ip, u64 block, |
89 | struct buffer_head **bhp) | 89 | struct buffer_head **bhp) |
90 | { | 90 | { |
@@ -127,8 +127,8 @@ static int gfs2_dir_write_stuffed(struct gfs2_inode *ip, const char *buf, | |||
127 | 127 | ||
128 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 128 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
129 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); | 129 | memcpy(dibh->b_data + offset + sizeof(struct gfs2_dinode), buf, size); |
130 | if (ip->i_disksize < offset + size) | 130 | if (ip->i_inode.i_size < offset + size) |
131 | ip->i_disksize = offset + size; | 131 | i_size_write(&ip->i_inode, offset + size); |
132 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 132 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
133 | gfs2_dinode_out(ip, dibh->b_data); | 133 | gfs2_dinode_out(ip, dibh->b_data); |
134 | 134 | ||
@@ -225,8 +225,8 @@ out: | |||
225 | if (error) | 225 | if (error) |
226 | return error; | 226 | return error; |
227 | 227 | ||
228 | if (ip->i_disksize < offset + copied) | 228 | if (ip->i_inode.i_size < offset + copied) |
229 | ip->i_disksize = offset + copied; | 229 | i_size_write(&ip->i_inode, offset + copied); |
230 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 230 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
231 | 231 | ||
232 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); | 232 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
@@ -275,12 +275,13 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset, | |||
275 | unsigned int o; | 275 | unsigned int o; |
276 | int copied = 0; | 276 | int copied = 0; |
277 | int error = 0; | 277 | int error = 0; |
278 | u64 disksize = i_size_read(&ip->i_inode); | ||
278 | 279 | ||
279 | if (offset >= ip->i_disksize) | 280 | if (offset >= disksize) |
280 | return 0; | 281 | return 0; |
281 | 282 | ||
282 | if (offset + size > ip->i_disksize) | 283 | if (offset + size > disksize) |
283 | size = ip->i_disksize - offset; | 284 | size = disksize - offset; |
284 | 285 | ||
285 | if (!size) | 286 | if (!size) |
286 | return 0; | 287 | return 0; |
@@ -727,7 +728,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode, | |||
727 | unsigned hsize = 1 << ip->i_depth; | 728 | unsigned hsize = 1 << ip->i_depth; |
728 | unsigned index; | 729 | unsigned index; |
729 | u64 ln; | 730 | u64 ln; |
730 | if (hsize * sizeof(u64) != ip->i_disksize) { | 731 | if (hsize * sizeof(u64) != i_size_read(inode)) { |
731 | gfs2_consist_inode(ip); | 732 | gfs2_consist_inode(ip); |
732 | return ERR_PTR(-EIO); | 733 | return ERR_PTR(-EIO); |
733 | } | 734 | } |
@@ -879,7 +880,7 @@ static int dir_make_exhash(struct inode *inode) | |||
879 | for (x = sdp->sd_hash_ptrs; x--; lp++) | 880 | for (x = sdp->sd_hash_ptrs; x--; lp++) |
880 | *lp = cpu_to_be64(bn); | 881 | *lp = cpu_to_be64(bn); |
881 | 882 | ||
882 | dip->i_disksize = sdp->sd_sb.sb_bsize / 2; | 883 | i_size_write(inode, sdp->sd_sb.sb_bsize / 2); |
883 | gfs2_add_inode_blocks(&dip->i_inode, 1); | 884 | gfs2_add_inode_blocks(&dip->i_inode, 1); |
884 | dip->i_diskflags |= GFS2_DIF_EXHASH; | 885 | dip->i_diskflags |= GFS2_DIF_EXHASH; |
885 | 886 | ||
@@ -1057,11 +1058,12 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
1057 | u64 *buf; | 1058 | u64 *buf; |
1058 | u64 *from, *to; | 1059 | u64 *from, *to; |
1059 | u64 block; | 1060 | u64 block; |
1061 | u64 disksize = i_size_read(&dip->i_inode); | ||
1060 | int x; | 1062 | int x; |
1061 | int error = 0; | 1063 | int error = 0; |
1062 | 1064 | ||
1063 | hsize = 1 << dip->i_depth; | 1065 | hsize = 1 << dip->i_depth; |
1064 | if (hsize * sizeof(u64) != dip->i_disksize) { | 1066 | if (hsize * sizeof(u64) != disksize) { |
1065 | gfs2_consist_inode(dip); | 1067 | gfs2_consist_inode(dip); |
1066 | return -EIO; | 1068 | return -EIO; |
1067 | } | 1069 | } |
@@ -1072,7 +1074,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
1072 | if (!buf) | 1074 | if (!buf) |
1073 | return -ENOMEM; | 1075 | return -ENOMEM; |
1074 | 1076 | ||
1075 | for (block = dip->i_disksize >> sdp->sd_hash_bsize_shift; block--;) { | 1077 | for (block = disksize >> sdp->sd_hash_bsize_shift; block--;) { |
1076 | error = gfs2_dir_read_data(dip, (char *)buf, | 1078 | error = gfs2_dir_read_data(dip, (char *)buf, |
1077 | block * sdp->sd_hash_bsize, | 1079 | block * sdp->sd_hash_bsize, |
1078 | sdp->sd_hash_bsize, 1); | 1080 | sdp->sd_hash_bsize, 1); |
@@ -1370,7 +1372,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1370 | unsigned depth = 0; | 1372 | unsigned depth = 0; |
1371 | 1373 | ||
1372 | hsize = 1 << dip->i_depth; | 1374 | hsize = 1 << dip->i_depth; |
1373 | if (hsize * sizeof(u64) != dip->i_disksize) { | 1375 | if (hsize * sizeof(u64) != i_size_read(inode)) { |
1374 | gfs2_consist_inode(dip); | 1376 | gfs2_consist_inode(dip); |
1375 | return -EIO; | 1377 | return -EIO; |
1376 | } | 1378 | } |
@@ -1501,7 +1503,7 @@ struct inode *gfs2_dir_search(struct inode *dir, const struct qstr *name) | |||
1501 | inode = gfs2_inode_lookup(dir->i_sb, | 1503 | inode = gfs2_inode_lookup(dir->i_sb, |
1502 | be16_to_cpu(dent->de_type), | 1504 | be16_to_cpu(dent->de_type), |
1503 | be64_to_cpu(dent->de_inum.no_addr), | 1505 | be64_to_cpu(dent->de_inum.no_addr), |
1504 | be64_to_cpu(dent->de_inum.no_formal_ino)); | 1506 | be64_to_cpu(dent->de_inum.no_formal_ino), 0); |
1505 | brelse(bh); | 1507 | brelse(bh); |
1506 | return inode; | 1508 | return inode; |
1507 | } | 1509 | } |
@@ -1595,7 +1597,7 @@ static int dir_new_leaf(struct inode *inode, const struct qstr *name) | |||
1595 | */ | 1597 | */ |
1596 | 1598 | ||
1597 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, | 1599 | int gfs2_dir_add(struct inode *inode, const struct qstr *name, |
1598 | const struct gfs2_inode *nip, unsigned type) | 1600 | const struct gfs2_inode *nip) |
1599 | { | 1601 | { |
1600 | struct gfs2_inode *ip = GFS2_I(inode); | 1602 | struct gfs2_inode *ip = GFS2_I(inode); |
1601 | struct buffer_head *bh; | 1603 | struct buffer_head *bh; |
@@ -1611,7 +1613,7 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1611 | return PTR_ERR(dent); | 1613 | return PTR_ERR(dent); |
1612 | dent = gfs2_init_dirent(inode, dent, name, bh); | 1614 | dent = gfs2_init_dirent(inode, dent, name, bh); |
1613 | gfs2_inum_out(nip, dent); | 1615 | gfs2_inum_out(nip, dent); |
1614 | dent->de_type = cpu_to_be16(type); | 1616 | dent->de_type = cpu_to_be16(IF2DT(nip->i_inode.i_mode)); |
1615 | if (ip->i_diskflags & GFS2_DIF_EXHASH) { | 1617 | if (ip->i_diskflags & GFS2_DIF_EXHASH) { |
1616 | leaf = (struct gfs2_leaf *)bh->b_data; | 1618 | leaf = (struct gfs2_leaf *)bh->b_data; |
1617 | be16_add_cpu(&leaf->lf_entries, 1); | 1619 | be16_add_cpu(&leaf->lf_entries, 1); |
@@ -1623,6 +1625,8 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1623 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 1625 | gfs2_trans_add_bh(ip->i_gl, bh, 1); |
1624 | ip->i_entries++; | 1626 | ip->i_entries++; |
1625 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; | 1627 | ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME; |
1628 | if (S_ISDIR(nip->i_inode.i_mode)) | ||
1629 | inc_nlink(&ip->i_inode); | ||
1626 | gfs2_dinode_out(ip, bh->b_data); | 1630 | gfs2_dinode_out(ip, bh->b_data); |
1627 | brelse(bh); | 1631 | brelse(bh); |
1628 | error = 0; | 1632 | error = 0; |
@@ -1667,8 +1671,9 @@ int gfs2_dir_add(struct inode *inode, const struct qstr *name, | |||
1667 | * Returns: 0 on success, error code on failure | 1671 | * Returns: 0 on success, error code on failure |
1668 | */ | 1672 | */ |
1669 | 1673 | ||
1670 | int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | 1674 | int gfs2_dir_del(struct gfs2_inode *dip, const struct dentry *dentry) |
1671 | { | 1675 | { |
1676 | const struct qstr *name = &dentry->d_name; | ||
1672 | struct gfs2_dirent *dent, *prev = NULL; | 1677 | struct gfs2_dirent *dent, *prev = NULL; |
1673 | struct buffer_head *bh; | 1678 | struct buffer_head *bh; |
1674 | int error; | 1679 | int error; |
@@ -1709,6 +1714,8 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name) | |||
1709 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1714 | gfs2_trans_add_bh(dip->i_gl, bh, 1); |
1710 | dip->i_entries--; | 1715 | dip->i_entries--; |
1711 | dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; | 1716 | dip->i_inode.i_mtime = dip->i_inode.i_ctime = CURRENT_TIME; |
1717 | if (S_ISDIR(dentry->d_inode->i_mode)) | ||
1718 | drop_nlink(&dip->i_inode); | ||
1712 | gfs2_dinode_out(dip, bh->b_data); | 1719 | gfs2_dinode_out(dip, bh->b_data); |
1713 | brelse(bh); | 1720 | brelse(bh); |
1714 | mark_inode_dirty(&dip->i_inode); | 1721 | mark_inode_dirty(&dip->i_inode); |
@@ -1763,94 +1770,20 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename, | |||
1763 | } | 1770 | } |
1764 | 1771 | ||
1765 | /** | 1772 | /** |
1766 | * foreach_leaf - call a function for each leaf in a directory | ||
1767 | * @dip: the directory | ||
1768 | * @lc: the function to call for each each | ||
1769 | * @data: private data to pass to it | ||
1770 | * | ||
1771 | * Returns: errno | ||
1772 | */ | ||
1773 | |||
1774 | static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | ||
1775 | { | ||
1776 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | ||
1777 | struct buffer_head *bh; | ||
1778 | struct gfs2_leaf *leaf; | ||
1779 | u32 hsize, len; | ||
1780 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | ||
1781 | u32 index = 0; | ||
1782 | __be64 *lp; | ||
1783 | u64 leaf_no; | ||
1784 | int error = 0; | ||
1785 | |||
1786 | hsize = 1 << dip->i_depth; | ||
1787 | if (hsize * sizeof(u64) != dip->i_disksize) { | ||
1788 | gfs2_consist_inode(dip); | ||
1789 | return -EIO; | ||
1790 | } | ||
1791 | |||
1792 | lp = kmalloc(sdp->sd_hash_bsize, GFP_NOFS); | ||
1793 | if (!lp) | ||
1794 | return -ENOMEM; | ||
1795 | |||
1796 | while (index < hsize) { | ||
1797 | lp_offset = index & (sdp->sd_hash_ptrs - 1); | ||
1798 | ht_offset = index - lp_offset; | ||
1799 | |||
1800 | if (ht_offset_cur != ht_offset) { | ||
1801 | error = gfs2_dir_read_data(dip, (char *)lp, | ||
1802 | ht_offset * sizeof(__be64), | ||
1803 | sdp->sd_hash_bsize, 1); | ||
1804 | if (error != sdp->sd_hash_bsize) { | ||
1805 | if (error >= 0) | ||
1806 | error = -EIO; | ||
1807 | goto out; | ||
1808 | } | ||
1809 | ht_offset_cur = ht_offset; | ||
1810 | } | ||
1811 | |||
1812 | leaf_no = be64_to_cpu(lp[lp_offset]); | ||
1813 | if (leaf_no) { | ||
1814 | error = get_leaf(dip, leaf_no, &bh); | ||
1815 | if (error) | ||
1816 | goto out; | ||
1817 | leaf = (struct gfs2_leaf *)bh->b_data; | ||
1818 | len = 1 << (dip->i_depth - be16_to_cpu(leaf->lf_depth)); | ||
1819 | brelse(bh); | ||
1820 | |||
1821 | error = lc(dip, index, len, leaf_no, data); | ||
1822 | if (error) | ||
1823 | goto out; | ||
1824 | |||
1825 | index = (index & ~(len - 1)) + len; | ||
1826 | } else | ||
1827 | index++; | ||
1828 | } | ||
1829 | |||
1830 | if (index != hsize) { | ||
1831 | gfs2_consist_inode(dip); | ||
1832 | error = -EIO; | ||
1833 | } | ||
1834 | |||
1835 | out: | ||
1836 | kfree(lp); | ||
1837 | |||
1838 | return error; | ||
1839 | } | ||
1840 | |||
1841 | /** | ||
1842 | * leaf_dealloc - Deallocate a directory leaf | 1773 | * leaf_dealloc - Deallocate a directory leaf |
1843 | * @dip: the directory | 1774 | * @dip: the directory |
1844 | * @index: the hash table offset in the directory | 1775 | * @index: the hash table offset in the directory |
1845 | * @len: the number of pointers to this leaf | 1776 | * @len: the number of pointers to this leaf |
1846 | * @leaf_no: the leaf number | 1777 | * @leaf_no: the leaf number |
1847 | * @data: not used | 1778 | * @leaf_bh: buffer_head for the starting leaf |
1779 | * last_dealloc: 1 if this is the final dealloc for the leaf, else 0 | ||
1848 | * | 1780 | * |
1849 | * Returns: errno | 1781 | * Returns: errno |
1850 | */ | 1782 | */ |
1851 | 1783 | ||
1852 | static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | 1784 | static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, |
1853 | u64 leaf_no, void *data) | 1785 | u64 leaf_no, struct buffer_head *leaf_bh, |
1786 | int last_dealloc) | ||
1854 | { | 1787 | { |
1855 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 1788 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
1856 | struct gfs2_leaf *tmp_leaf; | 1789 | struct gfs2_leaf *tmp_leaf; |
@@ -1882,14 +1815,18 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1882 | goto out_qs; | 1815 | goto out_qs; |
1883 | 1816 | ||
1884 | /* Count the number of leaves */ | 1817 | /* Count the number of leaves */ |
1818 | bh = leaf_bh; | ||
1885 | 1819 | ||
1886 | for (blk = leaf_no; blk; blk = nblk) { | 1820 | for (blk = leaf_no; blk; blk = nblk) { |
1887 | error = get_leaf(dip, blk, &bh); | 1821 | if (blk != leaf_no) { |
1888 | if (error) | 1822 | error = get_leaf(dip, blk, &bh); |
1889 | goto out_rlist; | 1823 | if (error) |
1824 | goto out_rlist; | ||
1825 | } | ||
1890 | tmp_leaf = (struct gfs2_leaf *)bh->b_data; | 1826 | tmp_leaf = (struct gfs2_leaf *)bh->b_data; |
1891 | nblk = be64_to_cpu(tmp_leaf->lf_next); | 1827 | nblk = be64_to_cpu(tmp_leaf->lf_next); |
1892 | brelse(bh); | 1828 | if (blk != leaf_no) |
1829 | brelse(bh); | ||
1893 | 1830 | ||
1894 | gfs2_rlist_add(sdp, &rlist, blk); | 1831 | gfs2_rlist_add(sdp, &rlist, blk); |
1895 | l_blocks++; | 1832 | l_blocks++; |
@@ -1913,13 +1850,18 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1913 | if (error) | 1850 | if (error) |
1914 | goto out_rg_gunlock; | 1851 | goto out_rg_gunlock; |
1915 | 1852 | ||
1853 | bh = leaf_bh; | ||
1854 | |||
1916 | for (blk = leaf_no; blk; blk = nblk) { | 1855 | for (blk = leaf_no; blk; blk = nblk) { |
1917 | error = get_leaf(dip, blk, &bh); | 1856 | if (blk != leaf_no) { |
1918 | if (error) | 1857 | error = get_leaf(dip, blk, &bh); |
1919 | goto out_end_trans; | 1858 | if (error) |
1859 | goto out_end_trans; | ||
1860 | } | ||
1920 | tmp_leaf = (struct gfs2_leaf *)bh->b_data; | 1861 | tmp_leaf = (struct gfs2_leaf *)bh->b_data; |
1921 | nblk = be64_to_cpu(tmp_leaf->lf_next); | 1862 | nblk = be64_to_cpu(tmp_leaf->lf_next); |
1922 | brelse(bh); | 1863 | if (blk != leaf_no) |
1864 | brelse(bh); | ||
1923 | 1865 | ||
1924 | gfs2_free_meta(dip, blk, 1); | 1866 | gfs2_free_meta(dip, blk, 1); |
1925 | gfs2_add_inode_blocks(&dip->i_inode, -1); | 1867 | gfs2_add_inode_blocks(&dip->i_inode, -1); |
@@ -1937,6 +1879,10 @@ static int leaf_dealloc(struct gfs2_inode *dip, u32 index, u32 len, | |||
1937 | goto out_end_trans; | 1879 | goto out_end_trans; |
1938 | 1880 | ||
1939 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); | 1881 | gfs2_trans_add_bh(dip->i_gl, dibh, 1); |
1882 | /* On the last dealloc, make this a regular file in case we crash. | ||
1883 | (We don't want to free these blocks a second time.) */ | ||
1884 | if (last_dealloc) | ||
1885 | dip->i_inode.i_mode = S_IFREG; | ||
1940 | gfs2_dinode_out(dip, dibh->b_data); | 1886 | gfs2_dinode_out(dip, dibh->b_data); |
1941 | brelse(dibh); | 1887 | brelse(dibh); |
1942 | 1888 | ||
@@ -1970,29 +1916,67 @@ int gfs2_dir_exhash_dealloc(struct gfs2_inode *dip) | |||
1970 | { | 1916 | { |
1971 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); | 1917 | struct gfs2_sbd *sdp = GFS2_SB(&dip->i_inode); |
1972 | struct buffer_head *bh; | 1918 | struct buffer_head *bh; |
1973 | int error; | 1919 | struct gfs2_leaf *leaf; |
1920 | u32 hsize, len; | ||
1921 | u32 ht_offset, lp_offset, ht_offset_cur = -1; | ||
1922 | u32 index = 0, next_index; | ||
1923 | __be64 *lp; | ||
1924 | u64 leaf_no; | ||
1925 | int error = 0, last; | ||
1974 | 1926 | ||
1975 | /* Dealloc on-disk leaves to FREEMETA state */ | 1927 | hsize = 1 << dip->i_depth; |
1976 | error = foreach_leaf(dip, leaf_dealloc, NULL); | 1928 | if (hsize * sizeof(u64) != i_size_read(&dip->i_inode)) { |
1977 | if (error) | 1929 | gfs2_consist_inode(dip); |
1978 | return error; | 1930 | return -EIO; |
1931 | } | ||
1979 | 1932 | ||
1980 | /* Make this a regular file in case we crash. | 1933 | lp = kmalloc(sdp->sd_hash_bsize, GFP_NOFS); |
1981 | (We don't want to free these blocks a second time.) */ | 1934 | if (!lp) |
1935 | return -ENOMEM; | ||
1982 | 1936 | ||
1983 | error = gfs2_trans_begin(sdp, RES_DINODE, 0); | 1937 | while (index < hsize) { |
1984 | if (error) | 1938 | lp_offset = index & (sdp->sd_hash_ptrs - 1); |
1985 | return error; | 1939 | ht_offset = index - lp_offset; |
1986 | 1940 | ||
1987 | error = gfs2_meta_inode_buffer(dip, &bh); | 1941 | if (ht_offset_cur != ht_offset) { |
1988 | if (!error) { | 1942 | error = gfs2_dir_read_data(dip, (char *)lp, |
1989 | gfs2_trans_add_bh(dip->i_gl, bh, 1); | 1943 | ht_offset * sizeof(__be64), |
1990 | ((struct gfs2_dinode *)bh->b_data)->di_mode = | 1944 | sdp->sd_hash_bsize, 1); |
1991 | cpu_to_be32(S_IFREG); | 1945 | if (error != sdp->sd_hash_bsize) { |
1992 | brelse(bh); | 1946 | if (error >= 0) |
1947 | error = -EIO; | ||
1948 | goto out; | ||
1949 | } | ||
1950 | ht_offset_cur = ht_offset; | ||
1951 | } | ||
1952 | |||
1953 | leaf_no = be64_to_cpu(lp[lp_offset]); | ||
1954 | if (leaf_no) { | ||
1955 | error = get_leaf(dip, leaf_no, &bh); | ||
1956 | if (error) | ||
1957 | goto out; | ||
1958 | leaf = (struct gfs2_leaf *)bh->b_data; | ||
1959 | len = 1 << (dip->i_depth - be16_to_cpu(leaf->lf_depth)); | ||
1960 | |||
1961 | next_index = (index & ~(len - 1)) + len; | ||
1962 | last = ((next_index >= hsize) ? 1 : 0); | ||
1963 | error = leaf_dealloc(dip, index, len, leaf_no, bh, | ||
1964 | last); | ||
1965 | brelse(bh); | ||
1966 | if (error) | ||
1967 | goto out; | ||
1968 | index = next_index; | ||
1969 | } else | ||
1970 | index++; | ||
1993 | } | 1971 | } |
1994 | 1972 | ||
1995 | gfs2_trans_end(sdp); | 1973 | if (index != hsize) { |
1974 | gfs2_consist_inode(dip); | ||
1975 | error = -EIO; | ||
1976 | } | ||
1977 | |||
1978 | out: | ||
1979 | kfree(lp); | ||
1996 | 1980 | ||
1997 | return error; | 1981 | return error; |
1998 | } | 1982 | } |