nilfs2: Using nobarrier option instead of barrier=off
[safe/jmp/linux-2.6] / fs / nilfs2 / inode.c
index 4bf1e2c..2a0a5a3 100644 (file)
  *
  * This function does not issue actual read request of the specified data
  * block. It is done by VFS.
- * Bulk read for direct-io is not supported yet. (should be supported)
  */
 int nilfs_get_block(struct inode *inode, sector_t blkoff,
                    struct buffer_head *bh_result, int create)
 {
        struct nilfs_inode_info *ii = NILFS_I(inode);
-       unsigned long blknum = 0;
+       __u64 blknum = 0;
        int err = 0, ret;
        struct inode *dat = nilfs_dat_inode(NILFS_I_NILFS(inode));
+       unsigned maxblocks = bh_result->b_size >> inode->i_blkbits;
 
-       /* This exclusion control is a workaround; should be revised */
-       down_read(&NILFS_MDT(dat)->mi_sem);     /* XXX */
-       ret = nilfs_bmap_lookup(ii->i_bmap, (unsigned long)blkoff, &blknum);
-       up_read(&NILFS_MDT(dat)->mi_sem);       /* XXX */
-       if (ret == 0) { /* found */
+       down_read(&NILFS_MDT(dat)->mi_sem);
+       ret = nilfs_bmap_lookup_contig(ii->i_bmap, blkoff, &blknum, maxblocks);
+       up_read(&NILFS_MDT(dat)->mi_sem);
+       if (ret >= 0) { /* found */
                map_bh(bh_result, inode->i_sb, blknum);
+               if (ret > 0)
+                       bh_result->b_size = (ret << inode->i_blkbits);
                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;
@@ -85,14 +80,14 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff,
                                 * 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",
@@ -243,10 +238,10 @@ nilfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
        return size;
 }
 
-struct address_space_operations nilfs_aops = {
+const struct address_space_operations nilfs_aops = {
        .writepage              = nilfs_writepage,
        .readpage               = nilfs_readpage,
-       /* .sync_page           = nilfs_sync_page, */
+       .sync_page              = block_sync_page,
        .writepages             = nilfs_writepages,
        .set_page_dirty         = nilfs_set_page_dirty,
        .readpages              = nilfs_readpages,
@@ -255,6 +250,7 @@ struct address_space_operations nilfs_aops = {
        /* .releasepage         = nilfs_releasepage, */
        .invalidatepage         = block_invalidatepage,
        .direct_IO              = nilfs_direct_IO,
+       .is_partially_uptodate  = block_is_partially_uptodate,
 };
 
 struct inode *nilfs_new_inode(struct inode *dir, int mode)
@@ -312,12 +308,7 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode)
 
        /* ii->i_file_acl = 0; */
        /* ii->i_dir_acl = 0; */
-       ii->i_dtime = 0;
        ii->i_dir_start_lookup = 0;
-#ifdef CONFIG_NILFS_FS_POSIX_ACL
-       ii->i_acl = NULL;
-       ii->i_default_acl = NULL;
-#endif
        ii->i_cno = 0;
        nilfs_set_inode_flags(inode);
        spin_lock(&sbi->s_next_gen_lock);
@@ -396,11 +387,10 @@ int nilfs_read_inode_common(struct inode *inode,
        inode->i_atime.tv_sec = le64_to_cpu(raw_inode->i_mtime);
        inode->i_ctime.tv_sec = le64_to_cpu(raw_inode->i_ctime);
        inode->i_mtime.tv_sec = le64_to_cpu(raw_inode->i_mtime);
-       inode->i_atime.tv_nsec = 0;
-       inode->i_ctime.tv_nsec = 0;
-       inode->i_mtime.tv_nsec = 0;
-       ii->i_dtime = le64_to_cpu(raw_inode->i_dtime);
-       if (inode->i_nlink == 0 && (inode->i_mode == 0 || ii->i_dtime))
+       inode->i_atime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);
+       inode->i_ctime.tv_nsec = le32_to_cpu(raw_inode->i_ctime_nsec);
+       inode->i_mtime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);
+       if (inode->i_nlink == 0 && inode->i_mode == 0)
                return -EINVAL; /* this inode is deleted */
 
        inode->i_blocks = le64_to_cpu(raw_inode->i_blocks);
@@ -410,6 +400,7 @@ int nilfs_read_inode_common(struct inode *inode,
        ii->i_dir_acl = S_ISREG(inode->i_mode) ?
                0 : le32_to_cpu(raw_inode->i_dir_acl);
 #endif
+       ii->i_dir_start_lookup = 0;
        ii->i_cno = 0;
        inode->i_generation = le32_to_cpu(raw_inode->i_generation);
 
@@ -424,30 +415,6 @@ int nilfs_read_inode_common(struct inode *inode,
        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)
 {
@@ -464,22 +431,14 @@ static int __nilfs_read_inode(struct super_block *sb, unsigned long ino,
 
        raw_inode = nilfs_ifile_map_inode(sbi->s_ifile, ino, bh);
 
-#ifdef CONFIG_NILFS_FS_POSIX_ACL
-       ii->i_acl = NILFS_ACL_NOT_CACHED;
-       ii->i_default_acl = NILFS_ACL_NOT_CACHED;
-#endif
-       if (nilfs_read_inode_common(inode, raw_inode))
+       err = nilfs_read_inode_common(inode, raw_inode);
+       if (err)
                goto failed_unmap;
 
        if (S_ISREG(inode->i_mode)) {
                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;
@@ -540,9 +499,10 @@ void nilfs_write_inode_common(struct inode *inode,
        raw_inode->i_size = cpu_to_le64(inode->i_size);
        raw_inode->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
        raw_inode->i_mtime = cpu_to_le64(inode->i_mtime.tv_sec);
+       raw_inode->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
+       raw_inode->i_mtime_nsec = cpu_to_le32(inode->i_mtime.tv_nsec);
        raw_inode->i_blocks = cpu_to_le64(inode->i_blocks);
 
-       raw_inode->i_dtime = cpu_to_le64(ii->i_dtime);
        raw_inode->i_flags = cpu_to_le32(ii->i_flags);
        raw_inode->i_generation = cpu_to_le32(inode->i_generation);
 
@@ -621,7 +581,6 @@ void nilfs_truncate(struct inode *inode)
        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;
@@ -630,8 +589,7 @@ void nilfs_truncate(struct inode *inode)
 
        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);
 
@@ -652,7 +610,6 @@ void nilfs_delete_inode(struct inode *inode)
        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)
@@ -660,8 +617,8 @@ void nilfs_delete_inode(struct inode *inode)
                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);
 
@@ -707,7 +664,6 @@ int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode,
        int err;
 
        spin_lock(&sbi->s_inode_lock);
-       /* Caller of this function MUST lock s_inode_lock */
        if (ii->i_bh == NULL) {
                spin_unlock(&sbi->s_inode_lock);
                err = nilfs_ifile_get_inode_block(sbi->s_ifile, inode->i_ino,
@@ -751,8 +707,7 @@ int nilfs_set_file_dirty(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);
@@ -820,7 +775,6 @@ void nilfs_dirty_inode(struct inode *inode)
                return;
        }
        nilfs_transaction_begin(inode->i_sb, &ti, 0);
-       if (likely(inode->i_ino != NILFS_SKETCH_INO))
-               nilfs_mark_inode_dirty(inode);
+       nilfs_mark_inode_dirty(inode);
        nilfs_transaction_commit(inode->i_sb); /* never fails */
 }