aboutsummaryrefslogtreecommitdiff
path: root/fs/nilfs2/mdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2/mdt.c')
-rw-r--r--fs/nilfs2/mdt.c72
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);