]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
add truncate_seq to inode, mds<->client protocol
authorSage Weil <sage@newdream.net>
Mon, 8 Sep 2008 22:39:35 +0000 (15:39 -0700)
committerSage Weil <sage@newdream.net>
Mon, 8 Sep 2008 22:39:35 +0000 (15:39 -0700)
12 files changed:
src/client/Client.cc
src/client/Client.h
src/include/ceph_fs.h
src/kernel/caps.c
src/kernel/inode.c
src/kernel/super.c
src/kernel/super.h
src/mds/CInode.cc
src/mds/Server.cc
src/mds/mdstypes.h
src/messages/MClientCaps.h
src/messages/MClientReply.h

index e43f6c9d171151e412278b390ff81cbc33f0c026..79e6e8dbdf7293d4ebf7d6425e49ee8c0c0df283 100644 (file)
@@ -318,15 +318,21 @@ void Client::trim_cache()
 
 
 void Client::update_inode_file_bits(Inode *in,
-                                   __u64 size,
-                                   utime_t ctime,
+                                   __u64 truncate_seq, __u64 size,
+                                   __u64 time_warp_seq, utime_t ctime,
                                    utime_t mtime,
                                    utime_t atime,
-                                   int issued,
-                                   __u64 time_warp_seq)
+                                   int issued)
 {
   bool warn = false;
 
+  if (truncate_seq > in->inode.truncate_seq ||
+      (truncate_seq == in->inode.truncate_seq && size > in->inode.size)) {
+    dout(10) << "size " << in->inode.size << " -> " << size << dendl;
+    in->inode.size = size;
+    in->reported_size = size;
+  }
+
   // be careful with size, mtime, atime
   if (issued & CEPH_CAP_EXCL) {
     if (ctime > in->inode.ctime) 
@@ -335,10 +341,6 @@ void Client::update_inode_file_bits(Inode *in,
       dout(0) << "WARNING: " << *in << " mds time_warp_seq "
              << time_warp_seq << " > " << in->inode.time_warp_seq << dendl;
   } else if (issued & (CEPH_CAP_WR|CEPH_CAP_WRBUFFER)) {
-    if (size > in->inode.size) {
-      in->inode.size = size;
-      in->reported_size = size;
-    }
     if (time_warp_seq > in->inode.time_warp_seq) {
       in->inode.ctime = ctime;
       in->inode.mtime = mtime;
@@ -354,8 +356,6 @@ void Client::update_inode_file_bits(Inode *in,
     } else
       warn = true;
   } else {
-    in->inode.size = size;
-    in->reported_size = size;
     if (time_warp_seq >= in->inode.time_warp_seq) {
       in->inode.ctime = ctime;
       in->inode.mtime = mtime;
@@ -400,7 +400,9 @@ void Client::update_inode(Inode *in, InodeStat *st, LeaseStat *lease, utime_t fr
     in->inode.ctime = st->ctime;
     in->inode.max_size = st->max_size;  // right?
 
-    update_inode_file_bits(in, st->size, st->ctime, st->mtime, st->atime, in->caps_issued(), st->time_warp_seq);
+    update_inode_file_bits(in, st->truncate_seq, st->size,
+                          st->time_warp_seq, st->ctime, st->mtime, st->atime,
+                          in->caps_issued());
   }
 
   if (lease->mask && 
@@ -2108,7 +2110,8 @@ void Client::handle_cap_grant(Inode *in, MClientCaps *m)
           << " was " << cap_string(old_caps) << dendl;
   
   // size/ctime/mtime/atime
-  update_inode_file_bits(in, m->get_size(), m->get_ctime(), m->get_mtime(), m->get_atime(), old_caps, m->get_time_warp_seq());
+  update_inode_file_bits(in, m->get_truncate_seq(), m->get_size(),
+                        m->get_time_warp_seq(), m->get_ctime(), m->get_mtime(), m->get_atime(), old_caps);
 
   // max_size
   bool kick_writers = false;
index 5ded3237a15d6e359ae1480cf2604f968223e2bb..3910249c41589581779418c2381f365ff19e6b28 100644 (file)
@@ -885,8 +885,10 @@ protected:
   void update_dir_dist(Inode *in, DirStat *st);
 
   Inode* insert_trace(MClientReply *reply, utime_t ttl);
-  void update_inode_file_bits(Inode *in, __u64 size, utime_t ctime, utime_t mtime, utime_t atime,
-                             int issued, __u64 time_warp_seq);
+  void update_inode_file_bits(Inode *in,
+                             __u64 truncat_seq,__u64 size,
+                             __u64 time_warp_seq, utime_t ctime, utime_t mtime, utime_t atime,
+                             int issued);
   void update_inode(Inode *in, InodeStat *st, LeaseStat *l, utime_t ttl);
   Inode* insert_dentry_inode(Dir *dir, const string& dname, LeaseStat *dlease, 
                             InodeStat *ist, LeaseStat *ilease, 
index 1a19b79e68e8196f570bbea1004b77739888e236..87b9082b7e253b7ff74ee043b3efbf4c3af10b6b 100644 (file)
@@ -722,7 +722,7 @@ struct ceph_mds_reply_inode {
        __le64 time_warp_seq;
        __le32 mode, uid, gid;
        __le32 nlink;
-       __le64 size, max_size;
+       __le64 size, max_size, truncate_seq;
        __le64 files, subdirs, rbytes, rfiles, rsubdirs;  /* dir stats */
        struct ceph_timespec rctime;
        __le32 rdev;
@@ -838,6 +838,7 @@ struct ceph_mds_caps {
        __le32 seq;
        __le32 caps, wanted;
        __le64 size, max_size;
+       __le64 truncate_seq;
        __le32 migrate_seq;
        struct ceph_timespec mtime, atime, ctime;
        struct ceph_file_layout layout;
index b01eac03b9e5db2291fe521495a08cf518be64db..2a376fadd5cb960c9fa0b420acacc8c889d85091 100644 (file)
@@ -736,8 +736,10 @@ static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant,
        ceph_decode_timespec(&mtime, &grant->mtime);
        ceph_decode_timespec(&atime, &grant->atime);
        ceph_decode_timespec(&ctime, &grant->ctime);
-       ceph_fill_file_bits(inode, issued, le64_to_cpu(grant->time_warp_seq),
-                           size, &ctime, &mtime, &atime);
+       ceph_fill_file_bits(inode, issued,
+                           le64_to_cpu(grant->truncate_seq), size,
+                           le64_to_cpu(grant->time_warp_seq), &ctime, &mtime,
+                           &atime);
 
        /* max size increase? */
        if (max_size != ci->i_max_size) {
index 1399d83005366bb7da01bc07e936d639e75dbeed..d05ced34587ad9d7daaa89e35358b5a11f9b55a7 100644 (file)
@@ -238,14 +238,23 @@ out:
  * depending on which capabilities/were help, and on the time_warp_seq
  * (which we increment on utimes()).
  */
-void ceph_fill_file_bits(struct inode *inode, int issued, u64 time_warp_seq,
-                        u64 size, struct timespec *ctime,
+void ceph_fill_file_bits(struct inode *inode, int issued,
+                        u64 truncate_seq, u64 size,
+                        u64 time_warp_seq, struct timespec *ctime,
                         struct timespec *mtime, struct timespec *atime)
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
-       u64 blocks = (size + (1<<9) - 1) >> 9;
        int warn = 0;
 
+       if (truncate_seq > ci->i_truncate_seq ||
+           (truncate_seq == ci->i_truncate_seq && size > inode->i_size)) {
+               dout(10, "size %lld -> %llu\n", inode->i_size, size);
+               inode->i_size = size;
+               inode->i_blocks = (size + (1<<9) - 1) >> 9;
+               ci->i_reported_size = size;
+               ci->i_truncate_seq = truncate_seq;
+       }
+
        if (issued & CEPH_CAP_EXCL) {
                if (timespec_compare(ctime, &inode->i_ctime) > 0)
                        inode->i_ctime = *ctime;
@@ -253,12 +262,6 @@ void ceph_fill_file_bits(struct inode *inode, int issued, u64 time_warp_seq,
                        derr(0, "WARNING: %p mds time_warp_seq %llu > %llu\n",
                             inode, time_warp_seq, ci->i_time_warp_seq);
        } else if (issued & (CEPH_CAP_WR|CEPH_CAP_WRBUFFER)) {
-               if (size > inode->i_size) {
-                       dout(10, "size %lld -> %llu\n", inode->i_size, size);
-                       inode->i_size = size;
-                       inode->i_blocks = blocks;
-                       ci->i_reported_size = size;
-               }
                if (time_warp_seq > ci->i_time_warp_seq) {
                        inode->i_ctime = *ctime;
                        inode->i_mtime = *mtime;
@@ -274,9 +277,6 @@ void ceph_fill_file_bits(struct inode *inode, int issued, u64 time_warp_seq,
                } else
                        warn = 1;
        } else {
-               inode->i_size = size;
-               inode->i_blocks = blocks;
-               ci->i_reported_size = size;
                if (time_warp_seq >= ci->i_time_warp_seq) {
                        inode->i_ctime = *ctime;
                        inode->i_mtime = *mtime;
@@ -335,8 +335,10 @@ int ceph_fill_inode(struct inode *inode,
        ceph_decode_timespec(&ctime, &info->ctime);
        issued = __ceph_caps_issued(ci, 0);
 
-       ceph_fill_file_bits(inode, issued, le64_to_cpu(info->time_warp_seq),
-                           size, &ctime, &mtime, &atime);
+       ceph_fill_file_bits(inode, issued,
+                           le64_to_cpu(info->truncate_seq), size,
+                           le64_to_cpu(info->time_warp_seq),
+                           &ctime, &mtime, &atime);
 
        inode->i_blkbits = blkbits;
 
index eb764bbc829cafb11e460bf51c5a6132eeb2e4ac..3eac8823200f0a750ef6fc4382a751c4fda3f422 100644 (file)
@@ -154,6 +154,7 @@ static struct inode *ceph_alloc_inode(struct super_block *sb)
        dout(10, "alloc_inode %p vfsi %p\n", ci, &ci->vfs_inode);
 
        ci->i_version = 0;
+       ci->i_truncate_seq = 0;
        ci->i_time_warp_seq = 0;
        ci->i_symlink = 0;
 
index f98d6f7171d449ada0d05a6325a541f7a2f26337..4cfc0bfe7e99f81f14f3f0766c6cb1fc432d00ca 100644 (file)
@@ -226,7 +226,7 @@ struct ceph_inode_info {
        struct ceph_vino i_vino;   /* ceph ino + snap */
 
        u64 i_version;
-       u64 i_time_warp_seq;
+       u64 i_truncate_seq, i_time_warp_seq;
 
        struct ceph_file_layout i_layout;
        char *i_symlink;
@@ -548,8 +548,8 @@ extern int ceph_fill_inode(struct inode *inode,
                           struct ceph_mds_reply_info_in *iinfo,
                           struct ceph_mds_reply_dirfrag *dirinfo);
 extern void ceph_fill_file_bits(struct inode *inode, int issued,
-                               u64 time_warp_seq,
-                               u64 size, struct timespec *ctime,
+                               u64 truncate_seq, u64 size,
+                               u64 time_warp_seq, struct timespec *ctime,
                                struct timespec *mtime, struct timespec *atime);
 extern int ceph_fill_trace(struct super_block *sb,
                           struct ceph_mds_request *req,
index c4da37859019f86cdb43e6674c2ac9df614c59c7..c0a70deb9c378215048e6cdbe14aec0a5e12ff9c 100644 (file)
@@ -1304,6 +1304,9 @@ bool CInode::encode_inodestat(bufferlist& bl, snapid_t snapid)
   e.snapid = snapid ? (__u64)snapid:CEPH_NOSNAP;  // 0 -> NOSNAP
   e.version = i->version;
   e.layout = i->layout;
+  e.size = i->size;
+  e.max_size = i->max_size;
+  e.truncate_seq = i->truncate_seq;
   i->ctime.encode_timeval(&e.ctime);
   i->mtime.encode_timeval(&e.mtime);
   i->atime.encode_timeval(&e.atime);
@@ -1312,8 +1315,6 @@ bool CInode::encode_inodestat(bufferlist& bl, snapid_t snapid)
   e.uid = i->uid;
   e.gid = i->gid;
   e.nlink = i->nlink;
-  e.size = i->size;
-  e.max_size = i->max_size;
   
   e.files = i->dirstat.nfiles;
   e.subdirs = i->dirstat.nsubdirs;
index 4494760f20b967bbc23102c6fc4adbec76a0ee0d..02a61dbc2d745f8b074544b3d196d199d4187234 100644 (file)
@@ -4547,6 +4547,7 @@ void Server::handle_client_truncate(MDRequest *mdr)
   pi->ctime = ctime;
   pi->version = pdv;
   pi->size = le64_to_cpu(req->head.args.truncate.length);
+  pi->truncate_seq++;
   mdcache->predirty_journal_parents(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false);
   mdcache->journal_dirty_inode(mdr, &le->metablob, cur);
   
@@ -4776,6 +4777,7 @@ void Server::handle_client_opent(MDRequest *mdr)
   pi->ctime = ctime;
   pi->version = pdv;
   pi->size = 0;
+  pi->truncate_seq++;
   mdcache->predirty_journal_parents(mdr, &le->metablob, cur, 0, PREDIRTY_PRIMARY, false);
   mdcache->journal_dirty_inode(mdr, &le->metablob, cur);
   
index 9c0d1f66b6b2c6808a79e3d045c0227f73bef283..5095c00ead5504042328451e3bbd7a04568611c3 100644 (file)
@@ -280,6 +280,7 @@ struct inode_t {
   ceph_file_layout layout;
   uint64_t   size;        // on directory, # dentries
   uint64_t   max_size;    // client(s) are auth to write this much...
+  uint64_t   truncate_seq;
   utime_t    mtime;   // file data modify time.
   utime_t    atime;   // file data access time.
   uint64_t   time_warp_seq;  // count of (potential) mtime/atime timewarps (i.e., utimes())
@@ -312,6 +313,7 @@ struct inode_t {
     ::encode(layout, bl);
     ::encode(size, bl);
     ::encode(max_size, bl);
+    ::encode(truncate_seq, bl);
     ::encode(mtime, bl);
     ::encode(atime, bl);
     ::encode(time_warp_seq, bl);
@@ -338,6 +340,7 @@ struct inode_t {
     ::decode(layout, p);
     ::decode(size, p);
     ::decode(max_size, p);
+    ::decode(truncate_seq, p);
     ::decode(mtime, p);
     ::decode(atime, p);
     ::decode(time_warp_seq, p);
index bb64cbf687d11863348454558bece4c4d0a46774..45a90a3ca9bae3bed7a6f6d45e0b204c02bb350e 100644 (file)
@@ -32,6 +32,7 @@ class MClientCaps : public Message {
 
   __u64 get_size() { return head.size;  }
   __u64 get_max_size() { return head.max_size;  }
+  __u64 get_truncate_seq() { return head.truncate_seq; }
   utime_t get_ctime() { return utime_t(head.ctime); }
   utime_t get_mtime() { return utime_t(head.mtime); }
   utime_t get_atime() { return utime_t(head.atime); }
@@ -75,6 +76,7 @@ class MClientCaps : public Message {
     head.layout = inode.layout;
     head.size = inode.size;
     head.max_size = inode.max_size;
+    head.truncate_seq = inode.truncate_seq;
     head.migrate_seq = mseq;
     inode.mtime.encode_timeval(&head.mtime);
     inode.atime.encode_timeval(&head.atime);
@@ -99,6 +101,7 @@ class MClientCaps : public Message {
        << " caps " << cap_string(head.caps)
        << " wanted" << cap_string(head.wanted)
        << " size " << head.size << "/" << head.max_size
+       << " ts" << head.truncate_seq
        << " mtime " << utime_t(head.mtime)
        << " tws " << head.time_warp_seq
        << " follows " << snapid_t(head.snap_follows);
index 2358a0eb457b0f7be6d546d2ddc96322c13a4c9a..9fee15dd3e575d133765963364f2da5b75f42cd0 100644 (file)
@@ -93,9 +93,10 @@ struct InodeStat {
   vinodeno_t vino;
   version_t version;
   ceph_file_layout layout;
-  utime_t ctime, mtime, atime;
   unsigned mode, uid, gid, nlink, rdev;
   loff_t size, max_size;
+  version_t truncate_seq;
+  utime_t ctime, mtime, atime;
   version_t time_warp_seq;
 
   frag_info_t dirstat;
@@ -118,6 +119,9 @@ struct InodeStat {
     vino.snapid = snapid_t(e.snapid);
     version = e.version;
     layout = e.layout;
+    size = e.size;
+    max_size = e.max_size;
+    truncate_seq = e.truncate_seq;
     ctime.decode_timeval(&e.ctime);
     mtime.decode_timeval(&e.mtime);
     atime.decode_timeval(&e.atime);
@@ -126,8 +130,6 @@ struct InodeStat {
     uid = e.uid;
     gid = e.gid;
     nlink = e.nlink;
-    size = e.size;
-    max_size = e.max_size;
     rdev = e.rdev;
 
     memset(&dirstat, 0, sizeof(dirstat));