Re: [PATCH] ceph: make nearfull sync writes opt-in

Xiubo Li <[email protected]>
Newsgroups org.kernel.vger.ceph-devel
Message-ID <CAOuZWzxM3PBvKxDz+e7EpWaPOetpEzeSXVDNfsPcb6Fy778V_w@mail.gmail.com>
LGTM.

Reviewed-by: Xiubo Li <[email protected]>

Alex Markuze <[email protected]> 于2026年7月6日周一 07:03写道:
>
> The kernel CephFS client has historically treated a cluster or pool
> NEARFULL condition as a request to force successful writes through
> generic_write_sync().  That effectively turns otherwise buffered writes
> into synchronous writes and can cause a severe throughput drop as soon
> as a single OSD or the file data pool crosses the nearfull threshold.
>
> On modern large clusters, NEARFULL is primarily an operator health
> signal rather than an immediate client-side capacity failure.  Operators
> can still have substantial usable capacity while a cluster is
> rebalancing, splitting PGs, or expanding onto new devices.  RBD, RGW and
> the userspace CephFS client do not impose this extra client-side
> sync-write throttle, so the kernel client behavior is surprising and
> operationally painful.
>
> Change the default behavior so NEARFULL no longer changes normal
> write-sync semantics.  FULL and pool FULL still fail with -ENOSPC, and
> explicitly synchronous writes continue to be synced by
> generic_write_sync().
>
> Add a nearfull_sync mount option for deployments that want the legacy
> backpressure behavior.  When this option is set, successful writes are
> promoted to IOCB_DSYNC if the cluster or file data pool is marked
> NEARFULL, preserving the old behavior for conservative deployments.
>
> Link: https://tracker.ceph.com/issues/74849
> Signed-off-by: Alex Markuze <[email protected]>
> ---
>  Documentation/filesystems/ceph.rst |  6 ++++++
>  fs/ceph/file.c                     |  8 +++++---
>  fs/ceph/super.c                    | 10 ++++++++++
>  fs/ceph/super.h                    |  1 +
>  4 files changed, 22 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/filesystems/ceph.rst b/Documentation/filesystems/ceph.rst
> index 6d2276a87a5a..ee2ca0c0c654 100644
> --- a/Documentation/filesystems/ceph.rst
> +++ b/Documentation/filesystems/ceph.rst
> @@ -194,6 +194,12 @@ Mount Options
>          copies.  Currently, it's only used in copy_file_range, which will revert
>          to the default VFS implementation if this option is used.
>
> +  nearfull_sync
> +       Force written data to stable storage when the cluster or file data pool is
> +       marked NEARFULL. This restores the legacy client-side backpressure
> +       behavior. By default, CephFS writes are not forced synchronous solely
> +       because of NEARFULL.
> +
>    recover_session=<no|clean>
>         Set auto reconnect mode in the case where the client is blocklisted. The
>         available modes are "no" and "clean". The default is "no".
> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
> index 3823671ab95a..0ae9f09aa233 100644
> --- a/fs/ceph/file.c
> +++ b/fs/ceph/file.c
> @@ -2400,7 +2400,8 @@ static ssize_t ceph_splice_read(struct file *in, loff_t *ppos,
>   * dropping our cap refs and allowing the pending snap to logically
>   * complete _before_ this write occurs.
>   *
> - * If we are near ENOSPC, write synchronously.
> + * If requested, nearfull writes are synced to preserve the legacy
> + * client-side backpressure behavior.
>   */
>  static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
>  {
> @@ -2568,8 +2569,9 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
>         }
>
>         if (written >= 0) {
> -               if ((map_flags & CEPH_OSDMAP_NEARFULL) ||
> -                   (pool_flags & CEPH_POOL_FLAG_NEARFULL))
> +               if (ceph_test_mount_opt(fsc, NEARFULL_SYNC) &&
> +                   ((map_flags & CEPH_OSDMAP_NEARFULL) ||
> +                    (pool_flags & CEPH_POOL_FLAG_NEARFULL)))
>                         iocb->ki_flags |= IOCB_DSYNC;
>                 written = generic_write_sync(iocb, written);
>         }
> diff --git a/fs/ceph/super.c b/fs/ceph/super.c
> index 0bbd38933f0e..4d129483e345 100644
> --- a/fs/ceph/super.c
> +++ b/fs/ceph/super.c
> @@ -178,6 +178,7 @@ enum {
>         Opt_pagecache,
>         Opt_sparseread,
>         Opt_lazyio,
> +       Opt_nearfull_sync,
>  };
>
>  enum ceph_recover_session_mode {
> @@ -207,6 +208,7 @@ static const struct fs_parameter_spec ceph_mount_parameters[] = {
>         fsparam_flag_no ("lazyio",                      Opt_lazyio),
>         fsparam_string  ("mds_namespace",               Opt_mds_namespace),
>         fsparam_string  ("mon_addr",                    Opt_mon_addr),
> +       fsparam_flag_no ("nearfull_sync",               Opt_nearfull_sync),
>         fsparam_flag_no ("poolperm",                    Opt_poolperm),
>         fsparam_flag_no ("quotadf",                     Opt_quotadf),
>         fsparam_u32     ("rasize",                      Opt_rasize),
> @@ -601,6 +603,12 @@ static int ceph_parse_mount_param(struct fs_context *fc,
>                 else
>                         fsopt->flags |= CEPH_MOUNT_OPT_LAZYIO;
>                 break;
> +       case Opt_nearfull_sync:
> +               if (result.negated)
> +                       fsopt->flags &= ~CEPH_MOUNT_OPT_NEARFULL_SYNC;
> +               else
> +                       fsopt->flags |= CEPH_MOUNT_OPT_NEARFULL_SYNC;
> +               break;
>         case Opt_test_dummy_encryption:
>  #ifdef CONFIG_FS_ENCRYPTION
>                 fscrypt_free_dummy_policy(&fsopt->dummy_enc_policy);
> @@ -759,6 +767,8 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root)
>                 seq_puts(m, ",sparseread");
>         if (fsopt->flags & CEPH_MOUNT_OPT_LAZYIO)
>                 seq_puts(m, ",lazyio");
> +       if (fsopt->flags & CEPH_MOUNT_OPT_NEARFULL_SYNC)
> +               seq_puts(m, ",nearfull_sync");
>
>         fscrypt_show_test_dummy_encryption(m, ',', root->d_sb);
>
> diff --git a/fs/ceph/super.h b/fs/ceph/super.h
> index 3737ea7ed88b..632ffb1b401e 100644
> --- a/fs/ceph/super.h
> +++ b/fs/ceph/super.h
> @@ -46,6 +46,7 @@
>  #define CEPH_MOUNT_OPT_NOPAGECACHE     (1<<16) /* bypass pagecache altogether */
>  #define CEPH_MOUNT_OPT_SPARSEREAD      (1<<17) /* always do sparse reads */
>  #define CEPH_MOUNT_OPT_LAZYIO          (1<<18) /* force lazyio for all file opens */
> +#define CEPH_MOUNT_OPT_NEARFULL_SYNC   (1<<19) /* sync writes when nearfull */
>
>  #define CEPH_MOUNT_OPT_DEFAULT                 \
>         (CEPH_MOUNT_OPT_DCACHE |                \
> --
> 2.34.1
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.