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; }
static int f2fs_ioc_release_volatile_write(struct file *filp) { struct inode *inode = file_inode(filp); if (!inode_owner_or_capable(inode)) return -EACCES; if (!f2fs_is_volatile_file(inode)) return 0; if (!f2fs_is_first_block_written(inode)) return truncate_partial_data_page(inode, 0, true); return punch_hole(inode, 0, F2FS_BLKSIZE); }
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; }