aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2019-08-29 12:04:07 -0400
committerDarrick J. Wong <darrick.wong@oracle.com>2019-08-31 01:43:57 -0400
commit0e822255f95db400e56e19773e04755d79b50bda (patch)
tree4bf283a5959b9ce864a25d9725ca8fc7593a13e5
parenta07258a695281109422011182db069a0e6f8855e (diff)
xfs: factor free block index lookup from xfs_dir2_node_addname_int()
Simplify the logic in xfs_dir2_node_addname_int() by factoring out the free block index lookup code that finds a block with enough free space for the entry to be added. The code that is moved gets a major cleanup at the same time, but there is no algorithm change here. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
-rw-r--r--fs/xfs/libxfs/xfs_dir2_node.c194
1 files changed, 102 insertions, 92 deletions
diff --git a/fs/xfs/libxfs/xfs_dir2_node.c b/fs/xfs/libxfs/xfs_dir2_node.c
index cc1f1c505a2b..93254f45a5f9 100644
--- a/fs/xfs/libxfs/xfs_dir2_node.c
+++ b/fs/xfs/libxfs/xfs_dir2_node.c
@@ -1635,7 +1635,7 @@ xfs_dir2_node_add_datablk(
1635 int error; 1635 int error;
1636 1636
1637 /* Not allowed to allocate, return failure. */ 1637 /* Not allowed to allocate, return failure. */
1638 if ((args->op_flags & XFS_DA_OP_JUSTCHECK) || args->total == 0) 1638 if (args->total == 0)
1639 return -ENOSPC; 1639 return -ENOSPC;
1640 1640
1641 /* Allocate and initialize the new data block. */ 1641 /* Allocate and initialize the new data block. */
@@ -1731,43 +1731,29 @@ xfs_dir2_node_add_datablk(
1731 return 0; 1731 return 0;
1732} 1732}
1733 1733
1734/* 1734static int
1735 * Add the data entry for a node-format directory name addition. 1735xfs_dir2_node_find_freeblk(
1736 * The leaf entry is added in xfs_dir2_leafn_add. 1736 struct xfs_da_args *args,
1737 * We may enter with a freespace block that the lookup found. 1737 struct xfs_da_state_blk *fblk,
1738 */ 1738 xfs_dir2_db_t *dbnop,
1739static int /* error */ 1739 struct xfs_buf **fbpp,
1740xfs_dir2_node_addname_int( 1740 int *findexp,
1741 xfs_da_args_t *args, /* operation arguments */ 1741 int length)
1742 xfs_da_state_blk_t *fblk) /* optional freespace block */
1743{ 1742{
1744 xfs_dir2_data_hdr_t *hdr; /* data block header */
1745 xfs_dir2_db_t dbno; /* data block number */
1746 struct xfs_buf *dbp; /* data block buffer */
1747 xfs_dir2_data_entry_t *dep; /* data entry pointer */
1748 xfs_inode_t *dp; /* incore directory inode */
1749 xfs_dir2_data_unused_t *dup; /* data unused entry pointer */
1750 int error; /* error return value */
1751 xfs_dir2_db_t fbno; /* freespace block number */
1752 struct xfs_buf *fbp; /* freespace buffer */
1753 int findex; /* freespace entry index */
1754 xfs_dir2_free_t *free=NULL; /* freespace block structure */
1755 xfs_dir2_db_t ifbno; /* initial freespace block no */
1756 xfs_dir2_db_t lastfbno=0; /* highest freespace block no */
1757 int length; /* length of the new entry */
1758 int logfree = 0; /* need to log free entry */
1759 int needlog = 0; /* need to log data header */
1760 int needscan = 0; /* need to rescan data frees */
1761 __be16 *tagp; /* data entry tag pointer */
1762 xfs_trans_t *tp; /* transaction pointer */
1763 __be16 *bests;
1764 struct xfs_dir3_icfree_hdr freehdr; 1743 struct xfs_dir3_icfree_hdr freehdr;
1765 struct xfs_dir2_data_free *bf; 1744 struct xfs_dir2_free *free = NULL;
1766 xfs_dir2_data_aoff_t aoff; 1745 struct xfs_inode *dp = args->dp;
1746 struct xfs_trans *tp = args->trans;
1747 struct xfs_buf *fbp = NULL;
1748 xfs_dir2_db_t lastfbno;
1749 xfs_dir2_db_t ifbno = -1;
1750 xfs_dir2_db_t dbno = -1;
1751 xfs_dir2_db_t fbno = -1;
1752 xfs_fileoff_t fo;
1753 __be16 *bests;
1754 int findex;
1755 int error;
1767 1756
1768 dp = args->dp;
1769 tp = args->trans;
1770 length = dp->d_ops->data_entsize(args->namelen);
1771 /* 1757 /*
1772 * If we came in with a freespace block that means that lookup 1758 * If we came in with a freespace block that means that lookup
1773 * found an entry with our hash value. This is the freespace 1759 * found an entry with our hash value. This is the freespace
@@ -1775,56 +1761,44 @@ xfs_dir2_node_addname_int(
1775 */ 1761 */
1776 if (fblk) { 1762 if (fblk) {
1777 fbp = fblk->bp; 1763 fbp = fblk->bp;
1778 /*
1779 * Remember initial freespace block number.
1780 */
1781 ifbno = fblk->blkno;
1782 free = fbp->b_addr; 1764 free = fbp->b_addr;
1783 findex = fblk->index; 1765 findex = fblk->index;
1784 bests = dp->d_ops->free_bests_p(free);
1785 dp->d_ops->free_hdr_from_disk(&freehdr, free);
1786
1787 /*
1788 * This means the free entry showed that the data block had
1789 * space for our entry, so we remembered it.
1790 * Use that data block.
1791 */
1792 if (findex >= 0) { 1766 if (findex >= 0) {
1767 /* caller already found the freespace for us. */
1768 bests = dp->d_ops->free_bests_p(free);
1769 dp->d_ops->free_hdr_from_disk(&freehdr, free);
1770
1793 ASSERT(findex < freehdr.nvalid); 1771 ASSERT(findex < freehdr.nvalid);
1794 ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF); 1772 ASSERT(be16_to_cpu(bests[findex]) != NULLDATAOFF);
1795 ASSERT(be16_to_cpu(bests[findex]) >= length); 1773 ASSERT(be16_to_cpu(bests[findex]) >= length);
1796 dbno = freehdr.firstdb + findex; 1774 dbno = freehdr.firstdb + findex;
1797 goto found_block; 1775 goto found_block;
1798 } else {
1799 /*
1800 * The data block looked at didn't have enough room.
1801 * We'll start at the beginning of the freespace entries.
1802 */
1803 dbno = -1;
1804 findex = 0;
1805 } 1776 }
1806 } else { 1777
1807 /* 1778 /*
1808 * Didn't come in with a freespace block, so no data block. 1779 * The data block looked at didn't have enough room.
1780 * We'll start at the beginning of the freespace entries.
1809 */ 1781 */
1810 ifbno = dbno = -1; 1782 ifbno = fblk->blkno;
1811 fbp = NULL; 1783 fbno = ifbno;
1812 findex = 0;
1813 } 1784 }
1785 ASSERT(dbno == -1);
1786 findex = 0;
1814 1787
1815 /* 1788 /*
1816 * If we don't have a data block yet, we're going to scan the 1789 * If we don't have a data block yet, we're going to scan the freespace
1817 * freespace blocks looking for one. Figure out what the 1790 * blocks looking for one. Figure out what the highest freespace block
1818 * highest freespace block number is. 1791 * number is.
1819 */ 1792 */
1820 if (dbno == -1) { 1793 error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK);
1821 xfs_fileoff_t fo; /* freespace block number */ 1794 if (error)
1795 return error;
1796 lastfbno = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo);
1797
1798 /* If we haven't get a search start block, set it now */
1799 if (fbno == -1)
1800 fbno = xfs_dir2_byte_to_db(args->geo, XFS_DIR2_FREE_OFFSET);
1822 1801
1823 if ((error = xfs_bmap_last_offset(dp, &fo, XFS_DATA_FORK)))
1824 return error;
1825 lastfbno = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)fo);
1826 fbno = ifbno;
1827 }
1828 /* 1802 /*
1829 * While we haven't identified a data block, search the freeblock 1803 * While we haven't identified a data block, search the freeblock
1830 * data for a good data block. If we find a null freeblock entry, 1804 * data for a good data block. If we find a null freeblock entry,
@@ -1836,16 +1810,9 @@ xfs_dir2_node_addname_int(
1836 */ 1810 */
1837 if (fbp == NULL) { 1811 if (fbp == NULL) {
1838 /* 1812 /*
1839 * Happens the first time through unless lookup gave
1840 * us a freespace block to start with.
1841 */
1842 if (++fbno == 0)
1843 fbno = xfs_dir2_byte_to_db(args->geo,
1844 XFS_DIR2_FREE_OFFSET);
1845 /*
1846 * If it's ifbno we already looked at it. 1813 * If it's ifbno we already looked at it.
1847 */ 1814 */
1848 if (fbno == ifbno) 1815 if (++fbno == ifbno)
1849 fbno++; 1816 fbno++;
1850 /* 1817 /*
1851 * If it's off the end we're done. 1818 * If it's off the end we're done.
@@ -1896,35 +1863,77 @@ xfs_dir2_node_addname_int(
1896 } 1863 }
1897 } 1864 }
1898 } 1865 }
1866found_block:
1867 *dbnop = dbno;
1868 *fbpp = fbp;
1869 *findexp = findex;
1870 return 0;
1871}
1872
1873
1874/*
1875 * Add the data entry for a node-format directory name addition.
1876 * The leaf entry is added in xfs_dir2_leafn_add.
1877 * We may enter with a freespace block that the lookup found.
1878 */
1879static int
1880xfs_dir2_node_addname_int(
1881 struct xfs_da_args *args, /* operation arguments */
1882 struct xfs_da_state_blk *fblk) /* optional freespace block */
1883{
1884 struct xfs_dir2_data_unused *dup; /* data unused entry pointer */
1885 struct xfs_dir2_data_entry *dep; /* data entry pointer */
1886 struct xfs_dir2_data_hdr *hdr; /* data block header */
1887 struct xfs_dir2_data_free *bf;
1888 struct xfs_dir2_free *free = NULL; /* freespace block structure */
1889 struct xfs_trans *tp = args->trans;
1890 struct xfs_inode *dp = args->dp;
1891 struct xfs_buf *dbp; /* data block buffer */
1892 struct xfs_buf *fbp; /* freespace buffer */
1893 xfs_dir2_data_aoff_t aoff;
1894 xfs_dir2_db_t dbno; /* data block number */
1895 int error; /* error return value */
1896 int findex; /* freespace entry index */
1897 int length; /* length of the new entry */
1898 int logfree = 0; /* need to log free entry */
1899 int needlog = 0; /* need to log data header */
1900 int needscan = 0; /* need to rescan data frees */
1901 __be16 *tagp; /* data entry tag pointer */
1902 __be16 *bests;
1903
1904 length = dp->d_ops->data_entsize(args->namelen);
1905 error = xfs_dir2_node_find_freeblk(args, fblk, &dbno, &fbp, &findex,
1906 length);
1907 if (error)
1908 return error;
1909
1910 /*
1911 * Now we know if we must allocate blocks, so if we are checking whether
1912 * we can insert without allocation then we can return now.
1913 */
1914 if (args->op_flags & XFS_DA_OP_JUSTCHECK) {
1915 if (dbno == -1)
1916 return -ENOSPC;
1917 return 0;
1918 }
1899 1919
1900 /* 1920 /*
1901 * If we don't have a data block, we need to allocate one and make 1921 * If we don't have a data block, we need to allocate one and make
1902 * the freespace entries refer to it. 1922 * the freespace entries refer to it.
1903 */ 1923 */
1904 if (dbno == -1) { 1924 if (dbno == -1) {
1905 error = xfs_dir2_node_add_datablk(args, fblk, &dbno, &dbp, &fbp,
1906 &findex);
1907 if (error)
1908 return error;
1909
1910 /* setup current free block buffer */
1911 free = fbp->b_addr;
1912
1913 /* we're going to have to log the free block index later */ 1925 /* we're going to have to log the free block index later */
1914 logfree = 1; 1926 logfree = 1;
1927 error = xfs_dir2_node_add_datablk(args, fblk, &dbno, &dbp, &fbp,
1928 &findex);
1915 } else { 1929 } else {
1916found_block:
1917 /* If just checking, we succeeded. */
1918 if (args->op_flags & XFS_DA_OP_JUSTCHECK)
1919 return 0;
1920
1921 /* Read the data block in. */ 1930 /* Read the data block in. */
1922 error = xfs_dir3_data_read(tp, dp, 1931 error = xfs_dir3_data_read(tp, dp,
1923 xfs_dir2_db_to_da(args->geo, dbno), 1932 xfs_dir2_db_to_da(args->geo, dbno),
1924 -1, &dbp); 1933 -1, &dbp);
1925 if (error)
1926 return error;
1927 } 1934 }
1935 if (error)
1936 return error;
1928 1937
1929 /* setup for data block up now */ 1938 /* setup for data block up now */
1930 hdr = dbp->b_addr; 1939 hdr = dbp->b_addr;
@@ -1961,6 +1970,7 @@ found_block:
1961 xfs_dir2_data_log_header(args, dbp); 1970 xfs_dir2_data_log_header(args, dbp);
1962 1971
1963 /* If the freespace block entry is now wrong, update it. */ 1972 /* If the freespace block entry is now wrong, update it. */
1973 free = fbp->b_addr;
1964 bests = dp->d_ops->free_bests_p(free); 1974 bests = dp->d_ops->free_bests_p(free);
1965 if (bests[findex] != bf[0].length) { 1975 if (bests[findex] != bf[0].length) {
1966 bests[findex] = bf[0].length; 1976 bests[findex] = bf[0].length;