From 81c4aaa86af35b7c46de09702697fd0823100709 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 9 Apr 2008 13:44:37 -0700 Subject: [PATCH] kclient: send mds a cap message when we approach file_max --- src/TODO | 3 +-- src/kernel/addr.c | 7 ++++++- src/kernel/inode.c | 22 +++++++++++++++++----- src/kernel/super.h | 6 +++--- src/mds/Locker.cc | 6 +++--- src/messages/MClientUnmount.h | 16 +++------------- 6 files changed, 33 insertions(+), 27 deletions(-) diff --git a/src/TODO b/src/TODO index 5e3a6842746e2..c7f9aafdfc329 100644 --- a/src/TODO +++ b/src/TODO @@ -19,12 +19,11 @@ yehuda: - apply_truncate needs to truncate page cache, or something? kernel client +- somehow get a max_size bump if we lseek into a (sparse) file ... - why is mds_client delayed work not working? - file_data_version stuff! - deal with CAP_RDCACHE properly: invalidate cache pages? - trim expired leases so we don't indefinitely hold dcache/icache refs... -- obey file_max -- send mds a file_cap message when we approach the current file_max - procfs/debugfs - adjust granular debug levels too - should we be using debugfs? diff --git a/src/kernel/addr.c b/src/kernel/addr.c index afc02756f17d7..33ff3f172c1bb 100644 --- a/src/kernel/addr.c +++ b/src/kernel/addr.c @@ -452,6 +452,7 @@ static int ceph_write_end(struct file *file, struct address_space *mapping, struct page *page, void *fsdata) { struct inode *inode = file->f_dentry->d_inode; + struct ceph_inode_info *ci = ceph_inode(inode); unsigned from = pos & (PAGE_CACHE_SIZE - 1); dout(10, "write_end file %p inode %p page %p %d~%d (%d)\n", file, @@ -467,8 +468,12 @@ static int ceph_write_end(struct file *file, struct address_space *mapping, /* did file size increase? */ /* (no need for i_size_read(); we caller holds i_mutex */ - if (pos+copied > inode->i_size) + if (pos+copied > inode->i_size) { i_size_write(inode, pos + copied); + if ((inode->i_size << 1) >= ci->i_max_size && + (ci->i_reported_size << 1) < ci->i_max_size) + ceph_check_caps(ci, GFP_KERNEL); + } if (!PageUptodate(page)) SetPageUptodate(page); diff --git a/src/kernel/inode.c b/src/kernel/inode.c index c30ff5f81eda3..8e73f10593474 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -134,6 +134,7 @@ int ceph_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *info) ci->i_old_atime = inode->i_atime; ci->i_max_size = le64_to_cpu(info->max_size); + ci->i_reported_size = inode->i_size; /* reset */ inode->i_mapping->a_ops = &ceph_aops; @@ -764,7 +765,7 @@ void ceph_remove_cap(struct ceph_inode_cap *cap) * examine currently used, wanted versus held caps. * release, ack revoked caps to mds as appropriate. */ -void ceph_check_caps_wanted(struct ceph_inode_info *ci, gfp_t gfpmask) +void ceph_check_caps(struct ceph_inode_info *ci, gfp_t gfpmask) { struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode); struct ceph_mds_client *mdsc = &client->mdsc; @@ -797,6 +798,15 @@ retry: goto ack; } + /* approaching file_max? */ + if ((cap->issued & CEPH_CAP_WR) && + (ci->vfs_inode.i_size << 1) >= ci->i_max_size && + (ci->i_reported_size << 1) < ci->i_max_size) { + dout(10, "i_size approaching max_size\n"); + ci->i_reported_size = ci->vfs_inode.i_size; + goto ack; + } + if ((cap->issued & ~wanted) == 0) continue; /* nothing extra, all good */ @@ -861,7 +871,7 @@ void ceph_put_mode(struct ceph_inode_info *ci, int mode) spin_unlock(&ci->vfs_inode.i_lock); if (last) - ceph_check_caps_wanted(ci, GFP_KERNEL); + ceph_check_caps(ci, GFP_KERNEL); } @@ -1001,10 +1011,13 @@ out: void apply_truncate(struct inode *inode, loff_t size) { + struct ceph_inode_info *ci = ceph_inode(inode); + spin_lock(&inode->i_lock); dout(10, "apply_truncate %p size %lld -> %llu\n", inode, inode->i_size, size); inode->i_size = size; + ci->i_reported_size = size; spin_unlock(&inode->i_lock); /* @@ -1021,7 +1034,6 @@ int ceph_handle_cap_trunc(struct inode *inode, struct ceph_mds_file_caps *trunc, u64 size = le64_to_cpu(trunc->size); dout(10, "handle_cap_trunc inode %p ci %p mds%d seq %d\n", inode, ci, mds, seq); - apply_truncate(inode, size); return 0; } @@ -1096,7 +1108,7 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) last ? "last":""); if (last) - ceph_check_caps_wanted(ci, GFP_KERNEL); + ceph_check_caps(ci, GFP_KERNEL); } void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr) @@ -1114,7 +1126,7 @@ void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr) last ? "last":""); if (last) - ceph_check_caps_wanted(ci, GFP_KERNEL); + ceph_check_caps(ci, GFP_KERNEL); } diff --git a/src/kernel/super.h b/src/kernel/super.h index 407dc43fd57dd..0ecdfa6bd74b4 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -156,8 +156,8 @@ struct ceph_inode_info { wait_queue_head_t i_cap_wq; int i_nr_by_mode[4]; - int i_cap_wanted; /* what we've told the mds(s) */ - loff_t i_max_size; /* size authorized by mds */ + loff_t i_max_size; /* size authorized by mds */ + loff_t i_reported_size; /* size we're reported to mds(s) */ struct timespec i_old_atime; /* held references to caps */ @@ -376,7 +376,7 @@ extern int ceph_get_cap_refs(struct ceph_inode_info *ci, int need, int want, int extern void ceph_take_cap_refs(struct ceph_inode_info *ci, int got); extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had); extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr); -extern void ceph_check_caps_wanted(struct ceph_inode_info *ci, gfp_t gfpmask); +extern void ceph_check_caps(struct ceph_inode_info *ci, gfp_t gfpmask); extern void ceph_get_mode(struct ceph_inode_info *ci, int mode); extern void ceph_put_mode(struct ceph_inode_info *ci, int mode); diff --git a/src/mds/Locker.cc b/src/mds/Locker.cc index b6f6fd1faf9e2..4d29c912cb23c 100644 --- a/src/mds/Locker.cc +++ b/src/mds/Locker.cc @@ -560,7 +560,7 @@ bool Locker::issue_caps(CInode *in) inode_t *latest = in->get_projected_inode(); int64_t inc = in->get_layout_size_increment(); if (latest->size + inc > latest->max_size) { - int64_t new_max = ROUND_UP_TO(latest->size + inc/2, inc); + int64_t new_max = latest->max_size ? (latest->max_size << 1):inc; dout(10) << "increasing max_size " << latest->max_size << " -> " << new_max << dendl; inode_t *pi = in->project_inode(); @@ -925,7 +925,7 @@ void Locker::handle_client_file_caps(MClientFileCaps *m) pi->max_size = 0; } else if (increase_max) { int64_t inc = in->get_layout_size_increment(); - int64_t new_max = ROUND_UP_TO(latest->size + inc, inc); + int64_t new_max = latest->max_size ? (latest->max_size << 1):inc; dout(7) << " increasing max_size " << pi->max_size << " to " << new_max << dendl; pi->max_size = new_max; } @@ -952,7 +952,7 @@ void Locker::handle_client_file_caps(MClientFileCaps *m) le->metablob.add_dir_context(in->get_parent_dir()); le->metablob.add_primary_dentry(in->parent, true, 0, pi); LogSegment *ls = mds->mdlog->get_current_segment(); - mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, ls)); + mds->mdlog->submit_entry(le, new C_Locker_FileUpdate_finish(this, in, ls, increase_max)); file_wrlock_start(&in->filelock); // wrlock for duration of journal } diff --git a/src/messages/MClientUnmount.h b/src/messages/MClientUnmount.h index 97e40c4c17168..4848a5bb86491 100644 --- a/src/messages/MClientUnmount.h +++ b/src/messages/MClientUnmount.h @@ -20,21 +20,11 @@ class MClientUnmount : public Message { public: MClientUnmount() : Message(CEPH_MSG_CLIENT_UNMOUNT) { } - /* - MClientUnmount(entity_inst_t i) : - Message(CEPH_MSG_CLIENT_UNMOUNT), - inst(i) { } - */ - + const char *get_type_name() { return "client_unmount"; } - void decode_payload() { - //int off = 0; - //::_decode(inst, payload, off); - } - void encode_payload() { - //::_encode(inst, payload); - } + void decode_payload() { } + void encode_payload() { } }; #endif -- 2.39.5