|
@@ -249,9 +249,6 @@ ino_t f2fs_inode_by_name(struct inode *dir, struct qstr *qstr)
|
|
|
void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,
|
|
|
struct page *page, struct inode *inode)
|
|
|
{
|
|
|
- struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
|
|
|
-
|
|
|
- mutex_lock_op(sbi, DENTRY_OPS);
|
|
|
lock_page(page);
|
|
|
wait_on_page_writeback(page);
|
|
|
de->ino = cpu_to_le32(inode->i_ino);
|
|
@@ -265,7 +262,6 @@ void f2fs_set_link(struct inode *dir, struct f2fs_dir_entry *de,
|
|
|
F2FS_I(inode)->i_pino = dir->i_ino;
|
|
|
|
|
|
f2fs_put_page(page, 1);
|
|
|
- mutex_unlock_op(sbi, DENTRY_OPS);
|
|
|
}
|
|
|
|
|
|
void init_dent_inode(const struct qstr *name, struct page *ipage)
|
|
@@ -284,6 +280,43 @@ void init_dent_inode(const struct qstr *name, struct page *ipage)
|
|
|
set_page_dirty(ipage);
|
|
|
}
|
|
|
|
|
|
+static int make_empty_dir(struct inode *inode, struct inode *parent)
|
|
|
+{
|
|
|
+ struct page *dentry_page;
|
|
|
+ struct f2fs_dentry_block *dentry_blk;
|
|
|
+ struct f2fs_dir_entry *de;
|
|
|
+ void *kaddr;
|
|
|
+
|
|
|
+ dentry_page = get_new_data_page(inode, 0, true);
|
|
|
+ if (IS_ERR(dentry_page))
|
|
|
+ return PTR_ERR(dentry_page);
|
|
|
+
|
|
|
+ kaddr = kmap_atomic(dentry_page);
|
|
|
+ dentry_blk = (struct f2fs_dentry_block *)kaddr;
|
|
|
+
|
|
|
+ de = &dentry_blk->dentry[0];
|
|
|
+ de->name_len = cpu_to_le16(1);
|
|
|
+ de->hash_code = 0;
|
|
|
+ de->ino = cpu_to_le32(inode->i_ino);
|
|
|
+ memcpy(dentry_blk->filename[0], ".", 1);
|
|
|
+ set_de_type(de, inode);
|
|
|
+
|
|
|
+ de = &dentry_blk->dentry[1];
|
|
|
+ de->hash_code = 0;
|
|
|
+ de->name_len = cpu_to_le16(2);
|
|
|
+ de->ino = cpu_to_le32(parent->i_ino);
|
|
|
+ memcpy(dentry_blk->filename[1], "..", 2);
|
|
|
+ set_de_type(de, inode);
|
|
|
+
|
|
|
+ test_and_set_bit_le(0, &dentry_blk->dentry_bitmap);
|
|
|
+ test_and_set_bit_le(1, &dentry_blk->dentry_bitmap);
|
|
|
+ kunmap_atomic(kaddr);
|
|
|
+
|
|
|
+ set_page_dirty(dentry_page);
|
|
|
+ f2fs_put_page(dentry_page, 1);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
static int init_inode_metadata(struct inode *inode,
|
|
|
struct inode *dir, const struct qstr *name)
|
|
|
{
|
|
@@ -294,7 +327,7 @@ static int init_inode_metadata(struct inode *inode,
|
|
|
return err;
|
|
|
|
|
|
if (S_ISDIR(inode->i_mode)) {
|
|
|
- err = f2fs_make_empty(inode, dir);
|
|
|
+ err = make_empty_dir(inode, dir);
|
|
|
if (err) {
|
|
|
remove_inode_page(inode);
|
|
|
return err;
|
|
@@ -317,7 +350,7 @@ static int init_inode_metadata(struct inode *inode,
|
|
|
}
|
|
|
if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) {
|
|
|
inc_nlink(inode);
|
|
|
- f2fs_write_inode(inode, NULL);
|
|
|
+ update_inode_page(inode);
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
@@ -341,7 +374,7 @@ static void update_parent_metadata(struct inode *dir, struct inode *inode,
|
|
|
}
|
|
|
|
|
|
if (need_dir_update)
|
|
|
- f2fs_write_inode(dir, NULL);
|
|
|
+ update_inode_page(dir);
|
|
|
else
|
|
|
mark_inode_dirty(dir);
|
|
|
|
|
@@ -373,6 +406,10 @@ next:
|
|
|
goto next;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * Caller should grab and release a mutex by calling mutex_lock_op() and
|
|
|
+ * mutex_unlock_op().
|
|
|
+ */
|
|
|
int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *inode)
|
|
|
{
|
|
|
unsigned int bit_pos;
|
|
@@ -382,7 +419,6 @@ int __f2fs_add_link(struct inode *dir, const struct qstr *name, struct inode *in
|
|
|
f2fs_hash_t dentry_hash;
|
|
|
struct f2fs_dir_entry *de;
|
|
|
unsigned int nbucket, nblock;
|
|
|
- struct f2fs_sb_info *sbi = F2FS_SB(dir->i_sb);
|
|
|
size_t namelen = name->len;
|
|
|
struct page *dentry_page = NULL;
|
|
|
struct f2fs_dentry_block *dentry_blk = NULL;
|
|
@@ -412,12 +448,9 @@ start:
|
|
|
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);
|
|
|
dentry_page = get_new_data_page(dir, block, true);
|
|
|
- if (IS_ERR(dentry_page)) {
|
|
|
- mutex_unlock_op(sbi, DENTRY_OPS);
|
|
|
+ if (IS_ERR(dentry_page))
|
|
|
return PTR_ERR(dentry_page);
|
|
|
- }
|
|
|
|
|
|
dentry_blk = kmap(dentry_page);
|
|
|
bit_pos = room_for_filename(dentry_blk, slots);
|
|
@@ -426,7 +459,6 @@ start:
|
|
|
|
|
|
kunmap(dentry_page);
|
|
|
f2fs_put_page(dentry_page, 1);
|
|
|
- mutex_unlock_op(sbi, DENTRY_OPS);
|
|
|
}
|
|
|
|
|
|
/* Move to next level to find the empty slot for new dentry */
|
|
@@ -456,7 +488,6 @@ add_dentry:
|
|
|
fail:
|
|
|
kunmap(dentry_page);
|
|
|
f2fs_put_page(dentry_page, 1);
|
|
|
- mutex_unlock_op(sbi, DENTRY_OPS);
|
|
|
return err;
|
|
|
}
|
|
|
|
|
@@ -476,8 +507,6 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
|
|
|
void *kaddr = page_address(page);
|
|
|
int i;
|
|
|
|
|
|
- mutex_lock_op(sbi, DENTRY_OPS);
|
|
|
-
|
|
|
lock_page(page);
|
|
|
wait_on_page_writeback(page);
|
|
|
|
|
@@ -497,7 +526,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
|
|
|
|
|
|
if (inode && S_ISDIR(inode->i_mode)) {
|
|
|
drop_nlink(dir);
|
|
|
- f2fs_write_inode(dir, NULL);
|
|
|
+ update_inode_page(dir);
|
|
|
} else {
|
|
|
mark_inode_dirty(dir);
|
|
|
}
|
|
@@ -509,7 +538,8 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
|
|
|
drop_nlink(inode);
|
|
|
i_size_write(inode, 0);
|
|
|
}
|
|
|
- f2fs_write_inode(inode, NULL);
|
|
|
+ update_inode_page(inode);
|
|
|
+
|
|
|
if (inode->i_nlink == 0)
|
|
|
add_orphan_inode(sbi, inode->i_ino);
|
|
|
}
|
|
@@ -522,45 +552,6 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
|
|
|
inode_dec_dirty_dents(dir);
|
|
|
}
|
|
|
f2fs_put_page(page, 1);
|
|
|
-
|
|
|
- mutex_unlock_op(sbi, DENTRY_OPS);
|
|
|
-}
|
|
|
-
|
|
|
-int f2fs_make_empty(struct inode *inode, struct inode *parent)
|
|
|
-{
|
|
|
- struct page *dentry_page;
|
|
|
- struct f2fs_dentry_block *dentry_blk;
|
|
|
- struct f2fs_dir_entry *de;
|
|
|
- void *kaddr;
|
|
|
-
|
|
|
- dentry_page = get_new_data_page(inode, 0, true);
|
|
|
- if (IS_ERR(dentry_page))
|
|
|
- return PTR_ERR(dentry_page);
|
|
|
-
|
|
|
- kaddr = kmap_atomic(dentry_page);
|
|
|
- dentry_blk = (struct f2fs_dentry_block *)kaddr;
|
|
|
-
|
|
|
- de = &dentry_blk->dentry[0];
|
|
|
- de->name_len = cpu_to_le16(1);
|
|
|
- de->hash_code = f2fs_dentry_hash(".", 1);
|
|
|
- de->ino = cpu_to_le32(inode->i_ino);
|
|
|
- memcpy(dentry_blk->filename[0], ".", 1);
|
|
|
- set_de_type(de, inode);
|
|
|
-
|
|
|
- de = &dentry_blk->dentry[1];
|
|
|
- de->hash_code = f2fs_dentry_hash("..", 2);
|
|
|
- de->name_len = cpu_to_le16(2);
|
|
|
- de->ino = cpu_to_le32(parent->i_ino);
|
|
|
- memcpy(dentry_blk->filename[1], "..", 2);
|
|
|
- set_de_type(de, inode);
|
|
|
-
|
|
|
- test_and_set_bit_le(0, &dentry_blk->dentry_bitmap);
|
|
|
- test_and_set_bit_le(1, &dentry_blk->dentry_bitmap);
|
|
|
- kunmap_atomic(kaddr);
|
|
|
-
|
|
|
- set_page_dirty(dentry_page);
|
|
|
- f2fs_put_page(dentry_page, 1);
|
|
|
- return 0;
|
|
|
}
|
|
|
|
|
|
bool f2fs_empty_dir(struct inode *dir)
|