diff options
Diffstat (limited to 'fs/nilfs2/mdt.c')
| -rw-r--r-- | fs/nilfs2/mdt.c | 72 | 
1 files changed, 35 insertions, 37 deletions
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c index 39a5b84e2c9..c4dcd1db57e 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c @@ -58,15 +58,15 @@ nilfs_mdt_insert_new_block(struct inode *inode, unsigned long block,  	set_buffer_mapped(bh); -	kaddr = kmap_atomic(bh->b_page, KM_USER0); +	kaddr = kmap_atomic(bh->b_page);  	memset(kaddr + bh_offset(bh), 0, 1 << inode->i_blkbits);  	if (init_block)  		init_block(inode, bh, kaddr);  	flush_dcache_page(bh->b_page); -	kunmap_atomic(kaddr, KM_USER0); +	kunmap_atomic(kaddr);  	set_buffer_uptodate(bh); -	nilfs_mark_buffer_dirty(bh); +	mark_buffer_dirty(bh);  	nilfs_mdt_mark_dirty(inode);  	return 0;  } @@ -237,8 +237,6 @@ static int nilfs_mdt_read_block(struct inode *inode, unsigned long block,   *   * %-ENOENT - the specified block does not exist (hole block)   * - * %-EINVAL - bmap is broken. (the caller should call nilfs_error()) - *   * %-EROFS - Read only filesystem (for create mode)   */  int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create, @@ -273,8 +271,6 @@ int nilfs_mdt_get_block(struct inode *inode, unsigned long blkoff, int create,   * %-ENOMEM - Insufficient memory available.   *   * %-EIO - I/O error - * - * %-EINVAL - bmap is broken. (the caller should call nilfs_error())   */  int nilfs_mdt_delete_block(struct inode *inode, unsigned long block)  { @@ -350,8 +346,6 @@ int nilfs_mdt_forget_block(struct inode *inode, unsigned long block)   * %-EIO - I/O error   *   * %-ENOENT - the specified block does not exist (hole block) - * - * %-EINVAL - bmap is broken. (the caller should call nilfs_error())   */  int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block)  { @@ -361,7 +355,7 @@ int nilfs_mdt_mark_block_dirty(struct inode *inode, unsigned long block)  	err = nilfs_mdt_read_block(inode, block, 0, &bh);  	if (unlikely(err))  		return err; -	nilfs_mark_buffer_dirty(bh); +	mark_buffer_dirty(bh);  	nilfs_mdt_mark_dirty(inode);  	brelse(bh);  	return 0; @@ -381,14 +375,25 @@ int nilfs_mdt_fetch_dirty(struct inode *inode)  static int  nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)  { -	struct inode *inode; +	struct inode *inode = page->mapping->host;  	struct super_block *sb;  	int err = 0; +	if (inode && (inode->i_sb->s_flags & MS_RDONLY)) { +		/* +		 * It means that filesystem was remounted in read-only +		 * mode because of error or metadata corruption. But we +		 * have dirty pages that try to be flushed in background. +		 * So, here we simply discard this dirty page. +		 */ +		nilfs_clear_dirty_page(page, false); +		unlock_page(page); +		return -EROFS; +	} +  	redirty_page_for_writepage(wbc, page);  	unlock_page(page); -	inode = page->mapping->host;  	if (!inode)  		return 0; @@ -405,7 +410,6 @@ nilfs_mdt_write_page(struct page *page, struct writeback_control *wbc)  static const struct address_space_operations def_mdt_aops = {  	.writepage		= nilfs_mdt_write_page, -	.sync_page		= block_sync_page,  };  static const struct inode_operations def_mdt_iops; @@ -444,10 +448,6 @@ void nilfs_mdt_set_entry_size(struct inode *inode, unsigned entry_size,  	mi->mi_first_entry_offset = DIV_ROUND_UP(header_size, entry_size);  } -static const struct address_space_operations shadow_map_aops = { -	.sync_page		= block_sync_page, -}; -  /**   * nilfs_mdt_setup_shadow_map - setup shadow map and bind it to metadata file   * @inode: inode of the metadata file @@ -460,10 +460,10 @@ int nilfs_mdt_setup_shadow_map(struct inode *inode,  	struct backing_dev_info *bdi = inode->i_sb->s_bdi;  	INIT_LIST_HEAD(&shadow->frozen_buffers); -	nilfs_mapping_init_once(&shadow->frozen_data); -	nilfs_mapping_init(&shadow->frozen_data, bdi, &shadow_map_aops); -	nilfs_mapping_init_once(&shadow->frozen_btnodes); -	nilfs_mapping_init(&shadow->frozen_btnodes, bdi, &shadow_map_aops); +	address_space_init_once(&shadow->frozen_data); +	nilfs_mapping_init(&shadow->frozen_data, inode, bdi); +	address_space_init_once(&shadow->frozen_btnodes); +	nilfs_mapping_init(&shadow->frozen_btnodes, inode, bdi);  	mi->mi_shadow = shadow;  	return 0;  } @@ -499,31 +499,29 @@ int nilfs_mdt_freeze_buffer(struct inode *inode, struct buffer_head *bh)  	struct buffer_head *bh_frozen;  	struct page *page;  	int blkbits = inode->i_blkbits; -	int ret = -ENOMEM;  	page = grab_cache_page(&shadow->frozen_data, bh->b_page->index);  	if (!page) -		return ret; +		return -ENOMEM;  	if (!page_has_buffers(page))  		create_empty_buffers(page, 1 << blkbits, 0);  	bh_frozen = nilfs_page_get_nth_block(page, bh_offset(bh) >> blkbits); -	if (bh_frozen) { -		if (!buffer_uptodate(bh_frozen)) -			nilfs_copy_buffer(bh_frozen, bh); -		if (list_empty(&bh_frozen->b_assoc_buffers)) { -			list_add_tail(&bh_frozen->b_assoc_buffers, -				      &shadow->frozen_buffers); -			set_buffer_nilfs_redirected(bh); -		} else { -			brelse(bh_frozen); /* already frozen */ -		} -		ret = 0; + +	if (!buffer_uptodate(bh_frozen)) +		nilfs_copy_buffer(bh_frozen, bh); +	if (list_empty(&bh_frozen->b_assoc_buffers)) { +		list_add_tail(&bh_frozen->b_assoc_buffers, +			      &shadow->frozen_buffers); +		set_buffer_nilfs_redirected(bh); +	} else { +		brelse(bh_frozen); /* already frozen */  	} +  	unlock_page(page);  	page_cache_release(page); -	return ret; +	return 0;  }  struct buffer_head * @@ -574,10 +572,10 @@ void nilfs_mdt_restore_from_shadow_map(struct inode *inode)  	if (mi->mi_palloc_cache)  		nilfs_palloc_clear_cache(inode); -	nilfs_clear_dirty_pages(inode->i_mapping); +	nilfs_clear_dirty_pages(inode->i_mapping, true);  	nilfs_copy_back_pages(inode->i_mapping, &shadow->frozen_data); -	nilfs_clear_dirty_pages(&ii->i_btnode_cache); +	nilfs_clear_dirty_pages(&ii->i_btnode_cache, true);  	nilfs_copy_back_pages(&ii->i_btnode_cache, &shadow->frozen_btnodes);  	nilfs_bmap_restore(ii->i_bmap, &shadow->bmap_store);  | 
