Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99c88e69 authored by Yan, Zheng's avatar Yan, Zheng Committed by Ilya Dryomov
Browse files

ceph: use i_size_{read,write} to get/set i_size



Cap message from MDS can update i_size. In that case, we don't
hold i_mutex. So it's unsafe to directly access inode->i_size
while holding i_mutex.

Signed-off-by: default avatarYan, Zheng <zyan@redhat.com>
parent 5be0389d
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -1108,7 +1108,7 @@ static int ceph_update_writeable_page(struct file *file,
		return 0;

	/* past end of file? */
	i_size = inode->i_size;   /* caller holds i_mutex */
	i_size = i_size_read(inode);

	if (page_off >= i_size ||
	    (pos_in_page == 0 && (pos+len) >= i_size &&
@@ -1183,8 +1183,7 @@ static int ceph_write_end(struct file *file, struct address_space *mapping,
		zero_user_segment(page, from+copied, len);

	/* did file size increase? */
	/* (no need for i_size_read(); we caller holds i_mutex */
	if (pos+copied > inode->i_size)
	if (pos+copied > i_size_read(inode))
		check_cap = ceph_inode_set_size(inode, pos+copied);

	if (!PageUptodate(page))
+3 −5
Original line number Diff line number Diff line
@@ -106,7 +106,7 @@ static uint16_t ceph_fscache_inode_get_aux(const void *cookie_netfs_data,

	memset(&aux, 0, sizeof(aux));
	aux.mtime = inode->i_mtime;
	aux.size = inode->i_size;
	aux.size = i_size_read(inode);

	memcpy(buffer, &aux, sizeof(aux));

@@ -117,9 +117,7 @@ static void ceph_fscache_inode_get_attr(const void *cookie_netfs_data,
					uint64_t *size)
{
	const struct ceph_inode_info* ci = cookie_netfs_data;
	const struct inode* inode = &ci->vfs_inode;

	*size = inode->i_size;
	*size = i_size_read(&ci->vfs_inode);
}

static enum fscache_checkaux ceph_fscache_inode_check_aux(
@@ -134,7 +132,7 @@ static enum fscache_checkaux ceph_fscache_inode_check_aux(

	memset(&aux, 0, sizeof(aux));
	aux.mtime = inode->i_mtime;
	aux.size = inode->i_size;
	aux.size = i_size_read(inode);

	if (memcmp(data, &aux, sizeof(aux)) != 0)
		return FSCACHE_CHECKAUX_OBSOLETE;
+16 −14
Original line number Diff line number Diff line
@@ -417,6 +417,7 @@ static int striped_read(struct inode *inode,
	struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
	struct ceph_inode_info *ci = ceph_inode(inode);
	u64 pos, this_len, left;
	loff_t i_size;
	int page_align, pages_left;
	int read, ret;
	struct page **page_pos;
@@ -446,11 +447,11 @@ static int striped_read(struct inode *inode,
	dout("striped_read %llu~%llu (read %u) got %d%s%s\n", pos, left, read,
	     ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");

	i_size = i_size_read(inode);
	if (ret >= 0) {
		int didpages;
		if (was_short && (pos + ret < inode->i_size)) {
			int zlen = min(this_len - ret,
				       inode->i_size - pos - ret);
		if (was_short && (pos + ret < i_size)) {
			int zlen = min(this_len - ret, i_size - pos - ret);
			int zoff = (off & ~PAGE_MASK) + read + ret;
			dout(" zero gap %llu to %llu\n",
				pos + ret, pos + ret + zlen);
@@ -466,14 +467,14 @@ static int striped_read(struct inode *inode,
		pages_left -= didpages;

		/* hit stripe and need continue*/
		if (left && hit_stripe && pos < inode->i_size)
		if (left && hit_stripe && pos < i_size)
			goto more;
	}

	if (read > 0) {
		ret = read;
		/* did we bounce off eof? */
		if (pos + left > inode->i_size)
		if (pos + left > i_size)
			*checkeof = CHECK_EOF;
	}

@@ -1209,8 +1210,7 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to)
		if (retry_op == CHECK_EOF && iocb->ki_pos < i_size &&
		    ret < len) {
			dout("sync_read hit hole, ppos %lld < size %lld"
			     ", reading more\n", iocb->ki_pos,
			     inode->i_size);
			     ", reading more\n", iocb->ki_pos, i_size);

			read += ret;
			len -= ret;
@@ -1293,7 +1293,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
	}

	dout("aio_write %p %llx.%llx %llu~%zd getting caps. i_size %llu\n",
	     inode, ceph_vinop(inode), pos, count, inode->i_size);
	     inode, ceph_vinop(inode), pos, count, i_size_read(inode));
	if (fi->fmode & CEPH_FILE_MODE_LAZY)
		want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
	else
@@ -1345,7 +1345,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
			iov_iter_advance(from, written);
		ceph_put_snap_context(snapc);
	} else {
		loff_t old_size = inode->i_size;
		loff_t old_size = i_size_read(inode);
		/*
		 * No need to acquire the i_truncate_mutex. Because
		 * the MDS revokes Fwb caps before sending truncate
@@ -1356,7 +1356,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
		written = generic_perform_write(file, from, pos);
		if (likely(written >= 0))
			iocb->ki_pos = pos + written;
		if (inode->i_size > old_size)
		if (i_size_read(inode) > old_size)
			ceph_fscache_update_objectsize(inode);
		mutex_unlock(&inode->i_mutex);
	}
@@ -1401,6 +1401,7 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
{
	struct inode *inode = file->f_mapping->host;
	loff_t i_size;
	int ret;

	mutex_lock(&inode->i_mutex);
@@ -1413,9 +1414,10 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
		}
	}

	i_size = i_size_read(inode);
	switch (whence) {
	case SEEK_END:
		offset += inode->i_size;
		offset += i_size;
		break;
	case SEEK_CUR:
		/*
@@ -1431,17 +1433,17 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
		offset += file->f_pos;
		break;
	case SEEK_DATA:
		if (offset >= inode->i_size) {
		if (offset >= i_size) {
			ret = -ENXIO;
			goto out;
		}
		break;
	case SEEK_HOLE:
		if (offset >= inode->i_size) {
		if (offset >= i_size) {
			ret = -ENXIO;
			goto out;
		}
		offset = inode->i_size;
		offset = i_size;
		break;
	}

+4 −4
Original line number Diff line number Diff line
@@ -548,7 +548,7 @@ 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;
		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) {
@@ -808,7 +808,7 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
			spin_unlock(&ci->i_ceph_lock);

			err = -EINVAL;
			if (WARN_ON(symlen != inode->i_size))
			if (WARN_ON(symlen != i_size_read(inode)))
				goto out;

			err = -ENOMEM;
@@ -1549,7 +1549,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 +1911,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;