From 7cdcae227822dffbb34b4da6eaf8e5724982bbb8 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Sat, 19 Apr 2008 18:43:19 -0700 Subject: [PATCH] fixed up getattr --- src/kernel/dir.c | 41 +++++++++++++++++++++++++++------------ src/kernel/inode.c | 43 +++++++++++++++++++++++++---------------- src/kernel/mds_client.c | 7 +++++-- src/kernel/super.h | 4 ++-- 4 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/kernel/dir.c b/src/kernel/dir.c index 4d9e25608910e..feb31405b7a91 100644 --- a/src/kernel/dir.c +++ b/src/kernel/dir.c @@ -191,7 +191,13 @@ nextfrag: return 0; } -int ceph_do_lookup(struct super_block *sb, struct dentry *dentry, int mask) +/* + * do a lookup / lstat (same thing). + * @on_inode indicates that we should stat the ino, and not a path + * built from @dentry. + */ +int ceph_do_lookup(struct super_block *sb, struct dentry *dentry, int mask, + int on_inode) { struct ceph_client *client = ceph_sb_to_client(sb); struct ceph_mds_client *mdsc = &client->mdsc; @@ -204,14 +210,25 @@ int ceph_do_lookup(struct super_block *sb, struct dentry *dentry, int mask) if (dentry->d_name.len > NAME_MAX) return -ENAMETOOLONG; - dout(10, "do_lookup %p mask %d\n", dentry, CEPH_STAT_MASK_INODE_ALL); - path = ceph_build_dentry_path(dentry, &pathlen); - if (IS_ERR(path)) - return PTR_ERR(path); - req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSTAT, - ceph_ino(sb->s_root->d_inode), - path, 0, 0); - kfree(path); + dout(10, "do_lookup %p %d mask %d\n", dentry, dentry->d_count, mask); + if (atomic_read(&dentry->d_count) > 1) { + dout(10, "hey!\n"); + } + if (on_inode) { + /* stat ino directly */ + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSTAT, + ceph_ino(dentry->d_inode), 0, + 0, 0); + } else { + /* build path */ + path = ceph_build_dentry_path(dentry, &pathlen); + if (IS_ERR(path)) + return PTR_ERR(path); + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LSTAT, + ceph_ino(sb->s_root->d_inode), + path, 0, 0); + kfree(path); + } if (IS_ERR(req)) return PTR_ERR(req); rhead = req->r_request->front.iov_base; @@ -225,7 +242,7 @@ int ceph_do_lookup(struct super_block *sb, struct dentry *dentry, int mask) d_add(dentry, NULL); err = 0; } - dout(20, "do_lookup result=%d\n", err); + dout(20, "do_lookup %p %d result=%d\n", dentry, dentry->d_count, err); return err; } @@ -245,7 +262,7 @@ static struct dentry *ceph_dir_lookup(struct inode *dir, struct dentry *dentry, return ERR_PTR(err); } - err = ceph_do_lookup(dir->i_sb, dentry, CEPH_STAT_MASK_INODE_ALL); + err = ceph_do_lookup(dir->i_sb, dentry, CEPH_STAT_MASK_INODE_ALL, 0); if (err == -ENOENT) d_add(dentry, NULL); else if (err < 0) @@ -504,7 +521,7 @@ static int ceph_dentry_revalidate(struct dentry *dentry, struct nameidata *nd) { struct inode *dir = dentry->d_parent->d_inode; - dout(10, "d_revalidate %p '%.*s' inode %p\n", dentry, + dout(10, "d_revalidate %p %d '%.*s' inode %p\n", dentry, dentry->d_count, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); dout(10, "nd flags %d chdir=%d\n", nd->flags, nd->flags & LOOKUP_CHDIR); diff --git a/src/kernel/inode.c b/src/kernel/inode.c index 8284e71a2f789..700f1547a7da1 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -217,15 +217,16 @@ void ceph_update_inode_lease(struct inode *inode, struct ceph_inode_info *ci = ceph_inode(inode); __u64 ttl = le32_to_cpu(lease->duration_ms) * HZ; int is_new = 0; + int mask = le16_to_cpu(lease->mask); do_div(ttl, 1000); ttl += from_time; dout(10, "update_inode_lease %p mask %d duration %d ms ttl %llu\n", - inode, le16_to_cpu(lease->mask), le32_to_cpu(lease->duration_ms), + inode, mask, le32_to_cpu(lease->duration_ms), ttl); - if (lease->mask == 0) + if (mask == 0) return; spin_lock(&inode->i_lock); @@ -236,7 +237,7 @@ void ceph_update_inode_lease(struct inode *inode, if (ttl > ci->i_lease_ttl && (!ci->i_lease_session || ci->i_lease_session == session)) { ci->i_lease_ttl = ttl; - ci->i_lease_mask = le16_to_cpu(lease->mask); + ci->i_lease_mask = mask; if (!ci->i_lease_session) { ci->i_lease_session = session; is_new = 1; @@ -306,7 +307,7 @@ void ceph_update_dentry_lease(struct dentry *dentry, spin_lock(&dentry->d_lock); if (ttl < dentry->d_time) - goto fail_unlock; /* older. */ + goto fail_unlock; /* we already have a newer lease. */ di = ceph_dentry(dentry); if (!di) { @@ -512,17 +513,24 @@ retry_lookup: } ceph_update_inode_lease(dn->d_inode, rinfo->trace_ilease[d+1], session, req->r_from_time); + dout(10, "dput %p %d\n", parent, parent->d_count); dput(parent); parent = NULL; } - if (parent) + if (parent) { + dout(10, "dput %p %d\n", parent, parent->d_count); dput(parent); + } dout(10, "fill_trace done, last dn %p in %p\n", dn, in); - if (req->r_old_dentry) + if (req->r_old_dentry) { + dout(10, "dput %p %d\n", req->r_old_dentry, req->r_old_dentry->d_count); dput(req->r_old_dentry); - if (req->r_last_dentry) + } + if (req->r_last_dentry) { + dout(10, "dput %p %d\n", req->r_last_dentry, req->r_last_dentry->d_count); dput(req->r_last_dentry); + } if (req->r_last_inode) iput(req->r_last_inode); req->r_last_dentry = dn; @@ -601,6 +609,7 @@ retry_lookup: req->r_session, req->r_from_time); ceph_update_inode_lease(in, rinfo->dir_ilease[i], req->r_session, req->r_from_time); + dout(10, "dput %p %d\n", dn, dn->d_count); dput(dn); } dout(10, "readdir_prepopulate done\n"); @@ -1538,23 +1547,23 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) return 0; } - -int ceph_inode_revalidate(struct inode *inode, int mask) -{ - if (ceph_inode_lease_valid(inode, mask)) - return 0; - return ceph_do_lookup(inode->i_sb, d_find_alias(inode), mask); -} - int ceph_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { int err = 0; + int mask = CEPH_STAT_MASK_INODE_ALL; + dout(30, "ceph_inode_getattr dentry %p inode %p\n", dentry, dentry->d_inode); - err = ceph_inode_revalidate(dentry->d_inode, CEPH_STAT_MASK_INODE_ALL); - + if (!ceph_inode_lease_valid(dentry->d_inode, mask)) + /* + * if the dentry is unhashed, stat the ino directly: we + * presumably have an open capability. + */ + err = ceph_do_lookup(dentry->d_inode->i_sb, dentry, mask, + d_unhashed(dentry)); + dout(30, "ceph_inode_getattr returned %d\n", err); if (!err) generic_fillattr(dentry->d_inode, stat); diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index 6a25a35c25c96..704936555a568 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -375,7 +375,7 @@ void ceph_mdsc_put_request(struct ceph_mds_request *req) iput(req->r_last_inode); if (req->r_last_dentry) { dput(req->r_last_dentry); - dout(10, "dput %p\n", req->r_last_dentry); + dout(10, "dput %p %d\n", req->r_last_dentry, req->r_last_dentry->d_count); } drop_request_session_attempt_refs(req); kfree(req); @@ -637,7 +637,7 @@ void revoke_dentry_lease(struct dentry *dentry) } spin_unlock(&dentry->d_lock); if (drop) { - dout(10, "lease dput on %p\n", dentry); + dout(10, "lease dput on %p %d\n", dentry, dentry->d_count); dput(dentry); } } @@ -710,6 +710,7 @@ static void trim_session_leases(struct ceph_mds_session *session) kfree(di); dentry->d_fsdata = 0; spin_unlock(&dentry->d_lock); + dout(10, "dput %p %d\n", dentry, dentry->d_count); dput(dentry); } } @@ -1250,6 +1251,7 @@ retry: ceph_decode_need(&p, end, pathlen+4, needmore); ceph_encode_string(&p, end, path, pathlen); kfree(path); + dout(10, "dput %p %d\n", dentry, dentry->d_count); dput(dentry); count++; } @@ -1552,6 +1554,7 @@ void ceph_mdsc_handle_lease(struct ceph_mds_client *mdsc, struct ceph_msg *msg) goto release; revoke_dentry_lease(dentry); dout(10, "lease revoked on dentry %p\n", dentry); + dout(10, "dput %p %d\n", dentry, dentry->d_count); dput(dentry); } diff --git a/src/kernel/super.h b/src/kernel/super.h index 89245db8d43a9..4b5eda8011d2e 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -402,7 +402,6 @@ extern int ceph_open(struct inode *inode, struct file *file); extern int ceph_lookup_open(struct inode *dir, struct dentry *dentry, struct nameidata *nd, int mode); extern int ceph_release(struct inode *inode, struct file *filp); -extern int ceph_inode_revalidate(struct inode *inode, int mask); /* dir.c */ @@ -411,7 +410,8 @@ extern const struct file_operations ceph_dir_fops; extern struct dentry_operations ceph_dentry_ops; extern char *ceph_build_dentry_path(struct dentry *dentry, int *len); -extern int ceph_do_lookup(struct super_block *sb, struct dentry *dentry, int m); +extern int ceph_do_lookup(struct super_block *sb, struct dentry *dentry, + int mask, int on_inode); static inline void ceph_init_dentry(struct dentry *dentry) { dentry->d_op = &ceph_dentry_ops; -- 2.39.5