[PATCH] fs/ntfs3: Remove recursion in indx_insert_into_buffer

Abhinav Jain posted 1 patch 1 year, 6 months ago
fs/ntfs3/index.c | 204 ++++++++++++++++++++++++-----------------------
1 file changed, 106 insertions(+), 98 deletions(-)
[PATCH] fs/ntfs3: Remove recursion in indx_insert_into_buffer
Posted by Abhinav Jain 1 year, 6 months ago
Remove recursion by using iteration.
Decrement the level so that parent buffer can be handled in the
next iteration.
Update the header of the index buffer to point to the correct buffer.
Set new_de to up_e so that the promoted entry is inserted into the
parent buffer.

Signed-off-by: Abhinav Jain <jain.abhinav177@gmail.com>
---
 fs/ntfs3/index.c | 204 ++++++++++++++++++++++++-----------------------
 1 file changed, 106 insertions(+), 98 deletions(-)

diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c
index d0f15bbf78f6..09d5dcbfcc38 100644
--- a/fs/ntfs3/index.c
+++ b/fs/ntfs3/index.c
@@ -1802,122 +1802,130 @@ indx_insert_into_buffer(struct ntfs_index *indx, struct ntfs_inode *ni,
 	u16 sp_size;
 	void *hdr1_saved = NULL;
 
-	/* Try the most easy case. */
-	e = fnd->level - 1 == level ? fnd->de[level] : NULL;
-	e = hdr_insert_de(indx, hdr1, new_de, e, ctx);
-	fnd->de[level] = e;
-	if (e) {
-		/* Just write updated index into disk. */
-		indx_write(indx, ni, n1, 0);
-		return 0;
-	}
+	while (true) {
+		/* Try the most easy case. */
+		e = fnd->level - 1 == level ? fnd->de[level] : NULL;
+		e = hdr_insert_de(indx, hdr1, new_de, e, ctx);
+		fnd->de[level] = e;
+		if (e) {
+			/* Just write updated index into disk. */
+			indx_write(indx, ni, n1, 0);
+			return 0;
+		}
 
-	/*
-	 * No space to insert into buffer. Split it.
-	 * To split we:
-	 *  - Save split point ('cause index buffers will be changed)
-	 * - Allocate NewBuffer and copy all entries <= sp into new buffer
-	 * - Remove all entries (sp including) from TargetBuffer
-	 * - Insert NewEntry into left or right buffer (depending on sp <=>
-	 *     NewEntry)
-	 * - Insert sp into parent buffer (or root)
-	 * - Make sp a parent for new buffer
-	 */
-	sp = hdr_find_split(hdr1);
-	if (!sp)
-		return -EINVAL;
+		/*
+		 * No space to insert into buffer. Split it.
+		 * To split we:
+		 * - Save split point because index buffers will be changed
+		 * - Allocate NewBuffer and copy all entries <= sp into new
+		 *   buffer
+		 * - Remove all entries (sp including) from TargetBuffer
+		 * - Insert NewEntry into left or right buffer
+		 *   (depending on sp <=> NewEntry)
+		 * - Insert sp into parent buffer (or root)
+		 * - Make sp a parent for new buffer
+		 */
+		sp = hdr_find_split(hdr1);
+		if (!sp)
+			return -EINVAL;
 
-	sp_size = le16_to_cpu(sp->size);
-	up_e = kmalloc(sp_size + sizeof(u64), GFP_NOFS);
-	if (!up_e)
-		return -ENOMEM;
-	memcpy(up_e, sp, sp_size);
+		sp_size = le16_to_cpu(sp->size);
+		up_e = kmalloc(sp_size + sizeof(u64), GFP_NOFS);
+		if (!up_e)
+			return -ENOMEM;
+		memcpy(up_e, sp, sp_size);
 
-	used1 = le32_to_cpu(hdr1->used);
-	hdr1_saved = kmemdup(hdr1, used1, GFP_NOFS);
-	if (!hdr1_saved) {
-		err = -ENOMEM;
-		goto out;
-	}
+		used1 = le32_to_cpu(hdr1->used);
+		hdr1_saved = kmemdup(hdr1, used1, GFP_NOFS);
+		if (!hdr1_saved) {
+			err = -ENOMEM;
+			goto out;
+		}
 
-	if (!hdr1->flags) {
-		up_e->flags |= NTFS_IE_HAS_SUBNODES;
-		up_e->size = cpu_to_le16(sp_size + sizeof(u64));
-		sub_vbn = NULL;
-	} else {
-		t_vbn = de_get_vbn_le(up_e);
-		sub_vbn = &t_vbn;
-	}
+		if (!hdr1->flags) {
+			up_e->flags |= NTFS_IE_HAS_SUBNODES;
+			up_e->size = cpu_to_le16(sp_size + sizeof(u64));
+			sub_vbn = NULL;
+		} else {
+			t_vbn = de_get_vbn_le(up_e);
+			sub_vbn = &t_vbn;
+		}
 
-	/* Allocate on disk a new index allocation buffer. */
-	err = indx_add_allocate(indx, ni, &new_vbn);
-	if (err)
-		goto out;
+		/* Allocate on disk a new index allocation buffer. */
+		err = indx_add_allocate(indx, ni, &new_vbn);
+		if (err)
+			goto out;
 
-	/* Allocate and format memory a new index buffer. */
-	n2 = indx_new(indx, ni, new_vbn, sub_vbn);
-	if (IS_ERR(n2)) {
-		err = PTR_ERR(n2);
-		goto out;
-	}
+		/* Allocate and format memory a new index buffer. */
+		n2 = indx_new(indx, ni, new_vbn, sub_vbn);
+		if (IS_ERR(n2)) {
+			err = PTR_ERR(n2);
+			goto out;
+		}
 
-	hdr2 = &n2->index->ihdr;
+		hdr2 = &n2->index->ihdr;
 
-	/* Make sp a parent for new buffer. */
-	de_set_vbn(up_e, new_vbn);
+		/* Make sp a parent for new buffer. */
+		de_set_vbn(up_e, new_vbn);
 
-	/* Copy all the entries <= sp into the new buffer. */
-	de_t = hdr_first_de(hdr1);
-	to_copy = PtrOffset(de_t, sp);
-	hdr_insert_head(hdr2, de_t, to_copy);
+		/* Copy all the entries <= sp into the new buffer. */
+		de_t = hdr_first_de(hdr1);
+		to_copy = PtrOffset(de_t, sp);
+		hdr_insert_head(hdr2, de_t, to_copy);
 
-	/* Remove all entries (sp including) from hdr1. */
-	used = used1 - to_copy - sp_size;
-	memmove(de_t, Add2Ptr(sp, sp_size), used - le32_to_cpu(hdr1->de_off));
-	hdr1->used = cpu_to_le32(used);
+		/* Remove all entries (sp including) from hdr1. */
+		used = used1 - to_copy - sp_size;
+		memmove(de_t, Add2Ptr(sp, sp_size),
+				used - le32_to_cpu(hdr1->de_off));
+		hdr1->used = cpu_to_le32(used);
 
-	/*
-	 * Insert new entry into left or right buffer
-	 * (depending on sp <=> new_de).
-	 */
-	hdr_insert_de(indx,
-		      (*indx->cmp)(new_de + 1, le16_to_cpu(new_de->key_size),
-				   up_e + 1, le16_to_cpu(up_e->key_size),
-				   ctx) < 0 ?
-			      hdr2 :
-			      hdr1,
-		      new_de, NULL, ctx);
+		/*
+		 * Insert new entry into left or right buffer
+		 * (depending on sp <=> new_de).
+		 */
+		hdr_insert_de(indx,
+				(*indx->cmp)(new_de + 1,
+				le16_to_cpu(new_de->key_size),
+				up_e + 1, le16_to_cpu(up_e->key_size),
+				ctx) < 0 ? hdr2 : hdr1,
+				new_de, NULL, ctx);
 
-	indx_mark_used(indx, ni, new_vbn >> indx->idx2vbn_bits);
+		indx_mark_used(indx, ni, new_vbn >> indx->idx2vbn_bits);
 
-	indx_write(indx, ni, n1, 0);
-	indx_write(indx, ni, n2, 0);
+		indx_write(indx, ni, n1, 0);
+		indx_write(indx, ni, n2, 0);
 
-	put_indx_node(n2);
+		put_indx_node(n2);
 
-	/*
-	 * We've finished splitting everybody, so we are ready to
-	 * insert the promoted entry into the parent.
-	 */
-	if (!level) {
-		/* Insert in root. */
-		err = indx_insert_into_root(indx, ni, up_e, NULL, ctx, fnd, 0);
-	} else {
 		/*
-		 * The target buffer's parent is another index buffer.
-		 * TODO: Remove recursion.
+		 * We've finished splitting everybody, so we are ready to
+		 * insert the promoted entry into the parent.
 		 */
-		err = indx_insert_into_buffer(indx, ni, root, up_e, ctx,
-					      level - 1, fnd);
-	}
+		if (!level) {
+			/* Insert in root. */
+			err = indx_insert_into_root(indx, ni, up_e,
+					NULL, ctx, fnd, 0);
+		} else {
+			/*
+			 * The target buffer's parent is another index
+			 * buffer. Move to the parent buffer for next
+			 * iteration.
+			 */
+			n1 = fnd->nodes[--level];
+			hrd1 = &n1->index->ihdr;
+			new_de = up_e;
+			continue;
+		}
 
-	if (err) {
-		/*
-		 * Undo critical operations.
-		 */
-		indx_mark_free(indx, ni, new_vbn >> indx->idx2vbn_bits);
-		memcpy(hdr1, hdr1_saved, used1);
-		indx_write(indx, ni, n1, 0);
+		if (err) {
+			/*
+			 * Undo critical operations.
+			 */
+			indx_mark_free(indx, ni,
+					new_vbn >> indx->idx2vbn_bits);
+			memcpy(hdr1, hdr1_saved, used1);
+			indx_write(indx, ni, n1, 0);
+		}
 	}
 
 out:
-- 
2.34.1
Re: [PATCH] fs/ntfs3: Remove recursion in indx_insert_into_buffer
Posted by kernel test robot 1 year, 6 months ago
Hi Abhinav,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.10-rc3 next-20240613]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Abhinav-Jain/fs-ntfs3-Remove-recursion-in-indx_insert_into_buffer/20240616-213846
base:   linus/master
patch link:    https://lore.kernel.org/r/20240616133704.45284-1-jain.abhinav177%40gmail.com
patch subject: [PATCH] fs/ntfs3: Remove recursion in indx_insert_into_buffer
config: arm-randconfig-004-20240616 (https://download.01.org/0day-ci/archive/20240617/202406170254.2fKFAwWr-lkp@intel.com/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 78ee473784e5ef6f0b19ce4cb111fb6e4d23c6b2)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240617/202406170254.2fKFAwWr-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202406170254.2fKFAwWr-lkp@intel.com/

All errors (new ones prefixed by >>):

   In file included from fs/ntfs3/index.c:8:
   In file included from include/linux/blkdev.h:9:
   In file included from include/linux/blk_types.h:10:
   In file included from include/linux/bvec.h:10:
   In file included from include/linux/highmem.h:8:
   In file included from include/linux/cacheflush.h:5:
   In file included from arch/arm/include/asm/cacheflush.h:10:
   In file included from include/linux/mm.h:2253:
   include/linux/vmstat.h:514:36: warning: arithmetic between different enumeration types ('enum node_stat_item' and 'enum lru_list') [-Wenum-enum-conversion]
     514 |         return node_stat_name(NR_LRU_BASE + lru) + 3; // skip "nr_"
         |                               ~~~~~~~~~~~ ^ ~~~
>> fs/ntfs3/index.c:1915:4: error: use of undeclared identifier 'hrd1'
    1915 |                         hrd1 = &n1->index->ihdr;
         |                         ^
   1 warning and 1 error generated.


vim +/hrd1 +1915 fs/ntfs3/index.c

  1780	
  1781	/*
  1782	 * indx_insert_into_buffer
  1783	 *
  1784	 * Attempt to insert an entry into an Index Allocation Buffer.
  1785	 * If necessary, it will split the buffer.
  1786	 */
  1787	static int
  1788	indx_insert_into_buffer(struct ntfs_index *indx, struct ntfs_inode *ni,
  1789				struct INDEX_ROOT *root, const struct NTFS_DE *new_de,
  1790				const void *ctx, int level, struct ntfs_fnd *fnd)
  1791	{
  1792		int err;
  1793		const struct NTFS_DE *sp;
  1794		struct NTFS_DE *e, *de_t, *up_e;
  1795		struct indx_node *n2;
  1796		struct indx_node *n1 = fnd->nodes[level];
  1797		struct INDEX_HDR *hdr1 = &n1->index->ihdr;
  1798		struct INDEX_HDR *hdr2;
  1799		u32 to_copy, used, used1;
  1800		CLST new_vbn;
  1801		__le64 t_vbn, *sub_vbn;
  1802		u16 sp_size;
  1803		void *hdr1_saved = NULL;
  1804	
  1805		while (true) {
  1806			/* Try the most easy case. */
  1807			e = fnd->level - 1 == level ? fnd->de[level] : NULL;
  1808			e = hdr_insert_de(indx, hdr1, new_de, e, ctx);
  1809			fnd->de[level] = e;
  1810			if (e) {
  1811				/* Just write updated index into disk. */
  1812				indx_write(indx, ni, n1, 0);
  1813				return 0;
  1814			}
  1815	
  1816			/*
  1817			 * No space to insert into buffer. Split it.
  1818			 * To split we:
  1819			 * - Save split point because index buffers will be changed
  1820			 * - Allocate NewBuffer and copy all entries <= sp into new
  1821			 *   buffer
  1822			 * - Remove all entries (sp including) from TargetBuffer
  1823			 * - Insert NewEntry into left or right buffer
  1824			 *   (depending on sp <=> NewEntry)
  1825			 * - Insert sp into parent buffer (or root)
  1826			 * - Make sp a parent for new buffer
  1827			 */
  1828			sp = hdr_find_split(hdr1);
  1829			if (!sp)
  1830				return -EINVAL;
  1831	
  1832			sp_size = le16_to_cpu(sp->size);
  1833			up_e = kmalloc(sp_size + sizeof(u64), GFP_NOFS);
  1834			if (!up_e)
  1835				return -ENOMEM;
  1836			memcpy(up_e, sp, sp_size);
  1837	
  1838			used1 = le32_to_cpu(hdr1->used);
  1839			hdr1_saved = kmemdup(hdr1, used1, GFP_NOFS);
  1840			if (!hdr1_saved) {
  1841				err = -ENOMEM;
  1842				goto out;
  1843			}
  1844	
  1845			if (!hdr1->flags) {
  1846				up_e->flags |= NTFS_IE_HAS_SUBNODES;
  1847				up_e->size = cpu_to_le16(sp_size + sizeof(u64));
  1848				sub_vbn = NULL;
  1849			} else {
  1850				t_vbn = de_get_vbn_le(up_e);
  1851				sub_vbn = &t_vbn;
  1852			}
  1853	
  1854			/* Allocate on disk a new index allocation buffer. */
  1855			err = indx_add_allocate(indx, ni, &new_vbn);
  1856			if (err)
  1857				goto out;
  1858	
  1859			/* Allocate and format memory a new index buffer. */
  1860			n2 = indx_new(indx, ni, new_vbn, sub_vbn);
  1861			if (IS_ERR(n2)) {
  1862				err = PTR_ERR(n2);
  1863				goto out;
  1864			}
  1865	
  1866			hdr2 = &n2->index->ihdr;
  1867	
  1868			/* Make sp a parent for new buffer. */
  1869			de_set_vbn(up_e, new_vbn);
  1870	
  1871			/* Copy all the entries <= sp into the new buffer. */
  1872			de_t = hdr_first_de(hdr1);
  1873			to_copy = PtrOffset(de_t, sp);
  1874			hdr_insert_head(hdr2, de_t, to_copy);
  1875	
  1876			/* Remove all entries (sp including) from hdr1. */
  1877			used = used1 - to_copy - sp_size;
  1878			memmove(de_t, Add2Ptr(sp, sp_size),
  1879					used - le32_to_cpu(hdr1->de_off));
  1880			hdr1->used = cpu_to_le32(used);
  1881	
  1882			/*
  1883			 * Insert new entry into left or right buffer
  1884			 * (depending on sp <=> new_de).
  1885			 */
  1886			hdr_insert_de(indx,
  1887					(*indx->cmp)(new_de + 1,
  1888					le16_to_cpu(new_de->key_size),
  1889					up_e + 1, le16_to_cpu(up_e->key_size),
  1890					ctx) < 0 ? hdr2 : hdr1,
  1891					new_de, NULL, ctx);
  1892	
  1893			indx_mark_used(indx, ni, new_vbn >> indx->idx2vbn_bits);
  1894	
  1895			indx_write(indx, ni, n1, 0);
  1896			indx_write(indx, ni, n2, 0);
  1897	
  1898			put_indx_node(n2);
  1899	
  1900			/*
  1901			 * We've finished splitting everybody, so we are ready to
  1902			 * insert the promoted entry into the parent.
  1903			 */
  1904			if (!level) {
  1905				/* Insert in root. */
  1906				err = indx_insert_into_root(indx, ni, up_e,
  1907						NULL, ctx, fnd, 0);
  1908			} else {
  1909				/*
  1910				 * The target buffer's parent is another index
  1911				 * buffer. Move to the parent buffer for next
  1912				 * iteration.
  1913				 */
  1914				n1 = fnd->nodes[--level];
> 1915				hrd1 = &n1->index->ihdr;
  1916				new_de = up_e;
  1917				continue;
  1918			}
  1919	
  1920			if (err) {
  1921				/*
  1922				 * Undo critical operations.
  1923				 */
  1924				indx_mark_free(indx, ni,
  1925						new_vbn >> indx->idx2vbn_bits);
  1926				memcpy(hdr1, hdr1_saved, used1);
  1927				indx_write(indx, ni, n1, 0);
  1928			}
  1929		}
  1930	
  1931	out:
  1932		kfree(up_e);
  1933		kfree(hdr1_saved);
  1934	
  1935		return err;
  1936	}
  1937	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] fs/ntfs3: Remove recursion in indx_insert_into_buffer
Posted by kernel test robot 1 year, 6 months ago
Hi Abhinav,

kernel test robot noticed the following build errors:

[auto build test ERROR on linus/master]
[also build test ERROR on v6.10-rc3 next-20240613]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Abhinav-Jain/fs-ntfs3-Remove-recursion-in-indx_insert_into_buffer/20240616-213846
base:   linus/master
patch link:    https://lore.kernel.org/r/20240616133704.45284-1-jain.abhinav177%40gmail.com
patch subject: [PATCH] fs/ntfs3: Remove recursion in indx_insert_into_buffer
config: arc-randconfig-001-20240616 (https://download.01.org/0day-ci/archive/20240617/202406170138.l8RDg80M-lkp@intel.com/config)
compiler: arc-elf-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240617/202406170138.l8RDg80M-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202406170138.l8RDg80M-lkp@intel.com/

All errors (new ones prefixed by >>):

   fs/ntfs3/index.c: In function 'indx_insert_into_buffer':
>> fs/ntfs3/index.c:1915:25: error: 'hrd1' undeclared (first use in this function); did you mean 'hdr1'?
    1915 |                         hrd1 = &n1->index->ihdr;
         |                         ^~~~
         |                         hdr1
   fs/ntfs3/index.c:1915:25: note: each undeclared identifier is reported only once for each function it appears in

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for REGMAP_SPI
   Depends on [n]: SPI [=n]
   Selected by [y]:
   - AD9739A [=y] && IIO [=y] && (SPI [=n] || COMPILE_TEST [=y])


vim +1915 fs/ntfs3/index.c

  1780	
  1781	/*
  1782	 * indx_insert_into_buffer
  1783	 *
  1784	 * Attempt to insert an entry into an Index Allocation Buffer.
  1785	 * If necessary, it will split the buffer.
  1786	 */
  1787	static int
  1788	indx_insert_into_buffer(struct ntfs_index *indx, struct ntfs_inode *ni,
  1789				struct INDEX_ROOT *root, const struct NTFS_DE *new_de,
  1790				const void *ctx, int level, struct ntfs_fnd *fnd)
  1791	{
  1792		int err;
  1793		const struct NTFS_DE *sp;
  1794		struct NTFS_DE *e, *de_t, *up_e;
  1795		struct indx_node *n2;
  1796		struct indx_node *n1 = fnd->nodes[level];
  1797		struct INDEX_HDR *hdr1 = &n1->index->ihdr;
  1798		struct INDEX_HDR *hdr2;
  1799		u32 to_copy, used, used1;
  1800		CLST new_vbn;
  1801		__le64 t_vbn, *sub_vbn;
  1802		u16 sp_size;
  1803		void *hdr1_saved = NULL;
  1804	
  1805		while (true) {
  1806			/* Try the most easy case. */
  1807			e = fnd->level - 1 == level ? fnd->de[level] : NULL;
  1808			e = hdr_insert_de(indx, hdr1, new_de, e, ctx);
  1809			fnd->de[level] = e;
  1810			if (e) {
  1811				/* Just write updated index into disk. */
  1812				indx_write(indx, ni, n1, 0);
  1813				return 0;
  1814			}
  1815	
  1816			/*
  1817			 * No space to insert into buffer. Split it.
  1818			 * To split we:
  1819			 * - Save split point because index buffers will be changed
  1820			 * - Allocate NewBuffer and copy all entries <= sp into new
  1821			 *   buffer
  1822			 * - Remove all entries (sp including) from TargetBuffer
  1823			 * - Insert NewEntry into left or right buffer
  1824			 *   (depending on sp <=> NewEntry)
  1825			 * - Insert sp into parent buffer (or root)
  1826			 * - Make sp a parent for new buffer
  1827			 */
  1828			sp = hdr_find_split(hdr1);
  1829			if (!sp)
  1830				return -EINVAL;
  1831	
  1832			sp_size = le16_to_cpu(sp->size);
  1833			up_e = kmalloc(sp_size + sizeof(u64), GFP_NOFS);
  1834			if (!up_e)
  1835				return -ENOMEM;
  1836			memcpy(up_e, sp, sp_size);
  1837	
  1838			used1 = le32_to_cpu(hdr1->used);
  1839			hdr1_saved = kmemdup(hdr1, used1, GFP_NOFS);
  1840			if (!hdr1_saved) {
  1841				err = -ENOMEM;
  1842				goto out;
  1843			}
  1844	
  1845			if (!hdr1->flags) {
  1846				up_e->flags |= NTFS_IE_HAS_SUBNODES;
  1847				up_e->size = cpu_to_le16(sp_size + sizeof(u64));
  1848				sub_vbn = NULL;
  1849			} else {
  1850				t_vbn = de_get_vbn_le(up_e);
  1851				sub_vbn = &t_vbn;
  1852			}
  1853	
  1854			/* Allocate on disk a new index allocation buffer. */
  1855			err = indx_add_allocate(indx, ni, &new_vbn);
  1856			if (err)
  1857				goto out;
  1858	
  1859			/* Allocate and format memory a new index buffer. */
  1860			n2 = indx_new(indx, ni, new_vbn, sub_vbn);
  1861			if (IS_ERR(n2)) {
  1862				err = PTR_ERR(n2);
  1863				goto out;
  1864			}
  1865	
  1866			hdr2 = &n2->index->ihdr;
  1867	
  1868			/* Make sp a parent for new buffer. */
  1869			de_set_vbn(up_e, new_vbn);
  1870	
  1871			/* Copy all the entries <= sp into the new buffer. */
  1872			de_t = hdr_first_de(hdr1);
  1873			to_copy = PtrOffset(de_t, sp);
  1874			hdr_insert_head(hdr2, de_t, to_copy);
  1875	
  1876			/* Remove all entries (sp including) from hdr1. */
  1877			used = used1 - to_copy - sp_size;
  1878			memmove(de_t, Add2Ptr(sp, sp_size),
  1879					used - le32_to_cpu(hdr1->de_off));
  1880			hdr1->used = cpu_to_le32(used);
  1881	
  1882			/*
  1883			 * Insert new entry into left or right buffer
  1884			 * (depending on sp <=> new_de).
  1885			 */
  1886			hdr_insert_de(indx,
  1887					(*indx->cmp)(new_de + 1,
  1888					le16_to_cpu(new_de->key_size),
  1889					up_e + 1, le16_to_cpu(up_e->key_size),
  1890					ctx) < 0 ? hdr2 : hdr1,
  1891					new_de, NULL, ctx);
  1892	
  1893			indx_mark_used(indx, ni, new_vbn >> indx->idx2vbn_bits);
  1894	
  1895			indx_write(indx, ni, n1, 0);
  1896			indx_write(indx, ni, n2, 0);
  1897	
  1898			put_indx_node(n2);
  1899	
  1900			/*
  1901			 * We've finished splitting everybody, so we are ready to
  1902			 * insert the promoted entry into the parent.
  1903			 */
  1904			if (!level) {
  1905				/* Insert in root. */
  1906				err = indx_insert_into_root(indx, ni, up_e,
  1907						NULL, ctx, fnd, 0);
  1908			} else {
  1909				/*
  1910				 * The target buffer's parent is another index
  1911				 * buffer. Move to the parent buffer for next
  1912				 * iteration.
  1913				 */
  1914				n1 = fnd->nodes[--level];
> 1915				hrd1 = &n1->index->ihdr;
  1916				new_de = up_e;
  1917				continue;
  1918			}
  1919	
  1920			if (err) {
  1921				/*
  1922				 * Undo critical operations.
  1923				 */
  1924				indx_mark_free(indx, ni,
  1925						new_vbn >> indx->idx2vbn_bits);
  1926				memcpy(hdr1, hdr1_saved, used1);
  1927				indx_write(indx, ni, n1, 0);
  1928			}
  1929		}
  1930	
  1931	out:
  1932		kfree(up_e);
  1933		kfree(hdr1_saved);
  1934	
  1935		return err;
  1936	}
  1937	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki