From: Sage Weil Date: Wed, 17 Aug 2011 21:11:15 +0000 (-0700) Subject: mds: handle O_TRUNC when size is already 0 X-Git-Tag: v0.34~70 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=79db9fc509933429f4a8f4aca6d3da5517c43d1f;p=ceph.git mds: handle O_TRUNC when size is already 0 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 --- diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 19c2fe6e2e67..33403f9513f4 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -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);