diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 63feaed83bc62c3263c6554e07bd9c4e854ad14b..06f577764414bba629be18c698fc51a821acd09c 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -507,6 +507,15 @@ static inline const char *cgroup_name(const struct cgroup *cgrp) return rcu_dereference(cgrp->name)->name; } +/* returns ino associated with a cgroup, 0 indicates unmounted root */ +static inline ino_t cgroup_ino(struct cgroup *cgrp) +{ + if (cgrp->dentry) + return cgrp->dentry->d_inode->i_ino; + else + return 0; +} + static inline struct cgroup_subsys_state *seq_css(struct seq_file *seq) { struct cgroup_open_file *of = seq->private; diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 42e588ef62d1ffb8d497952396cc8644065b8ca3..11f7a05e791ee413ec250841b7dea89947bcae79 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -792,7 +792,10 @@ static struct inode *cgroup_new_inode(umode_t mode, struct super_block *sb) struct inode *inode = new_inode(sb); if (inode) { - inode->i_ino = get_next_ino(); + do { + /* ino 0 is reserved for dummy_root */ + inode->i_ino = get_next_ino(); + } while (!inode->i_ino); inode->i_mode = mode; inode->i_uid = current_fsuid(); inode->i_gid = current_fsgid(); diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 4f08a2d61487f3c45dc01638c31b6aff689ce6e7..9b5933c66c165d9b5fea0164b639187d82157988 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -145,14 +145,10 @@ static int hwpoison_filter_task(struct page *p) return -EINVAL; css = mem_cgroup_css(mem); - /* root_mem_cgroup has NULL dentries */ - if (!css->cgroup->dentry) - return -EINVAL; - - ino = css->cgroup->dentry->d_inode->i_ino; + ino = cgroup_ino(css->cgroup); css_put(css); - if (ino != hwpoison_filter_memcg) + if (!ino || ino != hwpoison_filter_memcg) return -EINVAL; return 0;