提交 b1e6a015 编写于 作者: N Nick Piggin

fs: change d_hash for rcu-walk

Change d_hash so it may be called from lock-free RCU lookups. See similar
patch for d_compare for details.

For in-tree filesystems, this is just a mechanical change.
Signed-off-by: NNick Piggin <npiggin@kernel.dk>
上级 621e155a
...@@ -10,7 +10,8 @@ be able to use diff(1). ...@@ -10,7 +10,8 @@ be able to use diff(1).
--------------------------- dentry_operations -------------------------- --------------------------- dentry_operations --------------------------
prototypes: prototypes:
int (*d_revalidate)(struct dentry *, int); int (*d_revalidate)(struct dentry *, int);
int (*d_hash) (struct dentry *, struct qstr *); int (*d_hash)(const struct dentry *, const struct inode *,
struct qstr *);
int (*d_compare)(const struct dentry *, const struct inode *, int (*d_compare)(const struct dentry *, const struct inode *,
const struct dentry *, const struct inode *, const struct dentry *, const struct inode *,
unsigned int, const char *, const struct qstr *); unsigned int, const char *, const struct qstr *);
...@@ -22,7 +23,7 @@ prototypes: ...@@ -22,7 +23,7 @@ prototypes:
locking rules: locking rules:
dcache_lock rename_lock ->d_lock may block dcache_lock rename_lock ->d_lock may block
d_revalidate: no no no yes d_revalidate: no no no yes
d_hash no no no yes d_hash no no no no
d_compare: no yes no no d_compare: no yes no no
d_delete: yes no yes no d_delete: yes no yes no
d_release: no no no yes d_release: no no no yes
......
...@@ -333,3 +333,10 @@ unreferenced dentries, and is now only called when the dentry refcount goes to ...@@ -333,3 +333,10 @@ unreferenced dentries, and is now only called when the dentry refcount goes to
.d_compare() calling convention and locking rules are significantly .d_compare() calling convention and locking rules are significantly
changed. Read updated documentation in Documentation/filesystems/vfs.txt (and changed. Read updated documentation in Documentation/filesystems/vfs.txt (and
look at examples of other filesystems) for guidance. look at examples of other filesystems) for guidance.
---
[mandatory]
.d_hash() calling convention and locking rules are significantly
changed. Read updated documentation in Documentation/filesystems/vfs.txt (and
look at examples of other filesystems) for guidance.
...@@ -847,7 +847,8 @@ defined: ...@@ -847,7 +847,8 @@ defined:
struct dentry_operations { struct dentry_operations {
int (*d_revalidate)(struct dentry *, struct nameidata *); int (*d_revalidate)(struct dentry *, struct nameidata *);
int (*d_hash)(struct dentry *, struct qstr *); int (*d_hash)(const struct dentry *, const struct inode *,
struct qstr *);
int (*d_compare)(const struct dentry *, const struct inode *, int (*d_compare)(const struct dentry *, const struct inode *,
const struct dentry *, const struct inode *, const struct dentry *, const struct inode *,
unsigned int, const char *, const struct qstr *); unsigned int, const char *, const struct qstr *);
...@@ -864,7 +865,10 @@ struct dentry_operations { ...@@ -864,7 +865,10 @@ struct dentry_operations {
d_hash: called when the VFS adds a dentry to the hash table. The first d_hash: called when the VFS adds a dentry to the hash table. The first
dentry passed to d_hash is the parent directory that the name is dentry passed to d_hash is the parent directory that the name is
to be hashed into. to be hashed into. The inode is the dentry's inode.
Same locking and synchronisation rules as d_compare regarding
what is safe to dereference etc.
d_compare: called to compare a dentry name with a given name. The first d_compare: called to compare a dentry name with a given name. The first
dentry is the parent of the dentry to be compared, the second is dentry is the parent of the dentry to be compared, the second is
......
...@@ -134,7 +134,7 @@ smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir, ...@@ -134,7 +134,7 @@ smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
qname->hash = full_name_hash(qname->name, qname->len); qname->hash = full_name_hash(qname->name, qname->len);
if (dentry->d_op && dentry->d_op->d_hash) if (dentry->d_op && dentry->d_op->d_hash)
if (dentry->d_op->d_hash(dentry, qname) != 0) if (dentry->d_op->d_hash(dentry, inode, qname) != 0)
goto end_advance; goto end_advance;
newdent = d_lookup(dentry, qname); newdent = d_lookup(dentry, qname);
......
...@@ -274,7 +274,8 @@ smb_dir_open(struct inode *dir, struct file *file) ...@@ -274,7 +274,8 @@ smb_dir_open(struct inode *dir, struct file *file)
* Dentry operations routines * Dentry operations routines
*/ */
static int smb_lookup_validate(struct dentry *, struct nameidata *); static int smb_lookup_validate(struct dentry *, struct nameidata *);
static int smb_hash_dentry(struct dentry *, struct qstr *); static int smb_hash_dentry(const struct dentry *, const struct inode *,
struct qstr *);
static int smb_compare_dentry(const struct dentry *, static int smb_compare_dentry(const struct dentry *,
const struct inode *, const struct inode *,
const struct dentry *, const struct inode *, const struct dentry *, const struct inode *,
...@@ -336,7 +337,8 @@ smb_lookup_validate(struct dentry * dentry, struct nameidata *nd) ...@@ -336,7 +337,8 @@ smb_lookup_validate(struct dentry * dentry, struct nameidata *nd)
} }
static int static int
smb_hash_dentry(struct dentry *dir, struct qstr *this) smb_hash_dentry(const struct dentry *dir, const struct inode *inode,
struct qstr *this)
{ {
unsigned long hash; unsigned long hash;
int i; int i;
......
...@@ -201,7 +201,8 @@ const struct file_operations adfs_dir_operations = { ...@@ -201,7 +201,8 @@ const struct file_operations adfs_dir_operations = {
}; };
static int static int
adfs_hash(struct dentry *parent, struct qstr *qstr) adfs_hash(const struct dentry *parent, const struct inode *inode,
struct qstr *qstr)
{ {
const unsigned int name_len = ADFS_SB(parent->d_sb)->s_namelen; const unsigned int name_len = ADFS_SB(parent->d_sb)->s_namelen;
const unsigned char *name; const unsigned char *name;
......
...@@ -13,13 +13,15 @@ ...@@ -13,13 +13,15 @@
typedef int (*toupper_t)(int); typedef int (*toupper_t)(int);
static int affs_toupper(int ch); static int affs_toupper(int ch);
static int affs_hash_dentry(struct dentry *, struct qstr *); static int affs_hash_dentry(const struct dentry *,
const struct inode *, struct qstr *);
static int affs_compare_dentry(const struct dentry *parent, static int affs_compare_dentry(const struct dentry *parent,
const struct inode *pinode, const struct inode *pinode,
const struct dentry *dentry, const struct inode *inode, const struct dentry *dentry, const struct inode *inode,
unsigned int len, const char *str, const struct qstr *name); unsigned int len, const char *str, const struct qstr *name);
static int affs_intl_toupper(int ch); static int affs_intl_toupper(int ch);
static int affs_intl_hash_dentry(struct dentry *, struct qstr *); static int affs_intl_hash_dentry(const struct dentry *,
const struct inode *, struct qstr *);
static int affs_intl_compare_dentry(const struct dentry *parent, static int affs_intl_compare_dentry(const struct dentry *parent,
const struct inode *pinode, const struct inode *pinode,
const struct dentry *dentry, const struct inode *inode, const struct dentry *dentry, const struct inode *inode,
...@@ -64,13 +66,13 @@ affs_get_toupper(struct super_block *sb) ...@@ -64,13 +66,13 @@ affs_get_toupper(struct super_block *sb)
* Note: the dentry argument is the parent dentry. * Note: the dentry argument is the parent dentry.
*/ */
static inline int static inline int
__affs_hash_dentry(struct dentry *dentry, struct qstr *qstr, toupper_t toupper) __affs_hash_dentry(struct qstr *qstr, toupper_t toupper)
{ {
const u8 *name = qstr->name; const u8 *name = qstr->name;
unsigned long hash; unsigned long hash;
int i; int i;
i = affs_check_name(qstr->name,qstr->len); i = affs_check_name(qstr->name, qstr->len);
if (i) if (i)
return i; return i;
...@@ -84,14 +86,16 @@ __affs_hash_dentry(struct dentry *dentry, struct qstr *qstr, toupper_t toupper) ...@@ -84,14 +86,16 @@ __affs_hash_dentry(struct dentry *dentry, struct qstr *qstr, toupper_t toupper)
} }
static int static int
affs_hash_dentry(struct dentry *dentry, struct qstr *qstr) affs_hash_dentry(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{ {
return __affs_hash_dentry(dentry, qstr, affs_toupper); return __affs_hash_dentry(qstr, affs_toupper);
} }
static int static int
affs_intl_hash_dentry(struct dentry *dentry, struct qstr *qstr) affs_intl_hash_dentry(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{ {
return __affs_hash_dentry(dentry, qstr, affs_intl_toupper); return __affs_hash_dentry(qstr, affs_intl_toupper);
} }
static inline int __affs_compare_dentry(unsigned int len, static inline int __affs_compare_dentry(unsigned int len,
......
...@@ -700,9 +700,10 @@ const struct dentry_operations cifs_dentry_ops = { ...@@ -700,9 +700,10 @@ const struct dentry_operations cifs_dentry_ops = {
/* d_delete: cifs_d_delete, */ /* not needed except for debugging */ /* d_delete: cifs_d_delete, */ /* not needed except for debugging */
}; };
static int cifs_ci_hash(struct dentry *dentry, struct qstr *q) static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
struct qstr *q)
{ {
struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls; struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
unsigned long hash; unsigned long hash;
int i; int i;
......
...@@ -79,7 +79,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name, ...@@ -79,7 +79,7 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
cFYI(1, "For %s", name->name); cFYI(1, "For %s", name->name);
if (parent->d_op && parent->d_op->d_hash) if (parent->d_op && parent->d_op->d_hash)
parent->d_op->d_hash(parent, name); parent->d_op->d_hash(parent, parent->d_inode, name);
else else
name->hash = full_name_hash(name->name, name->len); name->hash = full_name_hash(name->name, name->len);
......
...@@ -1478,7 +1478,7 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name) ...@@ -1478,7 +1478,7 @@ struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)
*/ */
name->hash = full_name_hash(name->name, name->len); name->hash = full_name_hash(name->name, name->len);
if (dir->d_op && dir->d_op->d_hash) { if (dir->d_op && dir->d_op->d_hash) {
if (dir->d_op->d_hash(dir, name) < 0) if (dir->d_op->d_hash(dir, dir->d_inode, name) < 0)
goto out; goto out;
} }
dentry = d_lookup(dir, name); dentry = d_lookup(dir, name);
......
...@@ -454,7 +454,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, ...@@ -454,7 +454,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
lower_name.hash = ecryptfs_dentry->d_name.hash; lower_name.hash = ecryptfs_dentry->d_name.hash;
if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) {
rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry,
&lower_name); lower_dir_dentry->d_inode, &lower_name);
if (rc < 0) if (rc < 0)
goto out_d_drop; goto out_d_drop;
} }
...@@ -489,7 +489,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode, ...@@ -489,7 +489,7 @@ static struct dentry *ecryptfs_lookup(struct inode *ecryptfs_dir_inode,
lower_name.hash = full_name_hash(lower_name.name, lower_name.len); lower_name.hash = full_name_hash(lower_name.name, lower_name.len);
if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) { if (lower_dir_dentry->d_op && lower_dir_dentry->d_op->d_hash) {
rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry, rc = lower_dir_dentry->d_op->d_hash(lower_dir_dentry,
&lower_name); lower_dir_dentry->d_inode, &lower_name);
if (rc < 0) if (rc < 0)
goto out_d_drop; goto out_d_drop;
} }
......
...@@ -148,7 +148,8 @@ static int msdos_find(struct inode *dir, const unsigned char *name, int len, ...@@ -148,7 +148,8 @@ static int msdos_find(struct inode *dir, const unsigned char *name, int len,
* that the existing dentry can be used. The msdos fs routines will * that the existing dentry can be used. The msdos fs routines will
* return ENOENT or EINVAL as appropriate. * return ENOENT or EINVAL as appropriate.
*/ */
static int msdos_hash(struct dentry *dentry, struct qstr *qstr) static int msdos_hash(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{ {
struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options; struct fat_mount_options *options = &MSDOS_SB(dentry->d_sb)->options;
unsigned char msdos_name[MSDOS_NAME]; unsigned char msdos_name[MSDOS_NAME];
......
...@@ -103,7 +103,8 @@ static unsigned int vfat_striptail_len(const struct qstr *qstr) ...@@ -103,7 +103,8 @@ static unsigned int vfat_striptail_len(const struct qstr *qstr)
* that the existing dentry can be used. The vfat fs routines will * that the existing dentry can be used. The vfat fs routines will
* return ENOENT or EINVAL as appropriate. * return ENOENT or EINVAL as appropriate.
*/ */
static int vfat_hash(struct dentry *dentry, struct qstr *qstr) static int vfat_hash(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{ {
qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr)); qstr->hash = full_name_hash(qstr->name, vfat_striptail_len(qstr));
return 0; return 0;
...@@ -115,9 +116,10 @@ static int vfat_hash(struct dentry *dentry, struct qstr *qstr) ...@@ -115,9 +116,10 @@ static int vfat_hash(struct dentry *dentry, struct qstr *qstr)
* that the existing dentry can be used. The vfat fs routines will * that the existing dentry can be used. The vfat fs routines will
* return ENOENT or EINVAL as appropriate. * return ENOENT or EINVAL as appropriate.
*/ */
static int vfat_hashi(struct dentry *dentry, struct qstr *qstr) static int vfat_hashi(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{ {
struct nls_table *t = MSDOS_SB(dentry->d_inode->i_sb)->nls_io; struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io;
const unsigned char *name; const unsigned char *name;
unsigned int len; unsigned int len;
unsigned long hash; unsigned long hash;
......
...@@ -100,7 +100,8 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -100,7 +100,8 @@ static int gfs2_drevalidate(struct dentry *dentry, struct nameidata *nd)
return 0; return 0;
} }
static int gfs2_dhash(struct dentry *dentry, struct qstr *str) static int gfs2_dhash(const struct dentry *dentry, const struct inode *inode,
struct qstr *str)
{ {
str->hash = gfs2_disk_hash(str->name, str->len); str->hash = gfs2_disk_hash(str->name, str->len);
return 0; return 0;
......
...@@ -213,7 +213,8 @@ extern int hfs_part_find(struct super_block *, sector_t *, sector_t *); ...@@ -213,7 +213,8 @@ extern int hfs_part_find(struct super_block *, sector_t *, sector_t *);
/* string.c */ /* string.c */
extern const struct dentry_operations hfs_dentry_operations; extern const struct dentry_operations hfs_dentry_operations;
extern int hfs_hash_dentry(struct dentry *, struct qstr *); extern int hfs_hash_dentry(const struct dentry *, const struct inode *,
struct qstr *);
extern int hfs_strcmp(const unsigned char *, unsigned int, extern int hfs_strcmp(const unsigned char *, unsigned int,
const unsigned char *, unsigned int); const unsigned char *, unsigned int);
extern int hfs_compare_dentry(const struct dentry *parent, extern int hfs_compare_dentry(const struct dentry *parent,
......
...@@ -51,7 +51,8 @@ static unsigned char caseorder[256] = { ...@@ -51,7 +51,8 @@ static unsigned char caseorder[256] = {
/* /*
* Hash a string to an integer in a case-independent way * Hash a string to an integer in a case-independent way
*/ */
int hfs_hash_dentry(struct dentry *dentry, struct qstr *this) int hfs_hash_dentry(const struct dentry *dentry, const struct inode *inode,
struct qstr *this)
{ {
const unsigned char *name = this->name; const unsigned char *name = this->name;
unsigned int hash, len = this->len; unsigned int hash, len = this->len;
......
...@@ -379,7 +379,8 @@ int hfsplus_strcasecmp(const struct hfsplus_unistr *, const struct hfsplus_unist ...@@ -379,7 +379,8 @@ int hfsplus_strcasecmp(const struct hfsplus_unistr *, const struct hfsplus_unist
int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *); int hfsplus_strcmp(const struct hfsplus_unistr *, const struct hfsplus_unistr *);
int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *); int hfsplus_uni2asc(struct super_block *, const struct hfsplus_unistr *, char *, int *);
int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int); int hfsplus_asc2uni(struct super_block *, struct hfsplus_unistr *, const char *, int);
int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str); int hfsplus_hash_dentry(const struct dentry *dentry, const struct inode *inode,
struct qstr *str);
int hfsplus_compare_dentry(const struct dentry *parent, int hfsplus_compare_dentry(const struct dentry *parent,
const struct inode *pinode, const struct inode *pinode,
const struct dentry *dentry, const struct inode *inode, const struct dentry *dentry, const struct inode *inode,
......
...@@ -320,7 +320,8 @@ int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr, ...@@ -320,7 +320,8 @@ int hfsplus_asc2uni(struct super_block *sb, struct hfsplus_unistr *ustr,
* Composed unicode characters are decomposed and case-folding is performed * Composed unicode characters are decomposed and case-folding is performed
* if the appropriate bits are (un)set on the superblock. * if the appropriate bits are (un)set on the superblock.
*/ */
int hfsplus_hash_dentry(struct dentry *dentry, struct qstr *str) int hfsplus_hash_dentry(const struct dentry *dentry, const struct inode *inode,
struct qstr *str)
{ {
struct super_block *sb = dentry->d_sb; struct super_block *sb = dentry->d_sb;
const char *astr; const char *astr;
......
...@@ -12,7 +12,8 @@ ...@@ -12,7 +12,8 @@
* Note: the dentry argument is the parent dentry. * Note: the dentry argument is the parent dentry.
*/ */
static int hpfs_hash_dentry(struct dentry *dentry, struct qstr *qstr) static int hpfs_hash_dentry(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{ {
unsigned long hash; unsigned long hash;
int i; int i;
......
...@@ -26,8 +26,10 @@ ...@@ -26,8 +26,10 @@
#define BEQUIET #define BEQUIET
static int isofs_hashi(struct dentry *parent, struct qstr *qstr); static int isofs_hashi(const struct dentry *parent, const struct inode *inode,
static int isofs_hash(struct dentry *parent, struct qstr *qstr); struct qstr *qstr);
static int isofs_hash(const struct dentry *parent, const struct inode *inode,
struct qstr *qstr);
static int isofs_dentry_cmpi(const struct dentry *parent, static int isofs_dentry_cmpi(const struct dentry *parent,
const struct inode *pinode, const struct inode *pinode,
const struct dentry *dentry, const struct inode *inode, const struct dentry *dentry, const struct inode *inode,
...@@ -38,8 +40,10 @@ static int isofs_dentry_cmp(const struct dentry *parent, ...@@ -38,8 +40,10 @@ static int isofs_dentry_cmp(const struct dentry *parent,
unsigned int len, const char *str, const struct qstr *name); unsigned int len, const char *str, const struct qstr *name);
#ifdef CONFIG_JOLIET #ifdef CONFIG_JOLIET
static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr); static int isofs_hashi_ms(const struct dentry *parent, const struct inode *inode,
static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr); struct qstr *qstr);
static int isofs_hash_ms(const struct dentry *parent, const struct inode *inode,
struct qstr *qstr);
static int isofs_dentry_cmpi_ms(const struct dentry *parent, static int isofs_dentry_cmpi_ms(const struct dentry *parent,
const struct inode *pinode, const struct inode *pinode,
const struct dentry *dentry, const struct inode *inode, const struct dentry *dentry, const struct inode *inode,
...@@ -172,7 +176,7 @@ struct iso9660_options{ ...@@ -172,7 +176,7 @@ struct iso9660_options{
* Compute the hash for the isofs name corresponding to the dentry. * Compute the hash for the isofs name corresponding to the dentry.
*/ */
static int static int
isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms) isofs_hash_common(const struct dentry *dentry, struct qstr *qstr, int ms)
{ {
const char *name; const char *name;
int len; int len;
...@@ -193,7 +197,7 @@ isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms) ...@@ -193,7 +197,7 @@ isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms)
* Compute the hash for the isofs name corresponding to the dentry. * Compute the hash for the isofs name corresponding to the dentry.
*/ */
static int static int
isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms) isofs_hashi_common(const struct dentry *dentry, struct qstr *qstr, int ms)
{ {
const char *name; const char *name;
int len; int len;
...@@ -248,13 +252,15 @@ static int isofs_dentry_cmp_common( ...@@ -248,13 +252,15 @@ static int isofs_dentry_cmp_common(
} }
static int static int
isofs_hash(struct dentry *dentry, struct qstr *qstr) isofs_hash(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{ {
return isofs_hash_common(dentry, qstr, 0); return isofs_hash_common(dentry, qstr, 0);
} }
static int static int
isofs_hashi(struct dentry *dentry, struct qstr *qstr) isofs_hashi(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{ {
return isofs_hashi_common(dentry, qstr, 0); return isofs_hashi_common(dentry, qstr, 0);
} }
...@@ -277,13 +283,15 @@ isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode, ...@@ -277,13 +283,15 @@ isofs_dentry_cmpi(const struct dentry *parent, const struct inode *pinode,
#ifdef CONFIG_JOLIET #ifdef CONFIG_JOLIET
static int static int
isofs_hash_ms(struct dentry *dentry, struct qstr *qstr) isofs_hash_ms(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{ {
return isofs_hash_common(dentry, qstr, 1); return isofs_hash_common(dentry, qstr, 1);
} }
static int static int
isofs_hashi_ms(struct dentry *dentry, struct qstr *qstr) isofs_hashi_ms(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{ {
return isofs_hashi_common(dentry, qstr, 1); return isofs_hashi_common(dentry, qstr, 1);
} }
......
...@@ -1574,7 +1574,8 @@ const struct file_operations jfs_dir_operations = { ...@@ -1574,7 +1574,8 @@ const struct file_operations jfs_dir_operations = {
.llseek = generic_file_llseek, .llseek = generic_file_llseek,
}; };
static int jfs_ci_hash(struct dentry *dir, struct qstr *this) static int jfs_ci_hash(const struct dentry *dir, const struct inode *inode,
struct qstr *this)
{ {
unsigned long hash; unsigned long hash;
int i; int i;
......
...@@ -731,7 +731,8 @@ static int do_lookup(struct nameidata *nd, struct qstr *name, ...@@ -731,7 +731,8 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
* to use its own hash.. * to use its own hash..
*/ */
if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) { if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) {
int err = nd->path.dentry->d_op->d_hash(nd->path.dentry, name); int err = nd->path.dentry->d_op->d_hash(nd->path.dentry,
nd->path.dentry->d_inode, name);
if (err < 0) if (err < 0)
return err; return err;
} }
...@@ -1134,7 +1135,7 @@ static struct dentry *__lookup_hash(struct qstr *name, ...@@ -1134,7 +1135,7 @@ static struct dentry *__lookup_hash(struct qstr *name,
* to use its own hash.. * to use its own hash..
*/ */
if (base->d_op && base->d_op->d_hash) { if (base->d_op && base->d_op->d_hash) {
err = base->d_op->d_hash(base, name); err = base->d_op->d_hash(base, inode, name);
dentry = ERR_PTR(err); dentry = ERR_PTR(err);
if (err < 0) if (err < 0)
goto out; goto out;
......
...@@ -74,7 +74,8 @@ const struct inode_operations ncp_dir_inode_operations = ...@@ -74,7 +74,8 @@ const struct inode_operations ncp_dir_inode_operations =
* Dentry operations routines * Dentry operations routines
*/ */
static int ncp_lookup_validate(struct dentry *, struct nameidata *); static int ncp_lookup_validate(struct dentry *, struct nameidata *);
static int ncp_hash_dentry(struct dentry *, struct qstr *); static int ncp_hash_dentry(const struct dentry *, const struct inode *,
struct qstr *);
static int ncp_compare_dentry(const struct dentry *, const struct inode *, static int ncp_compare_dentry(const struct dentry *, const struct inode *,
const struct dentry *, const struct inode *, const struct dentry *, const struct inode *,
unsigned int, const char *, const struct qstr *); unsigned int, const char *, const struct qstr *);
...@@ -129,9 +130,10 @@ static inline int ncp_case_sensitive(const struct inode *i) ...@@ -129,9 +130,10 @@ static inline int ncp_case_sensitive(const struct inode *i)
* is case-sensitive. * is case-sensitive.
*/ */
static int static int
ncp_hash_dentry(struct dentry *dentry, struct qstr *this) ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode,
struct qstr *this)
{ {
if (!ncp_case_sensitive(dentry->d_inode)) { if (!ncp_case_sensitive(inode)) {
struct super_block *sb = dentry->d_sb; struct super_block *sb = dentry->d_sb;
struct nls_table *t; struct nls_table *t;
unsigned long hash; unsigned long hash;
...@@ -597,7 +599,7 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir, ...@@ -597,7 +599,7 @@ ncp_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
qname.hash = full_name_hash(qname.name, qname.len); qname.hash = full_name_hash(qname.name, qname.len);
if (dentry->d_op && dentry->d_op->d_hash) if (dentry->d_op && dentry->d_op->d_hash)
if (dentry->d_op->d_hash(dentry, &qname) != 0) if (dentry->d_op->d_hash(dentry, dentry->d_inode, &qname) != 0)
goto end_advance; goto end_advance;
newdent = d_lookup(dentry, &qname); newdent = d_lookup(dentry, &qname);
......
...@@ -27,7 +27,8 @@ static int add_nondir(struct dentry *dentry, struct inode *inode) ...@@ -27,7 +27,8 @@ static int add_nondir(struct dentry *dentry, struct inode *inode)
return err; return err;
} }
static int sysv_hash(struct dentry *dentry, struct qstr *qstr) static int sysv_hash(const struct dentry *dentry, const struct inode *inode,
struct qstr *qstr)
{ {
/* Truncate the name in place, avoids having to define a compare /* Truncate the name in place, avoids having to define a compare
function. */ function. */
......
...@@ -133,7 +133,8 @@ enum dentry_d_lock_class ...@@ -133,7 +133,8 @@ enum dentry_d_lock_class
struct dentry_operations { struct dentry_operations {
int (*d_revalidate)(struct dentry *, struct nameidata *); int (*d_revalidate)(struct dentry *, struct nameidata *);
int (*d_hash)(struct dentry *, struct qstr *); int (*d_hash)(const struct dentry *, const struct inode *,
struct qstr *);
int (*d_compare)(const struct dentry *, const struct inode *, int (*d_compare)(const struct dentry *, const struct inode *,
const struct dentry *, const struct inode *, const struct dentry *, const struct inode *,
unsigned int, const char *, const struct qstr *); unsigned int, const char *, const struct qstr *);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册