diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 498dcfa..0ef66c9 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -548,9 +548,14 @@ int ceph_fill_file_size(struct inode *inode, int issued, if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) > 0 || (truncate_seq == ci->i_truncate_seq && size > inode->i_size)) { dout("size %lld -> %llu\n", inode->i_size, size); - inode->i_size = size; - inode->i_blocks = (size + (1<<9) - 1) >> 9; - ci->i_reported_size = size; + if (size > 0 && S_ISDIR(inode->i_mode)) { + pr_err("%p size %lld -> %llu\n", inode, inode->i_size, size); + WARN_ON_ONCE(1); + } else { + i_size_write(inode, size); + inode->i_blocks = (size + (1<<9) - 1) >> 9; + ci->i_reported_size = size; + } if (truncate_seq != ci->i_truncate_seq) { dout("truncate_seq %u -> %u\n", ci->i_truncate_seq, truncate_seq); @@ -1358,15 +1363,21 @@ static int fill_readdir_cache(struct inode *dir, struct dentry *dn, if (!ctl->page || pgoff != page_index(ctl->page)) { ceph_readdir_cache_release(ctl); - ctl->page = grab_cache_page(&dir->i_data, pgoff); + if (idx == 0) + ctl->page = grab_cache_page(&dir->i_data, pgoff); + else + ctl->page = find_lock_page(&dir->i_data, pgoff); + if (!ctl->page) { ctl->index = -1; - return -ENOMEM; + return (idx == 0) ? -ENOMEM : 0; } /* reading/filling the cache are serialized by * i_mutex, no need to use page lock */ unlock_page(ctl->page); ctl->dentries = kmap(ctl->page); + if (idx == 0) + memset(ctl->dentries, 0, PAGE_CACHE_SIZE); } if (req->r_dir_release_cnt == atomic64_read(&ci->i_release_count) && @@ -1549,7 +1560,7 @@ int ceph_inode_set_size(struct inode *inode, loff_t size) spin_lock(&ci->i_ceph_lock); dout("set_size %p %llu -> %llu\n", inode, inode->i_size, size); - inode->i_size = size; + i_size_write(inode, size); inode->i_blocks = (size + (1 << 9) - 1) >> 9; /* tell the MDS if we are approaching max_size */ @@ -1911,7 +1922,7 @@ int ceph_setattr(struct dentry *dentry, struct iattr *attr) inode->i_size, attr->ia_size); if ((issued & CEPH_CAP_FILE_EXCL) && attr->ia_size > inode->i_size) { - inode->i_size = attr->ia_size; + i_size_write(inode, attr->ia_size); inode->i_blocks = (attr->ia_size + (1 << 9) - 1) >> 9; inode->i_ctime = attr->ia_ctime;