/* open() implementation for gcov data files. Create a copy of the profiling data set and initialize the iterator and seq_file interface.  */
static int gcov_seq_open(struct inode *inode, struct file *file)
/* open() implementation for gcov data files. Create a copy of the profiling data set and initialize the iterator and seq_file interface.  */
static int gcov_seq_open(struct inode *inode, struct file *file)
{
	struct gcov_node *node = inode->i_private;
	struct gcov_iterator *iter;
	struct seq_file *seq;
	struct gcov_info *info;
	int rc = -ENOMEM;
	mutex_lock(&node_lock);
	info = gcov_info_dup(get_node_info(node));
	if (!info)
		goto out_unlock;
	iter = gcov_iter_new(info);
	if (!iter)
		goto err_free_info;
	rc = seq_open(file, &gcov_seq_ops);
	if (rc)
		goto err_free_iter_info;
	seq = file->private_data;
	seq->private = iter;
out_unlock:
	mutex_unlock(&node_lock);
	return rc;
err_free_iter_info:
	gcov_iter_free(iter);
err_free_info:
	gcov_info_free(info);
	goto out_unlock;
}