Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ee3b8d37 authored by Martin Brandenburg's avatar Martin Brandenburg Committed by Mike Marshall
Browse files

orangefs: free readdir buffer index before the dir_emit loop



We only need it while the service operation is actually in progress
since it is only used to co-ordinate the client-core's memory use. The
kernel allocates its own space.

Also clean up some comments which mislead the reader into thinking
the readdir buffers are shared memory.

Signed-off-by: default avatarMartin Brandenburg <martin@omnibond.com>
Signed-off-by: default avatarMike Marshall <hubcap@omnibond.com>
parent adcf34a2
Loading
Loading
Loading
Loading
+9 −25
Original line number Original line Diff line number Diff line
@@ -9,7 +9,6 @@
#include "orangefs-bufmap.h"
#include "orangefs-bufmap.h"


struct readdir_handle_s {
struct readdir_handle_s {
	int buffer_index;
	struct orangefs_readdir_response_s readdir_response;
	struct orangefs_readdir_response_s readdir_response;
	void *dents_buf;
	void *dents_buf;
};
};
@@ -143,7 +142,7 @@ static long decode_dirents(char *ptr, size_t size,
}
}


static long readdir_handle_ctor(struct readdir_handle_s *rhandle, void *buf,
static long readdir_handle_ctor(struct readdir_handle_s *rhandle, void *buf,
				size_t size, int buffer_index)
				size_t size)
{
{
	long ret;
	long ret;


@@ -152,17 +151,10 @@ static long readdir_handle_ctor(struct readdir_handle_s *rhandle, void *buf,
		    ("Invalid NULL buffer specified in readdir_handle_ctor\n");
		    ("Invalid NULL buffer specified in readdir_handle_ctor\n");
		return -ENOMEM;
		return -ENOMEM;
	}
	}
	if (buffer_index < 0) {
		gossip_err
		    ("Invalid buffer index specified in readdir_handle_ctor\n");
		return -EINVAL;
	}
	rhandle->buffer_index = buffer_index;
	rhandle->dents_buf = buf;
	rhandle->dents_buf = buf;
	ret = decode_dirents(buf, size, &rhandle->readdir_response);
	ret = decode_dirents(buf, size, &rhandle->readdir_response);
	if (ret < 0) {
	if (ret < 0) {
		gossip_err("Could not decode readdir from buffer %ld\n", ret);
		gossip_err("Could not decode readdir from buffer %ld\n", ret);
		rhandle->buffer_index = -1;
		gossip_debug(GOSSIP_DIR_DEBUG, "vfree %p\n", buf);
		gossip_debug(GOSSIP_DIR_DEBUG, "vfree %p\n", buf);
		vfree(buf);
		vfree(buf);
		rhandle->dents_buf = NULL;
		rhandle->dents_buf = NULL;
@@ -179,10 +171,6 @@ static void readdir_handle_dtor(struct readdir_handle_s *rhandle)
	kfree(rhandle->readdir_response.dirent_array);
	kfree(rhandle->readdir_response.dirent_array);
	rhandle->readdir_response.dirent_array = NULL;
	rhandle->readdir_response.dirent_array = NULL;


	if (rhandle->buffer_index >= 0) {
		orangefs_readdir_index_put(rhandle->buffer_index);
		rhandle->buffer_index = -1;
	}
	if (rhandle->dents_buf) {
	if (rhandle->dents_buf) {
		gossip_debug(GOSSIP_DIR_DEBUG, "vfree %p\n",
		gossip_debug(GOSSIP_DIR_DEBUG, "vfree %p\n",
			     rhandle->dents_buf);
			     rhandle->dents_buf);
@@ -236,7 +224,6 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx)
		     "orangefs_readdir called on %s (pos=%llu)\n",
		     "orangefs_readdir called on %s (pos=%llu)\n",
		     dentry->d_name.name, llu(pos));
		     dentry->d_name.name, llu(pos));


	rhandle.buffer_index = -1;
	rhandle.dents_buf = NULL;
	rhandle.dents_buf = NULL;
	memset(&rhandle.readdir_response, 0, sizeof(rhandle.readdir_response));
	memset(&rhandle.readdir_response, 0, sizeof(rhandle.readdir_response));


@@ -244,6 +231,10 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx)
	if (!new_op)
	if (!new_op)
		return -ENOMEM;
		return -ENOMEM;


	/*
	 * Only the indices are shared. No memory is actually shared, but the
	 * mechanism is used.
	 */
	new_op->uses_shared_memory = 1;
	new_op->uses_shared_memory = 1;
	new_op->upcall.req.readdir.refn = orangefs_inode->refn;
	new_op->upcall.req.readdir.refn = orangefs_inode->refn;
	new_op->upcall.req.readdir.max_dirent_count =
	new_op->upcall.req.readdir.max_dirent_count =
@@ -274,23 +265,19 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx)
		     new_op->downcall.status,
		     new_op->downcall.status,
		     ret);
		     ret);


	orangefs_readdir_index_put(buffer_index);

	if (ret == -EAGAIN && op_state_purged(new_op)) {
	if (ret == -EAGAIN && op_state_purged(new_op)) {
		/*
		/* Client-core indices are invalid after it restarted. */
		 * readdir shared memory aread has been wiped due to
		 * pvfs2-client-core restarting, so we must get a new
		 * index into the shared memory.
		 */
		gossip_debug(GOSSIP_DIR_DEBUG,
		gossip_debug(GOSSIP_DIR_DEBUG,
			"%s: Getting new buffer_index for retry of readdir..\n",
			"%s: Getting new buffer_index for retry of readdir..\n",
			 __func__);
			 __func__);
		orangefs_readdir_index_put(buffer_index);
		goto get_new_buffer_index;
		goto get_new_buffer_index;
	}
	}


	if (ret == -EIO && op_state_purged(new_op)) {
	if (ret == -EIO && op_state_purged(new_op)) {
		gossip_err("%s: Client is down. Aborting readdir call.\n",
		gossip_err("%s: Client is down. Aborting readdir call.\n",
			__func__);
			__func__);
		orangefs_readdir_index_put(buffer_index);
		goto out_free_op;
		goto out_free_op;
	}
	}


@@ -298,7 +285,6 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx)
		gossip_debug(GOSSIP_DIR_DEBUG,
		gossip_debug(GOSSIP_DIR_DEBUG,
			     "Readdir request failed.  Status:%d\n",
			     "Readdir request failed.  Status:%d\n",
			     new_op->downcall.status);
			     new_op->downcall.status);
		orangefs_readdir_index_put(buffer_index);
		if (ret >= 0)
		if (ret >= 0)
			ret = new_op->downcall.status;
			ret = new_op->downcall.status;
		goto out_free_op;
		goto out_free_op;
@@ -307,13 +293,11 @@ static int orangefs_readdir(struct file *file, struct dir_context *ctx)
	bytes_decoded =
	bytes_decoded =
		readdir_handle_ctor(&rhandle,
		readdir_handle_ctor(&rhandle,
				    new_op->downcall.trailer_buf,
				    new_op->downcall.trailer_buf,
				    new_op->downcall.trailer_size,
				    new_op->downcall.trailer_size);
				    buffer_index);
	if (bytes_decoded < 0) {
	if (bytes_decoded < 0) {
		gossip_err("orangefs_readdir: Could not decode trailer buffer into a readdir response %d\n",
		gossip_err("orangefs_readdir: Could not decode trailer buffer into a readdir response %d\n",
			ret);
			ret);
		ret = bytes_decoded;
		ret = bytes_decoded;
		orangefs_readdir_index_put(buffer_index);
		goto out_free_op;
		goto out_free_op;
	}
	}