Beispiel #1
0
static int sdcardfskk_hash_ci(const struct dentry *dentry,
				const struct inode *inode, struct qstr *qstr)
{
	/*
	 * This function is copy of vfat_hashi.
	 * FIXME Should we support national language?
	 *       Refer to vfat_hashi()
	 * struct nls_table *t = MSDOS_SB(dentry->d_sb)->nls_io;
	 */
	const unsigned char *name;
	unsigned int len;
	unsigned long hash;

	name = qstr->name;
	//len = vfat_striptail_len(qstr);
	len = qstr->len;

	hash = init_name_hash();
	while (len--)
		//hash = partial_name_hash(nls_tolower(t, *name++), hash);
		hash = partial_name_hash(tolower(*name++), hash);
	qstr->hash = end_name_hash(hash);

	return 0;
}
Beispiel #2
0
static int
adfs_hash(struct dentry *parent, struct qstr *qstr)
{
	const unsigned int name_len = parent->d_sb->u.adfs_sb.s_namelen;
	const unsigned char *name;
	unsigned long hash;
	int i;

	if (qstr->len < name_len)
		return 0;

	/*
	 * Truncate the name in place, avoids
	 * having to define a compare function.
	 */
	qstr->len = i = name_len;
	name = qstr->name;
	hash = init_name_hash();
	while (i--) {
		char c;

		c = *name++;
		if (c >= 'A' && c <= 'Z')
			c += 'a' - 'A';

		hash = partial_name_hash(c, hash);
	}
	qstr->hash = end_name_hash(hash);

	return 0;
}
Beispiel #3
0
static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
{
	struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
	unsigned long hash;
	int i;

	hash = init_name_hash();
	for (i = 0; i < q->len; i++)
		hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
					 hash);
	q->hash = end_name_hash(hash);

	return 0;
}
Beispiel #4
0
/*! 2016-06-04 study -ing */
static unsigned int kernfs_name_hash(const char *name, const void *ns)
{
	unsigned long hash = init_name_hash();
	unsigned int len = strlen(name);
	while (len--)
		hash = partial_name_hash(*name++, hash);
	hash = (end_name_hash(hash) ^ hash_ptr((void *)ns, 31));
	hash &= 0x7fffffffU;
	/* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */
	if (hash < 2)
		hash += 2;
	if (hash >= INT_MAX)
		hash = INT_MAX - 1;
	return hash;
}
Beispiel #5
0
/* based on vfat_hashi() in fs/fat/namei_vfat.c (no code pages) */
static int esdfs_d_hash(const struct dentry *dentry,
		const struct inode *inode, struct qstr *qstr)
{
	const unsigned char *name;
	unsigned int len;
	unsigned long hash;

	name = qstr->name;
	len = vfat_striptail_len(qstr);

	hash = init_name_hash();
	while (len--)
		hash = partial_name_hash(tolower(*name++), hash);
	qstr->hash = end_name_hash(hash);

	return 0;
}
Beispiel #6
0
/*
 * Hash a string to an integer as appropriate for the HFS+ filesystem.
 * Composed unicode characters are decomposed and case-folding is performed
 * if the appropriate bits are (un)set on the superblock.
 */
int hfsplus_hash_dentry(const struct dentry *dentry, struct qstr *str)
{
	struct super_block *sb = dentry->d_sb;
	const char *astr;
	const u16 *dstr;
	int casefold, decompose, size, len;
	unsigned long hash;
	wchar_t c;
	u16 c2;

	casefold = test_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
	decompose = !test_bit(HFSPLUS_SB_NODECOMPOSE, &HFSPLUS_SB(sb)->flags);
	hash = init_name_hash(dentry);
	astr = str->name;
	len = str->len;
	while (len > 0) {
		int uninitialized_var(dsize);
		size = asc2unichar(sb, astr, len, &c);
		astr += size;
		len -= size;

		if (decompose)
			dstr = decompose_unichar(c, &dsize);
		else
			dstr = NULL;
		if (dstr) {
			do {
				c2 = *dstr++;
				if (casefold)
					c2 = case_fold(c2);
				if (!casefold || c2)
					hash = partial_name_hash(c2, hash);
			} while (--dsize > 0);
		} else {
			c2 = c;
			if (casefold)
				c2 = case_fold(c2);
			if (!casefold || c2)
				hash = partial_name_hash(c2, hash);
		}
	}
	str->hash = end_name_hash(hash);

	return 0;
}
Beispiel #7
0
static int minix_hash(struct dentry *dentry, struct qstr *qstr)
{
	unsigned long hash;
	int i;
	const unsigned char *name;

	i = minix_sb(dentry->d_inode->i_sb)->s_namelen;
	if (i >= qstr->len)
		return 0;
	/* Truncate the name in place, avoids having to define a compare
	   function. */
	qstr->len = i;
	name = qstr->name;
	hash = init_name_hash();
	while (i--)
		hash = partial_name_hash(*name++, hash);
	qstr->hash = end_name_hash(hash);
	return 0;
}
Beispiel #8
0
/*
 * Note: the dentry argument is the parent dentry.
 */
static inline int
__affs_hash_dentry(struct dentry *dentry, struct qstr *qstr, toupper_t toupper)
{
	const u8 *name = qstr->name;
	unsigned long hash;
	int i;

	i = affs_check_name(qstr->name,qstr->len);
	if (i)
		return i;

	hash = init_name_hash();
	i = min(qstr->len, 30u);
	for (; i > 0; name++, i--)
		hash = partial_name_hash(toupper(*name), hash);
	qstr->hash = end_name_hash(hash);

	return 0;
}
Beispiel #9
0
static int cifs_ci_hash(const struct dentry *dentry, struct qstr *q)
{
	struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
	unsigned long hash;
	wchar_t c;
	int i, charlen;

	hash = init_name_hash();
	for (i = 0; i < q->len; i += charlen) {
		charlen = codepage->char2uni(&q->name[i], q->len - i, &c);
		/* error out if we can't convert the character */
		if (unlikely(charlen < 0))
			return charlen;
		hash = partial_name_hash(cifs_toupper(c), hash);
	}
	q->hash = end_name_hash(hash);

	return 0;
}
static int efivarfs_d_hash(const struct dentry *dentry, struct qstr *qstr)
{
	unsigned long hash = init_name_hash();
	const unsigned char *s = qstr->name;
	unsigned int len = qstr->len;

	if (!efivarfs_valid_name(s, len))
		return -EINVAL;

	while (len-- > EFI_VARIABLE_GUID_LEN)
		hash = partial_name_hash(*s++, hash);

	/* GUID is case-insensitive. */
	while (len--)
		hash = partial_name_hash(tolower(*s++), hash);

	qstr->hash = end_name_hash(hash);
	return 0;
}
Beispiel #11
0
/*
 * Note: the dentry argument is the parent dentry.
 */
static inline int
__affs_hash_dentry(struct qstr *qstr, toupper_t toupper, bool notruncate)
{
	const u8 *name = qstr->name;
	unsigned long hash;
	int retval;
	u32 len;

	retval = affs_check_name(qstr->name, qstr->len, notruncate);
	if (retval)
		return retval;

	hash = init_name_hash();
	len = min(qstr->len, AFFSNAMEMAX);
	for (; len > 0; name++, len--)
		hash = partial_name_hash(toupper(*name), hash);
	qstr->hash = end_name_hash(hash);

	return 0;
}
Beispiel #12
0
/*
 * Note: the dentry argument is the parent dentry.
 */
static int
affs_hash_dentry(struct dentry *dentry, struct qstr *qstr)
{
	unsigned int (*toupper)(unsigned int) = affs_toupper;
	unsigned long	 hash;
	int		 i;

	if ((i = affs_check_name(qstr->name,qstr->len)))
		return i;

	/* Check whether to use the international 'toupper' routine */
	if (AFFS_I2FSTYPE(dentry->d_inode))
		toupper = affs_intl_toupper;
	hash = init_name_hash();
	for (i = 0; i < qstr->len && i < 30; i++)
		hash = partial_name_hash(toupper(qstr->name[i]), hash);
	qstr->hash = end_name_hash(hash);

	return 0;
}
Beispiel #13
0
static int hpfs_hash_dentry(struct dentry *dentry, struct qstr *qstr)
{
	unsigned long	 hash;
	int		 i;
	unsigned l = qstr->len;

	if (l == 1) if (qstr->name[0]=='.') goto x;
	if (l == 2) if (qstr->name[0]=='.' || qstr->name[1]=='.') goto x;
	hpfs_adjust_length((char *)qstr->name, &l);
	/*if (hpfs_chk_name((char *)qstr->name,&l))*/
		/*return -ENAMETOOLONG;*/
		/*return -ENOENT;*/
	x:

	hash = init_name_hash();
	for (i = 0; i < l; i++)
		hash = partial_name_hash(hpfs_upcase(hpfs_sb(dentry->d_sb)->sb_cp_table,qstr->name[i]), hash);
	qstr->hash = end_name_hash(hash);

	return 0;
}
Beispiel #14
0
static struct dentry *lkup_hash(const char *name, struct dentry *parent,
				int len, struct lkup_args *lkup)
{
	struct dentry *dentry;
	char *p;
	unsigned long hash;
	struct qstr this;
	unsigned int c;
	struct nameidata tmp_nd;

	dentry = ERR_PTR(-EACCES);
	this.name = name;
	this.len = len;
	if (unlikely(!len))
		goto out;

	p = (void*)name;
	hash = init_name_hash();
	while (len--) {
		c = *p++;
		if (unlikely(c == '/' || c == '\0'))
			goto out;
		hash = partial_name_hash(c, hash);
	}
	this.hash = end_name_hash(hash);

	memset(&tmp_nd, 0, sizeof(tmp_nd));
	tmp_nd.dentry = dget(parent);
	tmp_nd.mnt = mntget(lkup->nfsmnt);
#ifndef CONFIG_AUFS_DLGT
	dentry = __lookup_hash(&this, parent, &tmp_nd);
#else
	if (!lkup->dlgt)
		dentry = __lookup_hash(&this, parent, &tmp_nd);
	else {
		int wkq_err;
		struct lookup_hash_args args = {
			.errp	= &dentry,
			.name	= &this,
			.base	= parent,
			.nd	= &tmp_nd
		};
		wkq_err = au_wkq_wait(call_lookup_hash, &args, /*dlgt*/1);
		if (unlikely(wkq_err))
			dentry = ERR_PTR(wkq_err);
	}
#endif
	path_release(&tmp_nd);

 out:
	TraceErrPtr(dentry);
	return dentry;
}
#elif defined(CONFIG_AUFS_DLGT)
static struct dentry *lkup_hash(const char *name, struct dentry *parent,
				int len, struct lkup_args *lkup)
{
	return ERR_PTR(-ENOSYS);
}
#endif

#ifdef CONFIG_AUFS_DLGT
struct lookup_one_len_args {
	struct dentry **errp;
	const char *name;
	struct dentry *parent;
	int len;
};

static void call_lookup_one_len(void *args)
{
	struct lookup_one_len_args *a = args;
	*a->errp = lookup_one_len(a->name, a->parent, a->len);
}
#endif /* CONFIG_AUFS_DLGT */

#if defined(CONFIG_AUFS_LHASH_PATCH) || defined(CONFIG_AUFS_DLGT)
/* cf. lookup_one_len() in linux/fs/namei.c */
struct dentry *lkup_one(const char *name, struct dentry *parent, int len,
			struct lkup_args *lkup)
{
	struct dentry *dentry;

	LKTRTrace("%.*s/%.*s, lkup{%p, %d}\n",
		  DLNPair(parent), len, name, lkup->nfsmnt, lkup->dlgt);

	if (!lkup->nfsmnt) {
#ifndef CONFIG_AUFS_DLGT
		dentry = lookup_one_len(name, parent, len);
#else
		if (!lkup->dlgt)
			dentry = lookup_one_len(name, parent, len);
		else {
			int wkq_err;
			struct lookup_one_len_args args = {
				.errp	= &dentry,
				.name	= name,
				.parent	= parent,
				.len	= len
			};
			wkq_err = au_wkq_wait(call_lookup_one_len, &args,
					      /*dlgt*/1);
			if (unlikely(wkq_err))
				dentry = ERR_PTR(wkq_err);
		}
#endif
	} else
Beispiel #15
0
/*
                                                  
                     
 */
static int 
ncp_hash_dentry(const struct dentry *dentry, const struct inode *inode,
		struct qstr *this)
{
	if (!ncp_case_sensitive(inode)) {
		struct super_block *sb = dentry->d_sb;
		struct nls_table *t;
		unsigned long hash;
		int i;

		t = NCP_IO_TABLE(sb);
		hash = init_name_hash();
		for (i=0; i<this->len ; i++)
			hash = partial_name_hash(ncp_tolower(t, this->name[i]),
									hash);
		this->hash = end_name_hash(hash);
	}
	return 0;
}

static int
ncp_compare_dentry(const struct dentry *parent, const struct inode *pinode,
		const struct dentry *dentry, const struct inode *inode,
		unsigned int len, const char *str, const struct qstr *name)
{
	if (len != name->len)
		return 1;
Beispiel #16
0
	.read		= generic_read_dir,
	.iterate	= jfs_readdir,
	.fsync		= jfs_fsync,
	.unlocked_ioctl = jfs_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl	= jfs_compat_ioctl,
#endif
	.llseek		= generic_file_llseek,
};

static int jfs_ci_hash(const struct dentry *dir, struct qstr *this)
{
	unsigned long hash;
	int i;

	hash = init_name_hash(dir);
	for (i=0; i < this->len; i++)
		hash = partial_name_hash(tolower(this->name[i]), hash);
	this->hash = end_name_hash(hash);

	return 0;
}

static int jfs_ci_compare(const struct dentry *dentry,
		unsigned int len, const char *str, const struct qstr *name)
{
	int i, result = 1;

	if (len != name->len)
		goto out;
	for (i=0; i < len; i++) {
Beispiel #17
0
/*
 * Name resolution.
 * This is the basic name resolution function, turning a pathname into
 * the final dentry. We expect 'base' to be positive and a directory.
 *
 * Returns 0 and nd will have valid dentry and mnt on success.
 * Returns error and drops reference to input namei data on failure.
 */
static int link_path_walk(const char *name, struct nameidata *nd) {
	struct path next;
	int err;
	unsigned int lookup_flags  = nd->flags;

	while (*name=='/')
		name++;
	if (!*name)
		goto return_reval;

	if (nd->depth)
		lookup_flags = LOOKUP_FOLLOW | (nd->flags & LOOKUP_CONTINUE);	

	/* At this point we know we have a real path component. */
	for(;;) {
		struct inode *inode;
		unsigned long hash;
		struct qstr this;
		unsigned int c;

		nd->flags |= LOOKUP_CONTINUE;

		this.name = name;
		c = *(const unsigned char *)name;
		hash = init_name_hash();
		do {
			name++;
			hash = partial_name_hash(c, hash);
			c = *(const unsigned char *)name;
		} while (c && (c != '/'));
		this.len = name - (const char *) this.name;
		this.hash = end_name_hash(hash);
		
		/* remove trailing slashes? */
		if (!c)
			goto last_component;
		while (*++name == '/');
			if (!*name)
				goto last_with_slashes;

		/* This does the actual lookups.. */
		err = do_lookup(nd, &this, &next, &inode);

		if (err)
			break;
		err = -1;
		if (!inode)
			goto out_dput;

		if (inode->i_op->follow_link){
			err = do_follow_link(inode, &next, nd);
		}

last_with_slashes:

last_component:

return_reval:

out_dput:

	}
	
}
Beispiel #18
0
struct dentry *vfsub_lookup_hash(struct nameidata *nd)
{
    struct path path = {
        .mnt = nd->path.mnt
    };

    IMustLock(nd->path.dentry->d_inode);

    path.dentry = lookup_hash(nd);
    if (IS_ERR(path.dentry))
        goto out;
    if (path.dentry->d_inode)
        vfsub_update_h_iattr(&path, /*did*/NULL); /*ignore*/

out:
    AuTraceErrPtr(path.dentry);
    return path.dentry;
}

/*
 * this is "VFS:__lookup_one_len()" which was removed and merged into
 * VFS:lookup_one_len() by the commit.
 *	6a96ba5 2011-03-14 kill __lookup_one_len()
 * this function should always be equivalent to the corresponding part in
 * VFS:lookup_one_len().
 */
int vfsub_name_hash(const char *name, struct qstr *this, int len)
{
    unsigned long hash;
    unsigned int c;

    this->name = name;
    this->len = len;
    if (!len)
        return -EACCES;

    hash = init_name_hash();
    while (len--) {
        c = *(const unsigned char *)name++;
        if (c == '/' || c == '\0')
            return -EACCES;
        hash = partial_name_hash(c, hash);
    }
    this->hash = end_name_hash(hash);
    return 0;
}

/* ---------------------------------------------------------------------- */

struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
                                 struct dentry *d2, struct au_hinode *hdir2)
{
    struct dentry *d;

    lockdep_off();
    d = lock_rename(d1, d2);
    lockdep_on();
    au_hn_suspend(hdir1);
    if (hdir1 != hdir2)
        au_hn_suspend(hdir2);

    return d;
}

void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
                         struct dentry *d2, struct au_hinode *hdir2)
{
    au_hn_resume(hdir1);
    if (hdir1 != hdir2)
        au_hn_resume(hdir2);
    lockdep_off();
    unlock_rename(d1, d2);
    lockdep_on();
}