From: Sage Weil Date: Mon, 31 Mar 2008 19:05:25 +0000 (-0700) Subject: kclient: reworked cap-related locking, now protected by i_lock X-Git-Tag: v0.2~239 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=293dcab2ec2cdacdb1cbaef5f3e419530c9e3da5;p=ceph.git kclient: reworked cap-related locking, now protected by i_lock --- diff --git a/src/kernel/dir.c b/src/kernel/dir.c index f92990e392c4..ab8036f67a49 100644 --- a/src/kernel/dir.c +++ b/src/kernel/dir.c @@ -487,38 +487,49 @@ static int ceph_dir_rename(struct inode *old_dir, struct dentry *old_dentry, return err; } +/* + * check if dentry lease, or parent directory inode lease or cap says + * this dentry is still valid + */ static int ceph_d_revalidate(struct dentry *dentry, struct nameidata *nd) { - int mds = (long)dentry->d_fsdata; struct inode *dir = dentry->d_parent->d_inode; struct ceph_inode_info *dirci = ceph_inode(dir); + struct ceph_dentry_info *di; - dout(20, "d_revalidate ttl %lu mds %d now %lu\n", dentry->d_time, - mds, jiffies); - /* does dir inode lease or cap cover it? */ + spin_lock(&dirci->vfs_inode.i_lock); if (dirci->i_lease_session && time_after(dirci->i_lease_ttl, jiffies) && (dirci->i_lease_mask & CEPH_LOCK_ICONTENT)) { dout(20, "d_revalidate have ICONTENT on dir inode %p, ok\n", dir); - return 1; + goto inode_ok; } - if (ceph_caps_issued(dirci) & (CEPH_CAP_EXCL|CEPH_CAP_RDCACHE)) { + if (__ceph_caps_issued(dirci) & (CEPH_CAP_EXCL|CEPH_CAP_RDCACHE)) { dout(20, "d_revalidate have EXCL|RDCACHE caps on dir inode %p" ", ok\n", dir); - return 1; + goto inode_ok; } + spin_unlock(&dirci->vfs_inode.i_lock); /* dentry lease? */ - if (mds >= 0 && time_after(dentry->d_time, jiffies)) { + spin_lock(&dentry->d_lock); + di = ceph_dentry(dentry); + if (di && time_after(dentry->d_time, jiffies)) { dout(20, "d_revalidate - dentry %p lease valid\n", dentry); + spin_unlock(&dentry->d_lock); return 1; } + spin_unlock(&dentry->d_lock); dout(20, "d_revalidate - dentry %p expired\n", dentry); d_drop(dentry); return 0; + +inode_ok: + spin_unlock(&dirci->vfs_inode.i_lock); + return 1; } static void ceph_d_release(struct dentry *dentry) diff --git a/src/kernel/file.c b/src/kernel/file.c index 97a65c59d91f..3831a6245d96 100644 --- a/src/kernel/file.c +++ b/src/kernel/file.c @@ -54,24 +54,14 @@ static int ceph_init_file(struct inode *inode, struct file *file, struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_file_info *cf; int mode = ceph_file_mode(flags); - int wanted; cf = kzalloc(sizeof(*cf), GFP_KERNEL); if (cf == NULL) return -ENOMEM; file->private_data = cf; - spin_lock(&inode->i_lock); cf->mode = mode; - ci->i_nr_by_mode[mode]++; - wanted = ceph_caps_wanted(ci); - dout(10, "init_file %p flags 0%o mode %d nr now %d. wanted %d -> %d\n", - file, flags, - mode, ci->i_nr_by_mode[mode], - ci->i_cap_wanted, ci->i_cap_wanted|wanted); - ci->i_cap_wanted |= wanted; /* FIXME this isn't quite right */ - spin_unlock(&inode->i_lock); - + ceph_get_mode(ci, mode); return 0; } @@ -95,11 +85,6 @@ int ceph_open(struct inode *inode, struct file *file) return 0; } - /* - if (file->f_flags == O_DIRECTORY && ... ) - cap = ceph_find_cap(inode, 0); - */ - req = prepare_open_request(inode->i_sb, dentry, flags, 0); if (IS_ERR(req)) return PTR_ERR(req); @@ -158,8 +143,6 @@ int ceph_release(struct inode *inode, struct file *file) { struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_file_info *cf = file->private_data; - int mode = cf->mode; - int wanted; dout(5, "release inode %p file %p\n", inode, file); @@ -172,16 +155,8 @@ int ceph_release(struct inode *inode, struct file *file) * ceph_file: released 000000006fa3ebd0 flags 0100001 mode 3 nr now -1. wanted 30 was 30 * for now, store the open mode in ceph_file_info. */ - mode = cf->mode; - ci->i_nr_by_mode[mode]--; - wanted = ceph_caps_wanted(ci); - dout(10, "released %p flags 0%o mode %d nr now %d, wanted %d -> %d\n", - file, file->f_flags, mode, - ci->i_nr_by_mode[mode], wanted, ci->i_cap_wanted); - wanted |= ceph_caps_used(ci); - if (wanted != ci->i_cap_wanted) - ceph_mdsc_update_cap_wanted(ci, wanted); - + + ceph_put_mode(ci, cf->mode); if (cf->last_readdir) ceph_mdsc_put_request(cf->last_readdir); kfree(cf); diff --git a/src/kernel/inode.c b/src/kernel/inode.c index 6ad935ca1323..abb24b30b468 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -81,7 +81,7 @@ int ceph_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *info) /* be careful with mtime, atime, size */ ceph_decode_timespec(&atime, &info->atime); ceph_decode_timespec(&mtime, &info->mtime); - issued = ceph_caps_issued(ci); + issued = __ceph_caps_issued(ci); spin_lock(&inode->i_lock); if (issued & (CEPH_CAP_WR|CEPH_CAP_WRBUFFER)) { if ((issued & CEPH_CAP_EXCL) == 0) { @@ -225,7 +225,10 @@ void ceph_update_inode_lease(struct inode *inode, void ceph_revoke_inode_lease(struct ceph_inode_info *ci, int mask) { int drop = 0; + spin_lock(&ci->vfs_inode.i_lock); + dout(10, "revoke_inode_lease on inode %p, mask %d -> %d\n", + &ci->vfs_inode, ci->i_lease_mask, ci->i_lease_mask & ~mask); ci->i_lease_mask &= ~mask; if (ci->i_lease_mask == 0) { spin_lock(&ci->i_lease_session->s_cap_lock); @@ -241,6 +244,7 @@ void ceph_revoke_inode_lease(struct ceph_inode_info *ci, int mask) } } + /* * dentry lease lock order is * dentry->d_lock @@ -558,24 +562,7 @@ int ceph_readdir_prepopulate(struct ceph_mds_request *req) * capabilities */ -struct ceph_inode_cap *ceph_find_cap(struct inode *inode, int want) -{ - struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_inode_cap *cap; - struct list_head *p; - - list_for_each(p, &ci->i_caps) { - cap = list_entry(p, struct ceph_inode_cap, ci_caps); - if ((cap->caps & want) == want) { - dout(40, "find_cap found %p caps %d want %d\n", cap, - cap->caps, want); - return cap; - } - } - return 0; -} - -static struct ceph_inode_cap *get_cap_for_mds(struct inode *inode, int mds) +static struct ceph_inode_cap *__get_cap_for_mds(struct inode *inode, int mds) { struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_inode_cap *cap; @@ -589,37 +576,53 @@ static struct ceph_inode_cap *get_cap_for_mds(struct inode *inode, int mds) return 0; } - -struct ceph_inode_cap *ceph_add_cap(struct inode *inode, struct ceph_mds_session *session, u32 caps, u32 seq) +/* + * lock ordering is + * inode->i_lock + * session->s_cap_lock + */ +struct ceph_inode_cap *ceph_add_cap(struct inode *inode, + struct ceph_mds_session *session, + u32 caps, u32 seq) { int mds = session->s_mds; struct ceph_inode_info *ci = ceph_inode(inode); - struct ceph_inode_cap *cap; + struct ceph_inode_cap *cap, *new_cap = 0; int i; + int is_new = 0; - dout(10, "ceph_add_cap on %p mds%d cap %d seq %d\n", inode, session->s_mds, caps, seq); - cap = get_cap_for_mds(inode, mds); + dout(10, "ceph_add_cap on %p mds%d cap %d seq %d\n", inode, + session->s_mds, caps, seq); + spin_lock(&inode->i_lock); + cap = __get_cap_for_mds(inode, mds); if (!cap) { for (i=0; ii_static_caps[i].mds == -1) { cap = &ci->i_static_caps[i]; break; } - if (!cap) - cap = kmalloc(sizeof(*cap), GFP_KERNEL); - if (cap == 0) - return ERR_PTR(-ENOMEM); + if (!cap) { + if (new_cap) + cap = new_cap; + else { + spin_unlock(&inode->i_lock); + new_cap = kmalloc(sizeof(*cap), GFP_KERNEL); + if (new_cap == 0) + return ERR_PTR(-ENOMEM); + spin_lock(&inode->i_lock); + } + } + is_new = 1; /* grab inode later */ cap->caps = 0; cap->mds = mds; cap->seq = 0; cap->flags = 0; - if (list_empty(&ci->i_caps)) - igrab(inode); cap->ci = ci; list_add(&cap->ci_caps, &ci->i_caps); + /* add to session cap list */ cap->session = session; spin_lock(&session->s_cap_lock); list_add(&cap->session_caps, &session->s_caps); @@ -631,10 +634,13 @@ struct ceph_inode_cap *ceph_add_cap(struct inode *inode, struct ceph_mds_session inode, ceph_ino(inode), caps, caps|cap->caps, seq, mds); cap->caps |= caps; cap->seq = seq; + spin_unlock(&inode->i_lock); + if (is_new) + igrab(inode); return cap; } -int ceph_caps_issued(struct ceph_inode_info *ci) +int __ceph_caps_issued(struct ceph_inode_info *ci) { int have = 0; struct ceph_inode_cap *cap; @@ -647,49 +653,121 @@ int ceph_caps_issued(struct ceph_inode_info *ci) return have; } -void ceph_remove_cap(struct ceph_inode_cap *cap) +void __ceph_remove_cap(struct ceph_inode_cap *cap) { struct ceph_mds_session *session = cap->session; - struct ceph_inode_info *ci = cap->ci; - dout(10, "ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode); + dout(10, "__ceph_remove_cap %p from %p\n", cap, &cap->ci->vfs_inode); /* remove from session list */ spin_lock(&session->s_cap_lock); list_del(&cap->session_caps); session->s_nr_caps--; - cap->session = 0; spin_unlock(&session->s_cap_lock); /* remove from inode list */ - spin_lock(&ci->vfs_inode.i_lock); list_del(&cap->ci_caps); - if (list_empty(&ci->i_caps)) - iput(&ci->vfs_inode); - cap->ci = 0; + cap->session = 0; cap->mds = -1; /* mark unused */ - spin_unlock(&ci->vfs_inode.i_lock); - if (cap < ci->i_static_caps || cap >= ci->i_static_caps + STATIC_CAPS) + if (cap < cap->ci->i_static_caps || + cap >= cap->ci->i_static_caps + STATIC_CAPS) kfree(cap); } -void ceph_remove_all_caps(struct ceph_inode_info *ci) +void ceph_remove_cap(struct ceph_inode_cap *cap) { + struct inode *inode = &cap->ci->vfs_inode; + + spin_lock(&inode->i_lock); + __ceph_remove_cap(cap); + spin_unlock(&inode->i_lock); + iput(inode); +} + +/* + * examine currently wanted versus held caps, and release caps to mds + * as appropriate. + */ +void ceph_check_caps_wanted(struct ceph_inode_info *ci) +{ + struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode); + struct ceph_mds_client *mdsc = &client->mdsc; struct ceph_inode_cap *cap; - dout(10, "remove_caps on %p\n", &ci->vfs_inode); - while (!list_empty(&ci->i_caps)) { - cap = list_entry(ci->i_caps.next, struct ceph_inode_cap, - ci_caps); - ceph_remove_cap(cap); + struct list_head *p; + int wanted; + int keep; + __u64 seq; + __u64 size, max_size; + struct timespec mtime, atime; + int mds; + +retry: + spin_lock(&ci->vfs_inode.i_lock); + wanted = __ceph_caps_wanted(ci); + + list_for_each(p, &ci->i_caps) { + cap = list_entry(p, struct ceph_inode_cap, ci_caps); + if ((cap->caps & ~wanted) == 0) + continue; /* nothing extra, all good */ + + cap->caps &= wanted; /* drop bits we don't want */ + + keep = cap->caps; + seq = cap->seq; + size = ci->vfs_inode.i_size; + max_size = ci->i_max_size; + mtime = ci->vfs_inode.i_mtime; + atime = ci->vfs_inode.i_atime; + mds = cap->mds; + if (wanted == 0) + __ceph_remove_cap(cap); + spin_unlock(&ci->vfs_inode.i_lock); + + ceph_mdsc_send_cap_ack(mdsc, ceph_ino(&ci->vfs_inode), + keep, wanted, seq, + size, max_size, &mtime, &atime, mds); + + if (wanted == 0) + iput(&ci->vfs_inode); /* removed cap */ + goto retry; } + + /* okay */ + spin_unlock(&ci->vfs_inode.i_lock); } +/* + * called on struct file init and release, to safely track which + * capabilities we want due to currently open files + */ +void ceph_get_mode(struct ceph_inode_info *ci, int mode) +{ + spin_lock(&ci->vfs_inode.i_lock); + ci->i_nr_by_mode[mode]++; + spin_unlock(&ci->vfs_inode.i_lock); +} + +void ceph_put_mode(struct ceph_inode_info *ci, int mode) +{ + int last = 0; + + spin_lock(&ci->vfs_inode.i_lock); + if (--ci->i_nr_by_mode[mode] == 0) + last++; + spin_unlock(&ci->vfs_inode.i_lock); + + if (last) + ceph_check_caps_wanted(ci); +} + + /* * 0 - ok * 1 - send the msg back to mds */ -int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant, struct ceph_mds_session *session) +int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant, + struct ceph_mds_session *session) { struct ceph_inode_cap *cap; struct ceph_inode_info *ci = ceph_inode(inode); @@ -698,7 +776,7 @@ int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant, int newcaps; int used; int issued; /* to me, before */ - int wanted = ceph_caps_wanted(ci) | ceph_caps_used(ci); + int wanted; int ret = 0; u64 size = le64_to_cpu(grant->size); u64 max_size = le64_to_cpu(grant->max_size); @@ -707,7 +785,6 @@ int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant, dout(10, "handle_cap_grant inode %p ci %p mds%d seq %d\n", inode, ci, mds, seq); - dout(10, " my wanted = %d\n", wanted); dout(10, " size %llu max_size %llu\n", size, max_size); /* size change? */ @@ -724,7 +801,7 @@ int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant, } /* mtime/atime? */ - issued = ceph_caps_issued(ci); + issued = __ceph_caps_issued(ci); if ((issued & CEPH_CAP_EXCL) == 0) { ceph_decode_timespec(&mtime, &grant->mtime); ceph_decode_timespec(&atime, &grant->atime); @@ -742,9 +819,8 @@ int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant, } } - cap = get_cap_for_mds(inode, mds); - /* do we have this cap? */ + cap = __get_cap_for_mds(inode, mds); if (!cap) { /* * then ignore. never reply to cap messages out of turn, @@ -756,20 +832,21 @@ int ceph_handle_cap_grant(struct inode *inode, struct ceph_mds_file_caps *grant, goto out; } - cap->seq = seq; - + wanted = __ceph_caps_wanted(ci); + used = __ceph_caps_used(ci); + dout(10, " my wanted = %d, used = %d\n", wanted, used); if (wanted != le32_to_cpu(grant->wanted)) { - dout(10, "wanted %d -> %d\n", le32_to_cpu(grant->wanted), + dout(10, "mds wanted %d -> %d\n", le32_to_cpu(grant->wanted), wanted); grant->wanted = cpu_to_le32(wanted); } + cap->seq = seq; + /* revocation? */ newcaps = le32_to_cpu(grant->caps); if (cap->caps & ~newcaps) { - used = ceph_caps_used(ci); - dout(10, "revocation: %d -> %d, used %d\n", cap->caps, - newcaps, used); + dout(10, "revocation: %d -> %d\n", cap->caps, newcaps); if (newcaps & used) { /* FIXME FIXME FIXME DO STUFF HERE */ /* but blindly ack for now... */ @@ -835,7 +912,7 @@ int ceph_get_cap_refs(struct ceph_inode_info *ci, int need, int want, int *got) dout(10, "get_cap_refs on %p need %d want %d\n", &ci->vfs_inode, need, want); spin_lock(&ci->vfs_inode.i_lock); - have = ceph_caps_issued(ci); + have = __ceph_caps_issued(ci); if ((have & need) == need) { *got = need | (have & want); __take_cap_refs(ci, *got); @@ -849,7 +926,7 @@ int ceph_get_cap_refs(struct ceph_inode_info *ci, int need, int want, int *got) void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) { - int last = 0, wanted; + int last = 0; spin_lock(&ci->vfs_inode.i_lock); if (had & CEPH_CAP_RD) @@ -866,12 +943,8 @@ void ceph_put_cap_refs(struct ceph_inode_info *ci, int had) last++; spin_unlock(&ci->vfs_inode.i_lock); - if (last) { - wanted = ceph_caps_wanted(ci); - wanted |= ceph_caps_used(ci); - if (wanted != ci->i_cap_wanted) - ceph_mdsc_update_cap_wanted(ci, wanted); - } + if (last) + ceph_check_caps_wanted(ci); } @@ -988,7 +1061,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) ((ia_valid & ATTR_MTIME) && !timespec_equal(&inode->i_mtime, &attr->ia_mtime))) { /* do i hold CAP_EXCL? */ - if (ceph_caps_issued(ci) & CEPH_CAP_EXCL) { + if (__ceph_caps_issued(ci) & CEPH_CAP_EXCL) { dout(10, "utime holding EXCL, doing nothing\n"); inode->i_atime = attr->ia_atime; inode->i_mtime = attr->ia_mtime; @@ -1036,16 +1109,21 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) int ceph_inode_revalidate(struct inode *inode, int mask) { struct ceph_inode_info *ci = ceph_inode(inode); - int havemask = ci->i_lease_mask; + int havemask; + int valid; + spin_lock(&inode->i_lock); + havemask = ci->i_lease_mask; /* EXCL cap counts for an ICONTENT lease */ - if (ceph_caps_issued(ci) & CEPH_CAP_EXCL) + if (__ceph_caps_issued(ci) & CEPH_CAP_EXCL) havemask |= CEPH_LOCK_ICONTENT; /* any ICONTENT bits imply all bits */ if (havemask & CEPH_LOCK_ICONTENT) havemask |= CEPH_LOCK_ICONTENT; - - if (time_before(jiffies, ci->i_lease_ttl)) { + valid = time_before(jiffies, ci->i_lease_ttl); + spin_unlock(&inode->i_lock); + + if (valid) { if ((havemask & mask) == mask) { dout(10, "inode_revalidate %p mask %d still valid\n", inode, mask); @@ -1056,8 +1134,8 @@ int ceph_inode_revalidate(struct inode *inode, int mask) } else { dout(10, "inode_revalidate %p have %d want %d, lease expired\n", inode, havemask, mask); - ceph_revoke_inode_lease(ci, mask); } + return ceph_do_lookup(inode->i_sb, d_find_alias(inode), mask); } diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index 50c0754839d6..e56dc25d5655 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -607,13 +607,11 @@ static void remove_session_caps(struct ceph_mds_session *session) cap = list_entry(session->s_caps.next, struct ceph_inode_cap, session_caps); ci = cap->ci; - igrab(&ci->vfs_inode); dout(10, "removing cap %p, ci is %p, inode is %p\n", cap, ci, &ci->vfs_inode); spin_unlock(&session->s_cap_lock); ceph_remove_cap(cap); spin_lock(&session->s_cap_lock); - iput(&ci->vfs_inode); } BUG_ON(session->s_nr_caps > 0); spin_unlock(&session->s_cap_lock); @@ -1127,11 +1125,13 @@ retry: rec = p; p += sizeof(*rec); BUG_ON(p > end); - rec->wanted = cpu_to_le32(ceph_caps_wanted(ci)); - rec->issued = cpu_to_le32(ceph_caps_issued(ci)); + spin_lock(&ci->vfs_inode.i_lock); + rec->wanted = cpu_to_le32(__ceph_caps_wanted(ci)); + rec->issued = cpu_to_le32(__ceph_caps_issued(ci)); rec->size = cpu_to_le64(ci->vfs_inode.i_size); ceph_encode_timespec(&rec->mtime, &ci->vfs_inode.i_mtime); ceph_encode_timespec(&rec->atime, &ci->vfs_inode.i_atime); + spin_unlock(&ci->vfs_inode.i_lock); dentry = d_find_alias(&ci->vfs_inode); path = ceph_build_dentry_path(dentry, &pathlen); if (IS_ERR(path)) { @@ -1236,10 +1236,10 @@ void check_new_map(struct ceph_mds_client *mdsc, /* caps */ -void send_cap_ack(struct ceph_mds_client *mdsc, __u64 ino, int caps, - int wanted, __u32 seq, __u64 size, __u64 max_size, - struct timespec *mtime, struct timespec *atime, - int mds) +void ceph_mdsc_send_cap_ack(struct ceph_mds_client *mdsc, __u64 ino, int caps, + int wanted, __u32 seq, __u64 size, __u64 max_size, + struct timespec *mtime, struct timespec *atime, + int mds) { struct ceph_mds_file_caps *fc; struct ceph_msg *msg; @@ -1323,7 +1323,8 @@ void ceph_mdsc_handle_filecaps(struct ceph_mds_client *mdsc, if (!inode) { dout(10, "wtf, i don't have ino %lu=%llx? closing out cap\n", inot, ino); - send_cap_ack(mdsc, ino, 0, 0, seq, size, max_size, 0, 0, mds); + ceph_mdsc_send_cap_ack(mdsc, ino, 0, 0, seq, + size, max_size, 0, 0, mds); return; } @@ -1353,36 +1354,6 @@ bad: return; } -int ceph_mdsc_update_cap_wanted(struct ceph_inode_info *ci, int wanted) -{ - struct ceph_client *client = ceph_inode_to_client(&ci->vfs_inode); - struct ceph_mds_client *mdsc = &client->mdsc; - struct ceph_inode_cap *cap; - struct ceph_mds_session *session; - struct list_head *p; - - dout(10, "update_cap_wanted %d -> %d\n", ci->i_cap_wanted, wanted); - - list_for_each(p, &ci->i_caps) { - cap = list_entry(p, struct ceph_inode_cap, ci_caps); - - session = __get_session(mdsc, cap->mds); - BUG_ON(!session); - - cap->caps &= wanted; /* drop caps we don't want */ - send_cap_ack(mdsc, ceph_ino(&ci->vfs_inode), cap->caps, wanted, - cap->seq, ci->vfs_inode.i_size, ci->i_max_size, - &ci->vfs_inode.i_mtime, &ci->vfs_inode.i_atime, - cap->mds); - } - - ci->i_cap_wanted = wanted; - if (wanted == 0) - ceph_remove_all_caps(ci); - - return 0; -} - int send_renewcaps(struct ceph_mds_client *mdsc, int mds) { struct ceph_msg *msg; @@ -1454,11 +1425,7 @@ void ceph_mdsc_handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg) /* inode */ ci = ceph_inode(inode); - if (mask & ci->i_lease_mask) { - ceph_revoke_inode_lease(ci, mask); - dout(10, "lease mask %d revoked on inode %p, still have %d\n", - mask, inode, ci->i_lease_mask); - } + ceph_revoke_inode_lease(ci, mask); /* dentry */ if (mask & CEPH_LOCK_DN) { diff --git a/src/kernel/mds_client.h b/src/kernel/mds_client.h index 479d3a427a98..1d3a9cbb2ba1 100644 --- a/src/kernel/mds_client.h +++ b/src/kernel/mds_client.h @@ -125,8 +125,6 @@ extern void ceph_mdsc_handle_forward(struct ceph_mds_client *mdsc, extern void ceph_mdsc_handle_filecaps(struct ceph_mds_client *mdsc, struct ceph_msg *msg); -struct ceph_inode_info; -extern int ceph_mdsc_update_cap_wanted(struct ceph_inode_info *ci, int wanted); extern void ceph_mdsc_handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg); @@ -143,4 +141,11 @@ 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 void ceph_mdsc_send_cap_ack(struct ceph_mds_client *mdsc, __u64 ino, + int caps, int wanted, __u32 seq, + __u64 size, __u64 max_size, + struct timespec *mtime, + struct timespec *atime, + int mds); + #endif diff --git a/src/kernel/super.c b/src/kernel/super.c index 110e3451da9a..a32ab1b244c8 100644 --- a/src/kernel/super.c +++ b/src/kernel/super.c @@ -128,7 +128,6 @@ static struct inode *ceph_alloc_inode(struct super_block *sb) ci->i_static_caps[i].mds = -1; for (i = 0; i < 4; i++) ci->i_nr_by_mode[i] = 0; - ci->i_cap_wanted = 0; init_waitqueue_head(&ci->i_cap_wq); ci->i_rd_ref = ci->i_rdcache_ref = 0; diff --git a/src/kernel/super.h b/src/kernel/super.h index bc0499babd1b..ef7f13123a87 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -231,9 +231,23 @@ static inline int ceph_ino_compare(struct inode *inode, void *data) /* * caps helpers */ -extern int ceph_caps_issued(struct ceph_inode_info *ci); +extern int __ceph_caps_issued(struct ceph_inode_info *ci); -static inline int ceph_caps_wanted(struct ceph_inode_info *ci) +static inline int __ceph_caps_used(struct ceph_inode_info *ci) +{ + int used = 0; + if (ci->i_rd_ref) + used |= CEPH_CAP_RD; + if (ci->i_rdcache_ref) + used |= CEPH_CAP_RDCACHE; + if (ci->i_wr_ref) + used |= CEPH_CAP_WR; + if (ci->i_wrbuffer_ref) + used |= CEPH_CAP_WRBUFFER; + return used; +} + +static inline int __ceph_caps_file_wanted(struct ceph_inode_info *ci) { int want = 0; if (ci->i_nr_by_mode[0]) @@ -249,18 +263,9 @@ static inline int ceph_caps_wanted(struct ceph_inode_info *ci) return want; } -static inline int ceph_caps_used(struct ceph_inode_info *ci) +static inline int __ceph_caps_wanted(struct ceph_inode_info *ci) { - int used = 0; - if (ci->i_rd_ref) - used |= CEPH_CAP_RD; - if (ci->i_rdcache_ref) - used |= CEPH_CAP_RDCACHE; - if (ci->i_wr_ref) - used |= CEPH_CAP_WR; - if (ci->i_wrbuffer_ref) - used |= CEPH_CAP_WRBUFFER; - return used; + return __ceph_caps_file_wanted(ci) | __ceph_caps_used(ci); } static inline int ceph_file_mode(int flags) @@ -343,7 +348,6 @@ extern void ceph_update_dentry_lease(struct dentry *dentry, struct ceph_mds_session *session, unsigned long from_time); -extern struct ceph_inode_cap *ceph_find_cap(struct inode *inode, int want); extern struct ceph_inode_cap *ceph_add_cap(struct inode *inode, struct ceph_mds_session *session, u32 cap, u32 seq); @@ -357,6 +361,9 @@ extern int ceph_handle_cap_trunc(struct inode *inode, struct ceph_mds_session *session); extern int ceph_get_cap_refs(struct ceph_inode_info *ci, int need, int want, int *got); extern void ceph_put_cap_refs(struct ceph_inode_info *ci, int had); +extern void ceph_check_caps_wanted(struct ceph_inode_info *ci); +extern void ceph_get_mode(struct ceph_inode_info *ci, int mode); +extern void ceph_put_mode(struct ceph_inode_info *ci, int mode); extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); extern int ceph_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,