Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1afb678 authored by Lachlan McIlroy's avatar Lachlan McIlroy Committed by Lachlan McIlroy
Browse files

[XFS] Fixed a few bugs in xfs_buf_associate_memory()



- calculation of 'page_count' was incorrect as it did not
  consider the offset of 'mem' into the first page. The
  logic to bump 'page_count' didn't work if 'len' was <=
  PAGE_CACHE_SIZE (ie offset = 3k, len = 2k).
- setting b_buffer_length to 'len' is incorrect if 'offset'
  is > 0. Set it to the total length of the buffer.
- I suspect that passing a non-aligned address into
  mem_to_page() for the first page may have been causing
  issues - don't know but just tidy up that code anyway.

SGI-PV: 971596
SGI-Modid: xfs-linux-melb:xfs-kern:30143a

Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
Signed-off-by: default avatarChristoph Hellwig <hch@infradead.org>
parent cd57e594
Loading
Loading
Loading
Loading
+13 −20
Original line number Original line Diff line number Diff line
@@ -725,15 +725,15 @@ xfs_buf_associate_memory(
{
{
	int			rval;
	int			rval;
	int			i = 0;
	int			i = 0;
	size_t			ptr;
	unsigned long		pageaddr;
	size_t			end, end_cur;
	unsigned long		offset;
	off_t			offset;
	size_t			buflen;
	int			page_count;
	int			page_count;


	page_count = PAGE_CACHE_ALIGN(len) >> PAGE_CACHE_SHIFT;
	pageaddr = (unsigned long)mem & PAGE_CACHE_MASK;
	offset = (off_t) mem - ((off_t)mem & PAGE_CACHE_MASK);
	offset = (unsigned long)mem - pageaddr;
	if (offset && (len > PAGE_CACHE_SIZE))
	buflen = PAGE_CACHE_ALIGN(len + offset);
		page_count++;
	page_count = buflen >> PAGE_CACHE_SHIFT;


	/* Free any previous set of page pointers */
	/* Free any previous set of page pointers */
	if (bp->b_pages)
	if (bp->b_pages)
@@ -747,22 +747,15 @@ xfs_buf_associate_memory(
		return rval;
		return rval;


	bp->b_offset = offset;
	bp->b_offset = offset;
	ptr = (size_t) mem & PAGE_CACHE_MASK;

	end = PAGE_CACHE_ALIGN((size_t) mem + len);
	for (i = 0; i < bp->b_page_count; i++) {
	end_cur = end;
		bp->b_pages[i] = mem_to_page((void *)pageaddr);
	/* set up first page */
		pageaddr += PAGE_CACHE_SIZE;
	bp->b_pages[0] = mem_to_page(mem);

	ptr += PAGE_CACHE_SIZE;
	bp->b_page_count = ++i;
	while (ptr < end) {
		bp->b_pages[i] = mem_to_page((void *)ptr);
		bp->b_page_count = ++i;
		ptr += PAGE_CACHE_SIZE;
	}
	}
	bp->b_locked = 0;
	bp->b_locked = 0;


	bp->b_count_desired = bp->b_buffer_length = len;
	bp->b_count_desired = len;
	bp->b_buffer_length = buflen;
	bp->b_flags |= XBF_MAPPED;
	bp->b_flags |= XBF_MAPPED;


	return 0;
	return 0;