ceph: fix up some bare fetches of i_size
authorJeff Layton <jlayton@kernel.org>
Fri, 9 Apr 2021 19:58:35 +0000 (15:58 -0400)
committerIlya Dryomov <idryomov@gmail.com>
Tue, 27 Apr 2021 21:52:23 +0000 (23:52 +0200)
We need to use i_size_read(), which properly handles the torn read
case on 32-bit arches.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/caps.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/snap.c

index 010621d095f50540fc8ac20911852461c22e37e1..d2f955a144292eeddacb2dda4b56f4b3f8317ecc 100644 (file)
@@ -1390,7 +1390,7 @@ static void __prep_cap(struct cap_msg_args *arg, struct ceph_cap *cap,
        arg->flush_tid = flush_tid;
        arg->oldest_flush_tid = oldest_flush_tid;
 
-       arg->size = inode->i_size;
+       arg->size = i_size_read(inode);
        ci->i_reported_size = arg->size;
        arg->max_size = ci->i_wanted_max_size;
        if (cap == ci->i_auth_cap) {
@@ -1885,7 +1885,7 @@ static int try_nonblocking_invalidate(struct inode *inode)
 
 bool __ceph_should_report_size(struct ceph_inode_info *ci)
 {
-       loff_t size = ci->vfs_inode.i_size;
+       loff_t size = i_size_read(&ci->vfs_inode);
        /* mds will adjust max size according to the reported size */
        if (ci->i_flushing_caps & CEPH_CAP_FILE_WR)
                return false;
@@ -3299,7 +3299,7 @@ static void handle_cap_grant(struct inode *inode,
        dout("handle_cap_grant inode %p cap %p mds%d seq %d %s\n",
             inode, cap, session->s_mds, seq, ceph_cap_string(newcaps));
        dout(" size %llu max_size %llu, i_size %llu\n", size, max_size,
-               inode->i_size);
+               i_size_read(inode));
 
 
        /*
index d6ff9b4585faee38da395dfa72583796ebccea0e..8b96370306cf592318dccb778d39cd5619487108 100644 (file)
@@ -617,10 +617,11 @@ int ceph_fill_file_size(struct inode *inode, int issued,
 {
        struct ceph_inode_info *ci = ceph_inode(inode);
        int queue_trunc = 0;
+       loff_t isize = i_size_read(inode);
 
        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);
+           (truncate_seq == ci->i_truncate_seq && size > isize)) {
+               dout("size %lld -> %llu\n", isize, size);
                if (size > 0 && S_ISDIR(inode->i_mode)) {
                        pr_err("fill_file_size non-zero size for directory\n");
                        size = 0;
@@ -1789,7 +1790,7 @@ bool ceph_inode_set_size(struct inode *inode, loff_t size)
        bool ret;
 
        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, i_size_read(inode), size);
        i_size_write(inode, size);
        inode->i_blocks = calc_inode_blocks(size);
 
@@ -2096,20 +2097,19 @@ int __ceph_setattr(struct inode *inode, struct iattr *attr)
                }
        }
        if (ia_valid & ATTR_SIZE) {
-               dout("setattr %p size %lld -> %lld\n", inode,
-                    inode->i_size, attr->ia_size);
-               if ((issued & CEPH_CAP_FILE_EXCL) &&
-                   attr->ia_size > inode->i_size) {
+               loff_t isize = i_size_read(inode);
+
+               dout("setattr %p size %lld -> %lld\n", inode, isize, attr->ia_size);
+               if ((issued & CEPH_CAP_FILE_EXCL) && attr->ia_size > isize) {
                        i_size_write(inode, attr->ia_size);
                        inode->i_blocks = calc_inode_blocks(attr->ia_size);
                        ci->i_reported_size = attr->ia_size;
                        dirtied |= CEPH_CAP_FILE_EXCL;
                        ia_valid |= ATTR_MTIME;
                } else if ((issued & CEPH_CAP_FILE_SHARED) == 0 ||
-                          attr->ia_size != inode->i_size) {
+                          attr->ia_size != isize) {
                        req->r_args.setattr.size = cpu_to_le64(attr->ia_size);
-                       req->r_args.setattr.old_size =
-                               cpu_to_le64(inode->i_size);
+                       req->r_args.setattr.old_size = cpu_to_le64(isize);
                        mask |= CEPH_SETATTR_SIZE;
                        release |= CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL |
                                   CEPH_CAP_FILE_RD | CEPH_CAP_FILE_WR;
@@ -2219,7 +2219,7 @@ int ceph_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
                return err;
 
        if ((attr->ia_valid & ATTR_SIZE) &&
-           attr->ia_size > max(inode->i_size, fsc->max_file_size))
+           attr->ia_size > max(i_size_read(inode), fsc->max_file_size))
                return -EFBIG;
 
        if ((attr->ia_valid & ATTR_SIZE) &&
index 5c50f7986404432a42aa87270549eff3d50fc5ae..63b53098360cc612c5caece468bca5eb196dc231 100644 (file)
@@ -3787,7 +3787,7 @@ static int reconnect_caps_cb(struct inode *inode, struct ceph_cap *cap,
                rec.v1.cap_id = cpu_to_le64(cap->cap_id);
                rec.v1.wanted = cpu_to_le32(__ceph_caps_wanted(ci));
                rec.v1.issued = cpu_to_le32(cap->issued);
-               rec.v1.size = cpu_to_le64(inode->i_size);
+               rec.v1.size = cpu_to_le64(i_size_read(inode));
                ceph_encode_timespec64(&rec.v1.mtime, &inode->i_mtime);
                ceph_encode_timespec64(&rec.v1.atime, &inode->i_atime);
                rec.v1.snaprealm = cpu_to_le64(ci->i_snap_realm->ino);
index 0728b01d4d431f0d4f6860975146b59d46727cbb..4ce18055d9316d00eafdd0e2c2f9c09b75ec579d 100644 (file)
@@ -605,7 +605,7 @@ int __ceph_finish_cap_snap(struct ceph_inode_info *ci,
        struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(inode->i_sb);
 
        BUG_ON(capsnap->writing);
-       capsnap->size = inode->i_size;
+       capsnap->size = i_size_read(inode);
        capsnap->mtime = inode->i_mtime;
        capsnap->atime = inode->i_atime;
        capsnap->ctime = inode->i_ctime;