From 9d8e4e8a384d2f443694a816d41f414e3e9715f6 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 20 Aug 2008 09:36:24 -0700 Subject: [PATCH] kclient: introduce ceph_cap_snap --- src/kernel/caps.c | 58 ++++++++++++++++++++--------------------- src/kernel/mds_client.c | 12 ++++----- src/kernel/mds_client.h | 7 +---- src/kernel/super.c | 1 + src/kernel/super.h | 37 +++++++++++++++++++------- 5 files changed, 64 insertions(+), 51 deletions(-) diff --git a/src/kernel/caps.c b/src/kernel/caps.c index 695c04a9700b3..c977b443f9653 100644 --- a/src/kernel/caps.c +++ b/src/kernel/caps.c @@ -12,14 +12,14 @@ int ceph_debug_caps = -1; #include "messenger.h" -static struct ceph_inode_cap *__get_cap_for_mds(struct inode *inode, int mds) +static struct ceph_cap *__get_cap_for_mds(struct inode *inode, int mds) { struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_inode_cap *cap; + struct ceph_cap *cap; struct rb_node *n = ci->i_caps.rb_node; while (n) { - cap = rb_entry(n, struct ceph_inode_cap, ci_node); + cap = rb_entry(n, struct ceph_cap, ci_node); if (mds < cap->mds) n = n->rb_left; else if (mds > cap->mds) @@ -31,15 +31,15 @@ static struct ceph_inode_cap *__get_cap_for_mds(struct inode *inode, int mds) } static void __insert_cap_node(struct ceph_inode_info *ci, - struct ceph_inode_cap *new) + struct ceph_cap *new) { struct rb_node **p = &ci->i_caps.rb_node; struct rb_node *parent = NULL; - struct ceph_inode_cap *cap = 0; + struct ceph_cap *cap = 0; while (*p) { parent = *p; - cap = rb_entry(parent, struct ceph_inode_cap, ci_node); + cap = rb_entry(parent, struct ceph_cap, ci_node); if (new->mds < cap->mds) p = &(*p)->rb_left; else if (new->mds > cap->mds) @@ -55,7 +55,7 @@ static void __insert_cap_node(struct ceph_inode_info *ci, int ceph_get_cap_mds(struct inode *inode) { struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_inode_cap *cap; + struct ceph_cap *cap; int mds = -1; /* @@ -63,7 +63,7 @@ int ceph_get_cap_mds(struct inode *inode) */ spin_lock(&inode->i_lock); if (!RB_EMPTY_ROOT(&ci->i_caps)) { - cap = rb_entry(ci->i_caps.rb_node, struct ceph_inode_cap, + cap = rb_entry(ci->i_caps.rb_node, struct ceph_cap, ci_node); mds = cap->mds; } @@ -84,7 +84,7 @@ int ceph_add_cap(struct inode *inode, { int mds = session->s_mds; struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_inode_cap *cap, *new_cap = 0; + struct ceph_cap *cap, *new_cap = 0; int i; int is_first = 0; struct ceph_snaprealm *realm = 0; @@ -166,13 +166,13 @@ retry: int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented) { int have = ci->i_snap_caps; - struct ceph_inode_cap *cap; + struct ceph_cap *cap; u32 gen; unsigned long ttl; struct rb_node *p; for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { - cap = rb_entry(p, struct ceph_inode_cap, ci_node); + cap = rb_entry(p, struct ceph_cap, ci_node); spin_lock(&cap->session->s_cap_lock); gen = cap->session->s_cap_gen; @@ -198,7 +198,7 @@ int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented) * caller should hold i_lock, snap_rwsem, and session s_mutex. * returns true if this is the last cap. if so, caller should iput. */ -int __ceph_remove_cap(struct ceph_inode_cap *cap) +int __ceph_remove_cap(struct ceph_cap *cap) { struct ceph_mds_session *session = cap->session; struct ceph_inode_info *ci = cap->ci; @@ -228,7 +228,7 @@ int __ceph_remove_cap(struct ceph_inode_cap *cap) /* * caller should hold snap_rwsem and session s_mutex. */ -void ceph_remove_cap(struct ceph_inode_cap *cap) +void ceph_remove_cap(struct ceph_cap *cap) { struct inode *inode = &cap->ci->vfs_inode; int was_last; @@ -272,7 +272,7 @@ void ceph_check_caps(struct ceph_inode_info *ci, int is_delayed, int flush_snap) struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode); struct ceph_mds_client *mdsc = &client->mdsc; struct inode *inode = &ci->vfs_inode; - struct ceph_inode_cap *cap; + struct ceph_cap *cap; int wanted, used; struct ceph_mds_session *session = 0; /* if non-NULL, i hold s_mutex */ int took_snap_rwsem = 0; /* true if mdsc->snap_rwsem held */ @@ -291,7 +291,7 @@ retry: __ceph_cap_delay_requeue(mdsc, ci); for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { - cap = rb_entry(p, struct ceph_inode_cap, ci_node); + cap = rb_entry(p, struct ceph_cap, ci_node); if (mds >= cap->mds) continue; @@ -374,8 +374,8 @@ ack: mds = cap->mds; /* remember mds, so we don't repeat */ /* send_cap drops i_lock */ - __ceph_mdsc_send_cap(mdsc, session, cap, - used, wanted, flush_snap); + __ceph_send_cap(mdsc, session, cap, + used, wanted, flush_snap); goto retry; /* retake i_lock and restart our cap scan. */ } @@ -561,7 +561,7 @@ static void send_cap(struct ceph_mds_client *mdsc, __u64 ino, int op, static int handle_cap_grant(struct inode *inode, struct ceph_mds_caps *grant, struct ceph_mds_session *session) { - struct ceph_inode_cap *cap; + struct ceph_cap *cap; struct ceph_inode_info *ci = ceph_inode(inode); int mds = session->s_mds; int seq = le32_to_cpu(grant->seq); @@ -707,7 +707,7 @@ static void handle_cap_released(struct inode *inode, struct ceph_inode_info *ci = ceph_inode(inode); int seq = le32_to_cpu(m->seq); int removed_last; - struct ceph_inode_cap *cap; + struct ceph_cap *cap; dout(10, "handle_cap_released inode %p ci %p mds%d seq %d\n", inode, ci, session->s_mds, seq); @@ -797,7 +797,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, struct ceph_inode_info *ci = ceph_inode(inode); int mds = session->s_mds; unsigned mseq = le32_to_cpu(ex->migrate_seq); - struct ceph_inode_cap *cap = 0, *t; + struct ceph_cap *cap = 0, *t; struct rb_node *p; int was_last = 0; @@ -808,7 +808,7 @@ static void handle_cap_export(struct inode *inode, struct ceph_mds_caps *ex, /* make sure we haven't seen a higher mseq */ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) { - t = rb_entry(p, struct ceph_inode_cap, ci_node); + t = rb_entry(p, struct ceph_cap, ci_node); if (t->mseq > mseq) { dout(10, " higher mseq on cap from mds%d\n", t->session->s_mds); @@ -982,11 +982,11 @@ bad: * * returns true if we removed the last cap on this inode. */ -int __ceph_mdsc_send_cap(struct ceph_mds_client *mdsc, - struct ceph_mds_session *session, - struct ceph_inode_cap *cap, - int used, int wanted, - int flush_snap) +int __ceph_send_cap(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, + struct ceph_cap *cap, + int used, int wanted, + int flush_snap) { struct ceph_inode_info *ci = cap->ci; struct inode *inode = &ci->vfs_inode; @@ -1078,8 +1078,8 @@ void ceph_flush_write_caps(struct ceph_mds_client *mdsc, struct list_head *p, *n; list_for_each_safe (p, n, &session->s_caps) { - struct ceph_inode_cap *cap = - list_entry(p, struct ceph_inode_cap, session_caps); + struct ceph_cap *cap = + list_entry(p, struct ceph_cap, session_caps); struct inode *inode = &cap->ci->vfs_inode; int used, wanted; @@ -1099,7 +1099,7 @@ void ceph_flush_write_caps(struct ceph_mds_client *mdsc, used = wanted = 0; } - __ceph_mdsc_send_cap(mdsc, session, cap, used, wanted, 0); + __ceph_send_cap(mdsc, session, cap, used, wanted, 0); } } diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index 54b2aebed8e1d..c4ba343b8fd6a 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -606,7 +606,7 @@ static int open_session(struct ceph_mds_client *mdsc, */ static void remove_session_caps(struct ceph_mds_session *session) { - struct ceph_inode_cap *cap; + struct ceph_cap *cap; struct ceph_inode_info *ci; /* @@ -615,7 +615,7 @@ static void remove_session_caps(struct ceph_mds_session *session) */ dout(10, "remove_session_caps on %p\n", session); while (session->s_nr_caps > 0) { - cap = list_entry(session->s_caps.next, struct ceph_inode_cap, + cap = list_entry(session->s_caps.next, struct ceph_cap, session_caps); ci = cap->ci; dout(10, "removing cap %p, ci is %p, inode is %p\n", @@ -752,11 +752,11 @@ static void remove_session_leases(struct ceph_mds_session *session) static void wake_up_session_caps(struct ceph_mds_session *session) { struct list_head *p; - struct ceph_inode_cap *cap; + struct ceph_cap *cap; dout(10, "wake_up_session_caps %p mds%d\n", session, session->s_mds); list_for_each(p, &session->s_caps) { - cap = list_entry(p, struct ceph_inode_cap, session_caps); + cap = list_entry(p, struct ceph_cap, session_caps); dout(20, "waking up waiters on %p\n", &cap->ci->vfs_inode); wake_up(&cap->ci->i_cap_wq); } @@ -1285,7 +1285,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds) int newlen, len = 4 + 1; void *p, *end; struct list_head *cp; - struct ceph_inode_cap *cap; + struct ceph_cap *cap; char *path; int pathlen, err; u64 pathbase; @@ -1340,7 +1340,7 @@ retry: ceph_encode_32(&p, session->s_nr_caps); count = 0; list_for_each(cp, &session->s_caps) { - cap = list_entry(cp, struct ceph_inode_cap, session_caps); + cap = list_entry(cp, struct ceph_cap, session_caps); ci = cap->ci; ceph_decode_need(&p, end, sizeof(u64) + sizeof(struct ceph_mds_cap_reconnect), diff --git a/src/kernel/mds_client.h b/src/kernel/mds_client.h index 768ad0aa7ebba..9610f88a4ac9a 100644 --- a/src/kernel/mds_client.h +++ b/src/kernel/mds_client.h @@ -12,7 +12,7 @@ #include "mdsmap.h" struct ceph_client; -struct ceph_inode_cap; +struct ceph_cap; /* * for mds reply parsing @@ -186,11 +186,6 @@ extern int ceph_mdsc_do_request(struct ceph_mds_client *mdsc, struct ceph_mds_request *req); extern void ceph_mdsc_put_request(struct ceph_mds_request *req); -extern int __ceph_mdsc_send_cap(struct ceph_mds_client *mdsc, - struct ceph_mds_session *session, - struct ceph_inode_cap *cap, - int used, int wanted, - int flush_snap); extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc); #endif diff --git a/src/kernel/super.c b/src/kernel/super.c index 3115c9fdf84ba..5318ff43f15ce 100644 --- a/src/kernel/super.c +++ b/src/kernel/super.c @@ -173,6 +173,7 @@ static struct inode *ceph_alloc_inode(struct super_block *sb) for (i = 0; i < CEPH_FILE_MODE_NUM; i++) ci->i_nr_by_mode[i] = 0; init_waitqueue_head(&ci->i_cap_wq); + INIT_LIST_HEAD(&ci->i_cap_snaps); ci->i_wanted_max_size = 0; ci->i_requested_max_size = 0; diff --git a/src/kernel/super.h b/src/kernel/super.h index c8e6c2ba94491..78d83bccf9007 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -166,10 +166,11 @@ static inline struct ceph_client *ceph_client(struct super_block *sb) } /* - * CEPH file system in-core inode info + * file i/o capability */ +#define STATIC_CAPS 1 -struct ceph_inode_cap { +struct ceph_cap { struct ceph_inode_info *ci; struct rb_node ci_node; /* per-ci cap tree */ struct ceph_mds_session *session; @@ -182,12 +183,23 @@ struct ceph_inode_cap { u64 flushed_snap; }; -#define MAX_DIRFRAG_REP 4 +/* + * snapped cap state, pending flush to mds + */ +struct ceph_cap_snap { + struct list_head ci_item; + int mds; + u64 follows; + u64 size; + struct timespec mtime, atime; +}; /* * a _leaf_ frag will be present in the i_fragtree IFF there is * delegation info. that is, if mds >= 0 || ndist > 0. */ +#define MAX_DIRFRAG_REP 4 + struct ceph_inode_frag { struct rb_node node; @@ -201,7 +213,6 @@ struct ceph_inode_frag { int dist[MAX_DIRFRAG_REP]; }; -#define STATIC_CAPS 1 struct ceph_dir_info { u64 nfiles, nsubdirs; @@ -234,19 +245,20 @@ struct ceph_inode_info { char *i_xattr_data; struct rb_root i_caps; - struct ceph_inode_cap i_static_caps[STATIC_CAPS]; + struct ceph_cap i_static_caps[STATIC_CAPS]; wait_queue_head_t i_cap_wq; unsigned long i_hold_caps_until; /* jiffies */ struct list_head i_cap_delay_list; int i_cap_exporting_mds; unsigned i_cap_exporting_mseq; unsigned i_cap_exporting_issued; - unsigned i_snap_caps; + struct list_head i_cap_snaps; + unsigned i_snap_caps; /* cap bits for snap i/o */ int i_nr_by_mode[CEPH_FILE_MODE_NUM]; - loff_t i_max_size; /* size authorized by mds */ + loff_t i_max_size; /* size authorized by mds */ loff_t i_reported_size; /* (max_)size reported to or requested of mds */ - loff_t i_wanted_max_size; /* offset we'd like to write too */ + loff_t i_wanted_max_size; /* offset we'd like to write too */ loff_t i_requested_max_size; /* max_size we've requested */ struct timespec i_old_atime; @@ -564,8 +576,8 @@ extern int ceph_add_cap(struct inode *inode, int fmode, unsigned issued, unsigned cap, unsigned seq, void *snapblob, int snapblob_len); -extern int __ceph_remove_cap(struct ceph_inode_cap *cap); -extern void ceph_remove_cap(struct ceph_inode_cap *cap); +extern int __ceph_remove_cap(struct ceph_cap *cap); +extern void ceph_remove_cap(struct ceph_cap *cap); extern void ceph_remove_all_caps(struct ceph_inode_info *ci); extern int ceph_get_cap_mds(struct inode *inode); extern int ceph_get_cap_refs(struct ceph_inode_info *ci, int need, int want, int *got, loff_t offset); @@ -577,6 +589,11 @@ extern void ceph_check_delayed_caps(struct ceph_mds_client *mdsc); extern void ceph_flush_write_caps(struct ceph_mds_client *mdsc, struct ceph_mds_session *session, int purge); +extern int __ceph_send_cap(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, + struct ceph_cap *cap, + int used, int wanted, + int flush_snap); /* addr.c */ extern const struct address_space_operations ceph_aops; -- 2.39.5