From f377735b3f334db0fd807fca036cd48c665e9491 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Fri, 18 Apr 2008 16:40:18 -0700 Subject: [PATCH] kclient: fix lease release, fix truncate, set iops on non-directories --- src/kernel/dir.c | 3 +++ src/kernel/file.c | 9 --------- src/kernel/inode.c | 40 +++++++++++++++++++++++++++++----------- src/kernel/mds_client.c | 4 +++- src/kernel/super.c | 4 ++-- src/kernel/super.h | 3 ++- 6 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/kernel/dir.c b/src/kernel/dir.c index 243d6c126c0f3..4d9e25608910e 100644 --- a/src/kernel/dir.c +++ b/src/kernel/dir.c @@ -443,6 +443,7 @@ static int ceph_dir_unlink(struct inode *dir, struct dentry *dentry) err = ceph_mdsc_do_request(mdsc, req); ceph_mdsc_put_request(req); + /* hmm? */ if (!err) { if (dentry->d_inode) drop_nlink(dentry->d_inode); @@ -503,6 +504,8 @@ 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, + 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); if (ceph_inode_lease_valid(dir, CEPH_LOCK_ICONTENT)) { diff --git a/src/kernel/file.c b/src/kernel/file.c index 46420e5db8707..2936309c58896 100644 --- a/src/kernel/file.c +++ b/src/kernel/file.c @@ -187,15 +187,6 @@ int ceph_release(struct inode *inode, struct file *file) return 0; } -const struct inode_operations ceph_file_iops = { - .setattr = ceph_setattr, -/* .getattr = ceph_vfs_getattr, - .setattr = ceph_vfs_setattr, -*/ -}; - - - /* * completely synchronous read and write methods. direct from __user * buffer to osd. diff --git a/src/kernel/inode.c b/src/kernel/inode.c index cf3172b1a99fc..64d178183f266 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -50,6 +50,18 @@ struct inode *ceph_get_inode(struct super_block *sb, __u64 ino) return inode; } + +const struct inode_operations ceph_file_iops = { + .setattr = ceph_setattr, + .getattr = ceph_inode_getattr, +}; + +const struct inode_operations ceph_special_iops = { + .setattr = ceph_setattr, + .getattr = ceph_inode_getattr, +}; + + /* * populate an inode based on info from mds. * may be called on new or existing inodes. @@ -156,6 +168,7 @@ no_change: case S_IFSOCK: dout(20, "%p is special\n", inode); init_special_inode(inode, inode->i_mode, inode->i_rdev); + inode->i_op = &ceph_special_iops; break; case S_IFREG: dout(20, "%p is a file\n", inode); @@ -244,7 +257,8 @@ int ceph_inode_lease_valid(struct inode *inode, int mask) { struct ceph_inode_info *ci = ceph_inode(inode); int havemask; - int valid = 0; + int valid; + int ret = 0; spin_lock(&inode->i_lock); havemask = ci->i_lease_mask; @@ -253,18 +267,19 @@ int ceph_inode_lease_valid(struct inode *inode, int mask) dout(20, "lease_valid inode %p EXCL cap -> ICONTENT\n", inode); havemask |= CEPH_LOCK_ICONTENT; } - /* any ICONTENT bits imply all bits */ + /* any ICONTENT bits imply all ICONTENT bits */ if (havemask & CEPH_LOCK_ICONTENT) havemask |= CEPH_LOCK_ICONTENT; - if ((havemask & mask) != mask) - goto out; - valid = time_before(jiffies, ci->i_lease_ttl); -out: + + if (valid && (havemask & mask) == mask) + ret = 1; + spin_unlock(&inode->i_lock); - dout(10, "lease_valid inode %p mask %d = %d\n", inode, mask, valid); - return valid; + dout(10, "lease_valid inode %p have %d want %d valid %d = %d\n", inode, + havemask, mask, valid, ret); + return ret; } @@ -450,6 +465,7 @@ retry_lookup: if (d_unhashed(dn)) d_rehash(dn); } + in = 0; break; } @@ -511,7 +527,8 @@ retry_lookup: iput(req->r_last_inode); req->r_last_dentry = dn; req->r_last_inode = in; - igrab(in); + if (in) + igrab(in); return err; } @@ -1434,7 +1451,7 @@ static int ceph_setattr_size(struct dentry *dentry, struct iattr *attr) dout(10, "truncate: ia_size %d i_size %d\n", (int)attr->ia_size, (int)inode->i_size); if (ceph_inode_lease_valid(inode, CEPH_LOCK_ICONTENT) && - attr->ia_size < inode->i_size) { + attr->ia_size == inode->i_size) { dout(10, "lease indicates truncate is a no-op\n"); return 0; } @@ -1533,7 +1550,8 @@ int ceph_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) { int err = 0; - dout(30, "ceph_inode_getattr\n"); + 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); diff --git a/src/kernel/mds_client.c b/src/kernel/mds_client.c index f648ea3726a3b..944df5bced1d9 100644 --- a/src/kernel/mds_client.c +++ b/src/kernel/mds_client.c @@ -1589,14 +1589,16 @@ void ceph_mdsc_lease_release(struct ceph_mds_client *mdsc, struct inode *inode, dnamelen = dentry->d_name.len; len += dentry->d_name.len; mds = ceph_dentry(dentry)->lease_session->s_mds; + ceph_dentry(dentry)->lease_session->s_mds = -1; } else mask &= ~CEPH_LOCK_DN; /* nothing to release */ ci = ceph_inode(inode); ino = ci->i_ceph_ino; if (ci->i_lease_session && time_after(ci->i_lease_ttl, jiffies) && ci->i_lease_session->s_mds >= 0) { - mask &= CEPH_LOCK_DN | ci->i_lease_mask; /* lease is valid */ mds = ci->i_lease_session->s_mds; + mask &= CEPH_LOCK_DN | ci->i_lease_mask; /* lease is valid */ + ci->i_lease_mask &= ~mask; } else mask &= CEPH_LOCK_DN; /* no lease; clear all but DN bits */ if (mask == 0) { diff --git a/src/kernel/super.c b/src/kernel/super.c index 34bbf2f1d063b..40f673eebfbe7 100644 --- a/src/kernel/super.c +++ b/src/kernel/super.c @@ -404,7 +404,7 @@ static int ceph_set_super(struct super_block *s, void *data) dout(10, "set_super %p data %p\n", s, data); s->s_flags = args->mntflags; - s->s_maxbytes = 1ULL << (32 + 20); /* assuming objects >= 1MB */ + s->s_maxbytes = min((u64)MAX_LFS_FILESIZE, CEPH_FILE_MAX_SIZE); /* create client */ client = ceph_create_client(args, s); @@ -417,7 +417,7 @@ static int ceph_set_super(struct super_block *s, void *data) memcpy(&client->mount_args, args, sizeof(*args)); /* set time granularity */ - s->s_time_gran = 1000; /* 1 us == 1000 ns */ + s->s_time_gran = 1000; /* 1000 ns == 1 us */ ret = set_anon_super(s, 0); /* what is the second arg for? */ if (ret != 0) diff --git a/src/kernel/super.h b/src/kernel/super.h index 8978a409fe52f..89245db8d43a9 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -346,6 +346,8 @@ extern const char *ceph_msg_type_name(int type); /* inode.c */ +extern const struct inode_operations ceph_file_iops; +extern const struct inode_operations ceph_special_iops; extern struct inode *ceph_get_inode(struct super_block *sb, u64 ino); extern int ceph_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *info); @@ -394,7 +396,6 @@ extern int ceph_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, extern const struct address_space_operations ceph_aops; /* file.c */ -extern const struct inode_operations ceph_file_iops; extern const struct file_operations ceph_file_fops; extern const struct address_space_operations ceph_aops; extern int ceph_open(struct inode *inode, struct file *file); -- 2.39.5