From 34d140a1df84aeb59a46d2c53a51d7b904295768 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 8 Sep 2008 15:39:35 -0700 Subject: [PATCH] add truncate_seq to inode, mds<->client protocol --- src/client/Client.cc | 27 +++++++++++++++------------ src/client/Client.h | 6 ++++-- src/include/ceph_fs.h | 3 ++- src/kernel/caps.c | 6 ++++-- src/kernel/inode.c | 30 ++++++++++++++++-------------- src/kernel/super.c | 1 + src/kernel/super.h | 6 +++--- src/mds/CInode.cc | 5 +++-- src/mds/Server.cc | 2 ++ src/mds/mdstypes.h | 3 +++ src/messages/MClientCaps.h | 3 +++ src/messages/MClientReply.h | 8 +++++--- 12 files changed, 61 insertions(+), 39 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index e43f6c9d17115..79e6e8dbdf729 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -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; diff --git a/src/client/Client.h b/src/client/Client.h index 5ded3237a15d6..3910249c41589 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -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, diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index 1a19b79e68e81..87b9082b7e253 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -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; diff --git a/src/kernel/caps.c b/src/kernel/caps.c index b01eac03b9e5d..2a376fadd5cb9 100644 --- a/src/kernel/caps.c +++ b/src/kernel/caps.c @@ -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) { diff --git a/src/kernel/inode.c b/src/kernel/inode.c index 1399d83005366..d05ced34587ad 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -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; diff --git a/src/kernel/super.c b/src/kernel/super.c index eb764bbc829ca..3eac8823200f0 100644 --- a/src/kernel/super.c +++ b/src/kernel/super.c @@ -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; diff --git a/src/kernel/super.h b/src/kernel/super.h index f98d6f7171d44..4cfc0bfe7e99f 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -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, diff --git a/src/mds/CInode.cc b/src/mds/CInode.cc index c4da37859019f..c0a70deb9c378 100644 --- a/src/mds/CInode.cc +++ b/src/mds/CInode.cc @@ -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; diff --git a/src/mds/Server.cc b/src/mds/Server.cc index 4494760f20b96..02a61dbc2d745 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -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); diff --git a/src/mds/mdstypes.h b/src/mds/mdstypes.h index 9c0d1f66b6b2c..5095c00ead550 100644 --- a/src/mds/mdstypes.h +++ b/src/mds/mdstypes.h @@ -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); diff --git a/src/messages/MClientCaps.h b/src/messages/MClientCaps.h index bb64cbf687d11..45a90a3ca9bae 100644 --- a/src/messages/MClientCaps.h +++ b/src/messages/MClientCaps.h @@ -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); diff --git a/src/messages/MClientReply.h b/src/messages/MClientReply.h index 2358a0eb457b0..9fee15dd3e575 100644 --- a/src/messages/MClientReply.h +++ b/src/messages/MClientReply.h @@ -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)); -- 2.39.5