}
        path.mnt = mntget(pfmfs_mnt);
 
-       path.dentry->d_op = &pfmfs_dentry_operations;
+       d_set_d_op(path.dentry, &pfmfs_dentry_operations);
        d_add(path.dentry, inode);
 
        file = alloc_file(&path, FMODE_READ, &pfm_file_ops);
 
         *
         * We need to do this before we release the directory semaphore.
         */
-       dentry->d_op = &autofs_dentry_operations;
+       d_set_d_op(dentry, &autofs_dentry_operations);
        dentry->d_flags |= DCACHE_AUTOFS_PENDING;
        d_add(dentry, NULL);
 
 
        struct smb_sb_info *server = server_from_dentry(dentry);
 
        if (server->mnt->flags & SMB_MOUNT_CASE)
-               dentry->d_op = &smbfs_dentry_operations_case;
+               d_set_d_op(dentry, &smbfs_dentry_operations_case);
        else
-               dentry->d_op = &smbfs_dentry_operations;
+               d_set_d_op(dentry, &smbfs_dentry_operations);
        dentry->d_time = jiffies;
 }
 
        add_entry:
                        server = server_from_dentry(dentry);
                        if (server->mnt->flags & SMB_MOUNT_CASE)
-                               dentry->d_op = &smbfs_dentry_operations_case;
+                               d_set_d_op(dentry, &smbfs_dentry_operations_case);
                        else
-                               dentry->d_op = &smbfs_dentry_operations;
+                               d_set_d_op(dentry, &smbfs_dentry_operations);
 
                        d_add(dentry, inode);
                        smb_renew_times(dentry);
 
        }
 
        if (v9ses->cache)
-               dentry->d_op = &v9fs_cached_dentry_operations;
+               d_set_d_op(dentry, &v9fs_cached_dentry_operations);
        else
-               dentry->d_op = &v9fs_dentry_operations;
+               d_set_d_op(dentry, &v9fs_dentry_operations);
 
        d_instantiate(dentry, inode);
        err = v9fs_fid_add(dentry, fid);
                                err);
                        goto error;
                }
-               dentry->d_op = &v9fs_cached_dentry_operations;
+               d_set_d_op(dentry, &v9fs_cached_dentry_operations);
                d_instantiate(dentry, inode);
                err = v9fs_fid_add(dentry, fid);
                if (err < 0)
                        err = PTR_ERR(inode);
                        goto error;
                }
-               dentry->d_op = &v9fs_dentry_operations;
+               d_set_d_op(dentry, &v9fs_dentry_operations);
                d_instantiate(dentry, inode);
        }
        /* Now set the ACL based on the default value */
                                err);
                        goto error;
                }
-               dentry->d_op = &v9fs_cached_dentry_operations;
+               d_set_d_op(dentry, &v9fs_cached_dentry_operations);
                d_instantiate(dentry, inode);
                err = v9fs_fid_add(dentry, fid);
                if (err < 0)
                        err = PTR_ERR(inode);
                        goto error;
                }
-               dentry->d_op = &v9fs_dentry_operations;
+               d_set_d_op(dentry, &v9fs_dentry_operations);
                d_instantiate(dentry, inode);
        }
        /* Now set the ACL based on the default value */
 
 inst_out:
        if (v9ses->cache)
-               dentry->d_op = &v9fs_cached_dentry_operations;
+               d_set_d_op(dentry, &v9fs_cached_dentry_operations);
        else
-               dentry->d_op = &v9fs_dentry_operations;
+               d_set_d_op(dentry, &v9fs_dentry_operations);
 
        d_add(dentry, inode);
        return NULL;
                                        err);
                        goto error;
                }
-               dentry->d_op = &v9fs_cached_dentry_operations;
+               d_set_d_op(dentry, &v9fs_cached_dentry_operations);
                d_instantiate(dentry, inode);
                err = v9fs_fid_add(dentry, fid);
                if (err < 0)
                        err = PTR_ERR(inode);
                        goto error;
                }
-               dentry->d_op = &v9fs_dentry_operations;
+               d_set_d_op(dentry, &v9fs_dentry_operations);
                d_instantiate(dentry, inode);
        }
 
                ihold(old_dentry->d_inode);
        }
 
-       dentry->d_op = old_dentry->d_op;
+       d_set_d_op(dentry, old_dentry->d_op);
        d_instantiate(dentry, old_dentry->d_inode);
 
        return err;
                                err);
                        goto error;
                }
-               dentry->d_op = &v9fs_cached_dentry_operations;
+               d_set_d_op(dentry, &v9fs_cached_dentry_operations);
                d_instantiate(dentry, inode);
                err = v9fs_fid_add(dentry, fid);
                if (err < 0)
                        err = PTR_ERR(inode);
                        goto error;
                }
-               dentry->d_op = &v9fs_dentry_operations;
+               d_set_d_op(dentry, &v9fs_dentry_operations);
                d_instantiate(dentry, inode);
        }
        /* Now set the ACL based on the default value */
 
        struct object_info obj;
        int error;
 
-       dentry->d_op = &adfs_dentry_operations; 
+       d_set_d_op(dentry, &adfs_dentry_operations);
        lock_kernel();
        error = adfs_dir_lookup_byname(dir, &dentry->d_name, &obj);
        if (error == 0) {
 
                adfs_error(sb, "get root inode failed\n");
                goto error;
        } else
-               sb->s_root->d_op = &adfs_dentry_operations;
+               d_set_d_op(sb->s_root, &adfs_dentry_operations);
        unlock_kernel();
        return 0;
 
 
                if (IS_ERR(inode))
                        return ERR_CAST(inode);
        }
-       dentry->d_op = AFFS_SB(sb)->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations;
+       d_set_d_op(dentry, AFFS_SB(sb)->s_flags & SF_INTL ? &affs_intl_dentry_operations : &affs_dentry_operations);
        d_add(dentry, inode);
        return NULL;
 }
 
                printk(KERN_ERR "AFFS: Get root inode failed\n");
                goto out_error;
        }
-       sb->s_root->d_op = &affs_dentry_operations;
+       d_set_d_op(sb->s_root, &affs_dentry_operations);
 
        pr_debug("AFFS: s_flags=%lX\n",sb->s_flags);
        return 0;
 
        }
 
 success:
-       dentry->d_op = &afs_fs_dentry_operations;
+       d_set_d_op(dentry, &afs_fs_dentry_operations);
 
        d_add(dentry, inode);
        _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%llu }",
 
         */
        ihold(anon_inode_inode);
 
-       path.dentry->d_op = &anon_inodefs_dentry_operations;
+       d_set_d_op(path.dentry, &anon_inodefs_dentry_operations);
        d_instantiate(path.dentry, anon_inode_inode);
 
        error = -ENFILE;
 
                goto fail_iput;
        pipe = NULL;
 
-       root->d_op = &autofs4_sb_dentry_operations;
+       d_set_d_op(root, &autofs4_sb_dentry_operations);
        root->d_fsdata = ino;
 
        /* Can this call block? */
 
                 * we check for the hashed dentry and return the newly
                 * hashed dentry.
                 */
-               dentry->d_op = &autofs4_root_dentry_operations;
+               d_set_d_op(dentry, &autofs4_root_dentry_operations);
 
                /*
                 * And we need to ensure that the same dentry is used for
        d_add(dentry, inode);
 
        if (dir == dir->i_sb->s_root->d_inode)
-               dentry->d_op = &autofs4_root_dentry_operations;
+               d_set_d_op(dentry, &autofs4_root_dentry_operations);
        else
-               dentry->d_op = &autofs4_dentry_operations;
+               d_set_d_op(dentry, &autofs4_dentry_operations);
 
        dentry->d_fsdata = ino;
        ino->dentry = dget(dentry);
        d_add(dentry, inode);
 
        if (dir == dir->i_sb->s_root->d_inode)
-               dentry->d_op = &autofs4_root_dentry_operations;
+               d_set_d_op(dentry, &autofs4_root_dentry_operations);
        else
-               dentry->d_op = &autofs4_dentry_operations;
+               d_set_d_op(dentry, &autofs4_dentry_operations);
 
        dentry->d_fsdata = ino;
        ino->dentry = dget(dentry);
 
 
        dentry = d_obtain_alias(inode);
        if (!IS_ERR(dentry))
-               dentry->d_op = &btrfs_dentry_operations;
+               d_set_d_op(dentry, &btrfs_dentry_operations);
        return dentry;
 fail:
        srcu_read_unlock(&fs_info->subvol_srcu, index);
        key.offset = 0;
        dentry = d_obtain_alias(btrfs_iget(root->fs_info->sb, &key, root, NULL));
        if (!IS_ERR(dentry))
-               dentry->d_op = &btrfs_dentry_operations;
+               d_set_d_op(dentry, &btrfs_dentry_operations);
        return dentry;
 fail:
        btrfs_free_path(path);
 
        int index;
        int ret;
 
-       dentry->d_op = &btrfs_dentry_operations;
+       d_set_d_op(dentry, &btrfs_dentry_operations);
 
        if (dentry->d_name.len > BTRFS_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
 
 
        if (dentry->d_parent == NULL ||   /* nfs fh_to_dentry */
            ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP)
-               dentry->d_op = &ceph_dentry_ops;
+               d_set_d_op(dentry, &ceph_dentry_ops);
        else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR)
-               dentry->d_op = &ceph_snapdir_dentry_ops;
+               d_set_d_op(dentry, &ceph_snapdir_dentry_ops);
        else
-               dentry->d_op = &ceph_snap_dentry_ops;
+               d_set_d_op(dentry, &ceph_snap_dentry_ops);
 
        di = kmem_cache_alloc(ceph_dentry_cachep, GFP_NOFS | __GFP_ZERO);
        if (!di)
 
                              struct inode *newinode)
 {
        if (tcon->nocase)
-               direntry->d_op = &cifs_ci_dentry_ops;
+               d_set_d_op(direntry, &cifs_ci_dentry_ops);
        else
-               direntry->d_op = &cifs_dentry_ops;
+               d_set_d_op(direntry, &cifs_dentry_ops);
        d_instantiate(direntry, newinode);
 }
 
                rc = cifs_get_inode_info_unix(&newinode, full_path,
                                                inode->i_sb, xid);
                if (pTcon->nocase)
-                       direntry->d_op = &cifs_ci_dentry_ops;
+                       d_set_d_op(direntry, &cifs_ci_dentry_ops);
                else
-                       direntry->d_op = &cifs_dentry_ops;
+                       d_set_d_op(direntry, &cifs_dentry_ops);
 
                if (rc == 0)
                        d_instantiate(direntry, newinode);
 
        if ((rc == 0) && (newInode != NULL)) {
                if (pTcon->nocase)
-                       direntry->d_op = &cifs_ci_dentry_ops;
+                       d_set_d_op(direntry, &cifs_ci_dentry_ops);
                else
-                       direntry->d_op = &cifs_dentry_ops;
+                       d_set_d_op(direntry, &cifs_dentry_ops);
                d_add(direntry, newInode);
                if (posix_open) {
                        filp = lookup_instantiate_filp(nd, direntry,
                rc = 0;
                direntry->d_time = jiffies;
                if (pTcon->nocase)
-                       direntry->d_op = &cifs_ci_dentry_ops;
+                       d_set_d_op(direntry, &cifs_ci_dentry_ops);
                else
-                       direntry->d_op = &cifs_dentry_ops;
+                       d_set_d_op(direntry, &cifs_dentry_ops);
                d_add(direntry, NULL);
        /*      if it was once a directory (but how can we tell?) we could do
                shrink_dcache_parent(direntry); */
 
        to set uid/gid */
                        inc_nlink(inode);
                        if (pTcon->nocase)
-                               direntry->d_op = &cifs_ci_dentry_ops;
+                               d_set_d_op(direntry, &cifs_ci_dentry_ops);
                        else
-                               direntry->d_op = &cifs_dentry_ops;
+                               d_set_d_op(direntry, &cifs_dentry_ops);
 
                        cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
                        cifs_fill_uniqueid(inode->i_sb, &fattr);
                                                 inode->i_sb, xid, NULL);
 
                if (pTcon->nocase)
-                       direntry->d_op = &cifs_ci_dentry_ops;
+                       d_set_d_op(direntry, &cifs_ci_dentry_ops);
                else
-                       direntry->d_op = &cifs_dentry_ops;
+                       d_set_d_op(direntry, &cifs_dentry_ops);
                d_instantiate(direntry, newinode);
                 /* setting nlink not necessary except in cases where we
                  * failed to get it from the server or was set bogus */
 
                              rc);
                } else {
                        if (pTcon->nocase)
-                               direntry->d_op = &cifs_ci_dentry_ops;
+                               d_set_d_op(direntry, &cifs_ci_dentry_ops);
                        else
-                               direntry->d_op = &cifs_dentry_ops;
+                               d_set_d_op(direntry, &cifs_dentry_ops);
                        d_instantiate(direntry, newinode);
                }
        }
 
        }
 
        if (cifs_sb_master_tcon(CIFS_SB(sb))->nocase)
-               dentry->d_op = &cifs_ci_dentry_ops;
+               d_set_d_op(dentry, &cifs_ci_dentry_ops);
        else
-               dentry->d_op = &cifs_dentry_ops;
+               d_set_d_op(dentry, &cifs_dentry_ops);
 
        alias = d_materialise_unique(dentry, inode);
        if (alias != NULL) {
 
                return ERR_PTR(error);
 
 exit:
-       entry->d_op = &coda_dentry_operations;
+       d_set_d_op(entry, &coda_dentry_operations);
 
        if (inode && (type & CODA_NOCACHE))
                coda_flag_inode(inode, C_VATTR | C_PURGE);
 
                return error;
        }
 
-       dentry->d_op = &configfs_dentry_ops;
+       d_set_d_op(dentry, &configfs_dentry_ops);
        d_rehash(dentry);
 
        return 0;
                 */
                if (dentry->d_name.len > NAME_MAX)
                        return ERR_PTR(-ENAMETOOLONG);
-               dentry->d_op = &configfs_dentry_ops;
+               d_set_d_op(dentry, &configfs_dentry_ops);
                d_add(dentry, NULL);
                return NULL;
        }
        ret = -ENOMEM;
        child = d_alloc(parent, &name);
        if (child) {
-               child->d_op = &configfs_dentry_ops;
+               d_set_d_op(child, &configfs_dentry_ops);
                d_add(child, NULL);
 
                ret = configfs_attach_group(&parent_group->cg_item,
        err = -ENOMEM;
        dentry = d_alloc(configfs_sb->s_root, &name);
        if (dentry) {
-               dentry->d_op = &configfs_dentry_ops;
+               d_set_d_op(dentry, &configfs_dentry_ops);
                d_add(dentry, NULL);
 
                err = configfs_attach_group(sd->s_element, &group->cg_item,
 
                return;
        }
 
-       if (dentry->d_op && dentry->d_op->d_delete) {
+       if (dentry->d_flags & DCACHE_OP_DELETE) {
                if (dentry->d_op->d_delete(dentry))
                        goto kill_it;
        }
 }
 EXPORT_SYMBOL(d_alloc_name);
 
+void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op)
+{
+       BUG_ON(dentry->d_op);
+       BUG_ON(dentry->d_flags & (DCACHE_OP_HASH        |
+                               DCACHE_OP_COMPARE       |
+                               DCACHE_OP_REVALIDATE    |
+                               DCACHE_OP_DELETE ));
+       dentry->d_op = op;
+       if (!op)
+               return;
+       if (op->d_hash)
+               dentry->d_flags |= DCACHE_OP_HASH;
+       if (op->d_compare)
+               dentry->d_flags |= DCACHE_OP_COMPARE;
+       if (op->d_revalidate)
+               dentry->d_flags |= DCACHE_OP_REVALIDATE;
+       if (op->d_delete)
+               dentry->d_flags |= DCACHE_OP_DELETE;
+
+}
+EXPORT_SYMBOL(d_set_d_op);
+
 static void __d_instantiate(struct dentry *dentry, struct inode *inode)
 {
        spin_lock(&dentry->d_lock);
                 */
                if (read_seqcount_retry(&dentry->d_seq, *seq))
                        goto seqretry;
-               if (parent->d_op && parent->d_op->d_compare) {
+               if (parent->d_flags & DCACHE_OP_COMPARE) {
                        if (parent->d_op->d_compare(parent, *inode,
                                                dentry, i,
                                                tlen, tname, name))
                 */
                tlen = dentry->d_name.len;
                tname = dentry->d_name.name;
-               if (parent->d_op && parent->d_op->d_compare) {
+               if (parent->d_flags & DCACHE_OP_COMPARE) {
                        if (parent->d_op->d_compare(parent, parent->d_inode,
                                                dentry, dentry->d_inode,
                                                tlen, tname, name))
         * routine may choose to leave the hash value unchanged.
         */
        name->hash = full_name_hash(name->name, name->len);
-       if (dir->d_op && dir->d_op->d_hash) {
+       if (dir->d_flags & DCACHE_OP_HASH) {
                if (dir->d_op->d_hash(dir, dir->d_inode, name) < 0)
                        goto out;
        }
 
        struct qstr lower_name;
        int rc = 0;
 
-       ecryptfs_dentry->d_op = &ecryptfs_dops;
+       d_set_d_op(ecryptfs_dentry, &ecryptfs_dops);
        if ((ecryptfs_dentry->d_name.len == 1
             && !strcmp(ecryptfs_dentry->d_name.name, "."))
            || (ecryptfs_dentry->d_name.len == 2
 
        if (special_file(lower_inode->i_mode))
                init_special_inode(inode, lower_inode->i_mode,
                                   lower_inode->i_rdev);
-       dentry->d_op = &ecryptfs_dops;
+       d_set_d_op(dentry, &ecryptfs_dops);
        fsstack_copy_attr_all(inode, lower_inode);
        /* This size will be overwritten for real files w/ headers and
         * other metadata */
                deactivate_locked_super(s);
                goto out;
        }
-       s->s_root->d_op = &ecryptfs_dops;
+       d_set_d_op(s->s_root, &ecryptfs_dops);
        s->s_root->d_sb = s;
        s->s_root->d_parent = s->s_root;
 
 
         */
        result = d_obtain_alias(inode);
        if (!IS_ERR(result))
-               result->d_op = sb->s_root->d_op;
+               d_set_d_op(result, sb->s_root->d_op);
        return result;
 }
 
 
        parent = d_obtain_alias(inode);
        if (!IS_ERR(parent))
-               parent->d_op = sb->s_root->d_op;
+               d_set_d_op(parent, sb->s_root->d_op);
 out:
        unlock_super(sb);
 
 
        }
 out:
        unlock_super(sb);
-       dentry->d_op = &msdos_dentry_operations;
+       d_set_d_op(dentry, &msdos_dentry_operations);
        dentry = d_splice_alias(inode, dentry);
        if (dentry)
-               dentry->d_op = &msdos_dentry_operations;
+               d_set_d_op(dentry, &msdos_dentry_operations);
        return dentry;
 
 error:
        }
 
        sb->s_flags |= MS_NOATIME;
-       sb->s_root->d_op = &msdos_dentry_operations;
+       d_set_d_op(sb->s_root, &msdos_dentry_operations);
        unlock_super(sb);
        return 0;
 }
 
 
 out:
        unlock_super(sb);
-       dentry->d_op = sb->s_root->d_op;
+       d_set_d_op(dentry, sb->s_root->d_op);
        dentry->d_time = dentry->d_parent->d_inode->i_version;
        dentry = d_splice_alias(inode, dentry);
        if (dentry) {
-               dentry->d_op = sb->s_root->d_op;
+               d_set_d_op(dentry, sb->s_root->d_op);
                dentry->d_time = dentry->d_parent->d_inode->i_version;
        }
        return dentry;
        }
 
        if (MSDOS_SB(sb)->options.name_check != 's')
-               sb->s_root->d_op = &vfat_ci_dentry_ops;
+               d_set_d_op(sb->s_root, &vfat_ci_dentry_ops);
        else
-               sb->s_root->d_op = &vfat_dentry_ops;
+               d_set_d_op(sb->s_root, &vfat_dentry_ops);
 
        unlock_super(sb);
        return 0;
 
        }
 
        entry = newent ? newent : entry;
-       entry->d_op = &fuse_dentry_operations;
+       d_set_d_op(entry, &fuse_dentry_operations);
        if (outarg_valid)
                fuse_change_entry_timeout(entry, &outarg);
        else
 
 
        entry = d_obtain_alias(inode);
        if (!IS_ERR(entry) && get_node_id(inode) != FUSE_ROOT_ID) {
-               entry->d_op = &fuse_dentry_operations;
+               d_set_d_op(entry, &fuse_dentry_operations);
                fuse_invalidate_entry_cache(entry);
        }
 
 
        parent = d_obtain_alias(inode);
        if (!IS_ERR(parent) && get_node_id(inode) != FUSE_ROOT_ID) {
-               parent->d_op = &fuse_dentry_operations;
+               d_set_d_op(parent, &fuse_dentry_operations);
                fuse_invalidate_entry_cache(parent);
        }
 
 
 
        dentry = d_obtain_alias(gfs2_lookupi(child->d_inode, &gfs2_qdotdot, 1));
        if (!IS_ERR(dentry))
-               dentry->d_op = &gfs2_dops;
+               d_set_d_op(dentry, &gfs2_dops);
        return dentry;
 }
 
 out_inode:
        dentry = d_obtain_alias(inode);
        if (!IS_ERR(dentry))
-               dentry->d_op = &gfs2_dops;
+               d_set_d_op(dentry, &gfs2_dops);
        return dentry;
 }
 
 
                iput(inode);
                return -ENOMEM;
        }
-       dentry->d_op = &gfs2_dops;
+       d_set_d_op(dentry, &gfs2_dops);
        *dptr = dentry;
        return 0;
 }
 
 {
        struct inode *inode = NULL;
 
-       dentry->d_op = &gfs2_dops;
+       d_set_d_op(dentry, &gfs2_dops);
 
        inode = gfs2_lookupi(dir, &dentry->d_name, 0);
        if (inode && IS_ERR(inode))
 
        struct inode *inode = NULL;
        int res;
 
-       dentry->d_op = &hfs_dentry_operations;
+       d_set_d_op(dentry, &hfs_dentry_operations);
 
        hfs_find_init(HFS_SB(dir->i_sb)->cat_tree, &fd);
        hfs_cat_build_key(dir->i_sb, fd.search_key, dir->i_ino, &dentry->d_name);
 
        if (!sb->s_root)
                goto bail_iput;
 
-       sb->s_root->d_op = &hfs_dentry_operations;
+       d_set_d_op(sb->s_root, &hfs_dentry_operations);
 
        /* everything's okay */
        return 0;
 
 
        sb = dir->i_sb;
 
-       dentry->d_op = &hfsplus_dentry_operations;
+       d_set_d_op(dentry, &hfsplus_dentry_operations);
        dentry->d_fsdata = NULL;
        hfs_find_init(HFSPLUS_SB(sb)->cat_tree, &fd);
        hfsplus_cat_build_key(sb, fd.search_key, dir->i_ino, &dentry->d_name);
 
                err = -ENOMEM;
                goto cleanup;
        }
-       sb->s_root->d_op = &hfsplus_dentry_operations;
+       d_set_d_op(sb->s_root, &hfsplus_dentry_operations);
 
        str.len = sizeof(HFSP_HIDDENDIR_NAME) - 1;
        str.name = HFSP_HIDDENDIR_NAME;
 
                goto out_put;
 
        d_add(dentry, inode);
-       dentry->d_op = &hostfs_dentry_ops;
+       d_set_d_op(dentry, &hostfs_dentry_ops);
        return NULL;
 
  out_put:
 
 
 void hpfs_set_dentry_operations(struct dentry *dentry)
 {
-       dentry->d_op = &hpfs_dentry_operations;
+       d_set_d_op(dentry, &hpfs_dentry_operations);
 }
 
                table += 2;
        if (opt.check == 'r')
                table++;
-       s->s_root->d_op = &isofs_dentry_ops[table];
+       d_set_d_op(s->s_root, &isofs_dentry_ops[table]);
 
        kfree(opt.iocharset);
 
 
        struct inode *inode;
        struct page *page;
 
-       dentry->d_op = dir->i_sb->s_root->d_op;
+       d_set_d_op(dentry, dir->i_sb->s_root->d_op);
 
        page = alloc_page(GFP_USER);
        if (!page)
 
        jfs_info("jfs_lookup: name = %s", name);
 
        if (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2)
-               dentry->d_op = &jfs_ci_dentry_operations;
+               d_set_d_op(dentry, &jfs_ci_dentry_operations);
 
        if ((name[0] == '.') && (len == 1))
                inum = dip->i_ino;
        dentry = d_splice_alias(ip, dentry);
 
        if (dentry && (JFS_SBI(dip->i_sb)->mntflag & JFS_OS2))
-               dentry->d_op = &jfs_ci_dentry_operations;
+               d_set_d_op(dentry, &jfs_ci_dentry_operations);
 
        return dentry;
 }
 
                goto out_no_root;
 
        if (sbi->mntflag & JFS_OS2)
-               sb->s_root->d_op = &jfs_ci_dentry_operations;
+               d_set_d_op(sb->s_root, &jfs_ci_dentry_operations);
 
        /* logical blocks are represented by 40 bits in pxd_t, etc. */
        sb->s_maxbytes = ((u64) sb->s_blocksize) << 40;
 
 
        if (dentry->d_name.len > NAME_MAX)
                return ERR_PTR(-ENAMETOOLONG);
-       dentry->d_op = &simple_dentry_operations;
+       d_set_d_op(dentry, &simple_dentry_operations);
        d_add(dentry, NULL);
        return NULL;
 }
 
        struct inode * inode = NULL;
        ino_t ino;
 
-       dentry->d_op = dir->i_sb->s_root->d_op;
+       d_set_d_op(dentry, dir->i_sb->s_root->d_op);
 
        if (dentry->d_name.len > minix_sb(dir->i_sb)->s_namelen)
                return ERR_PTR(-ENAMETOOLONG);
 
        return dentry;
 }
 
+static inline int need_reval_dot(struct dentry *dentry)
+{
+       if (likely(!(dentry->d_flags & DCACHE_OP_REVALIDATE)))
+               return 0;
+
+       if (likely(!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)))
+               return 0;
+
+       return 1;
+}
+
 /*
  * force_reval_path - force revalidation of a dentry
  *
 
        /*
         * only check on filesystems where it's possible for the dentry to
-        * become stale. It's assumed that if this flag is set then the
-        * d_revalidate op will also be defined.
+        * become stale.
         */
-       if (!(dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT))
+       if (!need_reval_dot(dentry))
                return 0;
 
        status = dentry->d_op->d_revalidate(dentry, nd);
         * See if the low-level filesystem might want
         * to use its own hash..
         */
-       if (parent->d_op && parent->d_op->d_hash) {
+       if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
                int err = parent->d_op->d_hash(parent, nd->inode, name);
                if (err < 0)
                        return err;
                        return -ECHILD;
 
                nd->seq = seq;
-               if (dentry->d_op && dentry->d_op->d_revalidate) {
+               if (dentry->d_flags & DCACHE_OP_REVALIDATE) {
                        /* We commonly drop rcu-walk here */
                        if (nameidata_dentry_drop_rcu(nd, dentry))
                                return -ECHILD;
                if (!dentry)
                        goto need_lookup;
 found:
-               if (dentry->d_op && dentry->d_op->d_revalidate)
+               if (dentry->d_flags & DCACHE_OP_REVALIDATE)
                        goto need_revalidate;
 done:
                path->mnt = mnt;
                 * We bypassed the ordinary revalidation routines.
                 * We may need to check the cached dentry for staleness.
                 */
-               if (nd->path.dentry && nd->path.dentry->d_sb &&
-                   (nd->path.dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
+               if (need_reval_dot(nd->path.dentry)) {
                        if (nameidata_drop_rcu_maybe(nd))
                                return -ECHILD;
                        err = -ESTALE;
         * See if the low-level filesystem might want
         * to use its own hash..
         */
-       if (base->d_op && base->d_op->d_hash) {
+       if (base->d_flags & DCACHE_OP_HASH) {
                err = base->d_op->d_hash(base, inode, name);
                dentry = ERR_PTR(err);
                if (err < 0)
         */
        dentry = d_lookup(base, name);
 
-       if (dentry && dentry->d_op && dentry->d_op->d_revalidate)
+       if (dentry && (dentry->d_flags & DCACHE_OP_REVALIDATE))
                dentry = do_revalidate(dentry, nd);
 
        if (!dentry)
                follow_dotdot(nd);
                dir = nd->path.dentry;
        case LAST_DOT:
-               if (nd->path.mnt->mnt_sb->s_type->fs_flags & FS_REVAL_DOT) {
+               if (need_reval_dot(dir)) {
                        if (!dir->d_op->d_revalidate(dir, nd)) {
                                error = -ESTALE;
                                goto exit;
 
                entry->ino = iunique(dir->i_sb, 2);
                inode = ncp_iget(dir->i_sb, entry);
                if (inode) {
-                       newdent->d_op = &ncp_dentry_operations;
+                       d_set_d_op(newdent, &ncp_dentry_operations);
                        d_instantiate(newdent, inode);
                        if (!hashed)
                                d_rehash(newdent);
        if (inode) {
                ncp_new_dentry(dentry);
 add_entry:
-               dentry->d_op = &ncp_dentry_operations;
+               d_set_d_op(dentry, &ncp_dentry_operations);
                d_add(dentry, inode);
                error = 0;
        }
 
        sb->s_root = d_alloc_root(root_inode);
         if (!sb->s_root)
                goto out_no_root;
-       sb->s_root->d_op = &ncp_root_dentry_operations;
+       d_set_d_op(sb->s_root, &ncp_root_dentry_operations);
        return 0;
 
 out_no_root:
 
        if (dentry == NULL)
                return;
 
-       dentry->d_op = NFS_PROTO(dir)->dentry_ops;
+       d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops);
        inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr);
        if (IS_ERR(inode))
                goto out;
        if (dentry->d_name.len > NFS_SERVER(dir)->namelen)
                goto out;
 
-       dentry->d_op = NFS_PROTO(dir)->dentry_ops;
+       d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops);
 
        /*
         * If we're doing an exclusive create, optimize away the lookup
                res = ERR_PTR(-ENAMETOOLONG);
                goto out;
        }
-       dentry->d_op = NFS_PROTO(dir)->dentry_ops;
+       d_set_d_op(dentry, NFS_PROTO(dir)->dentry_ops);
 
        /* Let vfs_create() deal with O_EXCL. Instantiate, but don't hash
         * the dentry. */
 
        security_d_instantiate(ret, inode);
 
        if (ret->d_op == NULL)
-               ret->d_op = server->nfs_client->rpc_ops->dentry_ops;
+               d_set_d_op(ret, server->nfs_client->rpc_ops->dentry_ops);
 out:
        nfs_free_fattr(fsinfo.fattr);
        return ret;
        security_d_instantiate(ret, inode);
 
        if (ret->d_op == NULL)
-               ret->d_op = server->nfs_client->rpc_ops->dentry_ops;
+               d_set_d_op(ret, server->nfs_client->rpc_ops->dentry_ops);
 
 out:
        nfs_free_fattr(fattr);
 
 
        result = d_obtain_alias(inode);
        if (!IS_ERR(result))
-               result->d_op = &ocfs2_dentry_ops;
+               d_set_d_op(result, &ocfs2_dentry_ops);
        else
                mlog_errno(PTR_ERR(result));
 
 
        parent = d_obtain_alias(ocfs2_iget(OCFS2_SB(dir->i_sb), blkno, 0, 0));
        if (!IS_ERR(parent))
-               parent->d_op = &ocfs2_dentry_ops;
+               d_set_d_op(parent, &ocfs2_dentry_ops);
 
 bail_unlock:
        ocfs2_inode_unlock(dir, 0);
 
        spin_unlock(&oi->ip_lock);
 
 bail_add:
-       dentry->d_op = &ocfs2_dentry_ops;
+       d_set_d_op(dentry, &ocfs2_dentry_ops);
        ret = d_splice_alias(inode, dentry);
 
        if (inode) {
                mlog_errno(status);
                goto leave;
        }
-       dentry->d_op = &ocfs2_dentry_ops;
+       d_set_d_op(dentry, &ocfs2_dentry_ops);
 
        status = ocfs2_add_entry(handle, dentry, inode,
                                 OCFS2_I(inode)->ip_blkno, parent_fe_bh,
        }
 
        ihold(inode);
-       dentry->d_op = &ocfs2_dentry_ops;
+       d_set_d_op(dentry, &ocfs2_dentry_ops);
        d_instantiate(dentry, inode);
 
 out_commit:
                mlog_errno(status);
                goto bail;
        }
-       dentry->d_op = &ocfs2_dentry_ops;
+       d_set_d_op(dentry, &ocfs2_dentry_ops);
 
        status = ocfs2_add_entry(handle, dentry, inode,
                                 le64_to_cpu(fe->i_blkno), parent_fe_bh,
                goto out_commit;
        }
 
-       dentry->d_op = &ocfs2_dentry_ops;
+       d_set_d_op(dentry, &ocfs2_dentry_ops);
        d_instantiate(dentry, inode);
        status = 0;
 out_commit:
 
                goto err_inode;
        path.mnt = mntget(pipe_mnt);
 
-       path.dentry->d_op = &pipefs_dentry_operations;
+       d_set_d_op(path.dentry, &pipefs_dentry_operations);
        d_instantiate(path.dentry, inode);
 
        err = -ENFILE;
 
        inode->i_op = &proc_pid_link_inode_operations;
        inode->i_size = 64;
        ei->op.proc_get_link = proc_fd_link;
-       dentry->d_op = &tid_fd_dentry_operations;
+       d_set_d_op(dentry, &tid_fd_dentry_operations);
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
        if (tid_fd_revalidate(dentry, NULL))
        ei->fd = fd;
        inode->i_mode = S_IFREG | S_IRUSR;
        inode->i_fop = &proc_fdinfo_file_operations;
-       dentry->d_op = &tid_fd_dentry_operations;
+       d_set_d_op(dentry, &tid_fd_dentry_operations);
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
        if (tid_fd_revalidate(dentry, NULL))
        if (p->fop)
                inode->i_fop = p->fop;
        ei->op = p->op;
-       dentry->d_op = &pid_dentry_operations;
+       d_set_d_op(dentry, &pid_dentry_operations);
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
        if (pid_revalidate(dentry, NULL))
        if (p->fop)
                inode->i_fop = p->fop;
        ei->op = p->op;
-       dentry->d_op = &proc_base_dentry_operations;
+       d_set_d_op(dentry, &proc_base_dentry_operations);
        d_add(dentry, inode);
        error = NULL;
 out:
        inode->i_nlink = 2 + pid_entry_count_dirs(tgid_base_stuff,
                ARRAY_SIZE(tgid_base_stuff));
 
-       dentry->d_op = &pid_dentry_operations;
+       d_set_d_op(dentry, &pid_dentry_operations);
 
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
        inode->i_nlink = 2 + pid_entry_count_dirs(tid_base_stuff,
                ARRAY_SIZE(tid_base_stuff));
 
-       dentry->d_op = &pid_dentry_operations;
+       d_set_d_op(dentry, &pid_dentry_operations);
 
        d_add(dentry, inode);
        /* Close the race of the process dying before we return the dentry */
 
 out_unlock:
 
        if (inode) {
-               dentry->d_op = &proc_dentry_operations;
+               d_set_d_op(dentry, &proc_dentry_operations);
                d_add(dentry, inode);
                return NULL;
        }
 
                goto out;
 
        err = NULL;
-       dentry->d_op = &proc_sys_dentry_operations;
+       d_set_d_op(dentry, &proc_sys_dentry_operations);
        d_add(dentry, inode);
 
 out:
                                dput(child);
                                return -ENOMEM;
                        } else {
-                               child->d_op = &proc_sys_dentry_operations;
+                               d_set_d_op(child, &proc_sys_dentry_operations);
                                d_add(child, inode);
                        }
                } else {
 
                                strlen(PRIVROOT_NAME));
        if (!IS_ERR(dentry)) {
                REISERFS_SB(s)->priv_root = dentry;
-               dentry->d_op = &xattr_lookup_poison_ops;
+               d_set_d_op(dentry, &xattr_lookup_poison_ops);
                if (dentry->d_inode)
                        dentry->d_inode->i_flags |= S_PRIVATE;
        } else
 
        /* instantiate and hash dentry */
        ret = d_find_alias(inode);
        if (!ret) {
-               dentry->d_op = &sysfs_dentry_ops;
+               d_set_d_op(dentry, &sysfs_dentry_ops);
                dentry->d_fsdata = sysfs_get(sd);
                d_add(dentry, inode);
        } else {
 
        struct inode * inode = NULL;
        ino_t ino;
 
-       dentry->d_op = dir->i_sb->s_root->d_op;
+       d_set_d_op(dentry, dir->i_sb->s_root->d_op);
        if (dentry->d_name.len > SYSV_NAMELEN)
                return ERR_PTR(-ENAMETOOLONG);
        ino = sysv_inode_by_name(dentry);
 
        if (sbi->s_forced_ro)
                sb->s_flags |= MS_RDONLY;
        if (sbi->s_truncate)
-               sb->s_root->d_op = &sysv_dentry_operations;
+               d_set_d_op(sb->s_root, &sysv_dentry_operations);
        return 1;
 }
 
 
 #define DCACHE_GENOCIDE                0x0200
 #define DCACHE_MOUNTED         0x0400  /* is a mountpoint */
 
+#define DCACHE_OP_HASH         0x1000
+#define DCACHE_OP_COMPARE      0x2000
+#define DCACHE_OP_REVALIDATE   0x4000
+#define DCACHE_OP_DELETE       0x8000
+
 
 extern spinlock_t dcache_inode_lock;
 extern seqlock_t rename_lock;
 extern void __d_drop(struct dentry *dentry);
 extern void d_drop(struct dentry *dentry);
 extern void d_delete(struct dentry *);
+extern void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op);
 
 /* allocate/de-allocate */
 extern struct dentry * d_alloc(struct dentry *, const struct qstr *);
 
 
        if (dentry->d_name.len > NAME_MAX)
                return ERR_PTR(-ENAMETOOLONG);
-       dentry->d_op = &cgroup_dentry_operations;
+       d_set_d_op(dentry, &cgroup_dentry_operations);
        d_add(dentry, NULL);
        return NULL;
 }
 
        }
        path.mnt = mntget(sock_mnt);
 
-       path.dentry->d_op = &sockfs_dentry_operations;
+       d_set_d_op(path.dentry, &sockfs_dentry_operations);
        d_instantiate(path.dentry, SOCK_INODE(sock));
        SOCK_INODE(sock)->i_fop = &socket_file_ops;
 
 
                }
        }
        if (!dentry->d_inode)
-               dentry->d_op = &rpc_dentry_operations;
+               d_set_d_op(dentry, &rpc_dentry_operations);
 out_err:
        return dentry;
 }