From 10e21dcb4f0096a8e740ba48886d158cde741ec7 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Wed, 9 Apr 2008 14:07:40 -0700 Subject: [PATCH] kclient: use inode_set_size helper to keep i_blocks accurate --- src/kernel/addr.c | 8 ++------ src/kernel/file.c | 10 ++-------- src/kernel/inode.c | 21 +++++++++++++++++++-- src/kernel/super.h | 1 + 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/kernel/addr.c b/src/kernel/addr.c index 33ff3f172c1bb..6409a9541c9b4 100644 --- a/src/kernel/addr.c +++ b/src/kernel/addr.c @@ -468,12 +468,8 @@ 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) { - 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 (pos+copied > inode->i_size) + ceph_inode_set_size(inode, pos); if (!PageUptodate(page)) SetPageUptodate(page); diff --git a/src/kernel/file.c b/src/kernel/file.c index 57b161c83fcea..359a572beea4c 100644 --- a/src/kernel/file.c +++ b/src/kernel/file.c @@ -215,14 +215,8 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, if (ret > 0) { pos += ret; *offset = pos; - - spin_lock(&inode->i_lock); - if (pos > inode->i_size) { - inode->i_size = pos; - inode->i_blocks = (inode->i_size + 512 - 1) >> 9; - dout(10, "extending file size to %lu\n", pos); - } - spin_unlock(&inode->i_lock); + if (pos > i_size_read(inode)) + ceph_inode_set_size(inode, pos); } return ret; } diff --git a/src/kernel/inode.c b/src/kernel/inode.c index 8e73f10593474..28645ad0c8918 100644 --- a/src/kernel/inode.c +++ b/src/kernel/inode.c @@ -61,8 +61,7 @@ int ceph_fill_inode(struct inode *inode, struct ceph_mds_reply_inode *info) u64 size = le64_to_cpu(info->size); int issued; struct timespec mtime, atime, ctime; - u64 blocks = size + blksize - 1; - do_div(blocks, blksize); + u64 blocks = (size + blksize - 1) >> blkbits; dout(30, "fill_inode %p ino %llx by %d.%d sz=%llu mode %o nlink %d\n", inode, info->ino, inode->i_uid, inode->i_gid, @@ -850,6 +849,24 @@ out: spin_unlock(&ci->vfs_inode.i_lock); } +void ceph_inode_set_size(struct inode *inode, loff_t size) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + + spin_lock(&inode->i_lock); + dout(20, "set_size %p %llu -> %llu\n", inode, inode->i_size, size); + inode->i_size = size; + inode->i_blocks = (size + (1 << inode->i_blkbits) - 1) >> + inode->i_blkbits; + + if ((size << 1) >= ci->i_max_size && + (ci->i_reported_size << 1) < ci->i_max_size) { + spin_unlock(&inode->i_lock); + ceph_check_caps(ci, GFP_KERNEL); + } else + spin_unlock(&inode->i_lock); +} + /* * called on struct file init and release, to safely track which * capabilities we want due to currently open files diff --git a/src/kernel/super.h b/src/kernel/super.h index 0ecdfa6bd74b4..e664b8ae1c414 100644 --- a/src/kernel/super.h +++ b/src/kernel/super.h @@ -379,6 +379,7 @@ extern void ceph_put_wrbuffer_cap_refs(struct ceph_inode_info *ci, int nr); 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); +extern void ceph_inode_set_size(struct inode *inode, loff_t size); extern int ceph_setattr(struct dentry *dentry, struct iattr *attr); extern int ceph_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, -- 2.39.5