mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	vfs: Create __block_page_mkwrite() helper passing error values back
Create __block_page_mkwrite() helper which does all what block_page_mkwrite() does except that it passes back errors from __block_write_begin / block_commit_write calls. Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
		
							parent
							
								
									7c6e984dfc
								
							
						
					
					
						commit
						24da4fab5a
					
				
					 2 changed files with 34 additions and 17 deletions
				
			
		
							
								
								
									
										33
									
								
								fs/buffer.c
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								fs/buffer.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -2332,23 +2332,22 @@ EXPORT_SYMBOL(block_commit_write);
 | 
			
		|||
 * beyond EOF, then the page is guaranteed safe against truncation until we
 | 
			
		||||
 * unlock the page.
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
 | 
			
		||||
int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
 | 
			
		||||
			 get_block_t get_block)
 | 
			
		||||
{
 | 
			
		||||
	struct page *page = vmf->page;
 | 
			
		||||
	struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
 | 
			
		||||
	unsigned long end;
 | 
			
		||||
	loff_t size;
 | 
			
		||||
	int ret = VM_FAULT_NOPAGE; /* make the VM retry the fault */
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	lock_page(page);
 | 
			
		||||
	size = i_size_read(inode);
 | 
			
		||||
	if ((page->mapping != inode->i_mapping) ||
 | 
			
		||||
	    (page_offset(page) > size)) {
 | 
			
		||||
		/* page got truncated out from underneath us */
 | 
			
		||||
		unlock_page(page);
 | 
			
		||||
		goto out;
 | 
			
		||||
		/* We overload EFAULT to mean page got truncated */
 | 
			
		||||
		ret = -EFAULT;
 | 
			
		||||
		goto out_unlock;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* page is wholly or partially inside EOF */
 | 
			
		||||
| 
						 | 
				
			
			@ -2361,18 +2360,22 @@ block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
 | 
			
		|||
	if (!ret)
 | 
			
		||||
		ret = block_commit_write(page, 0, end);
 | 
			
		||||
 | 
			
		||||
	if (unlikely(ret)) {
 | 
			
		||||
	if (unlikely(ret < 0))
 | 
			
		||||
		goto out_unlock;
 | 
			
		||||
	return 0;
 | 
			
		||||
out_unlock:
 | 
			
		||||
	unlock_page(page);
 | 
			
		||||
		if (ret == -ENOMEM)
 | 
			
		||||
			ret = VM_FAULT_OOM;
 | 
			
		||||
		else /* -ENOSPC, -EIO, etc */
 | 
			
		||||
			ret = VM_FAULT_SIGBUS;
 | 
			
		||||
	} else
 | 
			
		||||
		ret = VM_FAULT_LOCKED;
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(__block_page_mkwrite);
 | 
			
		||||
 | 
			
		||||
int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
 | 
			
		||||
		   get_block_t get_block)
 | 
			
		||||
{
 | 
			
		||||
	int ret = __block_page_mkwrite(vma, vmf, get_block);
 | 
			
		||||
 | 
			
		||||
	return block_page_mkwrite_return(ret);
 | 
			
		||||
}
 | 
			
		||||
EXPORT_SYMBOL(block_page_mkwrite);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -217,8 +217,22 @@ int cont_write_begin(struct file *, struct address_space *, loff_t,
 | 
			
		|||
			get_block_t *, loff_t *);
 | 
			
		||||
int generic_cont_expand_simple(struct inode *inode, loff_t size);
 | 
			
		||||
int block_commit_write(struct page *page, unsigned from, unsigned to);
 | 
			
		||||
int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
 | 
			
		||||
				get_block_t get_block);
 | 
			
		||||
int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
 | 
			
		||||
				get_block_t get_block);
 | 
			
		||||
/* Convert errno to return value from ->page_mkwrite() call */
 | 
			
		||||
static inline int block_page_mkwrite_return(int err)
 | 
			
		||||
{
 | 
			
		||||
	if (err == 0)
 | 
			
		||||
		return VM_FAULT_LOCKED;
 | 
			
		||||
	if (err == -EFAULT)
 | 
			
		||||
		return VM_FAULT_NOPAGE;
 | 
			
		||||
	if (err == -ENOMEM)
 | 
			
		||||
		return VM_FAULT_OOM;
 | 
			
		||||
	/* -ENOSPC, -EDQUOT, -EIO ... */
 | 
			
		||||
	return VM_FAULT_SIGBUS;
 | 
			
		||||
}
 | 
			
		||||
sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
 | 
			
		||||
int block_truncate_page(struct address_space *, loff_t, get_block_t *);
 | 
			
		||||
int nobh_write_begin(struct address_space *, loff_t, unsigned, unsigned,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue