コード例 #1
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t lookup(struct fsal_obj_handle *parent,
			    const struct req_op_context *opctx,
			    const char *path, struct fsal_obj_handle **handle)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct stat sb;
	struct glfs_object *glhandle = NULL;
	unsigned char globjhdl[GLAPI_HANDLE_LENGTH];
	struct glusterfs_handle *objhandle = NULL;
	struct glusterfs_export *glfs_export =
	    container_of(parent->export, struct glusterfs_export, export);
	struct glusterfs_handle *parenthandle =
	    container_of(parent, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	glhandle =
	    glfs_h_lookupat(glfs_export->gl_fs, parenthandle->glhandle, path,
			    &sb);
	if (glhandle == NULL) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	rc = glfs_h_extract_handle(glhandle, globjhdl, GLAPI_HANDLE_LENGTH);
	if (rc < 0) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	rc = construct_handle(glfs_export, &sb, glhandle, globjhdl,
			      GLAPI_HANDLE_LENGTH, &objhandle);
	if (rc != 0) {
		status = gluster2fsal_error(rc);
		goto out;
	}

	*handle = &objhandle->handle;

 out:
	if (status.major != ERR_FSAL_NO_ERROR) {
		gluster_cleanup_vars(glhandle);
	}
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_lookup);
#endif

	return status;
}
コード例 #2
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t renamefile(struct fsal_obj_handle *olddir_hdl,
				const struct req_op_context *opctx,
				const char *old_name,
				struct fsal_obj_handle *newdir_hdl,
				const char *new_name)
{
	int rc = 0, credrc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct glusterfs_export *glfs_export =
	    container_of(olddir_hdl->export, struct glusterfs_export, export);
	struct glusterfs_handle *srcparenthandle =
	    container_of(olddir_hdl, struct glusterfs_handle, handle);
	struct glusterfs_handle *dstparenthandle =
	    container_of(newdir_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	credrc =
	    setglustercreds(glfs_export, &opctx->creds->caller_uid,
			    &opctx->creds->caller_gid,
			    opctx->creds->caller_glen,
			    opctx->creds->caller_garray);
	if (credrc != 0) {
		status = gluster2fsal_error(EPERM);
		LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials");
		goto out;
	}

	rc = glfs_h_rename(glfs_export->gl_fs, srcparenthandle->glhandle,
			   old_name, dstparenthandle->glhandle, new_name);

	credrc = setglustercreds(glfs_export, NULL, NULL, 0, NULL);
	if (credrc != 0) {
		status = gluster2fsal_error(EPERM);
		LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials");
		goto out;
	}

	if (rc != 0) {
		status = gluster2fsal_error(errno);
		goto out;
	}

 out:
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_renamefile);
#endif

	return status;
}
コード例 #3
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t file_close(struct fsal_obj_handle *obj_hdl)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct glusterfs_handle *objhandle =
	    container_of(obj_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	rc = glfs_close(objhandle->glfd);
	if (rc != 0) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	objhandle->glfd = NULL;
	objhandle->openflags = FSAL_O_CLOSED;

 out:
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_file_close);
#endif
	return status;
}
コード例 #4
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t file_write(struct fsal_obj_handle *obj_hdl,
				const struct req_op_context *opctx,
				uint64_t seek_descriptor, size_t buffer_size,
				void *buffer, size_t * write_amount,
				bool * fsal_stable)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct glusterfs_handle *objhandle =
	    container_of(obj_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	rc = glfs_pwrite(objhandle->glfd, buffer, buffer_size, seek_descriptor,
			 ((*fsal_stable) ? O_SYNC : 0));
	if (rc < 0) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	*write_amount = rc;
	if (objhandle->openflags & FSAL_O_SYNC)
		*fsal_stable = true;

 out:
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_file_write);
#endif
	return status;
}
コード例 #5
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t readsymlink(struct fsal_obj_handle *obj_hdl,
				 const struct req_op_context *opctx,
				 struct gsh_buffdesc *link_content,
				 bool refresh)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct glusterfs_export *glfs_export =
	    container_of(obj_hdl->export, struct glusterfs_export, export);
	struct glusterfs_handle *objhandle =
	    container_of(obj_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	link_content->len = 1024;	// bad bad!!! need to determine size
	link_content->addr = gsh_malloc(link_content->len);
	if (link_content->addr == NULL) {
		status = gluster2fsal_error(rc);
		goto out;
	}

	rc = glfs_h_readlink(glfs_export->gl_fs, objhandle->glhandle,
			     link_content->addr, link_content->len);
	if (rc < 0) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	/* Check if return buffer overflowed, it is still '\0' terminated */
	link_content->len = (strlen(link_content->addr) + 1);

 out:
	if (status.major != ERR_FSAL_NO_ERROR) {
		gsh_free(link_content->addr);
		link_content->addr = NULL;
		link_content->len = 0;
	}
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_readsymlink);
#endif

	return status;
}
コード例 #6
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t handle_release(struct fsal_obj_handle *obj_hdl)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct glusterfs_handle *objhandle =
	    container_of(obj_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	rc = fsal_obj_handle_uninit(&objhandle->handle);
	if (rc != 0) {
		status = gluster2fsal_error(rc);
		goto out;
	}

	if (objhandle->glfd) {
		rc = glfs_close(objhandle->glfd);
		if (rc) {
			status = gluster2fsal_error(errno);
			/* cleanup as much as possible */
		}
	}

	if (objhandle->glhandle) {
		rc = glfs_h_close(objhandle->glhandle);
		if (rc) {
			status = gluster2fsal_error(errno);
			goto out;
		}
	}

	gsh_free(objhandle);

 out:
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_handle_release);
#endif

	return status;
}
コード例 #7
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t getattrs(struct fsal_obj_handle *obj_hdl,
			      const struct req_op_context *opctx)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct stat sb;
	struct glusterfs_export *glfs_export =
	    container_of(obj_hdl->export, struct glusterfs_export, export);
	struct glusterfs_handle *objhandle =
	    container_of(obj_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	/* FIXME: Should we hold the fd so that any async op does
	 * not close it */
	if (objhandle->openflags != FSAL_O_CLOSED) {
		rc = glfs_fstat(objhandle->glfd, &sb);
	} else {
		rc = glfs_h_stat(glfs_export->gl_fs, objhandle->glhandle, &sb);
	}

	if (rc != 0) {
		if (errno == ENOENT)
			status = gluster2fsal_error(ESTALE);
		else
			status = gluster2fsal_error(errno);

		goto out;
	}

	stat2fsal_attributes(&sb, &objhandle->handle.attributes);

 out:
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_getattrs);
#endif

	return status;
}
コード例 #8
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t file_open(struct fsal_obj_handle *obj_hdl,
			       const struct req_op_context *opctx,
			       fsal_openflags_t openflags)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct glfs_fd *glfd = NULL;
	int p_flags = 0;
	struct glusterfs_export *glfs_export =
	    container_of(obj_hdl->export, struct glusterfs_export, export);
	struct glusterfs_handle *objhandle =
	    container_of(obj_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	if (objhandle->openflags != FSAL_O_CLOSED) {
		return fsalstat(ERR_FSAL_SERVERFAULT, 0);
	}

	rc = fsal2posix_openflags(openflags, &p_flags);
	if (rc != 0) {
		status.major = rc;
		goto out;
	}

	glfd = glfs_h_open(glfs_export->gl_fs, objhandle->glhandle, p_flags);
	if (glfd == NULL) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	objhandle->openflags = openflags;
	objhandle->glfd = glfd;

 out:
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_file_open);
#endif
	return status;
}
コード例 #9
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t file_read(struct fsal_obj_handle *obj_hdl,
			       const struct req_op_context *opctx,
			       uint64_t seek_descriptor, size_t buffer_size,
			       void *buffer, size_t * read_amount,
			       bool * end_of_file)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct glusterfs_handle *objhandle =
	    container_of(obj_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	rc = glfs_pread(objhandle->glfd, buffer, buffer_size, seek_descriptor,
			0 /*TODO: flags is unused, so pass in something */ );
	if (rc < 0) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	if (rc < buffer_size) {
		*end_of_file = true;
	}

	*read_amount = rc;

 out:
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_file_read);
#endif
	return status;
}
コード例 #10
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t commit(struct fsal_obj_handle *obj_hdl,	/* sync */
			    off_t offset, size_t len)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct glusterfs_handle *objhandle =
	    container_of(obj_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	/* TODO: Everybody pretty much ignores the range sent */
	rc = glfs_fsync(objhandle->glfd);
	if (rc < 0) {
		status = gluster2fsal_error(errno);
	}
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_commit);
#endif
	return status;
}
コード例 #11
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t setattrs(struct fsal_obj_handle *obj_hdl,
			      const struct req_op_context *opctx,
			      struct attrlist *attrs)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct stat sb;
	int mask = 0;
	struct glusterfs_export *glfs_export =
	    container_of(obj_hdl->export, struct glusterfs_export, export);
	struct glusterfs_handle *objhandle =
	    container_of(obj_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	memset(&sb, 0, sizeof(struct stat));

	if (FSAL_TEST_MASK(attrs->mask, ATTR_SIZE)) {
		rc = glfs_h_truncate(glfs_export->gl_fs, objhandle->glhandle,
				     attrs->filesize);
		if (rc != 0) {
			status = gluster2fsal_error(errno);
			goto out;
		}
	}

	if (FSAL_TEST_MASK(attrs->mask, ATTR_MODE)) {
		mask |= GLAPI_SET_ATTR_MODE;
		sb.st_mode = fsal2unix_mode(attrs->mode);
	}

	if (FSAL_TEST_MASK(attrs->mask, ATTR_OWNER)) {
		mask |= GLAPI_SET_ATTR_UID;
		sb.st_uid = attrs->owner;
	}

	if (FSAL_TEST_MASK(attrs->mask, ATTR_GROUP)) {
		mask |= GLAPI_SET_ATTR_GID;
		sb.st_gid = attrs->group;
	}

	if (FSAL_TEST_MASK(attrs->mask, ATTR_ATIME)) {
		mask |= GLAPI_SET_ATTR_ATIME;
		sb.st_atim = attrs->atime;
	}

	if (FSAL_TEST_MASK(attrs->mask, ATTR_ATIME_SERVER)) {
		mask |= GLAPI_SET_ATTR_ATIME;
		struct timespec timestamp;

		rc = clock_gettime(CLOCK_REALTIME, &timestamp);
		if (rc != 0) {
			status = gluster2fsal_error(errno);
			goto out;
		}
		sb.st_atim = timestamp;
	}

	if (FSAL_TEST_MASK(attrs->mask, ATTR_MTIME)) {
		mask |= GLAPI_SET_ATTR_MTIME;
		sb.st_mtim = attrs->mtime;
	}
	if (FSAL_TEST_MASK(attrs->mask, ATTR_MTIME_SERVER)) {
		mask |= GLAPI_SET_ATTR_MTIME;
		struct timespec timestamp;

		rc = clock_gettime(CLOCK_REALTIME, &timestamp);
		if (rc != 0) {
			status = gluster2fsal_error(rc);
			goto out;
		}
		sb.st_mtim = timestamp;
	}

	rc = glfs_h_setattrs(glfs_export->gl_fs, objhandle->glhandle, &sb,
			     mask);
	if (rc != 0) {
		status = gluster2fsal_error(errno);
		goto out;
	}

 out:
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_setattrs);
#endif
	return status;
}
コード例 #12
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t makesymlink(struct fsal_obj_handle *dir_hdl,
				 const struct req_op_context *opctx,
				 const char *name, const char *link_path,
				 struct attrlist *attrib,
				 struct fsal_obj_handle **handle)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct stat sb;
	struct glfs_object *glhandle = NULL;
	unsigned char globjhdl[GLAPI_HANDLE_LENGTH];
	struct glusterfs_handle *objhandle = NULL;
	struct glusterfs_export *glfs_export =
	    container_of(dir_hdl->export, struct glusterfs_export, export);
	struct glusterfs_handle *parenthandle =
	    container_of(dir_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	rc = setglustercreds(glfs_export, &opctx->creds->caller_uid,
			     &opctx->creds->caller_gid,
			     opctx->creds->caller_glen,
			     opctx->creds->caller_garray);
	if (rc != 0) {
		status = gluster2fsal_error(EPERM);
		LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials");
		goto out;
	}

	/* FIXME: what else from attrib should we use? */
	glhandle =
	    glfs_h_symlink(glfs_export->gl_fs, parenthandle->glhandle, name,
			   link_path, &sb);

	rc = setglustercreds(glfs_export, NULL, NULL, 0, NULL);
	if (rc != 0) {
		status = gluster2fsal_error(EPERM);
		LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials");
		goto out;
	}

	if (glhandle == NULL) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	rc = glfs_h_extract_handle(glhandle, globjhdl, GLAPI_HANDLE_LENGTH);
	if (rc < 0) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	rc = construct_handle(glfs_export, &sb, glhandle, globjhdl,
			      GLAPI_HANDLE_LENGTH, &objhandle);
	if (rc != 0) {
		status = gluster2fsal_error(rc);
		goto out;
	}

	*handle = &objhandle->handle;
	*attrib = objhandle->handle.attributes;

 out:
	if (status.major != ERR_FSAL_NO_ERROR) {
		gluster_cleanup_vars(glhandle);
	}
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_makesymlink);
#endif

	return status;
}
コード例 #13
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t makenode(struct fsal_obj_handle *dir_hdl,
			      const struct req_op_context *opctx,
			      const char *name, object_file_type_t nodetype,
			      fsal_dev_t * dev, struct attrlist *attrib,
			      struct fsal_obj_handle **handle)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct stat sb;
	struct glfs_object *glhandle = NULL;
	unsigned char globjhdl[GLAPI_HANDLE_LENGTH];
	struct glusterfs_handle *objhandle = NULL;
	dev_t ndev = { 0, };
	struct glusterfs_export *glfs_export =
	    container_of(dir_hdl->export, struct glusterfs_export, export);
	struct glusterfs_handle *parenthandle =
	    container_of(dir_hdl, struct glusterfs_handle, handle);
	mode_t create_mode;
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	switch (nodetype) {
	case BLOCK_FILE:
		if (!dev)
			return fsalstat(ERR_FSAL_INVAL, 0);
		/* FIXME: This needs a feature flag test? */
		ndev = makedev(dev->major, dev->minor);
		create_mode = S_IFBLK;
		break;
	case CHARACTER_FILE:
		if (!dev)
			return fsalstat(ERR_FSAL_INVAL, 0);
		ndev = makedev(dev->major, dev->minor);
		create_mode = S_IFCHR;
		break;
	case FIFO_FILE:
		create_mode = S_IFIFO;
		break;
	case SOCKET_FILE:
		create_mode = S_IFSOCK;
		break;
	default:
		LogMajor(COMPONENT_FSAL, "Invalid node type in FSAL_mknode: %d",
			 nodetype);
		return fsalstat(ERR_FSAL_INVAL, 0);
	}

	rc = setglustercreds(glfs_export, &opctx->creds->caller_uid,
			     &opctx->creds->caller_gid,
			     opctx->creds->caller_glen,
			     opctx->creds->caller_garray);
	if (rc != 0) {
		status = gluster2fsal_error(EPERM);
		LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials");
		goto out;
	}

	/* FIXME: what else from attrib should we use? */
	glhandle =
	    glfs_h_mknod(glfs_export->gl_fs, parenthandle->glhandle, name,
			 create_mode | fsal2unix_mode(attrib->mode), ndev, &sb);

	rc = setglustercreds(glfs_export, NULL, NULL, 0, NULL);
	if (rc != 0) {
		status = gluster2fsal_error(EPERM);
		LogFatal(COMPONENT_FSAL, "Could not set Ganesha credentials");
		goto out;
	}

	if (glhandle == NULL) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	rc = glfs_h_extract_handle(glhandle, globjhdl, GLAPI_HANDLE_LENGTH);
	if (rc < 0) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	rc = construct_handle(glfs_export, &sb, glhandle, globjhdl,
			      GLAPI_HANDLE_LENGTH, &objhandle);
	if (rc != 0) {
		status = gluster2fsal_error(rc);
		goto out;
	}

	*handle = &objhandle->handle;
	*attrib = objhandle->handle.attributes;

 out:
	if (status.major != ERR_FSAL_NO_ERROR) {
		gluster_cleanup_vars(glhandle);
	}
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_makenode);
#endif
	return status;
}
コード例 #14
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t read_dirents(struct fsal_obj_handle *dir_hdl,
				  const struct req_op_context *opctx,
				  fsal_cookie_t * whence, void *dir_state,
				  fsal_readdir_cb cb, bool * eof)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct glfs_fd *glfd = NULL;
	long offset = 0;
	struct dirent *pde = NULL;
	struct glusterfs_export *glfs_export =
	    container_of(dir_hdl->export, struct glusterfs_export, export);
	struct glusterfs_handle *objhandle =
	    container_of(dir_hdl, struct glusterfs_handle, handle);
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	glfd = glfs_h_opendir(glfs_export->gl_fs, objhandle->glhandle);
	if (glfd == NULL) {
		return gluster2fsal_error(errno);
	}

	if (whence != NULL) {
		offset = *whence;
	}

	glfs_seekdir(glfd, offset);

	while (!(*eof)) {
		struct dirent de;

		rc = glfs_readdir_r(glfd, &de, &pde);
		if (rc == 0 && pde != NULL) {
			/* skip . and .. */
			if ((strcmp(de.d_name, ".") == 0)
			    || (strcmp(de.d_name, "..") == 0)) {
				continue;
			}

			if (!cb
			    (opctx, de.d_name, dir_state, glfs_telldir(glfd))) {
				goto out;
			}
		} else if (rc == 0 && pde == NULL) {
			*eof = true;
		} else if (rc != 0) {
			status = gluster2fsal_error(errno);
			goto out;
		} else {
			/* Can't happen */
			abort();
		}
	}

 out:
	rc = glfs_closedir(glfd);
	if (rc < 0) {
		status = gluster2fsal_error(errno);
	}
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_read_dirents);
#endif
	return status;
}
コード例 #15
0
ファイル: handle.c プロジェクト: asias/nfs-ganesha
static fsal_status_t lock_op(struct fsal_obj_handle *obj_hdl,
			     const struct req_op_context *opctx,
			     void * p_owner,
			     fsal_lock_op_t lock_op,
			     fsal_lock_param_t *request_lock,
			     fsal_lock_param_t *conflicting_lock)
{
	int rc = 0;
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	struct glusterfs_handle *objhandle =
	    container_of(obj_hdl, struct glusterfs_handle, handle);
	struct flock flock;
	int cmd;
	int saverrno = 0;
#ifdef GLTIMING
	struct timespec s_time, e_time;

	now(&s_time);
#endif

	if (objhandle->openflags == FSAL_O_CLOSED) {
		LogDebug(COMPONENT_FSAL,
			 "ERROR: Attempting to lock with no file descriptor open");
		status.major = ERR_FSAL_FAULT;
		goto out;
	}

	if (lock_op == FSAL_OP_LOCKT) {
		cmd = F_GETLK;
	} else if (lock_op == FSAL_OP_LOCK || lock_op == FSAL_OP_UNLOCK) {
		cmd = F_SETLK;
	} else {
		LogDebug(COMPONENT_FSAL,
			 "ERROR: Unsupported lock operation %d\n", lock_op);
		status.major = ERR_FSAL_NOTSUPP;
		goto out;
	}

	if (request_lock->lock_type == FSAL_LOCK_R) {
		flock.l_type = F_RDLCK;
	} else if (request_lock->lock_type == FSAL_LOCK_W) {
		flock.l_type = F_WRLCK;
	} else {
		LogDebug(COMPONENT_FSAL,
			 "ERROR: The requested lock type was not read or write.");
		status.major = ERR_FSAL_NOTSUPP;
		goto out;
	}

	/* TODO: Override R/W and just provide U? */
	if (lock_op == FSAL_OP_UNLOCK)
		flock.l_type = F_UNLCK;

	flock.l_len = request_lock->lock_length;
	flock.l_start = request_lock->lock_start;
	flock.l_whence = SEEK_SET;

	rc = glfs_posix_lock (objhandle->glfd, cmd, &flock);
	if (rc != 0 && lock_op == FSAL_OP_LOCK
	    && conflicting_lock && (errno == EACCES || errno == EAGAIN)) {
		/* process conflicting lock */
		saverrno = errno;
		cmd = F_GETLK;
		rc = glfs_posix_lock (objhandle->glfd, cmd, &flock);
		if (rc) {
			LogCrit(COMPONENT_FSAL,
				"Failed to get conflicting lock post lock"
				" failure");
			status = gluster2fsal_error(errno);
			goto out;
		}

		conflicting_lock->lock_length = flock.l_len;
		conflicting_lock->lock_start = flock.l_start;
		conflicting_lock->lock_type = flock.l_type;

		status = gluster2fsal_error(saverrno);
		goto out;
	} else if (rc != 0) {
		status = gluster2fsal_error(errno);
		goto out;
	}

	if (conflicting_lock != NULL) {
		if (lock_op == FSAL_OP_LOCKT && flock.l_type != F_UNLCK) {
			conflicting_lock->lock_length = flock.l_len;
			conflicting_lock->lock_start = flock.l_start;
			conflicting_lock->lock_type = flock.l_type;
		} else {
			conflicting_lock->lock_length = 0;
			conflicting_lock->lock_start = 0;
			conflicting_lock->lock_type = FSAL_NO_LOCK;
		}
	}

 out:
#ifdef GLTIMING
	now(&e_time);
	latency_update(&s_time, &e_time, lat_lock_op);
#endif
	return status;
}
コード例 #16
0
/*
 * Read the ACL in GlusterFS format and convert it into fsal ACL before
 * storing it in fsalattr
 */
fsal_status_t glusterfs_get_acl(struct glusterfs_export *glfs_export,
				struct glfs_object *glhandle,
				glusterfs_fsal_xstat_t *buffxstat,
				struct attrlist *fsalattr)
{
	fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 };
	fsal_acl_data_t acldata;
	fsal_acl_status_t aclstatus;
	fsal_ace_t *pace = NULL;
	int e_count = 0, i_count = 0, new_count = 0, new_i_count = 0;

	if (fsalattr->acl != NULL) {
		/* We should never be passed attributes that have an
		 * ACL attached, but just in case some future code
		 * path changes that assumption, let's release the
		 * old ACL properly.
		 */
		int acl_status;

		acl_status = nfs4_acl_release_entry(fsalattr->acl);

		if (acl_status != NFS_V4_ACL_SUCCESS)
			LogCrit(COMPONENT_FSAL,
				"Failed to release old acl, status=%d",
				acl_status);

		fsalattr->acl = NULL;
	}

	if (NFSv4_ACL_SUPPORT) {

		buffxstat->e_acl = glfs_h_acl_get(glfs_export->gl_fs->fs,
						glhandle, ACL_TYPE_ACCESS);

		if (!buffxstat->e_acl) {
			status = gluster2fsal_error(errno);
			return status;
		}

		e_count = ace_count(buffxstat->e_acl);

		if (buffxstat->is_dir) {
			buffxstat->i_acl =
					 glfs_h_acl_get(glfs_export->gl_fs->fs,
						glhandle, ACL_TYPE_DEFAULT);
			i_count = ace_count(buffxstat->i_acl);
		}

		/* Allocating memory for both ALLOW and DENY entries */
		acldata.naces = 2 * (e_count  + i_count);

		LogDebug(COMPONENT_FSAL, "No of aces present in fsal_acl_t = %d"
					, acldata.naces);
		if (!acldata.naces)
			return status;

		FSAL_SET_MASK(buffxstat->attr_valid, XATTR_ACL);

		acldata.aces = (fsal_ace_t *) nfs4_ace_alloc(acldata.naces);
		pace = acldata.aces;

		new_count = posix_acl_2_fsal_acl(buffxstat->e_acl,
					buffxstat->is_dir, false, &pace);
		if (new_count < 0)
			return fsalstat(ERR_FSAL_NO_ACE, -1);

		if (i_count > 0) {
			new_i_count = posix_acl_2_fsal_acl(buffxstat->i_acl,
							true, true, &pace);
			if (new_i_count > 0)
				new_count += new_i_count;
			else
				LogDebug(COMPONENT_FSAL,
				"Inherit acl is not set for this directory");
		}

		/* Reallocating acldata into the required size */
		acldata.aces = (fsal_ace_t *) gsh_realloc(acldata.aces,
				new_count*sizeof(fsal_ace_t));
		acldata.naces = new_count;

		fsalattr->acl = nfs4_acl_new_entry(&acldata, &aclstatus);
		LogDebug(COMPONENT_FSAL, "fsal acl = %p, fsal_acl_status = %u",
				fsalattr->acl, aclstatus);
		if (fsalattr->acl == NULL) {
			LogCrit(COMPONENT_FSAL,
			"failed to create a new acl entry");
			return fsalstat(ERR_FSAL_NOMEM, -1);
		}

		fsalattr->valid_mask |= ATTR_ACL;
	} else {
		/* We were asked for ACL but do not support. */
		status = fsalstat(ERR_FSAL_NOTSUPP, 0);
	}

	return status;

}