Beispiel #1
0
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;
}
Beispiel #2
0
/*
 * 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;
}