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

Commit 68b4449d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pul xfs updates from Dave Chinner:
 "There's a couple of small API changes to the core DAX code which
  required small changes to the ext2 and ext4 code bases, but otherwise
  everything is within the XFS codebase.

  This update contains:

   - A new sparse on-disk inode record format to allow small extents to
     be used for inode allocation when free space is fragmented.

   - DAX support.  This includes minor changes to the DAX core code to
     fix problems with lock ordering and bufferhead mapping abuse.

   - transaction commit interface cleanup

   - removal of various unnecessary XFS specific type definitions

   - cleanup and optimisation of freelist preparation before allocation

   - various minor cleanups

   - bug fixes for
	- transaction reservation leaks
	- incorrect inode logging in unwritten extent conversion
	- mmap lock vs freeze ordering
	- remote symlink mishandling
	- attribute fork removal issues"

* tag 'xfs-for-linus-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs: (49 commits)
  xfs: don't truncate attribute extents if no extents exist
  xfs: clean up XFS_MIN_FREELIST macros
  xfs: sanitise error handling in xfs_alloc_fix_freelist
  xfs: factor out free space extent length check
  xfs: xfs_alloc_fix_freelist() can use incore perag structures
  xfs: remove xfs_caddr_t
  xfs: use void pointers in log validation helpers
  xfs: return a void pointer from xfs_buf_offset
  xfs: remove inst_t
  xfs: remove __psint_t and __psunsigned_t
  xfs: fix remote symlinks on V5/CRC filesystems
  xfs: fix xfs_log_done interface
  xfs: saner xfs_trans_commit interface
  xfs: remove the flags argument to xfs_trans_cancel
  xfs: pass a boolean flag to xfs_trans_free_items
  xfs: switch remaining xfs_trans_dup users to xfs_trans_roll
  xfs: check min blks for random debug mode sparse allocations
  xfs: fix sparse inodes 32-bit compile failure
  xfs: add initial DAX support
  xfs: add DAX IO path support
  ...
parents 043cd049 de50e16f
Loading
Loading
Loading
Loading
+6 −6
Original line number Original line Diff line number Diff line
@@ -236,10 +236,10 @@ Removed Mount Options


  Name				Removed
  Name				Removed
  ----				-------
  ----				-------
  delaylog/nodelaylog		v3.20
  delaylog/nodelaylog		v4.0
  ihashsize			v3.20
  ihashsize			v4.0
  irixsgid			v3.20
  irixsgid			v4.0
  osyncisdsync/osyncisosync	v3.20
  osyncisdsync/osyncisosync	v4.0




sysctls
sysctls
@@ -346,5 +346,5 @@ Removed Sysctls


  Name				Removed
  Name				Removed
  ----				-------
  ----				-------
  fs.xfs.xfsbufd_centisec	v3.20
  fs.xfs.xfsbufd_centisec	v4.0
  fs.xfs.age_buffer_centisecs	v3.20
  fs.xfs.age_buffer_centisecs	v4.0
+27 −7
Original line number Original line Diff line number Diff line
@@ -309,14 +309,21 @@ static int dax_insert_mapping(struct inode *inode, struct buffer_head *bh,
 out:
 out:
	i_mmap_unlock_read(mapping);
	i_mmap_unlock_read(mapping);


	if (bh->b_end_io)
		bh->b_end_io(bh, 1);

	return error;
	return error;
}
}


static int do_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
/**
			get_block_t get_block)
 * __dax_fault - handle a page fault on a DAX file
 * @vma: The virtual memory area where the fault occurred
 * @vmf: The description of the fault
 * @get_block: The filesystem method used to translate file offsets to blocks
 *
 * When a page fault occurs, filesystems may call this helper in their
 * fault handler for DAX files. __dax_fault() assumes the caller has done all
 * the necessary locking for the page fault to proceed successfully.
 */
int __dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
			get_block_t get_block, dax_iodone_t complete_unwritten)
{
{
	struct file *file = vma->vm_file;
	struct file *file = vma->vm_file;
	struct address_space *mapping = file->f_mapping;
	struct address_space *mapping = file->f_mapping;
@@ -417,7 +424,19 @@ static int do_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
		page_cache_release(page);
		page_cache_release(page);
	}
	}


	/*
	 * If we successfully insert the new mapping over an unwritten extent,
	 * we need to ensure we convert the unwritten extent. If there is an
	 * error inserting the mapping, the filesystem needs to leave it as
	 * unwritten to prevent exposure of the stale underlying data to
	 * userspace, but we still need to call the completion function so
	 * the private resources on the mapping buffer can be released. We
	 * indicate what the callback should do via the uptodate variable, same
	 * as for normal BH based IO completions.
	 */
	error = dax_insert_mapping(inode, &bh, vma, vmf);
	error = dax_insert_mapping(inode, &bh, vma, vmf);
	if (buffer_unwritten(&bh))
		complete_unwritten(&bh, !error);


 out:
 out:
	if (error == -ENOMEM)
	if (error == -ENOMEM)
@@ -434,6 +453,7 @@ static int do_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
	}
	}
	goto out;
	goto out;
}
}
EXPORT_SYMBOL(__dax_fault);


/**
/**
 * dax_fault - handle a page fault on a DAX file
 * dax_fault - handle a page fault on a DAX file
@@ -445,7 +465,7 @@ static int do_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
 * fault handler for DAX files.
 * fault handler for DAX files.
 */
 */
int dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
int dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
			get_block_t get_block)
	      get_block_t get_block, dax_iodone_t complete_unwritten)
{
{
	int result;
	int result;
	struct super_block *sb = file_inode(vma->vm_file)->i_sb;
	struct super_block *sb = file_inode(vma->vm_file)->i_sb;
@@ -454,7 +474,7 @@ int dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf,
		sb_start_pagefault(sb);
		sb_start_pagefault(sb);
		file_update_time(vma->vm_file);
		file_update_time(vma->vm_file);
	}
	}
	result = do_dax_fault(vma, vmf, get_block);
	result = __dax_fault(vma, vmf, get_block, complete_unwritten);
	if (vmf->flags & FAULT_FLAG_WRITE)
	if (vmf->flags & FAULT_FLAG_WRITE)
		sb_end_pagefault(sb);
		sb_end_pagefault(sb);


+2 −2
Original line number Original line Diff line number Diff line
@@ -28,12 +28,12 @@
#ifdef CONFIG_FS_DAX
#ifdef CONFIG_FS_DAX
static int ext2_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
static int ext2_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
{
	return dax_fault(vma, vmf, ext2_get_block);
	return dax_fault(vma, vmf, ext2_get_block, NULL);
}
}


static int ext2_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
static int ext2_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
{
{
	return dax_mkwrite(vma, vmf, ext2_get_block);
	return dax_mkwrite(vma, vmf, ext2_get_block, NULL);
}
}


static const struct vm_operations_struct ext2_dax_vm_ops = {
static const struct vm_operations_struct ext2_dax_vm_ops = {
+14 −2
Original line number Original line Diff line number Diff line
@@ -192,15 +192,27 @@ out:
}
}


#ifdef CONFIG_FS_DAX
#ifdef CONFIG_FS_DAX
static void ext4_end_io_unwritten(struct buffer_head *bh, int uptodate)
{
	struct inode *inode = bh->b_assoc_map->host;
	/* XXX: breaks on 32-bit > 16GB. Is that even supported? */
	loff_t offset = (loff_t)(uintptr_t)bh->b_private << inode->i_blkbits;
	int err;
	if (!uptodate)
		return;
	WARN_ON(!buffer_unwritten(bh));
	err = ext4_convert_unwritten_extents(NULL, inode, offset, bh->b_size);
}

static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
static int ext4_dax_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
{
	return dax_fault(vma, vmf, ext4_get_block);
	return dax_fault(vma, vmf, ext4_get_block, ext4_end_io_unwritten);
					/* Is this the right get_block? */
					/* Is this the right get_block? */
}
}


static int ext4_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
static int ext4_dax_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
{
{
	return dax_mkwrite(vma, vmf, ext4_get_block);
	return dax_mkwrite(vma, vmf, ext4_get_block, ext4_end_io_unwritten);
}
}


static const struct vm_operations_struct ext4_dax_vm_ops = {
static const struct vm_operations_struct ext4_dax_vm_ops = {
+7 −14
Original line number Original line Diff line number Diff line
@@ -656,18 +656,6 @@ has_zeroout:
	return retval;
	return retval;
}
}


static void ext4_end_io_unwritten(struct buffer_head *bh, int uptodate)
{
	struct inode *inode = bh->b_assoc_map->host;
	/* XXX: breaks on 32-bit > 16GB. Is that even supported? */
	loff_t offset = (loff_t)(uintptr_t)bh->b_private << inode->i_blkbits;
	int err;
	if (!uptodate)
		return;
	WARN_ON(!buffer_unwritten(bh));
	err = ext4_convert_unwritten_extents(NULL, inode, offset, bh->b_size);
}

/* Maximum number of blocks we map for direct IO at once. */
/* Maximum number of blocks we map for direct IO at once. */
#define DIO_MAX_BLOCKS 4096
#define DIO_MAX_BLOCKS 4096


@@ -705,10 +693,15 @@ static int _ext4_get_block(struct inode *inode, sector_t iblock,


		map_bh(bh, inode->i_sb, map.m_pblk);
		map_bh(bh, inode->i_sb, map.m_pblk);
		bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
		bh->b_state = (bh->b_state & ~EXT4_MAP_FLAGS) | map.m_flags;
		if (IS_DAX(inode) && buffer_unwritten(bh) && !io_end) {
		if (IS_DAX(inode) && buffer_unwritten(bh)) {
			/*
			 * dgc: I suspect unwritten conversion on ext4+DAX is
			 * fundamentally broken here when there are concurrent
			 * read/write in progress on this inode.
			 */
			WARN_ON_ONCE(io_end);
			bh->b_assoc_map = inode->i_mapping;
			bh->b_assoc_map = inode->i_mapping;
			bh->b_private = (void *)(unsigned long)iblock;
			bh->b_private = (void *)(unsigned long)iblock;
			bh->b_end_io = ext4_end_io_unwritten;
		}
		}
		if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN)
		if (io_end && io_end->flag & EXT4_IO_END_UNWRITTEN)
			set_buffer_defer_completion(bh);
			set_buffer_defer_completion(bh);
Loading