]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ceph: flush the dirty caps immediatelly when quota is approaching
authorXiubo Li <xiubli@redhat.com>
Thu, 23 Jun 2022 09:17:21 +0000 (17:17 +0800)
committerIlya Dryomov <idryomov@gmail.com>
Tue, 2 Aug 2022 22:54:13 +0000 (00:54 +0200)
When the quota is approaching we need to notify it to the MDS as
soon as possible, or the client could write to the directory more
than expected.

This will flush the dirty caps without delaying after each write,
though this couldn't prevent the real size of a directory exceed
the quota but could prevent it as soon as possible.

Link: https://tracker.ceph.com/issues/56180
Signed-off-by: Xiubo Li <xiubli@redhat.com>
Reviewed-by: Luís Henriques <lhenriques@suse.de>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
fs/ceph/caps.c
fs/ceph/file.c

index 0acff406ba29727b9098cdb254a31ce05afdb3a1..53cfe026b3ea5353172c354279d9772e449fbe01 100644 (file)
@@ -1978,14 +1978,15 @@ retry:
        }
 
        dout("check_caps %llx.%llx file_want %s used %s dirty %s flushing %s"
-            " issued %s revoking %s retain %s %s%s\n", ceph_vinop(inode),
+            " issued %s revoking %s retain %s %s%s%s\n", ceph_vinop(inode),
             ceph_cap_string(file_wanted),
             ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps),
             ceph_cap_string(ci->i_flushing_caps),
             ceph_cap_string(issued), ceph_cap_string(revoking),
             ceph_cap_string(retain),
             (flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "",
-            (flags & CHECK_CAPS_FLUSH) ? " FLUSH" : "");
+            (flags & CHECK_CAPS_FLUSH) ? " FLUSH" : "",
+            (flags & CHECK_CAPS_NOINVAL) ? " NOINVAL" : "");
 
        /*
         * If we no longer need to hold onto old our caps, and we may
index ffb717e2c1dffce76f2cb21653ee2d40fd895d3f..cd025ff25bf017dc9899247a4220105579b34896 100644 (file)
@@ -1912,7 +1912,7 @@ retry_snap:
                if (dirty)
                        __mark_inode_dirty(inode, dirty);
                if (ceph_quota_is_max_bytes_approaching(inode, iocb->ki_pos))
-                       ceph_check_caps(ci, 0, NULL);
+                       ceph_check_caps(ci, CHECK_CAPS_FLUSH, NULL);
        }
 
        dout("aio_write %p %llx.%llx %llu~%u  dropping cap refs on %s\n",
@@ -2529,7 +2529,8 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
                /* Let the MDS know about dst file size change */
                if (ceph_inode_set_size(dst_inode, dst_off) ||
                    ceph_quota_is_max_bytes_approaching(dst_inode, dst_off))
-                       ceph_check_caps(dst_ci, CHECK_CAPS_AUTHONLY, NULL);
+                       ceph_check_caps(dst_ci, CHECK_CAPS_AUTHONLY | CHECK_CAPS_FLUSH,
+                                       NULL);
        }
        /* Mark Fw dirty */
        spin_lock(&dst_ci->i_ceph_lock);