ocfs2: sparse b-tree support
[powerpc.git] / fs / ocfs2 / file.c
index e9a82ad..8c97fa1 100644 (file)
@@ -149,10 +149,29 @@ int ocfs2_should_update_atime(struct inode *inode,
            ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)))
                return 0;
 
+       /*
+        * We can be called with no vfsmnt structure - NFSD will
+        * sometimes do this.
+        *
+        * Note that our action here is different than touch_atime() -
+        * if we can't tell whether this is a noatime mount, then we
+        * don't know whether to trust the value of s_atime_quantum.
+        */
+       if (vfsmnt == NULL)
+               return 0;
+
        if ((vfsmnt->mnt_flags & MNT_NOATIME) ||
            ((vfsmnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
                return 0;
 
+       if (vfsmnt->mnt_flags & MNT_RELATIME) {
+               if ((timespec_compare(&inode->i_atime, &inode->i_mtime) <= 0) ||
+                   (timespec_compare(&inode->i_atime, &inode->i_ctime) <= 0))
+                       return 1;
+
+               return 0;
+       }
+
        now = CURRENT_TIME;
        if ((now.tv_sec - inode->i_atime.tv_sec <= osb->s_atime_quantum))
                return 0;
@@ -378,6 +397,7 @@ bail:
  */
 int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
                               struct inode *inode,
+                              u32 *logical_offset,
                               u32 clusters_to_add,
                               struct buffer_head *fe_bh,
                               handle_t *handle,
@@ -441,18 +461,14 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
        block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
        mlog(0, "Allocating %u clusters at block %u for inode %llu\n",
             num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno);
-       status = ocfs2_insert_extent(osb, handle, inode, fe_bh, block,
-                                    num_bits, meta_ac);
+       status = ocfs2_insert_extent(osb, handle, inode, fe_bh,
+                                    *logical_offset, block, num_bits,
+                                    meta_ac);
        if (status < 0) {
                mlog_errno(status);
                goto leave;
        }
 
-       le32_add_cpu(&fe->i_clusters, num_bits);
-       spin_lock(&OCFS2_I(inode)->ip_lock);
-       OCFS2_I(inode)->ip_clusters = le32_to_cpu(fe->i_clusters);
-       spin_unlock(&OCFS2_I(inode)->ip_lock);
-
        status = ocfs2_journal_dirty(handle, fe_bh);
        if (status < 0) {
                mlog_errno(status);
@@ -460,6 +476,7 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
        }
 
        clusters_to_add -= num_bits;
+       *logical_offset += num_bits;
 
        if (clusters_to_add) {
                mlog(0, "need to alloc once more, clusters = %u, wanted = "
@@ -482,7 +499,7 @@ static int ocfs2_extend_allocation(struct inode *inode,
        int restart_func = 0;
        int drop_alloc_sem = 0;
        int credits, num_free_extents;
-       u32 prev_clusters;
+       u32 prev_clusters, logical_start;
        struct buffer_head *bh = NULL;
        struct ocfs2_dinode *fe = NULL;
        handle_t *handle = NULL;
@@ -493,6 +510,12 @@ static int ocfs2_extend_allocation(struct inode *inode,
 
        mlog_entry("(clusters_to_add = %u)\n", clusters_to_add);
 
+       /*
+        * This function only exists for file systems which don't
+        * support holes.
+        */
+       BUG_ON(ocfs2_sparse_alloc(osb));
+
        status = ocfs2_read_block(osb, OCFS2_I(inode)->ip_blkno, &bh,
                                  OCFS2_BH_CACHED, inode);
        if (status < 0) {
@@ -507,6 +530,8 @@ static int ocfs2_extend_allocation(struct inode *inode,
                goto leave;
        }
 
+       logical_start = OCFS2_I(inode)->ip_clusters;
+
 restart_all:
        BUG_ON(le32_to_cpu(fe->i_clusters) != OCFS2_I(inode)->ip_clusters);
 
@@ -571,6 +596,7 @@ restarted_transaction:
 
        status = ocfs2_do_extend_allocation(osb,
                                            inode,
+                                           &logical_start,
                                            clusters_to_add,
                                            bh,
                                            handle,
@@ -953,13 +979,12 @@ int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
 
        ret = ocfs2_meta_lock(inode, NULL, 0);
        if (ret) {
-               mlog_errno(ret);
+               if (ret != -ENOENT)
+                       mlog_errno(ret);
                goto out;
        }
 
        ret = generic_permission(inode, mask, NULL);
-       if (ret)
-               mlog_errno(ret);
 
        ocfs2_meta_unlock(inode, 0);
 out:
@@ -1348,13 +1373,13 @@ bail:
        return ret;
 }
 
-struct inode_operations ocfs2_file_iops = {
+const struct inode_operations ocfs2_file_iops = {
        .setattr        = ocfs2_setattr,
        .getattr        = ocfs2_getattr,
        .permission     = ocfs2_permission,
 };
 
-struct inode_operations ocfs2_special_file_iops = {
+const struct inode_operations ocfs2_special_file_iops = {
        .setattr        = ocfs2_setattr,
        .getattr        = ocfs2_getattr,
        .permission     = ocfs2_permission,