Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

make it easier to catch those who try to modify ->d_name

Turn d_name into an anon union of const struct qstr d_name with
struct qstr __d_name. Very few places need to modify it (all
in fs/dcache.c); those are switched to use of ->__d_name.

Note that ->d_name can actually change under you unless you have
the right locking environment; this const just prohibits accidentally
doing stores without being easily spotted.

Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Al Viro 180a9cc3 ca97d6c6

+17 -14
+13 -13
fs/dcache.c
··· 1717 1717 dname = dentry->d_shortname.string; 1718 1718 } 1719 1719 1720 - dentry->d_name.len = name->len; 1721 - dentry->d_name.hash = name->hash; 1720 + dentry->__d_name.len = name->len; 1721 + dentry->__d_name.hash = name->hash; 1722 1722 memcpy(dname, name->name, name->len); 1723 1723 dname[name->len] = 0; 1724 1724 1725 1725 /* Make sure we always see the terminating NUL character */ 1726 - smp_store_release(&dentry->d_name.name, dname); /* ^^^ */ 1726 + smp_store_release(&dentry->__d_name.name, dname); /* ^^^ */ 1727 1727 1728 1728 dentry->d_flags = 0; 1729 1729 lockref_init(&dentry->d_lockref); ··· 2743 2743 /* 2744 2744 * Both external: swap the pointers 2745 2745 */ 2746 - swap(target->d_name.name, dentry->d_name.name); 2746 + swap(target->__d_name.name, dentry->__d_name.name); 2747 2747 } else { 2748 2748 /* 2749 2749 * dentry:internal, target:external. Steal target's 2750 2750 * storage and make target internal. 2751 2751 */ 2752 - dentry->d_name.name = target->d_name.name; 2752 + dentry->__d_name.name = target->__d_name.name; 2753 2753 target->d_shortname = dentry->d_shortname; 2754 - target->d_name.name = target->d_shortname.string; 2754 + target->__d_name.name = target->d_shortname.string; 2755 2755 } 2756 2756 } else { 2757 2757 if (unlikely(dname_external(dentry))) { ··· 2759 2759 * dentry:external, target:internal. Give dentry's 2760 2760 * storage to target and make dentry internal 2761 2761 */ 2762 - target->d_name.name = dentry->d_name.name; 2762 + target->__d_name.name = dentry->__d_name.name; 2763 2763 dentry->d_shortname = target->d_shortname; 2764 - dentry->d_name.name = dentry->d_shortname.string; 2764 + dentry->__d_name.name = dentry->d_shortname.string; 2765 2765 } else { 2766 2766 /* 2767 2767 * Both are internal. ··· 2771 2771 target->d_shortname.words[i]); 2772 2772 } 2773 2773 } 2774 - swap(dentry->d_name.hash_len, target->d_name.hash_len); 2774 + swap(dentry->__d_name.hash_len, target->__d_name.hash_len); 2775 2775 } 2776 2776 2777 2777 static void copy_name(struct dentry *dentry, struct dentry *target) ··· 2781 2781 old_name = external_name(dentry); 2782 2782 if (unlikely(dname_external(target))) { 2783 2783 atomic_inc(&external_name(target)->count); 2784 - dentry->d_name = target->d_name; 2784 + dentry->__d_name = target->__d_name; 2785 2785 } else { 2786 2786 dentry->d_shortname = target->d_shortname; 2787 - dentry->d_name.name = dentry->d_shortname.string; 2788 - dentry->d_name.hash_len = target->d_name.hash_len; 2787 + dentry->__d_name.name = dentry->d_shortname.string; 2788 + dentry->__d_name.hash_len = target->__d_name.hash_len; 2789 2789 } 2790 2790 if (old_name && likely(atomic_dec_and_test(&old_name->count))) 2791 2791 kfree_rcu(old_name, head); ··· 3133 3133 !d_unlinked(dentry)); 3134 3134 spin_lock(&dentry->d_parent->d_lock); 3135 3135 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); 3136 - dentry->d_name.len = sprintf(dentry->d_shortname.string, "#%llu", 3136 + dentry->__d_name.len = sprintf(dentry->d_shortname.string, "#%llu", 3137 3137 (unsigned long long)inode->i_ino); 3138 3138 spin_unlock(&dentry->d_lock); 3139 3139 spin_unlock(&dentry->d_parent->d_lock);
+4 -1
include/linux/dcache.h
··· 95 95 seqcount_spinlock_t d_seq; /* per dentry seqlock */ 96 96 struct hlist_bl_node d_hash; /* lookup hash list */ 97 97 struct dentry *d_parent; /* parent directory */ 98 - struct qstr d_name; 98 + union { 99 + struct qstr __d_name; /* for use ONLY in fs/dcache.c */ 100 + const struct qstr d_name; 101 + }; 99 102 struct inode *d_inode; /* Where the name belongs to - NULL is 100 103 * negative */ 101 104 union shortname_store d_shortname;