From: Viacheslav Dubeyko <Slava.Dubeyko@xxxxxxx> This patch leaves BUG_ON() for debug case and introduces WARN_ON() for release case in ceph_readdir() logic. If dfi->readdir_cache_idx somehow is invalid, then we will have BUG_ON() in debug build but release build will issue WARN_ON() instead. Signed-off-by: Viacheslav Dubeyko <Slava.Dubeyko@xxxxxxx> --- fs/ceph/Kconfig | 13 +++++++++++++ fs/ceph/dir.c | 21 ++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/fs/ceph/Kconfig b/fs/ceph/Kconfig index 3e7def3d31c1..dba85d202a14 100644 --- a/fs/ceph/Kconfig +++ b/fs/ceph/Kconfig @@ -50,3 +50,16 @@ config CEPH_FS_SECURITY_LABEL If you are not using a security module that requires using extended attributes for file security labels, say N. + +config CEPH_FS_DEBUG + bool "Ceph client debugging" + depends on CEPH_FS + default n + help + If you say Y here, this option enables additional pre-condition + and post-condition checks in functions. Also it could enable + BUG_ON() instead of returning the error code. This option could + save more messages in system log and execute additional computation. + + If you are going to debug the code, then chose Y here. + If unsure, say N. diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index acecc16f2b99..c88326e2ddbf 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c @@ -614,13 +614,28 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) spin_lock(&ci->i_ceph_lock); if (dfi->dir_ordered_count == atomic64_read(&ci->i_ordered_count)) { + bool is_invalid; + size_t size; + doutc(cl, " marking %p %llx.%llx complete and ordered\n", inode, ceph_vinop(inode)); /* use i_size to track number of entries in * readdir cache */ - BUG_ON(dfi->readdir_cache_idx < 0); - i_size_write(inode, dfi->readdir_cache_idx * - sizeof(struct dentry*)); + + is_invalid = + is_cache_idx_invalid(dfi->readdir_cache_idx); + +#ifdef CONFIG_CEPH_FS_DEBUG + BUG_ON(is_invalid); +#else + WARN_ON(is_invalid); +#endif /* CONFIG_CEPH_FS_DEBUG */ + + if (!is_invalid) { + size = dfi->readdir_cache_idx; + size *= sizeof(struct dentry*); + i_size_write(inode, size); + } } else { doutc(cl, " marking %llx.%llx complete\n", ceph_vinop(inode)); -- 2.48.0