Ejemplo n.º 1
0
/* common code gpfs_open and gpfs_reopen */
fsal_status_t gpfs_open2(struct fsal_obj_handle *obj_hdl,
			 fsal_openflags_t openflags, bool reopen)
{
	struct gpfs_fsal_obj_handle *myself;
	int fd;
	fsal_status_t status;

	myself = container_of(obj_hdl, struct gpfs_fsal_obj_handle, obj_handle);

	if (reopen) {
		assert((myself->u.file.fd >= 0 &&
			myself->u.file.openflags != FSAL_O_CLOSED));
		fd = myself->u.file.fd;
	} else {
		assert(myself->u.file.fd == -1 &&
		       myself->u.file.openflags == FSAL_O_CLOSED);
	}

	status = GPFSFSAL_open(obj_hdl, op_ctx, openflags, &fd, NULL, reopen);
	if (FSAL_IS_ERROR(status))
		return status;

	myself->u.file.fd = fd;
	myself->u.file.openflags = openflags;

	return fsalstat(ERR_FSAL_NO_ERROR, 0);
}
Ejemplo n.º 2
0
static fsal_status_t
gpfs_open_again(struct fsal_obj_handle *obj_hdl, fsal_openflags_t openflags,
		bool reopen)
{
	struct gpfs_fsal_obj_handle *myself =
		container_of(obj_hdl, struct gpfs_fsal_obj_handle, obj_handle);
	fsal_status_t status;
	int posix_flags = 0;
	int fd = -1;

	if (reopen) {
		assert(myself->u.file.fd.fd >= 0 &&
		       myself->u.file.fd.openflags != FSAL_O_CLOSED);
		fd = myself->u.file.fd.fd;
	} else {
		assert(myself->u.file.fd.fd == -1 &&
		       myself->u.file.fd.openflags == FSAL_O_CLOSED);
	}
	fsal2posix_openflags(openflags, &posix_flags);

	status = GPFSFSAL_open(obj_hdl, op_ctx, posix_flags, &fd, reopen);
	if (FSAL_IS_ERROR(status) == false) {
		myself->u.file.fd.fd = fd;
		myself->u.file.fd.openflags = openflags;
	}

	return status;
}
Ejemplo n.º 3
0
fsal_status_t WRAP_GPFSFSAL_open(fsal_handle_t * p_filehandle,   /* IN */
                                fsal_op_context_t * p_context,  /* IN */
                                fsal_openflags_t openflags,     /* IN */
                                fsal_file_t * p_file_descriptor,        /* OUT */
                                fsal_attrib_list_t * p_file_attributes /* [ IN/OUT ] */ )
{
  return GPFSFSAL_open((gpfsfsal_handle_t *) p_filehandle,
                      (gpfsfsal_op_context_t *) p_context, openflags,
                      (gpfsfsal_file_t *) p_file_descriptor, p_file_attributes);
}
Ejemplo n.º 4
0
static fsal_status_t
gpfs_open_func(struct fsal_obj_handle *obj_hdl, fsal_openflags_t openflags,
		struct fsal_fd *fd)
{
	fsal_status_t status;
	struct gpfs_fd *my_fd = (struct gpfs_fd *)fd;
	int posix_flags = 0;

	my_fd->fd = -1;
	fsal2posix_openflags(openflags, &posix_flags);

	status = GPFSFSAL_open(obj_hdl, op_ctx, posix_flags, &my_fd->fd, false);
	if (FSAL_IS_ERROR(status) == false)
		my_fd->openflags = openflags;

	LogFullDebug(COMPONENT_FSAL, "new fd %d", my_fd->fd);

	return status;
}
Ejemplo n.º 5
0
/**
 * @brief Open a file descriptor for read or write and possibly create
 *
 * This function opens a file for read or write, possibly creating it.
 * If the caller is passing a state, it must hold the state_lock
 * exclusive.
 *
 * state can be NULL which indicates a stateless open (such as via the
 * NFS v3 CREATE operation), in which case the FSAL must assure protection
 * of any resources. If the file is being created, such protection is
 * simple since no one else will have access to the object yet, however,
 * in the case of an exclusive create, the common resources may still need
 * protection.
 *
 * If Name is NULL, obj_hdl is the file itself, otherwise obj_hdl is the
 * parent directory.
 *
 * On an exclusive create, the upper layer may know the object handle
 * already, so it MAY call with name == NULL. In this case, the caller
 * expects just to check the verifier.
 *
 * On a call with an existing object handle for an UNCHECKED create,
 * we can set the size to 0.
 *
 * At least the mode attribute must be set if createmode is not FSAL_NO_CREATE.
 * Some FSALs may still have to pass a mode on a create call for exclusive,
 * and even with FSAL_NO_CREATE, and empty set of attributes MUST be passed.
 *
 * If an open by name succeeds and did not result in Ganesha creating a file,
 * the caller will need to do a subsequent permission check to confirm the
 * open. This is because the permission attributes were not available
 * beforehand.
 *
 * @param[in] obj_hdl               File to open or parent directory
 * @param[in,out] state             state_t to use for this operation
 * @param[in] openflags             Mode for open
 * @param[in] createmode            Mode for create
 * @param[in] name                  Name for file if being created or opened
 * @param[in] attrib_set            Attributes to set on created file
 * @param[in] verifier              Verifier to use for exclusive create
 * @param[in,out] new_obj           Newly created object
 * @param[in,out] attrs_out         Newly created object attributes
 * @param[in,out] caller_perm_check The caller must do a permission check
 *
 * @return FSAL status.
 */
fsal_status_t gpfs_open2(struct fsal_obj_handle *obj_hdl,
			 struct state_t *state,
			 fsal_openflags_t openflags,
			 enum fsal_create_mode createmode,
			 const char *name,
			 struct attrlist *attrib_set,
			 fsal_verifier_t verifier,
			 struct fsal_obj_handle **new_obj,
			 struct attrlist *attrs_out,
			 bool *caller_perm_check)
{
	int posix_flags = 0;
	mode_t unix_mode;
	fsal_status_t status = {0, 0};
	struct gpfs_fd *my_fd = NULL;
	struct gpfs_fsal_obj_handle *myself;
	struct gpfs_fsal_obj_handle *hdl = NULL;
	struct gpfs_file_handle fh;
	bool truncated;
	bool created = false;
	struct fsal_export *export = op_ctx->fsal_export;
	struct gpfs_filesystem *gpfs_fs = obj_hdl->fs->private_data;
	int *fd = NULL;

	myself = container_of(obj_hdl, struct gpfs_fsal_obj_handle, obj_handle);

	if (name)
		LogFullDebug(COMPONENT_FSAL, "got name %s", name);
	else
		LogFullDebug(COMPONENT_FSAL, "no name");

	LogAttrlist(COMPONENT_FSAL, NIV_FULL_DEBUG,
		    "attrs ", attrib_set, false);

	if (state != NULL)
		my_fd = (struct gpfs_fd *)(state + 1);

	fsal2posix_openflags(openflags, &posix_flags);

	truncated = (posix_flags & O_TRUNC) != 0;

	if (createmode >= FSAL_EXCLUSIVE) {
		/* Now fixup attrs for verifier if exclusive create */
		set_common_verifier(attrib_set, verifier);
	}

	if (name == NULL) {
		/* This is an open by handle */
		if (state != NULL) {
		       /* Prepare to take the share reservation, but only if we
			* are called with a valid state (if state is NULL the
			* caller is a stateless create such as NFS v3 CREATE).
			*/

			/* This can block over an I/O operation. */
			PTHREAD_RWLOCK_wrlock(&obj_hdl->lock);

			/* Check share reservation conflicts. */
			status = check_share_conflict(&myself->u.file.share,
						      openflags,
						      false);

			if (FSAL_IS_ERROR(status)) {
				PTHREAD_RWLOCK_unlock(&obj_hdl->lock);
				return status;
			}

			/* Take the share reservation now by updating the
			 * counters.
			 */
			update_share_counters(&myself->u.file.share,
					      FSAL_O_CLOSED,
					      openflags);

			PTHREAD_RWLOCK_unlock(&obj_hdl->lock);

			fd = &my_fd->fd;
			my_fd->openflags = openflags;
		} else {
			/* We need to use the global fd to continue, and take
			 * the lock to protect it.
			 */
			fd = &myself->u.file.fd.fd;
			myself->u.file.fd.openflags = openflags;
			PTHREAD_RWLOCK_wrlock(&obj_hdl->lock);
		}
		status = GPFSFSAL_open(obj_hdl, op_ctx, posix_flags, fd, false);
		if (FSAL_IS_ERROR(status)) {
			if (state == NULL) {
				/* Release the lock taken above, and return
				 * since there is nothing to undo.
				 */
				PTHREAD_RWLOCK_unlock(&obj_hdl->lock);
				return status;
			}
			/* Error - need to release the share */
			goto undo_share;
		}
		if (attrs_out && (createmode >= FSAL_EXCLUSIVE || truncated)) {
			/* Refresh the attributes */
			status = GPFSFSAL_getattrs(export, gpfs_fs, op_ctx,
						   myself->handle, attrs_out);
			if (!FSAL_IS_ERROR(status)) {
				LogFullDebug(COMPONENT_FSAL,
					     "New size = %"PRIx64,
					     attrs_out->filesize);
			}
			/* Now check verifier for exclusive, but not for
			 * FSAL_EXCLUSIVE_9P.
			 */
			if (!FSAL_IS_ERROR(status) &&
			    createmode >= FSAL_EXCLUSIVE &&
			    createmode != FSAL_EXCLUSIVE_9P &&
			    !check_verifier_attrlist(attrs_out, verifier)) {
				/* Verifier didn't match, return EEXIST */
				status =
				    fsalstat(posix2fsal_error(EEXIST), EEXIST);
			}
		}
		if (state == NULL) {
			/* If no state, release the lock taken above and return
			 * status.
			 */
			PTHREAD_RWLOCK_unlock(&obj_hdl->lock);
			return status;
		}
		if (!FSAL_IS_ERROR(status)) {
			/* Return success. */
			return status;
		}
		(void) fsal_internal_close(*fd, state->state_owner, 0);

 undo_share:

		/* Can only get here with state not NULL and an error */

		/* On error we need to release our share reservation
		 * and undo the update of the share counters.
		 * This can block over an I/O operation.
		 */
		PTHREAD_RWLOCK_wrlock(&obj_hdl->lock);

		update_share_counters(&myself->u.file.share,
				      openflags,
				      FSAL_O_CLOSED);

		PTHREAD_RWLOCK_unlock(&obj_hdl->lock);

		return status;
	}