本文整理汇总了C++中set_new_dnode函数的典型用法代码示例。如果您正苦于以下问题:C++ set_new_dnode函数的具体用法?C++ set_new_dnode怎么用?C++ set_new_dnode使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了set_new_dnode函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: f2fs_convert_inline_dir
/*
* NOTE: ipage is grabbed by caller, but if any error occurs, we should
* release ipage in this function.
*/
static int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage,
struct f2fs_inline_dentry *inline_dentry)
{
struct page *page;
struct dnode_of_data dn;
struct f2fs_dentry_block *dentry_blk;
int err;
page = grab_cache_page(dir->i_mapping, 0);
if (!page) {
f2fs_put_page(ipage, 1);
return -ENOMEM;
}
set_new_dnode(&dn, dir, ipage, NULL, 0);
err = f2fs_reserve_block(&dn, 0);
if (err)
goto out;
f2fs_wait_on_page_writeback(page, DATA);
zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE);
dentry_blk = kmap_atomic(page);
/* copy data from inline dentry block to new dentry block */
memcpy(dentry_blk->dentry_bitmap, inline_dentry->dentry_bitmap,
INLINE_DENTRY_BITMAP_SIZE);
memset(dentry_blk->dentry_bitmap + INLINE_DENTRY_BITMAP_SIZE, 0,
SIZE_OF_DENTRY_BITMAP - INLINE_DENTRY_BITMAP_SIZE);
/*
* we do not need to zero out remainder part of dentry and filename
* field, since we have used bitmap for marking the usage status of
* them, besides, we can also ignore copying/zeroing reserved space
* of dentry block, because them haven't been used so far.
*/
memcpy(dentry_blk->dentry, inline_dentry->dentry,
sizeof(struct f2fs_dir_entry) * NR_INLINE_DENTRY);
memcpy(dentry_blk->filename, inline_dentry->filename,
NR_INLINE_DENTRY * F2FS_SLOT_LEN);
kunmap_atomic(dentry_blk);
SetPageUptodate(page);
set_page_dirty(page);
/* clear inline dir and flag after data writeback */
truncate_inline_inode(ipage, 0);
stat_dec_inline_dir(dir);
clear_inode_flag(F2FS_I(dir), FI_INLINE_DENTRY);
if (i_size_read(dir) < PAGE_CACHE_SIZE) {
i_size_write(dir, PAGE_CACHE_SIZE);
set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR);
}
sync_inode_page(&dn);
out:
f2fs_put_page(page, 1);
return err;
}
开发者ID:anrqkdrnl,项目名称:detonator,代码行数:64,代码来源:inline.c
示例2: expand_inode_data
static int expand_inode_data(struct inode *inode, loff_t offset,
loff_t len, int mode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
pgoff_t index, pg_start, pg_end;
loff_t new_size = i_size_read(inode);
loff_t off_start, off_end;
int ret = 0;
f2fs_balance_fs(sbi);
ret = inode_newsize_ok(inode, (len + offset));
if (ret)
return ret;
if (f2fs_has_inline_data(inode)) {
ret = f2fs_convert_inline_inode(inode);
if (ret)
return ret;
}
pg_start = ((unsigned long long) offset) >> PAGE_CACHE_SHIFT;
pg_end = ((unsigned long long) offset + len) >> PAGE_CACHE_SHIFT;
off_start = offset & (PAGE_CACHE_SIZE - 1);
off_end = (offset + len) & (PAGE_CACHE_SIZE - 1);
f2fs_lock_op(sbi);
for (index = pg_start; index <= pg_end; index++) {
struct dnode_of_data dn;
if (index == pg_end && !off_end)
goto noalloc;
set_new_dnode(&dn, inode, NULL, NULL, 0);
ret = f2fs_reserve_block(&dn, index);
if (ret)
break;
noalloc:
if (pg_start == pg_end)
new_size = offset + len;
else if (index == pg_start && off_start)
new_size = (index + 1) << PAGE_CACHE_SHIFT;
else if (index == pg_end)
new_size = (index << PAGE_CACHE_SHIFT) + off_end;
else
new_size += PAGE_CACHE_SIZE;
}
if (!(mode & FALLOC_FL_KEEP_SIZE) &&
i_size_read(inode) < new_size) {
i_size_write(inode, new_size);
mark_inode_dirty(inode);
update_inode_page(inode);
}
f2fs_unlock_op(sbi);
return ret;
}
开发者ID:handelxh,项目名称:ONEPLUS2RAZOR,代码行数:60,代码来源:file.c
示例3: f2fs_vm_page_mkwrite
static int f2fs_vm_page_mkwrite(struct vm_area_struct *vma,
struct vm_fault *vmf)
{
struct page *page = vmf->page;
struct inode *inode = file_inode(vma->vm_file);
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct dnode_of_data dn;
int err;
f2fs_balance_fs(sbi);
vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
f2fs_bug_on(sbi, f2fs_has_inline_data(inode));
/* block allocation */
f2fs_lock_op(sbi);
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = f2fs_reserve_block(&dn, page->index);
if (err) {
f2fs_unlock_op(sbi);
goto out;
}
f2fs_put_dnode(&dn);
f2fs_unlock_op(sbi);
file_update_time(vma->vm_file);
lock_page(page);
if (unlikely(page->mapping != inode->i_mapping ||
page_offset(page) > i_size_read(inode) ||
!PageUptodate(page))) {
unlock_page(page);
err = -EFAULT;
goto out;
}
/*
* check to see if the page is mapped already (no holes)
*/
if (PageMappedToDisk(page))
goto mapped;
/* page is wholly or partially inside EOF */
if (((page->index + 1) << PAGE_CACHE_SHIFT) > i_size_read(inode)) {
unsigned offset;
offset = i_size_read(inode) & ~PAGE_CACHE_MASK;
zero_user_segment(page, offset, PAGE_CACHE_SIZE);
}
set_page_dirty(page);
SetPageUptodate(page);
trace_f2fs_vm_page_mkwrite(page, DATA);
mapped:
/* fill the page */
f2fs_wait_on_page_writeback(page, DATA);
/* if gced page is attached, don't write to cold segment */
clear_cold_data(page);
out:
return block_page_mkwrite_return(err);
}
开发者ID:handelxh,项目名称:ONEPLUS2RAZOR,代码行数:60,代码来源:file.c
示例4: truncate_blocks
int truncate_blocks(struct inode *inode, u64 from, bool lock)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
unsigned int blocksize = inode->i_sb->s_blocksize;
struct dnode_of_data dn;
pgoff_t free_from;
int count = 0, err = 0;
struct page *ipage;
trace_f2fs_truncate_blocks_enter(inode, from);
free_from = (pgoff_t)F2FS_BYTES_TO_BLK(from + blocksize - 1);
if (lock)
f2fs_lock_op(sbi);
ipage = get_node_page(sbi, inode->i_ino);
if (IS_ERR(ipage)) {
err = PTR_ERR(ipage);
goto out;
}
if (f2fs_has_inline_data(inode)) {
f2fs_put_page(ipage, 1);
goto out;
}
set_new_dnode(&dn, inode, ipage, NULL, 0);
err = get_dnode_of_data(&dn, free_from, LOOKUP_NODE);
if (err) {
if (err == -ENOENT)
goto free_next;
goto out;
}
count = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode));
count -= dn.ofs_in_node;
f2fs_bug_on(sbi, count < 0);
if (dn.ofs_in_node || IS_INODE(dn.node_page)) {
truncate_data_blocks_range(&dn, count);
free_from += count;
}
f2fs_put_dnode(&dn);
free_next:
err = truncate_inode_blocks(inode, free_from);
out:
if (lock)
f2fs_unlock_op(sbi);
/* lastly zero out the first data page */
if (!err)
err = truncate_partial_data_page(inode, from);
trace_f2fs_truncate_blocks_exit(inode, err);
return err;
}
开发者ID:davidnguyenwm,项目名称:Hulk-Kernel,代码行数:59,代码来源:file.c
示例5: find_in_level
static int find_in_level(struct f2fs_sb_info *sbi,struct f2fs_node *dir,
unsigned int level, struct dentry *de)
{
unsigned int nbucket, nblock;
unsigned int bidx, end_block;
struct f2fs_dir_entry *dentry = NULL;
struct dnode_of_data dn;
void *dentry_blk;
int max_slots = 214;
nid_t ino = le32_to_cpu(dir->footer.ino);
f2fs_hash_t namehash;
unsigned int dir_level = dir->i.i_dir_level;
int ret = 0;
namehash = f2fs_dentry_hash(de->name, de->len);
nbucket = dir_buckets(level, dir_level);
nblock = bucket_blocks(level);
bidx = dir_block_index(level, dir_level, le32_to_cpu(namehash) % nbucket);
end_block = bidx + nblock;
dentry_blk = calloc(BLOCK_SZ, 1);
ASSERT(dentry_blk);
memset(&dn, 0, sizeof(dn));
for (; bidx < end_block; bidx++) {
/* Firstly, we should know direct node of target data blk */
if (dn.node_blk && dn.node_blk != dn.inode_blk)
free(dn.node_blk);
set_new_dnode(&dn, dir, NULL, ino);
get_dnode_of_data(sbi, &dn, bidx, LOOKUP_NODE);
if (dn.data_blkaddr == NULL_ADDR)
continue;
ret = dev_read_block(dentry_blk, dn.data_blkaddr);
ASSERT(ret >= 0);
dentry = find_in_block(dentry_blk, de->name, de->len,
namehash, &max_slots);
if (dentry) {
ret = 1;
de->ino = le32_to_cpu(dentry->ino);
break;
}
}
if (dn.node_blk && dn.node_blk != dn.inode_blk)
free(dn.node_blk);
free(dentry_blk);
return ret;
}
开发者ID:arter97,项目名称:android_external_f2fs-tools,代码行数:55,代码来源:dir.c
示例6: __allocate_data_blocks
static void __allocate_data_blocks(struct inode *inode, loff_t offset,
size_t count)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct dnode_of_data dn;
u64 start = F2FS_BYTES_TO_BLK(offset);
u64 len = F2FS_BYTES_TO_BLK(count);
bool allocated;
u64 end_offset;
while (len) {
f2fs_balance_fs(sbi);
f2fs_lock_op(sbi);
/* When reading holes, we need its node page */
set_new_dnode(&dn, inode, NULL, NULL, 0);
if (get_dnode_of_data(&dn, start, ALLOC_NODE))
goto out;
allocated = false;
end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode));
while (dn.ofs_in_node < end_offset && len) {
block_t blkaddr;
if (unlikely(f2fs_cp_error(sbi)))
goto sync_out;
blkaddr = datablock_addr(dn.node_page, dn.ofs_in_node);
if (blkaddr == NULL_ADDR || blkaddr == NEW_ADDR) {
if (__allocate_data_block(&dn))
goto sync_out;
allocated = true;
}
len--;
start++;
dn.ofs_in_node++;
}
if (allocated)
sync_inode_page(&dn);
f2fs_put_dnode(&dn);
f2fs_unlock_op(sbi);
}
return;
sync_out:
if (allocated)
sync_inode_page(&dn);
f2fs_put_dnode(&dn);
out:
f2fs_unlock_op(sbi);
return;
}
开发者ID:tyler6389,项目名称:android_kernel_samsung_slte,代码行数:55,代码来源:data.c
示例7: do_write_data_page
int do_write_data_page(struct f2fs_io_info *fio)
{
struct page *page = fio->page;
struct inode *inode = page->mapping->host;
struct dnode_of_data dn;
int err = 0;
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, page->index, LOOKUP_NODE);
if (err)
return err;
fio->blk_addr = dn.data_blkaddr;
/* This page is already truncated */
if (fio->blk_addr == NULL_ADDR) {
ClearPageUptodate(page);
goto out_writepage;
}
if (f2fs_encrypted_inode(inode) && S_ISREG(inode->i_mode)) {
fio->encrypted_page = f2fs_encrypt(inode, fio->page);
if (IS_ERR(fio->encrypted_page)) {
err = PTR_ERR(fio->encrypted_page);
goto out_writepage;
}
}
set_page_writeback(page);
/*
* If current allocation needs SSR,
* it had better in-place writes for updated data.
*/
if (unlikely(fio->blk_addr != NEW_ADDR &&
!is_cold_data(page) &&
need_inplace_update(inode))) {
rewrite_data_page(fio);
set_inode_flag(F2FS_I(inode), FI_UPDATE_WRITE);
trace_f2fs_do_write_data_page(page, IPU);
} else {
write_data_page(&dn, fio);
set_data_blkaddr(&dn);
f2fs_update_extent_cache(&dn);
trace_f2fs_do_write_data_page(page, OPU);
set_inode_flag(F2FS_I(inode), FI_APPEND_WRITE);
if (page->index == 0)
set_inode_flag(F2FS_I(inode), FI_FIRST_BLOCK_WRITTEN);
}
out_writepage:
f2fs_put_dnode(&dn);
return err;
}
开发者ID:aejsmith,项目名称:linux,代码行数:53,代码来源:data.c
示例8: grab_cache_page
/*
* Caller ensures that this data page is never allocated.
* A new zero-filled data page is allocated in the page cache.
*
* Also, caller should grab and release a rwsem by calling f2fs_lock_op() and
* f2fs_unlock_op().
* Note that, ipage is set only by make_empty_dir, and if any error occur,
* ipage should be released by this function.
*/
struct page *get_new_data_page(struct inode *inode,
struct page *ipage, pgoff_t index, bool new_i_size)
{
struct address_space *mapping = inode->i_mapping;
struct page *page;
struct dnode_of_data dn;
int err;
repeat:
page = grab_cache_page(mapping, index);
if (!page) {
/*
* before exiting, we should make sure ipage will be released
* if any error occur.
*/
f2fs_put_page(ipage, 1);
return ERR_PTR(-ENOMEM);
}
set_new_dnode(&dn, inode, ipage, NULL, 0);
err = f2fs_reserve_block(&dn, index);
if (err) {
f2fs_put_page(page, 1);
return ERR_PTR(err);
}
if (!ipage)
f2fs_put_dnode(&dn);
if (PageUptodate(page))
goto got_it;
if (dn.data_blkaddr == NEW_ADDR) {
zero_user_segment(page, 0, PAGE_CACHE_SIZE);
SetPageUptodate(page);
} else {
f2fs_put_page(page, 1);
page = get_read_data_page(inode, index, READ_SYNC);
if (IS_ERR(page))
goto repeat;
/* wait for read completion */
lock_page(page);
}
got_it:
if (new_i_size &&
i_size_read(inode) < ((index + 1) << PAGE_CACHE_SHIFT)) {
i_size_write(inode, ((index + 1) << PAGE_CACHE_SHIFT));
/* Only the directory inode sets new_i_size */
set_inode_flag(F2FS_I(inode), FI_UPDATE_DIR);
}
return page;
}
开发者ID:aejsmith,项目名称:linux,代码行数:61,代码来源:data.c
示例9: f2fs_convert_inline_dir
static int f2fs_convert_inline_dir(struct inode *dir, struct page *ipage,
struct f2fs_inline_dentry *inline_dentry)
{
struct page *page;
struct dnode_of_data dn;
struct f2fs_dentry_block *dentry_blk;
int err;
page = grab_cache_page(dir->i_mapping, 0);
if (!page)
return -ENOMEM;
set_new_dnode(&dn, dir, ipage, NULL, 0);
err = f2fs_reserve_block(&dn, 0);
if (err)
goto out;
f2fs_wait_on_page_writeback(page, DATA);
zero_user_segment(page, 0, PAGE_CACHE_SIZE);
dentry_blk = kmap_atomic(page);
/* copy data from inline dentry block to new dentry block */
memcpy(dentry_blk->dentry_bitmap, inline_dentry->dentry_bitmap,
INLINE_DENTRY_BITMAP_SIZE);
memcpy(dentry_blk->dentry, inline_dentry->dentry,
sizeof(struct f2fs_dir_entry) * NR_INLINE_DENTRY);
memcpy(dentry_blk->filename, inline_dentry->filename,
NR_INLINE_DENTRY * F2FS_SLOT_LEN);
kunmap_atomic(dentry_blk);
SetPageUptodate(page);
set_page_dirty(page);
/* clear inline dir and flag after data writeback */
truncate_inline_inode(ipage, 0);
stat_dec_inline_dir(dir);
clear_inode_flag(F2FS_I(dir), FI_INLINE_DENTRY);
if (i_size_read(dir) < PAGE_CACHE_SIZE) {
i_size_write(dir, PAGE_CACHE_SIZE);
set_inode_flag(F2FS_I(dir), FI_UPDATE_DIR);
}
sync_inode_page(&dn);
out:
f2fs_put_page(page, 1);
return err;
}
开发者ID:ench0,项目名称:android_kernel_samsung_hltet,代码行数:50,代码来源:inline.c
示例10: expand_inode_data
static int expand_inode_data(struct inode *inode, loff_t offset, loff_t len,
int mode)
{
pgoff_t index, pg_start, pg_end;
loff_t new_size = i_size_read(inode);
loff_t off_start, off_end;
struct dnode_of_data dn;
int ret, ilock;
struct hmfs_sb_info *sbi = HMFS_SB(inode->i_sb);
ret = inode_newsize_ok(inode, (len + offset));
if (ret)
return ret;
pg_start = ((u64) offset) >> HMFS_PAGE_SIZE_BITS;
pg_end = ((u64) offset + len) >> HMFS_PAGE_SIZE_BITS;
off_start = offset & (HMFS_PAGE_SIZE - 1);
off_end = (offset + len) & (HMFS_PAGE_SIZE - 1);
for (index = pg_start; index <= pg_end; index++) {
ilock = mutex_lock_op(sbi);
set_new_dnode(&dn, inode, NULL, NULL, 0);
ret = get_dnode_of_data(&dn, index, ALLOC_NODE);
mutex_unlock_op(sbi, ilock);
if (ret) {
break;
}
if (pg_start == pg_end)
new_size = offset + len;
else if (index == pg_start && off_start)
new_size = (index + 1) << HMFS_PAGE_SIZE_BITS;
else if (index == pg_end)
new_size = (index << HMFS_PAGE_SIZE_BITS) + off_end;
else
new_size += HMFS_PAGE_SIZE;
}
if (!(mode & FALLOC_FL_KEEP_SIZE) && i_size_read(inode) < new_size) {
mark_size_dirty(inode, new_size);
}
return ret;
}
开发者ID:sjtutravel,项目名称:hmfs,代码行数:46,代码来源:file.c
示例11: truncate_hole
int truncate_hole(struct inode *inode, pgoff_t start, pgoff_t end)
{
pgoff_t index;
int err;
struct dnode_of_data dn;
for (index = start; index < end; index++) {
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
if (err) {
if (err == -ENODATA)
continue;
return err;
}
truncate_data_blocks_range(&dn, 1);
}
return 0;
}
开发者ID:sjtutravel,项目名称:hmfs,代码行数:18,代码来源:file.c
示例12: truncate_hole
int truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end)
{
pgoff_t index;
int err;
for (index = pg_start; index < pg_end; index++) {
struct dnode_of_data dn;
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, index, LOOKUP_NODE);
if (err) {
if (err == -ENOENT)
continue;
return err;
}
if (dn.data_blkaddr != NULL_ADDR)
truncate_data_blocks_range(&dn, 1);
f2fs_put_dnode(&dn);
}
return 0;
}
开发者ID:handelxh,项目名称:ONEPLUS2RAZOR,代码行数:22,代码来源:file.c
示例13: truncate_blocks
static int truncate_blocks(struct inode *inode, u64 from)
{
struct dnode_of_data dn;
struct hmfs_sb_info *sbi = HMFS_SB(inode->i_sb);
int count, err;
u64 free_from;
int ilock;
free_from = (from + HMFS_PAGE_SIZE - 1) >> HMFS_PAGE_SIZE_BITS;
ilock = mutex_lock_op(sbi);
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, free_from, LOOKUP_NODE);
if (err) {
goto free_next;
}
if (!dn.level)
count = NORMAL_ADDRS_PER_INODE;
else
count = ADDRS_PER_BLOCK;
count -= dn.ofs_in_node;
BUG_ON(count < 0);
if (dn.ofs_in_node || !dn.level) {
truncate_data_blocks_range(&dn, count);
free_from += count;
}
free_next:err = truncate_inode_blocks(inode, free_from);
truncate_partial_data_page(inode, from);
mutex_unlock_op(sbi, ilock);
return err;
}
开发者ID:sjtutravel,项目名称:hmfs,代码行数:37,代码来源:file.c
示例14: write_all_xattrs
static inline int write_all_xattrs(struct inode *inode, __u32 hsize,
void *txattr_addr, struct page *ipage)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
size_t inline_size = 0;
void *xattr_addr;
struct page *xpage;
nid_t new_nid = 0;
int err;
inline_size = inline_xattr_size(inode);
if (hsize > inline_size && !F2FS_I(inode)->i_xattr_nid)
if (!alloc_nid(sbi, &new_nid))
return -ENOSPC;
/* write to inline xattr */
if (inline_size) {
struct page *page = NULL;
void *inline_addr;
if (ipage) {
inline_addr = inline_xattr_addr(ipage);
f2fs_wait_on_page_writeback(ipage, NODE, true);
set_page_dirty(ipage);
} else {
page = get_node_page(sbi, inode->i_ino);
if (IS_ERR(page)) {
alloc_nid_failed(sbi, new_nid);
return PTR_ERR(page);
}
inline_addr = inline_xattr_addr(page);
f2fs_wait_on_page_writeback(page, NODE, true);
}
memcpy(inline_addr, txattr_addr, inline_size);
f2fs_put_page(page, 1);
/* no need to use xattr node block */
if (hsize <= inline_size) {
err = truncate_xattr_node(inode, ipage);
alloc_nid_failed(sbi, new_nid);
return err;
}
}
/* write to xattr node block */
if (F2FS_I(inode)->i_xattr_nid) {
xpage = get_node_page(sbi, F2FS_I(inode)->i_xattr_nid);
if (IS_ERR(xpage)) {
alloc_nid_failed(sbi, new_nid);
return PTR_ERR(xpage);
}
f2fs_bug_on(sbi, new_nid);
f2fs_wait_on_page_writeback(xpage, NODE, true);
} else {
struct dnode_of_data dn;
set_new_dnode(&dn, inode, NULL, NULL, new_nid);
xpage = new_node_page(&dn, XATTR_NODE_OFFSET, ipage);
if (IS_ERR(xpage)) {
alloc_nid_failed(sbi, new_nid);
return PTR_ERR(xpage);
}
alloc_nid_done(sbi, new_nid);
}
xattr_addr = page_address(xpage);
memcpy(xattr_addr, txattr_addr + inline_size, PAGE_SIZE -
sizeof(struct node_footer));
set_page_dirty(xpage);
f2fs_put_page(xpage, 1);
/* need to checkpoint during fsync */
F2FS_I(inode)->xattr_ver = cur_cp_version(F2FS_CKPT(sbi));
return 0;
}
开发者ID:StanTRC,项目名称:boeffla-kernel-cm-s5,代码行数:75,代码来源:xattr.c
示例15: f2fs_convert_inline_page
int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
{
struct f2fs_io_info fio = {
.sbi = F2FS_I_SB(dn->inode),
.type = DATA,
.op = REQ_OP_WRITE,
.op_flags = REQ_SYNC | REQ_PRIO,
.page = page,
.encrypted_page = NULL,
};
int dirty, err;
if (!f2fs_exist_data(dn->inode))
goto clear_out;
err = f2fs_reserve_block(dn, 0);
if (err)
return err;
f2fs_bug_on(F2FS_P_SB(page), PageWriteback(page));
read_inline_data(page, dn->inode_page);
set_page_dirty(page);
/* clear dirty state */
dirty = clear_page_dirty_for_io(page);
/* write data page to try to make data consistent */
set_page_writeback(page);
fio.old_blkaddr = dn->data_blkaddr;
set_inode_flag(dn->inode, FI_HOT_DATA);
write_data_page(dn, &fio);
f2fs_wait_on_page_writeback(page, DATA, true);
if (dirty) {
inode_dec_dirty_pages(dn->inode);
remove_dirty_inode(dn->inode);
}
/* this converted inline_data should be recovered. */
set_inode_flag(dn->inode, FI_APPEND_WRITE);
/* clear inline data and flag after data writeback */
truncate_inline_inode(dn->inode, dn->inode_page, 0);
clear_inline_node(dn->inode_page);
clear_out:
stat_dec_inline_inode(dn->inode);
clear_inode_flag(dn->inode, FI_INLINE_DATA);
f2fs_put_dnode(dn);
return 0;
}
int f2fs_convert_inline_inode(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct dnode_of_data dn;
struct page *ipage, *page;
int err = 0;
if (!f2fs_has_inline_data(inode))
return 0;
page = f2fs_grab_cache_page(inode->i_mapping, 0, false);
if (!page)
return -ENOMEM;
f2fs_lock_op(sbi);
ipage = get_node_page(sbi, inode->i_ino);
if (IS_ERR(ipage)) {
err = PTR_ERR(ipage);
goto out;
}
set_new_dnode(&dn, inode, ipage, ipage, 0);
if (f2fs_has_inline_data(inode))
err = f2fs_convert_inline_page(&dn, page);
f2fs_put_dnode(&dn);
out:
f2fs_unlock_op(sbi);
f2fs_put_page(page, 1);
f2fs_balance_fs(sbi, dn.node_changed);
return err;
}
int f2fs_write_inline_data(struct inode *inode, struct page *page)
{
void *src_addr, *dst_addr;
struct dnode_of_data dn;
int err;
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, 0, LOOKUP_NODE);
if (err)
return err;
//.........这里部分代码省略.........
开发者ID:mdamt,项目名称:linux,代码行数:101,代码来源:inline.c
示例16: __f2fs_convert_inline_data
static int __f2fs_convert_inline_data(struct inode *inode, struct page *page)
{
int err;
struct page *ipage;
struct dnode_of_data dn;
void *src_addr, *dst_addr;
block_t new_blk_addr;
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
struct f2fs_io_info fio = {
.type = DATA,
.rw = WRITE_SYNC | REQ_PRIO,
};
f2fs_lock_op(sbi);
ipage = get_node_page(sbi, inode->i_ino);
if (IS_ERR(ipage))
return PTR_ERR(ipage);
/*
* i_addr[0] is not used for inline data,
* so reserving new block will not destroy inline data
*/
set_new_dnode(&dn, inode, ipage, NULL, 0);
err = f2fs_reserve_block(&dn, 0);
if (err) {
f2fs_unlock_op(sbi);
return err;
}
zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE);
/* Copy the whole inline data block */
src_addr = inline_data_addr(ipage);
dst_addr = kmap(page);
memcpy(dst_addr, src_addr, MAX_INLINE_DATA);
kunmap(page);
SetPageUptodate(page);
/* write data page to try to make data consistent */
set_page_writeback(page);
write_data_page(page, &dn, &new_blk_addr, &fio);
update_extent_cache(new_blk_addr, &dn);
f2fs_wait_on_page_writeback(page, DATA);
/* clear inline data and flag after data writeback */
zero_user_segment(ipage, INLINE_DATA_OFFSET,
INLINE_DATA_OFFSET + MAX_INLINE_DATA);
clear_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
stat_dec_inline_inode(inode);
sync_inode_page(&dn);
f2fs_put_dnode(&dn);
f2fs_unlock_op(sbi);
return err;
}
int f2fs_convert_inline_data(struct inode *inode, pgoff_t to_size)
{
struct page *page;
int err;
if (!f2fs_has_inline_data(inode))
return 0;
else if (to_size <= MAX_INLINE_DATA)
return 0;
page = grab_cache_page_write_begin(inode->i_mapping, 0, AOP_FLAG_NOFS);
if (!page)
return -ENOMEM;
err = __f2fs_convert_inline_data(inode, page);
f2fs_put_page(page, 1);
return err;
}
int f2fs_write_inline_data(struct inode *inode,
struct page *page, unsigned size)
{
void *src_addr, *dst_addr;
struct page *ipage;
struct dnode_of_data dn;
int err;
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, 0, LOOKUP_NODE);
if (err)
return err;
ipage = dn.inode_page;
zero_user_segment(ipage, INLINE_DATA_OFFSET,
INLINE_DATA_OFFSET + MAX_INLINE_DATA);
src_addr = kmap(page);
dst_addr = inline_data_addr(ipage);
memcpy(dst_addr, src_addr, size);
kunmap(page);
/* Release the first data block if it is allocated */
if (!f2fs_has_inline_data(inode)) {
truncate_data_blocks_range(&dn, 1);
set_inode_flag(F2FS_I(inode), FI_INLINE_DATA);
//.........这里部分代码省略.........
开发者ID:7799,项目名称:linux,代码行数:101,代码来源:inline.c
示例17: do_recover_data
static int do_recover_data(struct f2fs_sb_info *sbi, struct inode *inode,
struct page *page)
{
struct dnode_of_data dn;
struct node_info ni;
unsigned int start, end;
int err = 0, recovered = 0;
/* step 1: recover xattr */
if (IS_INODE(page)) {
f2fs_recover_inline_xattr(inode, page);
} else if (f2fs_has_xattr_block(ofs_of_node(page))) {
err = f2fs_recover_xattr_data(inode, page);
if (!err)
recovered++;
goto out;
}
/* step 2: recover inline data */
if (f2fs_recover_inline_data(inode, page))
goto out;
/* step 3: recover data indices */
start = f2fs_start_bidx_of_node(ofs_of_node(page), inode);
end = start + ADDRS_PER_PAGE(page, inode);
set_new_dnode(&dn, inode, NULL, NULL, 0);
retry_dn:
err = f2fs_get_dnode_of_data(&dn, start, ALLOC_NODE);
if (err) {
if (err == -ENOMEM) {
congestion_wait(BLK_RW_ASYNC, HZ/50);
goto retry_dn;
}
goto out;
}
f2fs_wait_on_page_writeback(dn.node_page, NODE, true, true);
err = f2fs_get_node_info(sbi, dn.nid, &ni);
if (err)
goto err;
f2fs_bug_on(sbi, ni.ino != ino_of_node(page));
if (ofs_of_node(dn.node_page) != ofs_of_node(page)) {
f2fs_msg(sbi->sb, KERN_WARNING,
"Inconsistent ofs_of_node, ino:%lu, ofs:%u, %u",
inode->i_ino, ofs_of_node(dn.node_page),
ofs_of_node(page));
err = -EFAULT;
goto err;
}
for (; start < end; start++, dn.ofs_in_node++) {
block_t src, dest;
src = datablock_addr(dn.inode, dn.node_page, dn.ofs_in_node);
dest = datablock_addr(dn.inode, page, dn.ofs_in_node);
if (__is_valid_data_blkaddr(src) &&
!f2fs_is_valid_blkaddr(sbi, src, META_POR)) {
err = -EFAULT;
goto err;
}
if (__is_valid_data_blkaddr(dest) &&
!f2fs_is_valid_blkaddr(sbi, dest, META_POR)) {
err = -EFAULT;
goto err;
}
/* skip recovering if dest is the same as src */
if (src == dest)
continue;
/* dest is invalid, just invalidate src block */
if (dest == NULL_ADDR) {
f2fs_truncate_data_blocks_range(&dn, 1);
continue;
}
if (!file_keep_isize(inode) &&
(i_size_read(inode) <= ((loff_t)start << PAGE_SHIFT)))
f2fs_i_size_write(inode,
(loff_t)(start + 1) << PAGE_SHIFT);
/*
* dest is reserved block, invalidate src block
* and then reserve one new block in dnode page.
*/
if (dest == NEW_ADDR) {
f2fs_truncate_data_blocks_range(&dn, 1);
f2fs_reserve_new_block(&dn);
continue;
}
/* dest is valid block, try to recover from src to dest */
if (f2fs_is_valid_blkaddr(sbi, dest, META_POR)) {
//.........这里部分代码省略.........
开发者ID:avagin,项目名称:linux,代码行数:101,代码来源:recovery.c
示例18: f2fs_convert_inline_page
int f2fs_convert_inline_page(struct dnode_of_data *dn, struct page *page)
{
void *src_addr, *dst_addr;
struct f2fs_io_info fio = {
.sbi = F2FS_I_SB(dn->inode),
.type = DATA,
.rw = WRITE_SYNC | REQ_PRIO,
.page = page,
.encrypted_page = NULL,
};
int dirty, err;
f2fs_bug_on(F2FS_I_SB(dn->inode), page->index);
if (!f2fs_exist_data(dn->inode))
goto clear_out;
err = f2fs_reserve_block(dn, 0);
if (err)
return err;
f2fs_wait_on_page_writeback(page, DATA);
if (PageUptodate(page))
goto no_update;
zero_user_segment(page, MAX_INLINE_DATA, PAGE_CACHE_SIZE);
/* Copy the whole inline data block */
src_addr = inline_data_addr(dn->inode_page);
dst_addr = kmap_atomic(page);
memcpy(dst_addr, src_addr, MAX_INLINE_DATA);
flush_dcache_page(page);
kunmap_atomic(dst_addr);
SetPageUptodate(page);
no_update:
set_page_dirty(page);
/* clear dirty state */
dirty = clear_page_dirty_for_io(page);
/* write data page to try to make data consistent */
set_page_writeback(page);
fio.blk_addr = dn->data_blkaddr;
write_data_page(dn, &fio);
set_data_blkaddr(dn);
f2fs_update_extent_cache(dn);
f2fs_wait_on_page_writeback(page, DATA);
if (dirty)
inode_dec_dirty_pages(dn->inode);
/* this converted inline_data should be recovered. */
set_inode_flag(F2FS_I(dn->inode), FI_APPEND_WRITE);
/* clear inline data and flag after data writeback */
truncate_inline_inode(dn->inode_page, 0);
clear_out:
stat_dec_inline_inode(dn->inode);
f2fs_clear_inline_inode(dn->inode);
sync_inode_page(dn);
f2fs_put_dnode(dn);
return 0;
}
int f2fs_convert_inline_inode(struct inode *inode)
{
struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct dnode_of_data dn;
struct page *ipage, *page;
int err = 0;
page = grab_cache_page(inode->i_mapping, 0);
if (!page)
return -ENOMEM;
f2fs_lock_op(sbi);
ipage = get_node_page(sbi, inode->i_ino);
if (IS_ERR(ipage)) {
err = PTR_ERR(ipage);
goto out;
}
set_new_dnode(&dn, inode, ipage, ipage, 0);
if (f2fs_has_inline_data(inode))
err = f2fs_convert_inline_page(&dn, page);
f2fs_put_dnode(&dn);
out:
f2fs_unlock_op(sbi);
f2fs_put_page(page, 1);
return err;
}
int f2fs_write_inline_data(struct inode *inode, struct page *page)
{
void *src_addr, *dst_addr;
struct dnode_of_data dn;
//.........这里部分代码省略.........
开发者ID:ench0,项目名称:android_kernel_samsung_hltet,代码行数:101,代码来源:inline.c
示例19: f2fs_map_blocks
/*
* f2fs_map_blocks() now supported readahead/bmap/rw direct_IO with
* f2fs_map_blocks structure.
* If original data blocks are allocated, then give them to blockdev.
* Otherwise,
* a. preallocate requested block addresses
* b. do not use extent cache for better performance
* c. give the block addresses to blockdev
*/
static int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map,
int create, int flag)
{
unsigned int maxblocks = map->m_len;
struct dnode_of_data dn;
int mode = create ? ALLOC_NODE : LOOKUP_NODE_RA;
pgoff_t pgofs, end_offset;
int err = 0, ofs = 1;
struct extent_info ei;
bool allocated = false;
map->m_len = 0;
map->m_flags = 0;
/* it only supports block size == page size */
pgofs = (pgoff_t)map->m_lblk;
if (f2fs_lookup_extent_cache(inode, pgofs, &ei)) {
map->m_pblk = ei.blk + pgofs - ei.fofs;
map->m_len = min((pgoff_t)maxblocks, ei.fofs + ei.len - pgofs);
map->m_flags = F2FS_MAP_MAPPED;
goto out;
}
if (create)
f2fs_lock_op(F2FS_I_SB(inode));
/* When reading holes, we need its node page */
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, pgofs, mode);
if (err) {
if (err == -ENOENT)
err = 0;
goto unlock_out;
}
if (dn.data_blkaddr == NEW_ADDR) {
if (flag == F2FS_GET_BLOCK_BMAP) {
err = -ENOENT;
goto put_out;
} else if (flag == F2FS_GET_BLOCK_READ ||
flag == F2FS_GET_BLOCK_DIO) {
goto put_out;
}
/*
* if it is in fiemap call path (flag = F2FS_GET_BLOCK_FIEMAP),
* mark it as mapped and unwritten block.
*/
}
if (dn.data_blkaddr != NULL_ADDR) {
map->m_flags = F2FS_MAP_MAPPED;
map->m_pblk = dn.data_blkaddr;
if (dn.data_blkaddr == NEW_ADDR)
map->m_flags |= F2FS_MAP_UNWRITTEN;
} else if (create) {
err = __allocate_data_block(&dn);
if (err)
goto put_out;
allocated = true;
map->m_flags = F2FS_MAP_NEW | F2FS_MAP_MAPPED;
map->m_pblk = dn.data_blkaddr;
} else {
if (flag == F2FS_GET_BLOCK_BMAP)
err = -ENOENT;
goto put_out;
}
end_offset = ADDRS_PER_PAGE(dn.node_page, F2FS_I(inode));
map->m_len = 1;
dn.ofs_in_node++;
pgofs++;
get_next:
if (dn.ofs_in_node >= end_offset) {
if (allocated)
sync_inode_page(&dn);
allocated = false;
f2fs_put_dnode(&dn);
set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, pgofs, mode);
if (err) {
if (err == -ENOENT)
err = 0;
goto unlock_out;
}
if (dn.data_blkaddr == NEW_ADDR &&
flag != F2FS_GET_BLOCK_FIEMAP)
goto put_out;
//.........这里部分代码省略.........
开发者ID:aejsmith,项目名称:linux,代码行数:101,代码来源:data.c
示例20: check_index_in_prev_nodes
static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi,
block_t blkaddr, struct dnode_of_data *dn)
{
struct seg_entry *sentry;
unsigned int segno = GET_SEGNO(sbi, blkaddr);
unsigned short blkoff = GET_BLKOFF_FROM_SEG0(sbi, blkaddr);
struct f2fs_summary_block *sum_node;
struct f2fs_summary sum;
struct page *sum_page, *node_page;
struct dnode_of_data tdn = *dn;
nid_t ino, nid;
struct inode *inode;
unsigned int offset;
block_t bidx;
int i;
sentry = get_seg_entry(sbi, segno);
if (!f2fs_test_bit(blkoff, sentry->cur_valid_map))
return 0;
/* Get the previous summary */
for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) {
struct curseg_info *curseg = CURSEG_I(sbi, i);
if (curseg->segno == segno) {
sum = curseg->sum_blk->entries[blkoff];
goto got_it;
}
}
sum_page = f2fs_get_sum_page(sbi, segno);
if (IS_ERR(sum_page))
return PTR_ERR(sum_page);
sum_node = (struct f2fs_summary_block *)page_address(sum_page);
sum = sum_node->entries[blkoff];
f2fs_put_page(sum_page, 1);
got_it:
/* Use the locked dnode page and inode */
nid = le32_to_cpu(sum.nid);
if (dn->inode->i_ino == nid) {
tdn.nid = nid;
if (!dn->inode_page_locked)
lock_page(dn->inode_page);
tdn.node_page = dn->inode_page;
tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node);
goto truncate_out;
} else if (dn->nid == nid) {
tdn.ofs_in_node = le16_to_cpu(sum.ofs_in_node);
goto truncate_out;
}
/* Get the node page */
node_page = f2fs_get_node_page(sbi, nid);
if (IS_ERR(node_page))
return PTR_ERR(node_page);
offset = ofs_of_node(node_page);
ino = ino_of_node(node_page);
f2fs_put_page(node_page, 1);
if (ino != dn->inode->i_ino) {
int ret;
/* Deallocate previous index in the node page */
inode = f2fs_iget_retry(sbi->sb, ino);
if (IS_ERR(inode))
return PTR_ERR(inode);
ret = dquot_initialize(inode);
if (ret) {
iput(inode);
return ret;
}
} else {
inode = dn->inode;
}
bidx = f2fs_start_bidx_of_node(offset, inode) +
le16_to_cpu(sum.ofs_in_node);
/*
* if inode page is locked, unlock temporarily, but its reference
* count keeps alive.
*/
if (ino == dn->inode->i_ino && dn->inode_page_locked)
unlock_page(dn->inode_page);
set_new_dnode(&tdn, inode, NULL, NULL, 0);
if (f2fs_get_dnode_of_data(&tdn, bidx, LOOKUP_NODE))
goto out;
if (tdn.data_blkaddr == blkaddr)
f2fs_truncate_data_blocks_range(&tdn, 1);
f2fs_put_dnode(&tdn);
out:
if (ino != dn->inode->i_ino)
iput(inode);
else if (dn->inode_page_locked)
lock_page(dn->inode_page);
return 0;
//.........这里部分代码省略.........
开发者ID:avagin,项目名称:linux,代码行数:101,代码来源:recovery.c
注:本文中的set_new_dnode函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论