Merge tag 'vfs-7.2-rc1.xattr' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Merge commit. Changes below are compared with the first parent: ec5d1ae9.
Changes
14 files changed · +526 −286
| File | Status | Add | Del | Content |
|---|---|---|---|---|
| fs/kernfs/dir.c | modified | +9 | −13 | View file |
| fs/kernfs/file.c | modified | +3 | −10 | View file |
| fs/kernfs/inode.c | modified | +18 | −18 | View file |
| fs/kernfs/kernfs-internal.h | modified | +23 | −1 | View file |
| fs/kernfs/mount.c | modified | +1 | −1 | View file |
| fs/pidfs.c | modified | +12 | −33 | View file |
| fs/xattr.c | modified | +164 | −114 | View file |
| include/linux/bpf.h | modified | +3 | −0 | View file |
| include/linux/kernfs.h | modified | +8 | −3 | View file |
| include/linux/shmem_fs.h | modified | +2 | −1 | View file |
| include/linux/xattr.h | modified | +20 | −19 | View file |
| kernel/bpf/inode.c | modified | +237 | −19 | View file |
| mm/shmem.c | modified | +17 | −33 | View file |
| net/socket.c | modified | +9 | −21 | View file |
Only the first 600 diff lines are shown. Download the complete patch.
fs/kernfs/dir.c
View filediff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index 4f9ade8..6d47b84 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -605,11 +605,8 @@ void kernfs_put(struct kernfs_node *kn)
if (kernfs_type(kn) == KERNFS_LINK)
kernfs_put(kn->symlink.target_kn);
- if (kn->iattr && kn->iattr->xattrs) {
- simple_xattrs_free(kn->iattr->xattrs, NULL);
- kfree(kn->iattr->xattrs);
- kn->iattr->xattrs = NULL;
- }
+ if (kn->iattr)
+ simple_xattrs_free(&root->xa_cache, &kn->iattr->xattrs, NULL);
spin_lock(&root->kernfs_idr_lock);
idr_remove(&root->ino_idr, (u32)kernfs_ino(kn));
@@ -624,6 +621,7 @@ void kernfs_put(struct kernfs_node *kn)
} else {
/* just released the root kn, free @root too */
idr_destroy(&root->ino_idr);
+ simple_xattr_cache_cleanup(&root->xa_cache);
kfree_rcu(root, rcu);
}
}
@@ -700,6 +698,9 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
}
if (parent) {
+ kernfs_get(parent);
+ rcu_assign_pointer(kn->__parent, parent);
+
ret = security_kernfs_init_security(parent, kn);
if (ret)
goto err_out4;
@@ -708,11 +709,10 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root,
return kn;
err_out4:
+ RCU_INIT_POINTER(kn->__parent, NULL);
+ kernfs_put(parent);
if (kn->iattr) {
- if (kn->iattr->xattrs) {
- simple_xattrs_free(kn->iattr->xattrs, NULL);
- kfree(kn->iattr->xattrs);
- }
+ simple_xattrs_free(&root->xa_cache, &kn->iattr->xattrs, NULL);
kmem_cache_free(kernfs_iattrs_cache, kn->iattr);
}
err_out3:
@@ -747,10 +747,6 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent,
kn = __kernfs_new_node(kernfs_root(parent), parent,
name, mode, uid, gid, flags);
- if (kn) {
- kernfs_get(parent);
- rcu_assign_pointer(kn->__parent, parent);
- }
return kn;
}
fs/kernfs/file.c
View filediff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 1163aa7..8e0e90c 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -40,22 +40,15 @@ struct kernfs_open_node {
static DEFINE_SPINLOCK(kernfs_notify_lock);
static struct kernfs_node *kernfs_notify_list = KERNFS_NOTIFY_EOL;
+/* Compatibility wrappers - use the common hashed node lock */
static inline struct mutex *kernfs_open_file_mutex_ptr(struct kernfs_node *kn)
{
- int idx = hash_ptr(kn, NR_KERNFS_LOCK_BITS);
-
- return &kernfs_locks->open_file_mutex[idx];
+ return kernfs_node_lock_ptr(kn);
}
static inline struct mutex *kernfs_open_file_mutex_lock(struct kernfs_node *kn)
{
- struct mutex *lock;
-
- lock = kernfs_open_file_mutex_ptr(kn);
-
- mutex_lock(lock);
-
- return lock;
+ return kernfs_node_lock(kn);
}
/**
fs/kernfs/inode.c
View filediff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index 38b28aa..2cb2029 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -37,6 +37,7 @@ static struct kernfs_iattrs *__kernfs_iattrs(struct kernfs_node *kn, bool alloc)
if (!ret)
return NULL;
+ INIT_LIST_HEAD_RCU(&ret->xattrs);
/* assign default attributes */
ret->ia_uid = GLOBAL_ROOT_UID;
ret->ia_gid = GLOBAL_ROOT_GID;
@@ -144,8 +145,7 @@ ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size)
if (!attrs)
return -ENOMEM;
- return simple_xattr_list(d_inode(dentry), READ_ONCE(attrs->xattrs),
- buf, size);
+ return simple_xattr_list(d_inode(dentry), &attrs->xattrs, buf, size);
}
static inline void set_default_inode_attr(struct inode *inode, umode_t mode)
@@ -297,34 +297,35 @@ int kernfs_xattr_get(struct kernfs_node *kn, const char *name,
void *value, size_t size)
{
struct kernfs_iattrs *attrs = kernfs_iattrs_noalloc(kn);
- struct simple_xattrs *xattrs;
+ struct simple_xattr_cache *cache = &kernfs_root(kn)->xa_cache;
if (!attrs)
return -ENODATA;
- xattrs = READ_ONCE(attrs->xattrs);
- if (!xattrs)
- return -ENODATA;
-
- return simple_xattr_get(xattrs, name, value, size);
+ return simple_xattr_get(cache, &attrs->xattrs, name, value, size);
}
int kernfs_xattr_set(struct kernfs_node *kn, const char *name,
const void *value, size_t size, int flags)
{
struct simple_xattr *old_xattr;
- struct simple_xattrs *xattrs;
struct kernfs_iattrs *attrs;
+ struct simple_xattr_cache *cache = &kernfs_root(kn)->xa_cache;
attrs = kernfs_iattrs(kn);
if (!attrs)
return -ENOMEM;
- xattrs = simple_xattrs_lazy_alloc(&attrs->xattrs, value, flags);
- if (IS_ERR_OR_NULL(xattrs))
- return PTR_ERR(xattrs);
+ /*
+ * Protect xattr modifications with the hashed per-node mutex.
+ * Multiple superblocks (with different namespaces) can share the same
+ * kernfs_node, so inode locking alone is insufficient. The hashed mutex
+ * ensures serialization of concurrent xattr operations on the same node,
+ * including the lazy allocation of the xattrs structure itself.
+ */
+ CLASS(kernfs_node_lock, lock)(kn);
- old_xattr = simple_xattr_set(xattrs, name, value, size, flags);
+ old_xattr = simple_xattr_set(cache, &attrs->xattrs, name, value, size, flags);
if (IS_ERR(old_xattr))
return PTR_ERR(old_xattr);
@@ -362,7 +363,6 @@ static int kernfs_vfs_user_xattr_set(const struct xattr_handler *handler,
{
const char *full_name = xattr_full_name(handler, suffix);
struct kernfs_node *kn = inode->i_private;
- struct simple_xattrs *xattrs;
struct kernfs_iattrs *attrs;
if (!(kernfs_root(kn)->flags & KERNFS_ROOT_SUPPORT_USER_XATTR))
@@ -372,11 +372,11 @@ static int kernfs_vfs_user_xattr_set(const struct xattr_handler *handler,
if (!attrs)
return -ENOMEM;
- xattrs = simple_xattrs_lazy_alloc(&attrs->xattrs, value, flags);
- if (IS_ERR_OR_NULL(xattrs))
- return PTR_ERR(xattrs);
+ /* See comment in kernfs_xattr_set() about locking. */
+ CLASS(kernfs_node_lock, lock)(kn);
- return simple_xattr_set_limited(xattrs, &attrs->xattr_limits,
+ return simple_xattr_set_limited(&kernfs_root(kn)->xa_cache,
+ &attrs->xattrs, &attrs->xattr_limits,
full_name, value, size, flags);
}
fs/kernfs/kernfs-internal.h
View filediff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h
index 8d8912f..aa784b5 100644
--- a/fs/kernfs/kernfs-internal.h
+++ b/fs/kernfs/kernfs-internal.h
@@ -26,7 +26,7 @@ struct kernfs_iattrs {
struct timespec64 ia_mtime;
struct timespec64 ia_ctime;
- struct simple_xattrs *xattrs;
+ struct list_head xattrs;
struct simple_xattr_limits xattr_limits;
};
@@ -54,6 +54,8 @@ struct kernfs_root {
rwlock_t kernfs_rename_lock;
struct rcu_head rcu;
+
+ struct simple_xattr_cache xa_cache;
};
/* +1 to avoid triggering overflow warning when negating it */
@@ -211,4 +213,24 @@ extern const struct inode_operations kernfs_symlink_iops;
* kernfs locks
*/
extern struct kernfs_global_locks *kernfs_locks;
+
+/* Hashed mutex helpers - protect per-node data structures */
+static inline struct mutex *kernfs_node_lock_ptr(struct kernfs_node *kn)
+{
+ int idx = hash_ptr(kn, NR_KERNFS_LOCK_BITS);
+
+ return &kernfs_locks->node_mutex[idx];
+}
+
+static inline struct mutex *kernfs_node_lock(struct kernfs_node *kn)
+{
+ struct mutex *lock = kernfs_node_lock_ptr(kn);
+
+ mutex_lock(lock);
+ return lock;
+}
+
+DEFINE_CLASS(kernfs_node_lock, struct mutex *,
+ mutex_unlock(_T), kernfs_node_lock(kn), struct kernfs_node *kn)
+
#endif /* __KERNFS_INTERNAL_H */
fs/kernfs/mount.c
View filediff --git a/fs/kernfs/mount.c b/fs/kernfs/mount.c
index 6e3217b..f183a96 100644
--- a/fs/kernfs/mount.c
+++ b/fs/kernfs/mount.c
@@ -446,7 +446,7 @@ static void __init kernfs_mutex_init(void)
int count;
for (count = 0; count < NR_KERNFS_LOCKS; count++)
- mutex_init(&kernfs_locks->open_file_mutex[count]);
+ mutex_init(&kernfs_locks->node_mutex[count]);
}
static void __init kernfs_lock_init(void)
fs/pidfs.c
View filediff --git a/fs/pidfs.c b/fs/pidfs.c
index b2ff950..ae307b7 100644
--- a/fs/pidfs.c
+++ b/fs/pidfs.c
@@ -37,6 +37,8 @@ static struct kmem_cache *pidfs_attr_cachep __ro_after_init;
static struct path pidfs_root_path = {};
+static struct simple_xattr_cache pidfs_xa_cache;
+
void pidfs_get_root(struct path *path)
{
*path = pidfs_root_path;
@@ -96,7 +98,7 @@ static const struct rhashtable_params pidfs_ino_ht_params = {
* use file handles.
*/
struct pidfs_attr {
- struct simple_xattrs *xattrs;
+ struct list_head xattrs;
union {
struct pidfs_anon_attr;
struct llist_node pidfs_llist;
@@ -196,12 +198,7 @@ static void pidfs_free_attr_work(struct work_struct *work)
head = llist_del_all(&pidfs_free_list);
llist_for_each_entry_safe(attr, next, head, pidfs_llist) {
- struct simple_xattrs *xattrs = attr->xattrs;
-
- if (xattrs) {
- simple_xattrs_free(xattrs, NULL);
- kfree(xattrs);
- }
+ simple_xattrs_free(&pidfs_xa_cache, &attr->xattrs, NULL);
kfree(attr);
}
}
@@ -229,7 +226,7 @@ void pidfs_free_pid(struct pid *pid)
if (IS_ERR(attr))
return;
- if (likely(!attr->xattrs))
+ if (likely(list_empty(&attr->xattrs)))
kfree(attr);
else if (llist_add(&attr->pidfs_llist, &pidfs_free_list))
schedule_work(&pidfs_free_work);
@@ -810,14 +807,8 @@ static ssize_t pidfs_listxattr(struct dentry *dentry, char *buf, size_t size)
{
struct inode *inode = d_inode(dentry);
struct pid *pid = inode->i_private;
- struct pidfs_attr *attr = pid->attr;
- struct simple_xattrs *xattrs;
-
- xattrs = READ_ONCE(attr->xattrs);
- if (!xattrs)
- return 0;
- return simple_xattr_list(inode, xattrs, buf, size);
+ return simple_xattr_list(inode, &pid->attr->xattrs, buf, size);
}
static const struct inode_operations pidfs_inode_operations = {
@@ -1013,6 +1004,8 @@ int pidfs_register_pid(struct pid *pid)
if (!new_attr)
return -ENOMEM;
+ INIT_LIST_HEAD_RCU(&new_attr->xattrs);
+
/* Synchronize with pidfs_exit(). */
guard(spinlock_irq)(&pid->wait_pidfd.lock);
@@ -1052,16 +1045,9 @@ static int pidfs_xattr_get(const struct xattr_handler *handler,
const char *suffix, void *value, size_t size)
{
struct pid *pid = inode->i_private;
- struct pidfs_attr *attr = pid->attr;
- const char *name;
- struct simple_xattrs *xattrs;
-
- xattrs = READ_ONCE(attr->xattrs);
- if (!xattrs)
- return -ENODATA;
+ const char *name = xattr_full_name(handler, suffix);
- name = xattr_full_name(handler, suffix);
- return simple_xattr_get(xattrs, name, value, size);
+ return simple_xattr_get(&pidfs_xa_cache, &pid->attr->xattrs, name, value, size);
}
static int pidfs_xattr_set(const struct xattr_handler *handler,
@@ -1070,20 +1056,13 @@ static int pidfs_xattr_set(const struct xattr_handler *handler,
const void *value, size_t size, int flags)
{
struct pid *pid = inode->i_private;
- struct pidfs_attr *attr = pid->attr;
- const char *name;
- struct simple_xattrs *xattrs;
+ const char *name = xattr_full_name(handler, suffix);
struct simple_xattr *old_xattr;
/* Ensure we're the only one to set @attr->xattrs. */
WARN_ON_ONCE(!inode_is_locked(inode));
- xattrs = simple_xattrs_lazy_alloc(&attr->xattrs, value, flags);
- if (IS_ERR_OR_NULL(xattrs))
- return PTR_ERR(xattrs);
-
- name = xattr_full_name(handler, suffix);
- old_xattr = simple_xattr_set(xattrs, name, value, size, flags);
+ old_xattr = simple_xattr_set(&pidfs_xa_cache, &pid->attr->xattrs, name, value, size, flags);
if (IS_ERR(old_xattr))
return PTR_ERR(old_xattr);
fs/xattr.c
View filediff --git a/fs/xattr.c b/fs/xattr.c
index efdcf2a..e1fc688 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -28,6 +28,11 @@
#include "internal.h"
+struct sx_key {
+ const struct list_head *parent;
+ const char *name;
+};
+
static const char *
strcmp_prefix(const char *a, const char *a_prefix)
{
@@ -1269,23 +1274,32 @@ struct simple_xattr *simple_xattr_alloc(const void *value, size_t size)
return new_xattr;
}
+static u32 sx_hashfn(const char *name, const struct list_head *parent, u32 seed)
+{
+ return jhash(name, strlen(name), jhash(&parent, sizeof(parent), seed));
+}
+
static u32 simple_xattr_hashfn(const void *data, u32 len, u32 seed)
{
- const char *name = data;
- return jhash(name, strlen(name), seed);
+ const struct sx_key *key = data;
+
+ return sx_hashfn(key->name, key->parent, seed);
}
static u32 simple_xattr_obj_hashfn(const void *obj, u32 len, u32 seed)
{
const struct simple_xattr *xattr = obj;
- return jhash(xattr->name, strlen(xattr->name), seed);
+
+ return sx_hashfn(xattr->name, xattr->parent, seed);
}
static int simple_xattr_obj_cmpfn(struct rhashtable_compare_arg *arg,
const void *obj)
{
const struct simple_xattr *xattr = obj;
- return strcmp(xattr->name, arg->key);
+ const struct sx_key *key = arg->key;
+
+ return xattr->parent != key->parent || strcmp(xattr->name, key->name);
}
static const struct rhashtable_params simple_xattr_params = {
@@ -1298,6 +1312,7 @@ static const struct rhashtable_params simple_xattr_params = {
/**
* simple_xattr_get - get an xattr object
+ * @cache: anchor for the hash table
* @xattrs: the header of the xattr object
* @name: the name of the xattr to retrieve
* @buffer: the buffer to store the value into
@@ -1311,14 +1326,19 @@ static const struct rhashtable_params simple_xattr_params = {
* Return: On success the length of the xattr value is returned. On error a
* negative error code is returned.
*/
-int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
- void *buffer, size_t size)
+int simple_xattr_get(struct simple_xattr_cache *cache, struct list_head *xattrs,
+ const char *name, void *buffer, size_t size)
{
struct simple_xattr *xattr;
+ struct sx_key key = { .parent = xattrs, .name = name };
+ struct rhashtable *ht = READ_ONCE(cache->ht);
int ret = -ENODATA;
+ if (!ht)
+ return ret;
+
guard(rcu)();
- xattr = rhashtable_lookup(&xattrs->ht, name, simple_xattr_params);
+ xattr = rhashtable_lookup(ht, &key, simple_xattr_params);
if (xattr) {
ret = xattr->size;
if (buffer) {
@@ -1331,8 +1351,45 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
return ret;
}
+static struct rhashtable *simple_xattrs_lazy_alloc(struct simple_xattr_cache *cache,
+ const void *value, int flags)
+{
+ struct rhashtable *oldht, *ht = READ_ONCE(cache->ht);
+ int err;
+
+ if (unlikely(!ht)) {
+ if (!value)
+ return (flags & XATTR_REPLACE) ? ERR_PTR(-ENODATA) : NULL;
+
+ ht = kzalloc_obj(*ht);
+ if (!ht)
+ return ERR_PTR(-ENOMEM);
+
+ err = rhashtable_init(ht, &simple_xattr_params);
+ if (err) {
+ kfree(ht);
+ return ERR_PTR(err);
+ }
+
+ /*
+ * Provides release semantics on success, so that use of a
+ * non-NULL READ_ONCE(cache->ht) will be ordered relative to the
+ * above initialization, due to implicit address dependency.
+ */
+ oldht = cmpxchg_release(&cache->ht, NULL, ht);
+ if (oldht) {
+ /* Race lost */
+ rhashtable_destroy(ht);
+ kfree(ht);
+ ht = oldht;
+ }
+ }
+ return ht;
+}
+
/**
* simple_xattr_set - set an xattr object
+ * @cache: anchor for the hash table
* @xattrs: the header of the xattr object
* @name: the name of the xattr to retrieve
* @value: the value to store along the xattr
@@ -1362,45 +1419,58 @@ int simple_xattr_get(struct simple_xattrs *xattrs, const char *name,
* Return: On success, the removed or replaced xattr is returned, to be freed
* by the caller; or NULL if none. On failure a negative error code is returned.
*/
-struct simple_xattr *simple_xattr_set(struct simple_xattrs *xattrs,
+struct simple_xattr *simple_xattr_set(struct simple_xattr_cache *cache, struct list_head *xattrs,
const char *name, const void *value,
size_t size, int flags)
{
+ struct sx_key key = { .parent = xattrs, .name = name };
struct simple_xattr *old_xattr = NULL;
+ struct rhashtable *ht;
int err;
+ ht = simple_xattrs_lazy_alloc(cache, value, flags);
+ if (IS_ERR_OR_NULL(ht))
+ return ERR_CAST(ht);
+
CLASS(simple_xattr, new_xattr)(value, size);
if (IS_ERR(new_xattr))
return new_xattr;
if (new_xattr) {
+ new_xattr->parent = xattrs;
new_xattr->name = kstrdup(name, GFP_KERNEL_ACCOUNT);
if (!new_xattr->name)
return ERR_PTR(-ENOMEM);
}
- /* Lookup is safe without RCU here since writes are serialized. */
- old_xattr = rhashtable_lookup_fast(&xattrs->ht, name,
- simple_xattr_params);
-
+ /*
+ * Hash table lookup/replace/remove will grab RCU read lock themselves.
+ * This makes sure that hash table lookup is safe against concurrent
+ * modification on another inode.
+ */
+ old_xattr = rhashtable_lookup_fast(ht, &key, simple_xattr_params);
if (old_xattr) {
/* Fail if XATTR_CREATE is requested and the xattr exists. */
if (flags & XATTR_CREATE)
return ERR_PTR(-EEXIST);
if (new_xattr) {
- err = rhashtable_replace_fast(&xattrs->ht,
+ err = rhashtable_replace_fast(ht,
&old_xattr->hash_node,
&new_xattr->hash_node,
simple_xattr_params);
if (err)
return ERR_PTR(err);
+
+ list_replace_rcu(&old_xattr->node, &new_xattr->node);
} else {
- err = rhashtable_remove_fast(&xattrs->ht,
+ err = rhashtable_remove_fast(ht,
&old_xattr->hash_node,
simple_xattr_params);
if (err)
return ERR_PTR(err);
+
+ list_del_rcu(&old_xattr->node);
}
} else {
/* Fail if XATTR_REPLACE is requested but no xattr is found. */
@@ -1412,11 +1482,13 @@ struct simple_xattr *simple_xattr_set(struct simple_xattrs *xattrs,
* new value simply insert it.
*/
if (new_xattr) {
- err = rhashtable_insert_fast(&xattrs->ht,
+ err = rhashtable_insert_fast(ht,
&new_xattr->hash_node,
simple_xattr_params);
if (err)
return ERR_PTR(err);
+
+ list_add_tail_rcu(&new_xattr->node, xattrs);
}
/*
@@ -1453,6 +1525,7 @@ static inline int simple_xattr_limits_inc(struct simple_xattr_limits *limits,
/**
* simple_xattr_set_limited - set an xattr with per-inode user.* limits
+ * @cache: anchor for the hash table
* @xattrs: the header of the xattr object
* @limits: per-inode limit counters for user.* xattrs
* @name: the name of the xattr to set or remove
@@ -1467,7 +1540,7 @@ static inline int simple_xattr_limits_inc(struct simple_xattr_limits *limits,
* Return: On success zero is returned. On failure a negative error code is
* returned.
*/
-int simple_xattr_set_limited(struct simple_xattrs *xattrs,
+int simple_xattr_set_limited(struct simple_xattr_cache *cache, struct list_head *xattrs,
struct simple_xattr_limits *limits,
const char *name, const void *value,
size_t size, int flags)
@@ -1481,7 +1554,7 @@ int simple_xattr_set_limited(struct simple_xattrs *xattrs,
return ret;
}
- old_xattr = simple_xattr_set(xattrs, name, value, size, flags);
+ old_xattr = simple_xattr_set(cache, xattrs, name, value, size, flags);
if (IS_ERR(old_xattr)) {
if (value)
simple_xattr_limits_dec(limits, size);
@@ -1527,11 +1600,10 @@ static bool xattr_is_maclabel(const char *name)
* Return: On success the required size or the size of the copied xattrs is
* returned. On error a negative error code is returned.
*/
-ssize_t simple_xattr_list(struct inode *inode, struct simple_xattrs *xattrs,
+ssize_t simple_xattr_list(struct inode *inode, struct list_head *xattrs,
This diff is incomplete. Download the complete patch.
include/linux/bpf.h
View fileThis diff is incomplete. Download the complete patch.
include/linux/kernfs.h
View fileThis diff is incomplete. Download the complete patch.
include/linux/shmem_fs.h
View fileThis diff is incomplete. Download the complete patch.
include/linux/xattr.h
View fileThis diff is incomplete. Download the complete patch.
kernel/bpf/inode.c
View fileThis diff is incomplete. Download the complete patch.
mm/shmem.c
View fileThis diff is incomplete. Download the complete patch.
net/socket.c
View fileThis diff is incomplete. Download the complete patch.