static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb, struct inode *inode, struct buffer_head *fe_bh, u64 new_i_size) { int status; handle_t *handle; struct ocfs2_dinode *di; mlog_entry_void(); /* TODO: This needs to actually orphan the inode in this * transaction. */ handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); if (IS_ERR(handle)) { status = PTR_ERR(handle); mlog_errno(status); goto out; } status = ocfs2_journal_access(handle, inode, fe_bh, OCFS2_JOURNAL_ACCESS_WRITE); if (status < 0) { mlog_errno(status); goto out_commit; } /* * Do this before setting i_size. */ status = ocfs2_zero_tail_for_truncate(inode, handle, new_i_size); if (status) { mlog_errno(status); goto out_commit; } i_size_write(inode, new_i_size); inode->i_blocks = ocfs2_align_bytes_to_sectors(new_i_size); inode->i_ctime = inode->i_mtime = CURRENT_TIME; di = (struct ocfs2_dinode *) fe_bh->b_data; di->i_size = cpu_to_le64(new_i_size); di->i_ctime = di->i_mtime = cpu_to_le64(inode->i_ctime.tv_sec); di->i_ctime_nsec = di->i_mtime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec); status = ocfs2_journal_dirty(handle, fe_bh); if (status < 0) mlog_errno(status); out_commit: ocfs2_commit_trans(osb, handle); out: mlog_exit(status); return status; }
/* * This function will truncate the file's cluster which exceeds * the cluster where new_size resides in and empty all the * bytes in the same cluster which exceeds new_size. */ static errcode_t ocfs2_zero_tail_and_truncate_full(ocfs2_filesys *fs, ocfs2_cached_inode *ci, uint64_t new_i_size, uint32_t *new_clusters, errcode_t (*free_clusters)(ocfs2_filesys *fs, uint32_t len, uint64_t start, void *free_data), void *free_data) { errcode_t ret; uint64_t new_size_in_blocks; struct truncate_ctxt ctxt; new_size_in_blocks = ocfs2_blocks_in_bytes(fs, new_i_size); ctxt.ino = ci->ci_blkno; ctxt.new_i_clusters = ci->ci_inode->i_clusters; ctxt.new_size_in_clusters = ocfs2_clusters_in_blocks(fs, new_size_in_blocks); ctxt.free_clusters = free_clusters; ctxt.free_data = free_data; ret = ocfs2_extent_iterate_inode(fs, ci->ci_inode, OCFS2_EXTENT_FLAG_DEPTH_TRAVERSE, NULL, truncate_iterate, &ctxt); if (ret) goto out; ret = ocfs2_zero_tail_for_truncate(ci, new_i_size); if (ret) goto out; if (new_clusters) *new_clusters = ctxt.new_i_clusters; out: return ret; }