-/**
+/*
* fs/f2fs/dir.c
*
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
if (le16_to_cpu(de->name_len) != namelen)
return false;
- if (le32_to_cpu(de->hash_code) != namehash)
+ if (de->hash_code != namehash)
return false;
return true;
NR_DENTRY_IN_BLOCK, 0);
while (bit_pos < NR_DENTRY_IN_BLOCK) {
de = &dentry_blk->dentry[bit_pos];
- slots = (le16_to_cpu(de->name_len) + F2FS_NAME_LEN - 1) /
- F2FS_NAME_LEN;
+ slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
if (early_match_name(name, namelen, namehash, de)) {
if (!memcmp(dentry_blk->filename[bit_pos],
unsigned int level, const char *name, int namelen,
f2fs_hash_t namehash, struct page **res_page)
{
- int s = (namelen + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;
+ int s = GET_DENTRY_SLOTS(namelen);
unsigned int nbucket, nblock;
unsigned int bidx, end_block;
struct page *dentry_page;
nbucket = dir_buckets(level);
nblock = bucket_blocks(level);
- bidx = dir_block_index(level, namehash % nbucket);
+ bidx = dir_block_index(level, le32_to_cpu(namehash) % nbucket);
end_block = bidx + nblock;
for (; bidx < end_block; bidx++) {
set_page_dirty(page);
dir->i_mtime = dir->i_ctime = CURRENT_TIME;
mark_inode_dirty(dir);
+
+ /* update parent inode number before releasing dentry page */
+ F2FS_I(inode)->i_pino = dir->i_ino;
+
f2fs_put_page(page, 1);
mutex_unlock_op(sbi, DENTRY_OPS);
}
void init_dent_inode(struct dentry *dentry, struct page *ipage)
{
- struct inode *dir = dentry->d_parent->d_inode;
struct f2fs_node *rn;
if (IS_ERR(ipage))
/* copy dentry info. to this inode page */
rn = (struct f2fs_node *)page_address(ipage);
- rn->i.i_pino = cpu_to_le32(dir->i_ino);
rn->i.i_namelen = cpu_to_le32(dentry->d_name.len);
memcpy(rn->i.i_name, dentry->d_name.name, dentry->d_name.len);
set_page_dirty(ipage);
int namelen = dentry->d_name.len;
struct page *dentry_page = NULL;
struct f2fs_dentry_block *dentry_blk = NULL;
- int slots = (namelen + F2FS_NAME_LEN - 1) / F2FS_NAME_LEN;
+ int slots = GET_DENTRY_SLOTS(namelen);
int err = 0;
int i;
nbucket = dir_buckets(level);
nblock = bucket_blocks(level);
- bidx = dir_block_index(level, (dentry_hash % nbucket));
+ bidx = dir_block_index(level, (le32_to_cpu(dentry_hash) % nbucket));
for (block = bidx; block <= (bidx + nblock - 1); block++) {
mutex_lock_op(sbi, DENTRY_OPS);
wait_on_page_writeback(dentry_page);
de = &dentry_blk->dentry[bit_pos];
- de->hash_code = cpu_to_le32(dentry_hash);
+ de->hash_code = dentry_hash;
de->name_len = cpu_to_le16(namelen);
memcpy(dentry_blk->filename[bit_pos], name, namelen);
de->ino = cpu_to_le32(inode->i_ino);
for (i = 0; i < slots; i++)
test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap);
set_page_dirty(dentry_page);
+
update_parent_metadata(dir, inode, current_depth);
+
+ /* update parent inode number before releasing dentry page */
+ F2FS_I(inode)->i_pino = dir->i_ino;
fail:
kunmap(dentry_page);
f2fs_put_page(dentry_page, 1);
return err;
}
-/**
+/*
* It only removes the dentry from the dentry page,corresponding name
* entry in name page does not need to be touched during deletion.
*/
struct address_space *mapping = page->mapping;
struct inode *dir = mapping->host;
struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
- int slots = (le16_to_cpu(dentry->name_len) + F2FS_NAME_LEN - 1) /
- F2FS_NAME_LEN;
+ int slots = GET_DENTRY_SLOTS(le16_to_cpu(dentry->name_len));
void *kaddr = page_address(page);
int i;
}
if (bit_pos == NR_DENTRY_IN_BLOCK) {
- loff_t page_offset;
truncate_hole(dir, page->index, page->index + 1);
clear_page_dirty_for_io(page);
ClearPageUptodate(page);
dec_page_count(sbi, F2FS_DIRTY_DENTS);
inode_dec_dirty_dents(dir);
- page_offset = page->index << PAGE_CACHE_SHIFT;
- f2fs_put_page(page, 1);
- } else {
- f2fs_put_page(page, 1);
}
+ f2fs_put_page(page, 1);
+
mutex_unlock_op(sbi, DENTRY_OPS);
}
file->f_pos += bit_pos - start_bit_pos;
goto success;
}
- slots = (le16_to_cpu(de->name_len) + F2FS_NAME_LEN - 1)
- / F2FS_NAME_LEN;
+ slots = GET_DENTRY_SLOTS(le16_to_cpu(de->name_len));
bit_pos += slots;
}
bit_pos = 0;