]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mds: handle O_TRUNC when size is already 0
authorSage Weil <sage@newdream.net>
Wed, 17 Aug 2011 21:11:15 +0000 (14:11 -0700)
committerSage Weil <sage@newdream.net>
Wed, 17 Aug 2011 21:11:15 +0000 (14:11 -0700)
We always want to go through the truncation path.  Two reasons:

 - even if the size is already 0, we still need to update ctime/mtime
 - we may not have the correct size (client could have dirty data), in
   which case we still want to bump truncate_seq etc.

Basically, we can't trust pi->size here because we are holding a wrlock,
not an xlock.  And that's fine, since we need to update the inode
unconditionally anyway.

This broke cfuse pjd open/00.t tests when we added the fuse option
atomic_o_trunc.  libceph has always been broken in this regard.

Fixes: #1393
Signed-off-by: Sage Weil <sage@newdream.net>
src/mds/Server.cc

index 19c2fe6e2e67c994150f704222ee2c60166348e9..33403f9513f43085415eaba22ffa5a1a9a29f8b5 100644 (file)
@@ -2414,19 +2414,17 @@ void Server::handle_client_open(MDRequest *mdr)
     if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
       return;
 
+    // wait for pending truncate?
     inode_t *pi = cur->get_projected_inode();
-    if (pi->size > 0) {
-      // wait for pending truncate?
-      if (pi->is_truncating()) {
-       dout(10) << " waiting for pending truncate from " << pi->truncate_from
-                << " to " << pi->truncate_size << " to complete on " << *cur << dendl;
-       cur->add_waiter(CInode::WAIT_TRUNC, new C_MDS_RetryRequest(mdcache, mdr));
-       return;
-      }
-
-      do_open_truncate(mdr, cmode);
+    if (pi->is_truncating()) {
+      dout(10) << " waiting for pending truncate from " << pi->truncate_from
+              << " to " << pi->truncate_size << " to complete on " << *cur << dendl;
+      cur->add_waiter(CInode::WAIT_TRUNC, new C_MDS_RetryRequest(mdcache, mdr));
       return;
     }
+    
+    do_open_truncate(mdr, cmode);
+    return;
   }
 
   // sync filelock if snapped.
@@ -3163,7 +3161,7 @@ void Server::do_open_truncate(MDRequest *mdr, int cmode)
     pi->client_ranges[client].range.last = pi->get_layout_size_increment();
     pi->client_ranges[client].follows = in->find_snaprealm()->get_newest_seq();
   }
-
+  
   mdr->ls = mdlog->get_current_segment();
   EUpdate *le = new EUpdate(mdlog, "open_truncate");
   mdlog->start_entry(le);