#include <linux/buffer_head.h>
#include <linux/mpage.h>
#include <linux/writeback.h>
+#include <linux/uio.h>
#include "nilfs.h"
#include "segment.h"
#include "page.h"
map_bh(bh_result, inode->i_sb, blknum);
goto out;
}
- if (unlikely(ret == 1)) {
- printk(KERN_ERR "nilfs_get_block: bmap_lookup returns "
- "buffer_head pointer (blkoff=%llu, blknum=%lu)\n",
- (unsigned long long)blkoff, blknum);
- BUG();
- }
/* data block was not found */
if (ret == -ENOENT && create) {
struct nilfs_transaction_info ti;
goto out;
err = nilfs_bmap_insert(ii->i_bmap, (unsigned long)blkoff,
(unsigned long)bh_result);
- nilfs_transaction_end(inode->i_sb, !err);
if (unlikely(err != 0)) {
if (err == -EEXIST) {
/*
* However, the page having this block must
* be locked in this case.
*/
- printk(KERN_ERR
+ printk(KERN_WARNING
"nilfs_get_block: a race condition "
"while inserting a data block. "
"(inode number=%lu, file block "
"offset=%llu)\n",
inode->i_ino,
(unsigned long long)blkoff);
- BUG();
+ err = 0;
} else if (err == -EINVAL) {
nilfs_error(inode->i_sb, __func__,
"broken bmap (inode=%lu)\n",
inode->i_ino);
err = -EIO;
}
+ nilfs_transaction_abort(inode->i_sb);
goto out;
}
+ nilfs_transaction_commit(inode->i_sb); /* never fails */
/* Error handling should be detailed */
set_buffer_new(bh_result);
map_bh(bh_result, inode->i_sb, 0); /* dbn must be changed
static int nilfs_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{
- /* This empty method is required not to call generic_writepages() */
- return 0;
+ struct inode *inode = mapping->host;
+ int err = 0;
+
+ if (wbc->sync_mode == WB_SYNC_ALL)
+ err = nilfs_construct_dsync_segment(inode->i_sb, inode,
+ wbc->range_start,
+ wbc->range_end);
+ return err;
}
static int nilfs_writepage(struct page *page, struct writeback_control *wbc)
err = block_write_begin(file, mapping, pos, len, flags, pagep,
fsdata, nilfs_get_block);
if (unlikely(err))
- nilfs_transaction_end(inode->i_sb, 0);
+ nilfs_transaction_abort(inode->i_sb);
return err;
}
copied = generic_write_end(file, mapping, pos, len, copied, page,
fsdata);
nilfs_set_file_dirty(NILFS_SB(inode->i_sb), inode, nr_dirty);
- err = nilfs_transaction_end(inode->i_sb, 1);
+ err = nilfs_transaction_commit(inode->i_sb);
return err ? : copied;
}
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_mapping->host;
ssize_t size;
- int err;
-
- err = nilfs_construct_dsync_segment(inode->i_sb, inode);
- if (unlikely(err))
- return err;
if (rw == WRITE)
return 0;
return 0;
}
-static int nilfs_read_sketch_inode(struct inode *inode)
-{
- struct nilfs_sb_info *sbi = NILFS_SB(inode->i_sb);
- int err = 0;
-
- if (sbi->s_snapshot_cno) {
- struct the_nilfs *nilfs = sbi->s_nilfs;
- struct buffer_head *bh_cp;
- struct nilfs_checkpoint *raw_cp;
-
- err = nilfs_cpfile_get_checkpoint(
- nilfs->ns_cpfile, sbi->s_snapshot_cno, 0, &raw_cp,
- &bh_cp);
- if (likely(!err)) {
- if (!nilfs_checkpoint_sketch(raw_cp))
- inode->i_size = 0;
- nilfs_cpfile_put_checkpoint(
- nilfs->ns_cpfile, sbi->s_snapshot_cno, bh_cp);
- }
- inode->i_flags |= S_NOCMTIME;
- }
- return err;
-}
-
static int __nilfs_read_inode(struct super_block *sb, unsigned long ino,
struct inode *inode)
{
inode->i_op = &nilfs_file_inode_operations;
inode->i_fop = &nilfs_file_operations;
inode->i_mapping->a_ops = &nilfs_aops;
- if (unlikely(inode->i_ino == NILFS_SKETCH_INO)) {
- err = nilfs_read_sketch_inode(inode);
- if (unlikely(err))
- goto failed_unmap;
- }
} else if (S_ISDIR(inode->i_mode)) {
inode->i_op = &nilfs_dir_inode_operations;
inode->i_fop = &nilfs_dir_operations;
struct nilfs_transaction_info ti;
struct super_block *sb = inode->i_sb;
struct nilfs_inode_info *ii = NILFS_I(inode);
- int ret;
if (!test_bit(NILFS_I_BMAP, &ii->i_state))
return;
blocksize = sb->s_blocksize;
blkoff = (inode->i_size + blocksize - 1) >> sb->s_blocksize_bits;
- ret = nilfs_transaction_begin(sb, &ti, 0);
- BUG_ON(ret);
+ nilfs_transaction_begin(sb, &ti, 0); /* never fails */
block_truncate_page(inode->i_mapping, inode->i_size, nilfs_get_block);
nilfs_set_transaction_flag(NILFS_TI_SYNC);
nilfs_set_file_dirty(NILFS_SB(sb), inode, 0);
- nilfs_transaction_end(sb, 1);
+ nilfs_transaction_commit(sb);
/* May construct a logical segment and may fail in sync mode.
But truncate has no return value. */
}
struct nilfs_transaction_info ti;
struct super_block *sb = inode->i_sb;
struct nilfs_inode_info *ii = NILFS_I(inode);
- int err;
if (unlikely(is_bad_inode(inode))) {
if (inode->i_data.nrpages)
clear_inode(inode);
return;
}
- err = nilfs_transaction_begin(sb, &ti, 0);
- BUG_ON(err);
+ nilfs_transaction_begin(sb, &ti, 0); /* never fails */
+
if (inode->i_data.nrpages)
truncate_inode_pages(&inode->i_data, 0);
/* nilfs_free_inode() marks inode buffer dirty */
if (IS_SYNC(inode))
nilfs_set_transaction_flag(NILFS_TI_SYNC);
- nilfs_transaction_end(sb, 1);
+ nilfs_transaction_commit(sb);
/* May construct a logical segment and may fail in sync mode.
But delete_inode has no return value. */
}
struct nilfs_transaction_info ti;
struct inode *inode = dentry->d_inode;
struct super_block *sb = inode->i_sb;
- int err, err2;
+ int err;
err = inode_change_ok(inode, iattr);
if (err)
err = inode_setattr(inode, iattr);
if (!err && (iattr->ia_valid & ATTR_MODE))
err = nilfs_acl_chmod(inode);
- err2 = nilfs_transaction_end(sb, 1);
- return err ? : err2;
+ if (likely(!err))
+ err = nilfs_transaction_commit(sb);
+ else
+ nilfs_transaction_abort(sb);
+
+ return err;
}
int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode,
atomic_add(nr_dirty, &sbi->s_nilfs->ns_ndirtyblks);
- if (test_and_set_bit(NILFS_I_DIRTY, &ii->i_state) ||
- unlikely(inode->i_ino == NILFS_SKETCH_INO))
+ if (test_and_set_bit(NILFS_I_DIRTY, &ii->i_state))
return 0;
spin_lock(&sbi->s_inode_lock);
return;
}
nilfs_transaction_begin(inode->i_sb, &ti, 0);
- if (likely(inode->i_ino != NILFS_SKETCH_INO))
- nilfs_mark_inode_dirty(inode);
- nilfs_transaction_end(inode->i_sb, 1); /* never fails */
+ nilfs_mark_inode_dirty(inode);
+ nilfs_transaction_commit(inode->i_sb); /* never fails */
}