示例#1
0
static struct buffer_head *
affs_find_entry(struct inode *dir, struct dentry *dentry)
{
	struct super_block *sb = dir->i_sb;
	struct buffer_head *bh;
	toupper_t toupper = affs_get_toupper(sb);
	u32 key;

	pr_debug("AFFS: find_entry(\"%.*s\")\n", (int)dentry->d_name.len, dentry->d_name.name);

	bh = affs_bread(sb, dir->i_ino);
	if (!bh)
		return ERR_PTR(-EIO);

	key = be32_to_cpu(AFFS_HEAD(bh)->table[affs_hash_name(sb, dentry->d_name.name, dentry->d_name.len)]);

	for (;;) {
		affs_brelse(bh);
		if (key == 0)
			return NULL;
		bh = affs_bread(sb, key);
		if (!bh)
			return ERR_PTR(-EIO);
		if (affs_match(dentry, AFFS_TAIL(sb, bh)->name, toupper))
			return bh;
		key = be32_to_cpu(AFFS_TAIL(sb, bh)->hash_chain);
	}
}
示例#2
0
int
affs_remove_hash(struct inode *dir, struct buffer_head *rem_bh)
{
    struct super_block *sb;
    struct buffer_head *bh;
    u32 rem_ino, hash_ino;
    __be32 ino;
    int offset, retval;

    sb = dir->i_sb;
    rem_ino = rem_bh->b_blocknr;
    offset = affs_hash_name(sb, AFFS_TAIL(sb, rem_bh)->name+1, AFFS_TAIL(sb, rem_bh)->name[0]);
    pr_debug("AFFS: remove_hash(dir=%d, ino=%d, hashval=%d)\n", (u32)dir->i_ino, rem_ino, offset);

    bh = affs_bread(sb, dir->i_ino);
    if (!bh)
        return -EIO;

    retval = -ENOENT;
    hash_ino = be32_to_cpu(AFFS_HEAD(bh)->table[offset]);
    while (hash_ino) {
        if (hash_ino == rem_ino) {
            ino = AFFS_TAIL(sb, rem_bh)->hash_chain;
            if (dir->i_ino == bh->b_blocknr)
                AFFS_HEAD(bh)->table[offset] = ino;
            else
                AFFS_TAIL(sb, bh)->hash_chain = ino;
            affs_adjust_checksum(bh, be32_to_cpu(ino) - hash_ino);
            mark_buffer_dirty_inode(bh, dir);
            AFFS_TAIL(sb, rem_bh)->parent = 0;
            retval = 0;
            break;
        }
        affs_brelse(bh);
        bh = affs_bread(sb, hash_ino);
        if (!bh)
            return -EIO;
        hash_ino = be32_to_cpu(AFFS_TAIL(sb, bh)->hash_chain);
    }

    affs_brelse(bh);

    dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
    dir->i_version++;
    mark_inode_dirty(dir);

    return retval;
}
示例#3
0
文件: namei.c 项目: dzavalishin/oskit
static struct buffer_head *
affs_find_entry(struct inode *dir, struct dentry *dentry, unsigned long *ino)
{
	struct buffer_head	*bh;
	int			 intl = AFFS_I2FSTYPE(dir);
	s32			 key;
	const char		*name = dentry->d_name.name;
	int			 namelen = dentry->d_name.len;

	pr_debug("AFFS: find_entry(\"%.*s\")\n",namelen,name);

	bh = affs_bread(dir->i_dev,dir->i_ino,AFFS_I2BSIZE(dir));
	if (!bh)
		return NULL;

	if (namelen == 1 && name[0] == '.') {
		*ino = dir->i_ino;
		return bh;
	}
	if (namelen == 2 && name[0] == '.' && name[1] == '.') {
		*ino = affs_parent_ino(dir);
		return bh;
	}

	key = AFFS_GET_HASHENTRY(bh->b_data,affs_hash_name(name,namelen,intl,AFFS_I2HSIZE(dir)));

	for (;;) {
		unsigned char *cname;
		int cnamelen;

		affs_brelse(bh);
		bh = NULL;
		if (key == 0)
			break;
		bh = affs_bread(dir->i_dev,key,AFFS_I2BSIZE(dir));
		if (!bh)
			break;
		cnamelen = affs_get_file_name(AFFS_I2BSIZE(dir),bh->b_data,&cname);
		if (affs_match(name,namelen,cname,cnamelen,intl))
			break;
		key = be32_to_cpu(FILE_END(bh->b_data,dir)->hash_chain);
	}
	*ino = key;
	return bh;
}
示例#4
0
int
affs_insert_hash(struct inode *dir, struct buffer_head *bh)
{
    struct super_block *sb = dir->i_sb;
    struct buffer_head *dir_bh;
    u32 ino, hash_ino;
    int offset;

    ino = bh->b_blocknr;
    offset = affs_hash_name(sb, AFFS_TAIL(sb, bh)->name + 1, AFFS_TAIL(sb, bh)->name[0]);

    pr_debug("AFFS: insert_hash(dir=%u, ino=%d)\n", (u32)dir->i_ino, ino);

    dir_bh = affs_bread(sb, dir->i_ino);
    if (!dir_bh)
        return -EIO;

    hash_ino = be32_to_cpu(AFFS_HEAD(dir_bh)->table[offset]);
    while (hash_ino) {
        affs_brelse(dir_bh);
        dir_bh = affs_bread(sb, hash_ino);
        if (!dir_bh)
            return -EIO;
        hash_ino = be32_to_cpu(AFFS_TAIL(sb, dir_bh)->hash_chain);
    }
    AFFS_TAIL(sb, bh)->parent = cpu_to_be32(dir->i_ino);
    AFFS_TAIL(sb, bh)->hash_chain = 0;
    affs_fix_checksum(sb, bh);

    if (dir->i_ino == dir_bh->b_blocknr)
        AFFS_HEAD(dir_bh)->table[offset] = cpu_to_be32(ino);
    else
        AFFS_TAIL(sb, dir_bh)->hash_chain = cpu_to_be32(ino);

    affs_adjust_checksum(dir_bh, ino);
    mark_buffer_dirty_inode(dir_bh, dir);
    affs_brelse(dir_bh);

    dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
    dir->i_version++;
    mark_inode_dirty(dir);

    return 0;
}