mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 16:48:26 +02:00 
			
		
		
		
	fs: factor out a __generic_write_end helper
Bits of the buffer.c based write_end implementations that don't know about buffer_heads and can be reused by other implementations. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Andreas Gruenbacher <agruenba@redhat.com> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
		
							parent
							
								
									ce397d215c
								
							
						
					
					
						commit
						a6d639da63
					
				
					 2 changed files with 37 additions and 32 deletions
				
			
		
							
								
								
									
										67
									
								
								fs/buffer.c
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								fs/buffer.c
									
									
									
									
									
								
							|  | @ -2076,6 +2076,40 @@ int block_write_begin(struct address_space *mapping, loff_t pos, unsigned len, | |||
| } | ||||
| EXPORT_SYMBOL(block_write_begin); | ||||
| 
 | ||||
| int __generic_write_end(struct inode *inode, loff_t pos, unsigned copied, | ||||
| 		struct page *page) | ||||
| { | ||||
| 	loff_t old_size = inode->i_size; | ||||
| 	bool i_size_changed = false; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * No need to use i_size_read() here, the i_size cannot change under us | ||||
| 	 * because we hold i_rwsem. | ||||
| 	 * | ||||
| 	 * But it's important to update i_size while still holding page lock: | ||||
| 	 * page writeout could otherwise come in and zero beyond i_size. | ||||
| 	 */ | ||||
| 	if (pos + copied > inode->i_size) { | ||||
| 		i_size_write(inode, pos + copied); | ||||
| 		i_size_changed = true; | ||||
| 	} | ||||
| 
 | ||||
| 	unlock_page(page); | ||||
| 	put_page(page); | ||||
| 
 | ||||
| 	if (old_size < pos) | ||||
| 		pagecache_isize_extended(inode, old_size, pos); | ||||
| 	/*
 | ||||
| 	 * Don't mark the inode dirty under page lock. First, it unnecessarily | ||||
| 	 * makes the holding time of page lock longer. Second, it forces lock | ||||
| 	 * ordering of page lock and transaction start for journaling | ||||
| 	 * filesystems. | ||||
| 	 */ | ||||
| 	if (i_size_changed) | ||||
| 		mark_inode_dirty(inode); | ||||
| 	return copied; | ||||
| } | ||||
| 
 | ||||
| int block_write_end(struct file *file, struct address_space *mapping, | ||||
| 			loff_t pos, unsigned len, unsigned copied, | ||||
| 			struct page *page, void *fsdata) | ||||
|  | @ -2116,39 +2150,8 @@ int generic_write_end(struct file *file, struct address_space *mapping, | |||
| 			loff_t pos, unsigned len, unsigned copied, | ||||
| 			struct page *page, void *fsdata) | ||||
| { | ||||
| 	struct inode *inode = mapping->host; | ||||
| 	loff_t old_size = inode->i_size; | ||||
| 	int i_size_changed = 0; | ||||
| 
 | ||||
| 	copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * No need to use i_size_read() here, the i_size | ||||
| 	 * cannot change under us because we hold i_mutex. | ||||
| 	 * | ||||
| 	 * But it's important to update i_size while still holding page lock: | ||||
| 	 * page writeout could otherwise come in and zero beyond i_size. | ||||
| 	 */ | ||||
| 	if (pos+copied > inode->i_size) { | ||||
| 		i_size_write(inode, pos+copied); | ||||
| 		i_size_changed = 1; | ||||
| 	} | ||||
| 
 | ||||
| 	unlock_page(page); | ||||
| 	put_page(page); | ||||
| 
 | ||||
| 	if (old_size < pos) | ||||
| 		pagecache_isize_extended(inode, old_size, pos); | ||||
| 	/*
 | ||||
| 	 * Don't mark the inode dirty under page lock. First, it unnecessarily | ||||
| 	 * makes the holding time of page lock longer. Second, it forces lock | ||||
| 	 * ordering of page lock and transaction start for journaling | ||||
| 	 * filesystems. | ||||
| 	 */ | ||||
| 	if (i_size_changed) | ||||
| 		mark_inode_dirty(inode); | ||||
| 
 | ||||
| 	return copied; | ||||
| 	return __generic_write_end(mapping->host, pos, copied, page); | ||||
| } | ||||
| EXPORT_SYMBOL(generic_write_end); | ||||
| 
 | ||||
|  |  | |||
|  | @ -43,6 +43,8 @@ static inline int __sync_blockdev(struct block_device *bdev, int wait) | |||
| extern void guard_bio_eod(int rw, struct bio *bio); | ||||
| extern int __block_write_begin_int(struct page *page, loff_t pos, unsigned len, | ||||
| 		get_block_t *get_block, struct iomap *iomap); | ||||
| int __generic_write_end(struct inode *inode, loff_t pos, unsigned copied, | ||||
| 		struct page *page); | ||||
| 
 | ||||
| /*
 | ||||
|  * char_dev.c | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Christoph Hellwig
						Christoph Hellwig