Пример #1
0
int nfs4_op_link(struct nfs_argop4 *op, compound_data_t *data,
		 struct nfs_resop4 *resp)
{
	LINK4args * const arg_LINK4 = &op->nfs_argop4_u.oplink;
	LINK4res * const res_LINK4 = &resp->nfs_resop4_u.oplink;
	cache_entry_t *dir_entry = NULL;
	cache_entry_t *file_entry = NULL;
	cache_inode_status_t cache_status = CACHE_INODE_SUCCESS;
	char *newname = NULL;

	resp->resop = NFS4_OP_LINK;
	res_LINK4->status = NFS4_OK;

	/* Do basic checks on a filehandle */
	res_LINK4->status = nfs4_sanity_check_FH(data, DIRECTORY, false);

	if (res_LINK4->status != NFS4_OK)
		goto out;

	res_LINK4->status = nfs4_sanity_check_saved_FH(data, -DIRECTORY, false);

	if (res_LINK4->status != NFS4_OK)
		goto out;

	/*
	 * This operation creates a hard link, for the file
	 * represented by the saved FH, in directory represented by
	 * currentFH under the name arg_LINK4.target
	 */

	/* Validate and convert the UFT8 objname to a regular string */
	res_LINK4->status = nfs4_utf8string2dynamic(&arg_LINK4->newname,
						    UTF8_SCAN_ALL,
						    &newname);

	if (res_LINK4->status != NFS4_OK)
		goto out;

	/* get info from compound data */
	dir_entry = data->current_entry;

	res_LINK4->LINK4res_u.resok4.cinfo.before =
	    cache_inode_get_changeid4(dir_entry);

	file_entry = data->saved_entry;

	/* make the link */
	cache_status =
	    cache_inode_link(file_entry, dir_entry, newname);

	if (cache_status != CACHE_INODE_SUCCESS) {
		res_LINK4->status = nfs4_Errno(cache_status);
		goto out;
	}

	res_LINK4->LINK4res_u.resok4.cinfo.after =
	    cache_inode_get_changeid4(dir_entry);
	res_LINK4->LINK4res_u.resok4.cinfo.atomic = FALSE;

	res_LINK4->status = NFS4_OK;

 out:

	if (newname)
		gsh_free(newname);

	return res_LINK4->status;
}				/* nfs4_op_link */
Пример #2
0
int nfs4_op_restorefh(struct nfs_argop4 *op, compound_data_t *data,
		      struct nfs_resop4 *resp)
{
	RESTOREFH4res * const res_RESTOREFH = &resp->nfs_resop4_u.oprestorefh;
	/* First of all, set the reply to zero to make sure it contains no
	   parasite information */
	memset(resp, 0, sizeof(struct nfs_resop4));

	resp->resop = NFS4_OP_RESTOREFH;
	res_RESTOREFH->status = NFS4_OK;

	LogFullDebugOpaque(COMPONENT_FILEHANDLE,
			   "Saved FH %s",
			   LEN_FH_STR,
			   data->savedFH.nfs_fh4_val,
			   data->savedFH.nfs_fh4_len);

	/* If there is no savedFH, then return an error */
	if (nfs4_Is_Fh_Empty(&(data->savedFH)) == NFS4ERR_NOFILEHANDLE) {
		/* There is no current FH, return NFS4ERR_RESTOREFH
		 * (cg RFC3530, page 202)
		 */
		res_RESTOREFH->status = NFS4ERR_RESTOREFH;
		return res_RESTOREFH->status;
	}

	/* Do basic checks on saved filehandle */
	res_RESTOREFH->status =
	    nfs4_sanity_check_saved_FH(data, NO_FILE_TYPE, true);

	if (res_RESTOREFH->status != NFS4_OK)
		return res_RESTOREFH->status;

	/* Determine if we can get a new export reference. If there is
	 * no saved export, don't get a reference to it.
	 */
	if (data->saved_export != NULL) {
		if (!export_ready(data->saved_export)) {
			/* The SavedFH export has gone bad. */
			res_RESTOREFH->status = NFS4ERR_STALE;
			return res_RESTOREFH->status;
		}
		get_gsh_export_ref(data->saved_export);
	}

	/* Copy the data from saved FH to current FH */
	memcpy(data->currentFH.nfs_fh4_val, data->savedFH.nfs_fh4_val,
	       data->savedFH.nfs_fh4_len);

	data->currentFH.nfs_fh4_len = data->savedFH.nfs_fh4_len;

	if (op_ctx->ctx_export != NULL)
		put_gsh_export(op_ctx->ctx_export);

	/* Restore the export information */
	op_ctx->ctx_export = data->saved_export;
	if (op_ctx->ctx_export != NULL)
		op_ctx->fsal_export = op_ctx->ctx_export->fsal_export;

	*op_ctx->export_perms = data->saved_export_perms;

	/* No need to call nfs4_SetCompoundExport or nfs4_MakeCred
	 * because we are restoring saved information, and the
	 * credential checking may be skipped.
	 */

	/* Update the current entry */
	set_current_entry(data, data->saved_obj);

	/* Restore the saved stateid */
	data->current_stateid = data->saved_stateid;
	data->current_stateid_valid = data->saved_stateid_valid;

	/* Make RESTOREFH work right for DS handle */
	if (data->current_ds != NULL) {
		data->current_ds = data->saved_ds;
		data->current_filetype = data->saved_filetype;
		ds_handle_get_ref(data->current_ds);
	}

	if (isFullDebug(COMPONENT_NFS_V4)) {
		char str[LEN_FH_STR];

		sprint_fhandle4(str, &data->currentFH);
		LogFullDebug(COMPONENT_NFS_V4,
			     "RESTORE FH: Current FH %s",
			     str);
	}

	return NFS4_OK;
}				/* nfs4_op_restorefh */