static inline int dentry_cmp(const struct dentry *dentry, const unsigned char *ct, unsigned tcount)
 {
+       const unsigned char *cs;
        /*
         * Be careful about RCU walk racing with rename:
         * use ACCESS_ONCE to fetch the name pointer.
         * early because the data cannot match (there can
         * be no NUL in the ct/tcount data)
         */
-       return dentry_string_cmp(ACCESS_ONCE(dentry->d_name.name), ct, tcount);
+       cs = ACCESS_ONCE(dentry->d_name.name);
+       smp_read_barrier_depends();
+       return dentry_string_cmp(cs, ct, tcount);
 }
 
 static void __d_free(struct rcu_head *head)
        if (!dentry)
                return NULL;
 
+       /*
+        * We guarantee that the inline name is always NUL-terminated.
+        * This way the memcpy() done by the name switching in rename
+        * will still always have a NUL at the end, even if we might
+        * be overwriting an internal NUL character
+        */
+       dentry->d_iname[DNAME_INLINE_LEN-1] = 0;
        if (name->len > DNAME_INLINE_LEN-1) {
                dname = kmalloc(name->len + 1, GFP_KERNEL);
                if (!dname) {
        } else  {
                dname = dentry->d_iname;
        }       
-       dentry->d_name.name = dname;
 
        dentry->d_name.len = name->len;
        dentry->d_name.hash = name->hash;
        memcpy(dname, name->name, name->len);
        dname[name->len] = 0;
 
+       /* Make sure we always see the terminating NUL character */
+       smp_wmb();
+       dentry->d_name.name = dname;
+
        dentry->d_count = 1;
        dentry->d_flags = 0;
        spin_lock_init(&dentry->d_lock);