Unverified Commit 2f8f5a20 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!3888 fs/dcache.c: avoid panic while lockref of dentry overflow

parents 8aa69e79 cf619953
Loading
Loading
Loading
Loading
+28 −4
Original line number Diff line number Diff line
@@ -1873,6 +1873,18 @@ static struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
	return dentry;
}

static inline bool d_forbid_overflow(struct dentry *dentry)
{
	if (unlikely(d_count(dentry) >= D_COUNT_MAX)) {
		shrink_dcache_parent(dentry);

		if (d_count(dentry) >= D_COUNT_MAX)
			return false;
	}

	return true;
}

/**
 * d_alloc	-	allocate a dcache entry
 * @parent: parent of entry to allocate
@@ -1884,9 +1896,15 @@ static struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name)
 */
struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
{
	struct dentry *dentry = __d_alloc(parent->d_sb, name);
	struct dentry *dentry = NULL;

	if (unlikely(!d_forbid_overflow(parent)))
		goto out;

	dentry = __d_alloc(parent->d_sb, name);
	if (!dentry)
		return NULL;
		goto out;

	spin_lock(&parent->d_lock);
	/*
	 * don't need child lock because it is not subject
@@ -1896,7 +1914,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
	dentry->d_parent = parent;
	list_add(&dentry->d_child, &parent->d_subdirs);
	spin_unlock(&parent->d_lock);

out:
	return dentry;
}
EXPORT_SYMBOL(d_alloc);
@@ -1909,11 +1927,17 @@ EXPORT_SYMBOL(d_alloc_anon);

struct dentry *d_alloc_cursor(struct dentry * parent)
{
	struct dentry *dentry = d_alloc_anon(parent->d_sb);
	struct dentry *dentry = NULL;

	if (unlikely(!d_forbid_overflow(parent)))
		goto out;

	dentry = d_alloc_anon(parent->d_sb);
	if (dentry) {
		dentry->d_flags |= DCACHE_DENTRY_CURSOR;
		dentry->d_parent = dget(parent);
	}
out:
	return dentry;
}

+1 −1
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@
#include <linux/sched/signal.h>
#include <linux/module.h>

#define FILES_MAX ULONG_MAX
#define FILES_MAX D_COUNT_MAX
#define FILES_MAX_STR "max"

static bool no_acct;
+3 −0
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@
#include <asm/byteorder.h>
#include <uapi/linux/fs.h>

#define D_COUNT_MAX (INT_MAX / 2)


struct backing_dev_info;
struct bdi_writeback;
struct bio;