mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-20 11:13:58 +08:00
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: Yan, Zheng <zyan@redhat.com>
This commit is contained in:
parent
5be0389dac
commit
99c88e6900
@ -1108,7 +1108,7 @@ retry_locked:
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* past end of file? */
|
/* past end of file? */
|
||||||
i_size = inode->i_size; /* caller holds i_mutex */
|
i_size = i_size_read(inode);
|
||||||
|
|
||||||
if (page_off >= i_size ||
|
if (page_off >= i_size ||
|
||||||
(pos_in_page == 0 && (pos+len) >= 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);
|
zero_user_segment(page, from+copied, len);
|
||||||
|
|
||||||
/* did file size increase? */
|
/* did file size increase? */
|
||||||
/* (no need for i_size_read(); we caller holds i_mutex */
|
if (pos+copied > i_size_read(inode))
|
||||||
if (pos+copied > inode->i_size)
|
|
||||||
check_cap = ceph_inode_set_size(inode, pos+copied);
|
check_cap = ceph_inode_set_size(inode, pos+copied);
|
||||||
|
|
||||||
if (!PageUptodate(page))
|
if (!PageUptodate(page))
|
||||||
|
@ -106,7 +106,7 @@ static uint16_t ceph_fscache_inode_get_aux(const void *cookie_netfs_data,
|
|||||||
|
|
||||||
memset(&aux, 0, sizeof(aux));
|
memset(&aux, 0, sizeof(aux));
|
||||||
aux.mtime = inode->i_mtime;
|
aux.mtime = inode->i_mtime;
|
||||||
aux.size = inode->i_size;
|
aux.size = i_size_read(inode);
|
||||||
|
|
||||||
memcpy(buffer, &aux, sizeof(aux));
|
memcpy(buffer, &aux, sizeof(aux));
|
||||||
|
|
||||||
@ -117,9 +117,7 @@ static void ceph_fscache_inode_get_attr(const void *cookie_netfs_data,
|
|||||||
uint64_t *size)
|
uint64_t *size)
|
||||||
{
|
{
|
||||||
const struct ceph_inode_info* ci = cookie_netfs_data;
|
const struct ceph_inode_info* ci = cookie_netfs_data;
|
||||||
const struct inode* inode = &ci->vfs_inode;
|
*size = i_size_read(&ci->vfs_inode);
|
||||||
|
|
||||||
*size = inode->i_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum fscache_checkaux ceph_fscache_inode_check_aux(
|
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));
|
memset(&aux, 0, sizeof(aux));
|
||||||
aux.mtime = inode->i_mtime;
|
aux.mtime = inode->i_mtime;
|
||||||
aux.size = inode->i_size;
|
aux.size = i_size_read(inode);
|
||||||
|
|
||||||
if (memcmp(data, &aux, sizeof(aux)) != 0)
|
if (memcmp(data, &aux, sizeof(aux)) != 0)
|
||||||
return FSCACHE_CHECKAUX_OBSOLETE;
|
return FSCACHE_CHECKAUX_OBSOLETE;
|
||||||
|
@ -417,6 +417,7 @@ static int striped_read(struct inode *inode,
|
|||||||
struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
|
struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
|
||||||
struct ceph_inode_info *ci = ceph_inode(inode);
|
struct ceph_inode_info *ci = ceph_inode(inode);
|
||||||
u64 pos, this_len, left;
|
u64 pos, this_len, left;
|
||||||
|
loff_t i_size;
|
||||||
int page_align, pages_left;
|
int page_align, pages_left;
|
||||||
int read, ret;
|
int read, ret;
|
||||||
struct page **page_pos;
|
struct page **page_pos;
|
||||||
@ -446,11 +447,11 @@ more:
|
|||||||
dout("striped_read %llu~%llu (read %u) got %d%s%s\n", pos, left, read,
|
dout("striped_read %llu~%llu (read %u) got %d%s%s\n", pos, left, read,
|
||||||
ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
|
ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : "");
|
||||||
|
|
||||||
|
i_size = i_size_read(inode);
|
||||||
if (ret >= 0) {
|
if (ret >= 0) {
|
||||||
int didpages;
|
int didpages;
|
||||||
if (was_short && (pos + ret < inode->i_size)) {
|
if (was_short && (pos + ret < i_size)) {
|
||||||
int zlen = min(this_len - ret,
|
int zlen = min(this_len - ret, i_size - pos - ret);
|
||||||
inode->i_size - pos - ret);
|
|
||||||
int zoff = (off & ~PAGE_MASK) + read + ret;
|
int zoff = (off & ~PAGE_MASK) + read + ret;
|
||||||
dout(" zero gap %llu to %llu\n",
|
dout(" zero gap %llu to %llu\n",
|
||||||
pos + ret, pos + ret + zlen);
|
pos + ret, pos + ret + zlen);
|
||||||
@ -466,14 +467,14 @@ more:
|
|||||||
pages_left -= didpages;
|
pages_left -= didpages;
|
||||||
|
|
||||||
/* hit stripe and need continue*/
|
/* hit stripe and need continue*/
|
||||||
if (left && hit_stripe && pos < inode->i_size)
|
if (left && hit_stripe && pos < i_size)
|
||||||
goto more;
|
goto more;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read > 0) {
|
if (read > 0) {
|
||||||
ret = read;
|
ret = read;
|
||||||
/* did we bounce off eof? */
|
/* did we bounce off eof? */
|
||||||
if (pos + left > inode->i_size)
|
if (pos + left > i_size)
|
||||||
*checkeof = CHECK_EOF;
|
*checkeof = CHECK_EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1209,8 +1210,7 @@ again:
|
|||||||
if (retry_op == CHECK_EOF && iocb->ki_pos < i_size &&
|
if (retry_op == CHECK_EOF && iocb->ki_pos < i_size &&
|
||||||
ret < len) {
|
ret < len) {
|
||||||
dout("sync_read hit hole, ppos %lld < size %lld"
|
dout("sync_read hit hole, ppos %lld < size %lld"
|
||||||
", reading more\n", iocb->ki_pos,
|
", reading more\n", iocb->ki_pos, i_size);
|
||||||
inode->i_size);
|
|
||||||
|
|
||||||
read += ret;
|
read += ret;
|
||||||
len -= ret;
|
len -= ret;
|
||||||
@ -1293,7 +1293,7 @@ retry_snap:
|
|||||||
}
|
}
|
||||||
|
|
||||||
dout("aio_write %p %llx.%llx %llu~%zd getting caps. i_size %llu\n",
|
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)
|
if (fi->fmode & CEPH_FILE_MODE_LAZY)
|
||||||
want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
|
want = CEPH_CAP_FILE_BUFFER | CEPH_CAP_FILE_LAZYIO;
|
||||||
else
|
else
|
||||||
@ -1345,7 +1345,7 @@ retry_snap:
|
|||||||
iov_iter_advance(from, written);
|
iov_iter_advance(from, written);
|
||||||
ceph_put_snap_context(snapc);
|
ceph_put_snap_context(snapc);
|
||||||
} else {
|
} 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
|
* No need to acquire the i_truncate_mutex. Because
|
||||||
* the MDS revokes Fwb caps before sending truncate
|
* the MDS revokes Fwb caps before sending truncate
|
||||||
@ -1356,7 +1356,7 @@ retry_snap:
|
|||||||
written = generic_perform_write(file, from, pos);
|
written = generic_perform_write(file, from, pos);
|
||||||
if (likely(written >= 0))
|
if (likely(written >= 0))
|
||||||
iocb->ki_pos = pos + written;
|
iocb->ki_pos = pos + written;
|
||||||
if (inode->i_size > old_size)
|
if (i_size_read(inode) > old_size)
|
||||||
ceph_fscache_update_objectsize(inode);
|
ceph_fscache_update_objectsize(inode);
|
||||||
mutex_unlock(&inode->i_mutex);
|
mutex_unlock(&inode->i_mutex);
|
||||||
}
|
}
|
||||||
@ -1401,6 +1401,7 @@ out_unlocked:
|
|||||||
static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
|
static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
|
||||||
{
|
{
|
||||||
struct inode *inode = file->f_mapping->host;
|
struct inode *inode = file->f_mapping->host;
|
||||||
|
loff_t i_size;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&inode->i_mutex);
|
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) {
|
switch (whence) {
|
||||||
case SEEK_END:
|
case SEEK_END:
|
||||||
offset += inode->i_size;
|
offset += i_size;
|
||||||
break;
|
break;
|
||||||
case SEEK_CUR:
|
case SEEK_CUR:
|
||||||
/*
|
/*
|
||||||
@ -1431,17 +1433,17 @@ static loff_t ceph_llseek(struct file *file, loff_t offset, int whence)
|
|||||||
offset += file->f_pos;
|
offset += file->f_pos;
|
||||||
break;
|
break;
|
||||||
case SEEK_DATA:
|
case SEEK_DATA:
|
||||||
if (offset >= inode->i_size) {
|
if (offset >= i_size) {
|
||||||
ret = -ENXIO;
|
ret = -ENXIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SEEK_HOLE:
|
case SEEK_HOLE:
|
||||||
if (offset >= inode->i_size) {
|
if (offset >= i_size) {
|
||||||
ret = -ENXIO;
|
ret = -ENXIO;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
offset = inode->i_size;
|
offset = i_size;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 ||
|
if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) > 0 ||
|
||||||
(truncate_seq == ci->i_truncate_seq && size > inode->i_size)) {
|
(truncate_seq == ci->i_truncate_seq && size > inode->i_size)) {
|
||||||
dout("size %lld -> %llu\n", inode->i_size, 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;
|
inode->i_blocks = (size + (1<<9) - 1) >> 9;
|
||||||
ci->i_reported_size = size;
|
ci->i_reported_size = size;
|
||||||
if (truncate_seq != ci->i_truncate_seq) {
|
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);
|
spin_unlock(&ci->i_ceph_lock);
|
||||||
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
if (WARN_ON(symlen != inode->i_size))
|
if (WARN_ON(symlen != i_size_read(inode)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
@ -1549,7 +1549,7 @@ int ceph_inode_set_size(struct inode *inode, loff_t size)
|
|||||||
|
|
||||||
spin_lock(&ci->i_ceph_lock);
|
spin_lock(&ci->i_ceph_lock);
|
||||||
dout("set_size %p %llu -> %llu\n", inode, inode->i_size, size);
|
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;
|
inode->i_blocks = (size + (1 << 9) - 1) >> 9;
|
||||||
|
|
||||||
/* tell the MDS if we are approaching max_size */
|
/* 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);
|
inode->i_size, attr->ia_size);
|
||||||
if ((issued & CEPH_CAP_FILE_EXCL) &&
|
if ((issued & CEPH_CAP_FILE_EXCL) &&
|
||||||
attr->ia_size > inode->i_size) {
|
attr->ia_size > inode->i_size) {
|
||||||
inode->i_size = attr->ia_size;
|
i_size_write(inode, attr->ia_size);
|
||||||
inode->i_blocks =
|
inode->i_blocks =
|
||||||
(attr->ia_size + (1 << 9) - 1) >> 9;
|
(attr->ia_size + (1 << 9) - 1) >> 9;
|
||||||
inode->i_ctime = attr->ia_ctime;
|
inode->i_ctime = attr->ia_ctime;
|
||||||
|
Loading…
Reference in New Issue
Block a user