From: Greg Farnum Date: Thu, 26 Aug 2010 21:04:45 +0000 (-0700) Subject: client: Make truncation work properly X-Git-Tag: v0.22~208 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=85814d45de05bcca390c39df020a7934e437c064;p=ceph.git client: Make truncation work properly The previous if block didn't work because inode->size was usually changed well before handle_cap_trunc was ever invoked, so it never did the truncation in the objectcacher! This was okay if you just truncated a file and then closed it, but if you wrote a file, truncated part of it out, and then wrote past the (new) end you would get reads that returned the previously-truncated data out of what should have been a hole. Now, we do the actual objectcacher truncation in update_inode_file_bits, because all methods of truncation will move through there and this maintains proper ordering. --- diff --git a/src/client/Client.cc b/src/client/Client.cc index 239752f80c814..bf068dc005095 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -357,6 +357,8 @@ void Client::update_inode_file_bits(Inode *in, dout(25) << "truncate_seq: mds " << truncate_seq << " local " << in->truncate_seq << " time_warp_seq: mds " << time_warp_seq << " local " << in->time_warp_seq << dendl; + uint64_t prior_size = in->size; + if (truncate_seq > in->truncate_seq || (truncate_seq == in->truncate_seq && size > in->size)) { dout(10) << "size " << in->size << " -> " << size << dendl; @@ -375,6 +377,13 @@ void Client::update_inode_file_bits(Inode *in, << truncate_size << dendl; in->truncate_size = truncate_size; in->oset.truncate_size = truncate_size; + if (g_conf.client_oc) { //do actual truncation + vector ls; + filer->file_to_extents(in->ino, &in->layout, + truncate_size, prior_size - truncate_size, + ls); + objectcacher->truncate_set(&in->oset, ls); + } } // be careful with size, mtime, atime @@ -2636,18 +2645,13 @@ void Client::handle_cap_trunc(Inode *in, MClientCaps *m) dout(10) << "handle_cap_trunc on ino " << *in << " size " << in->size << " -> " << m->get_size() << dendl; - // trim filecache? - if (g_conf.client_oc && - m->get_size() < in->size) { - // map range to objects - vector ls; - filer->file_to_extents(in->ino, &in->layout, - m->get_size(), in->size - m->get_size(), - ls); - objectcacher->truncate_set(&in->oset, ls); - } - in->reported_size = in->size = m->get_size(); + int implemented = 0; + int issued = in->caps_issued(&implemented) | in->caps_dirty(); + issued |= implemented; + update_inode_file_bits(in, m->get_truncate_seq(), m->get_truncate_size(), + m->get_size(), m->get_time_warp_seq(), m->get_ctime(), + m->get_mtime(), m->get_atime(), issued); m->put(); }