]> Pileus Git - ~andy/linux/blobdiff - fs/ceph/inode.c
libceph: record byte count not page count
[~andy/linux] / fs / ceph / inode.c
index 851814d951cd57c42b64b113c1055c31c8640106..eeac43dd04eb17444971323b8b2b0ef14e3d41b6 100644 (file)
@@ -561,7 +561,6 @@ static int fill_inode(struct inode *inode,
        struct ceph_inode_info *ci = ceph_inode(inode);
        int i;
        int issued = 0, implemented;
-       int updating_inode = 0;
        struct timespec mtime, atime, ctime;
        u32 nsplits;
        struct ceph_buffer *xattr_blob = NULL;
@@ -601,7 +600,6 @@ static int fill_inode(struct inode *inode,
            (ci->i_version & ~1) >= le64_to_cpu(info->version))
                goto no_change;
        
-       updating_inode = 1;
        issued = __ceph_caps_issued(ci, &implemented);
        issued |= implemented | __ceph_caps_dirty(ci);
 
@@ -717,6 +715,17 @@ static int fill_inode(struct inode *inode,
                       ceph_vinop(inode), inode->i_mode);
        }
 
+       /* set dir completion flag? */
+       if (S_ISDIR(inode->i_mode) &&
+           ci->i_files == 0 && ci->i_subdirs == 0 &&
+           ceph_snap(inode) == CEPH_NOSNAP &&
+           (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) &&
+           (issued & CEPH_CAP_FILE_EXCL) == 0 &&
+           (ci->i_ceph_flags & CEPH_I_COMPLETE) == 0) {
+               dout(" marking %p complete (empty)\n", inode);
+               ci->i_ceph_flags |= CEPH_I_COMPLETE;
+               ci->i_max_offset = 2;
+       }
 no_change:
        spin_unlock(&ci->i_ceph_lock);
 
@@ -767,19 +776,6 @@ no_change:
                __ceph_get_fmode(ci, cap_fmode);
        }
 
-       /* set dir completion flag? */
-       if (S_ISDIR(inode->i_mode) &&
-           updating_inode &&                 /* didn't jump to no_change */
-           ci->i_files == 0 && ci->i_subdirs == 0 &&
-           ceph_snap(inode) == CEPH_NOSNAP &&
-           (le32_to_cpu(info->cap.caps) & CEPH_CAP_FILE_SHARED) &&
-           (issued & CEPH_CAP_FILE_EXCL) == 0 &&
-           !ceph_dir_test_complete(inode)) {
-               dout(" marking %p complete (empty)\n", inode);
-               ceph_dir_set_complete(inode);
-               ci->i_max_offset = 2;
-       }
-
        /* update delegation info? */
        if (dirinfo)
                ceph_fill_dirfrag(inode, dirinfo);
@@ -861,7 +857,7 @@ static void ceph_set_dentry_offset(struct dentry *dn)
        di = ceph_dentry(dn);
 
        spin_lock(&ci->i_ceph_lock);
-       if (!ceph_dir_test_complete(inode)) {
+       if ((ceph_inode(inode)->i_ceph_flags & CEPH_I_COMPLETE) == 0) {
                spin_unlock(&ci->i_ceph_lock);
                return;
        }
@@ -1066,7 +1062,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req,
                         * d_move() puts the renamed dentry at the end of
                         * d_subdirs.  We need to assign it an appropriate
                         * directory offset so we can behave when holding
-                        * D_COMPLETE.
+                        * I_COMPLETE.
                         */
                        ceph_set_dentry_offset(req->r_old_dentry);
                        dout("dn %p gets new offset %lld\n", req->r_old_dentry, 
@@ -1457,7 +1453,7 @@ out:
 
 
 /*
- * called by trunc_wq; take i_mutex ourselves
+ * called by trunc_wq;
  *
  * We also truncate in a separate thread as well.
  */
@@ -1468,9 +1464,7 @@ static void ceph_vmtruncate_work(struct work_struct *work)
        struct inode *inode = &ci->vfs_inode;
 
        dout("vmtruncate_work %p\n", inode);
-       mutex_lock(&inode->i_mutex);
-       __ceph_do_pending_vmtruncate(inode);
-       mutex_unlock(&inode->i_mutex);
+       __ceph_do_pending_vmtruncate(inode, true);
        iput(inode);
 }
 
@@ -1494,12 +1488,10 @@ void ceph_queue_vmtruncate(struct inode *inode)
 }
 
 /*
- * called with i_mutex held.
- *
  * Make sure any pending truncation is applied before doing anything
  * that may depend on it.
  */
-void __ceph_do_pending_vmtruncate(struct inode *inode)
+void __ceph_do_pending_vmtruncate(struct inode *inode, bool needlock)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
        u64 to;
@@ -1532,7 +1524,11 @@ retry:
             ci->i_truncate_pending, to);
        spin_unlock(&ci->i_ceph_lock);
 
+       if (needlock)
+               mutex_lock(&inode->i_mutex);
        truncate_inode_pages(inode->i_mapping, to);
+       if (needlock)
+               mutex_unlock(&inode->i_mutex);
 
        spin_lock(&ci->i_ceph_lock);
        if (to == ci->i_truncate_size) {
@@ -1585,7 +1581,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
        if (ceph_snap(inode) != CEPH_NOSNAP)
                return -EROFS;
 
-       __ceph_do_pending_vmtruncate(inode);
+       __ceph_do_pending_vmtruncate(inode, false);
 
        err = inode_change_ok(inode, attr);
        if (err != 0)
@@ -1767,7 +1763,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr)
             ceph_cap_string(dirtied), mask);
 
        ceph_mdsc_put_request(req);
-       __ceph_do_pending_vmtruncate(inode);
+       __ceph_do_pending_vmtruncate(inode, false);
        return err;
 out:
        spin_unlock(&ci->i_ceph_lock);