From: Jeff Layton <jlayton@kernel.org>
To: Ilya Dryomov <idryomov@gmail.com>, ceph-devel@vger.kernel.org
Cc: Yanhu Cao <gmayyyha@gmail.com>
Subject: Re: [PATCH] ceph: check POOL_FLAG_FULL/NEARFULL in addition to OSDMAP_FULL/NEARFULL
Date: Thu, 19 Mar 2020 12:16:02 -0400 [thread overview]
Message-ID: <8aa2ca7a484d665c36db632ce38fb9c8552c43c1.camel@kernel.org> (raw)
In-Reply-To: <20200316090308.29004-1-idryomov@gmail.com>
On Mon, 2020-03-16 at 10:03 +0100, Ilya Dryomov wrote:
> CEPH_OSDMAP_FULL/NEARFULL aren't set since mimic, so we need to consult
> per-pool flags as well. Unfortunately the backwards compatibility here
> is lacking:
>
> - the change that deprecated OSDMAP_FULL/NEARFULL went into mimic, but
> was guarded by require_osd_release >= RELEASE_LUMINOUS
> - it was subsequently backported to luminous in v12.2.2, but that makes
> no difference to clients that only check OSDMAP_FULL/NEARFULL because
> require_osd_release is not client-facing -- it is for OSDs
>
> Since all kernels are affected, the best we can do here is just start
> checking both map flags and pool flags and send that to stable.
>
> These checks are best effort, so take osdc->lock and look up pool flags
> just once. Remove the FIXME, since filesystem quotas are checked above
> and RADOS quotas are reflected in POOL_FLAG_FULL: when the pool reaches
> its quota, both POOL_FLAG_FULL and POOL_FLAG_FULL_QUOTA are set.
>
> Cc: stable@vger.kernel.org
> Reported-by: Yanhu Cao <gmayyyha@gmail.com>
> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
> ---
> fs/ceph/file.c | 14 +++++++++++---
> include/linux/ceph/osdmap.h | 4 ++++
> include/linux/ceph/rados.h | 6 ++++--
> net/ceph/osdmap.c | 9 +++++++++
> 4 files changed, 28 insertions(+), 5 deletions(-)
>
> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
> index aa08fdff0d98..8e4002280c2b 100644
> --- a/fs/ceph/file.c
> +++ b/fs/ceph/file.c
> @@ -1689,10 +1689,13 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
> struct inode *inode = file_inode(file);
> struct ceph_inode_info *ci = ceph_inode(inode);
> struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
> + struct ceph_osd_client *osdc = &fsc->client->osdc;
> struct ceph_cap_flush *prealloc_cf;
> ssize_t count, written = 0;
> int err, want, got;
> bool direct_lock = false;
> + u32 map_flags;
> + u64 pool_flags;
> loff_t pos;
> loff_t limit = max(i_size_read(inode), fsc->max_file_size);
>
> @@ -1755,8 +1758,12 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
> goto out;
> }
>
> - /* FIXME: not complete since it doesn't account for being at quota */
> - if (ceph_osdmap_flag(&fsc->client->osdc, CEPH_OSDMAP_FULL)) {
> + down_read(&osdc->lock);
> + map_flags = osdc->osdmap->flags;
> + pool_flags = ceph_pg_pool_flags(osdc->osdmap, ci->i_layout.pool_id);
> + up_read(&osdc->lock);
> + if ((map_flags & CEPH_OSDMAP_FULL) ||
> + (pool_flags & CEPH_POOL_FLAG_FULL)) {
> err = -ENOSPC;
> goto out;
> }
> @@ -1849,7 +1856,8 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
> }
>
> if (written >= 0) {
> - if (ceph_osdmap_flag(&fsc->client->osdc, CEPH_OSDMAP_NEARFULL))
> + if ((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/include/linux/ceph/osdmap.h b/include/linux/ceph/osdmap.h
> index e081b56f1c1d..5e601975745f 100644
> --- a/include/linux/ceph/osdmap.h
> +++ b/include/linux/ceph/osdmap.h
> @@ -37,6 +37,9 @@ int ceph_spg_compare(const struct ceph_spg *lhs, const struct ceph_spg *rhs);
> #define CEPH_POOL_FLAG_HASHPSPOOL (1ULL << 0) /* hash pg seed and pool id
> together */
> #define CEPH_POOL_FLAG_FULL (1ULL << 1) /* pool is full */
> +#define CEPH_POOL_FLAG_FULL_QUOTA (1ULL << 10) /* pool ran out of quota,
> + will set FULL too */
> +#define CEPH_POOL_FLAG_NEARFULL (1ULL << 11) /* pool is nearfull */
>
> struct ceph_pg_pool_info {
> struct rb_node node;
> @@ -304,5 +307,6 @@ extern struct ceph_pg_pool_info *ceph_pg_pool_by_id(struct ceph_osdmap *map,
>
> extern const char *ceph_pg_pool_name_by_id(struct ceph_osdmap *map, u64 id);
> extern int ceph_pg_poolid_by_name(struct ceph_osdmap *map, const char *name);
> +u64 ceph_pg_pool_flags(struct ceph_osdmap *map, u64 id);
>
> #endif
> diff --git a/include/linux/ceph/rados.h b/include/linux/ceph/rados.h
> index 59bdfd470100..88ed3c5c04c5 100644
> --- a/include/linux/ceph/rados.h
> +++ b/include/linux/ceph/rados.h
> @@ -143,8 +143,10 @@ extern const char *ceph_osd_state_name(int s);
> /*
> * osd map flag bits
> */
> -#define CEPH_OSDMAP_NEARFULL (1<<0) /* sync writes (near ENOSPC) */
> -#define CEPH_OSDMAP_FULL (1<<1) /* no data writes (ENOSPC) */
> +#define CEPH_OSDMAP_NEARFULL (1<<0) /* sync writes (near ENOSPC),
> + not set since ~luminous */
> +#define CEPH_OSDMAP_FULL (1<<1) /* no data writes (ENOSPC),
> + not set since ~luminous */
> #define CEPH_OSDMAP_PAUSERD (1<<2) /* pause all reads */
> #define CEPH_OSDMAP_PAUSEWR (1<<3) /* pause all writes */
> #define CEPH_OSDMAP_PAUSEREC (1<<4) /* pause recovery */
> diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
> index 4e0de14f80bb..2a6e63a8edbe 100644
> --- a/net/ceph/osdmap.c
> +++ b/net/ceph/osdmap.c
> @@ -710,6 +710,15 @@ int ceph_pg_poolid_by_name(struct ceph_osdmap *map, const char *name)
> }
> EXPORT_SYMBOL(ceph_pg_poolid_by_name);
>
> +u64 ceph_pg_pool_flags(struct ceph_osdmap *map, u64 id)
> +{
> + struct ceph_pg_pool_info *pi;
> +
> + pi = __lookup_pg_pool(&map->pg_pools, id);
> + return pi ? pi->flags : 0;
> +}
> +EXPORT_SYMBOL(ceph_pg_pool_flags);
> +
> static void __remove_pg_pool(struct rb_root *root, struct ceph_pg_pool_info *pi)
> {
> rb_erase(&pi->node, root);
Not thrilled with the extra readlocking in ceph_write_iter, but I don't
see a real alternative (at least not one that would be suitable for
stable).
Reviewed-by: Jeff Layton <jlayton@kernel.org>
prev parent reply other threads:[~2020-03-19 16:16 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-16 9:03 [PATCH] ceph: check POOL_FLAG_FULL/NEARFULL in addition to OSDMAP_FULL/NEARFULL Ilya Dryomov
2020-03-19 16:16 ` Jeff Layton [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8aa2ca7a484d665c36db632ce38fb9c8552c43c1.camel@kernel.org \
--to=jlayton@kernel.org \
--cc=ceph-devel@vger.kernel.org \
--cc=gmayyyha@gmail.com \
--cc=idryomov@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox