Alien-Libjio

 view release on metacpan or  search on metacpan

libjio/bindings/preload/libjio_preload.c  view on Meta::CPAN

	fd_table[fd].fd = fd;
	fd_table[fd].refcount = malloc(sizeof(unsigned int));
	*fd_table[fd].refcount = 1;
	fd_table[fd].fs = fs;
	fd_unlock(fd);

	printd("return %d\n", fd);
	return fd;
}

/* close() is split in two functions: unlocked_close() that performs the real
 * actual close and cleanup, and close() which takes care of the locking and
 * calls unlocked_close(); this is because in dup*() we need to close with
 * locks already held to avoid races. */
int unlocked_close(int fd)
{
	int r;

	if (*fd_table[fd].refcount > 1) {
		/* we still have references, don't really close */
		printd("not closing, refcount: %d\n", *fd_table[fd].refcount);
		(*fd_table[fd].refcount)--;
		fd_table[fd].fd = -1;
		fd_table[fd].refcount = NULL;
		fd_table[fd].fs = NULL;

libjio/bindings/preload/libjio_preload.c  view on Meta::CPAN

		return -1;
	}
	fs = fd_table[fd].fs;
	if (fs == NULL) {
		printd("NULL fs, fd %d\n", fd);
		fd_unlock(fd);
		return (*c_close)(fd);
	}
	printd("libjio\n");

	r = unlocked_close(fd);
	fd_unlock(fd);

	printd("return %d\n", r);
	return r;
}


int unlink(const char *pathname)
{
	int r;

libjio/bindings/preload/libjio_preload.c  view on Meta::CPAN


	printd("libjio\n");

	rec_inc();
	r = (*c_dup2)(oldfd, newfd);
	rec_dec();

	if (r >= 0) {
		fd_lock(newfd);
		if (fd_table[newfd].fs != NULL) {
			unlocked_close(newfd);
		}
		fd_table[newfd].fd = newfd;
		fd_table[newfd].refcount = fd_table[oldfd].refcount;
		(*fd_table[newfd].refcount)++;
		fd_table[newfd].fs = fd_table[oldfd].fs;
		fd_unlock(newfd);
	}

	fd_unlock(oldfd);
	printd("return %d\n", r);

libjio/libjio/check.c  view on Meta::CPAN

		if (tfd < 0) {
			if (errno == ENOENT) {
				res->invalid++;
				goto nounlink_loop;
			} else {
				ret = J_EIO;
				goto exit;
			}
		}

		/* try to lock the transaction file, if it's locked then it is
		 * currently being used so we skip it */
		lr = plockf(tfd, F_TLOCKW, 0, 0);
		if (lr == -1) {
			res->in_progress++;
			goto loop;
		}

		filelen = lseek(tfd, 0, SEEK_END);
		if (filelen == 0) {
			res->broken++;

libjio/libjio/libjio.h  view on Meta::CPAN

 * @see jtrans_free()
 * @ingroup basic
 */
jtrans_t *jtrans_new(jfs_t *fs, unsigned int flags);

/** Add a write operation to a transaction.
 *
 * A write operation consists of a buffer, its length, and the offset to write
 * it to.
 *
 * The file will not be touched (not even locked) until commit time, where the
 * first count bytes of buf will be written at offset.
 *
 * Operations will be applied in order, and overlapping operations are
 * permitted, in which case the latest one will prevail.
 *
 * The buffer will be copied internally and can be free()d right after this
 * function returns.
 *
 * @param ts transaction
 * @param buf buffer to write

libjio/libjio/libjio.h  view on Meta::CPAN

 * @returns 0 on success, -1 on error
 * @ingroup basic
 */
int jtrans_add_w(jtrans_t *ts, const void *buf, size_t count, off_t offset);

/** Add a read operation to a transaction.
 *
 * An operation consists of a buffer, its length, and the offset to read it
 * from.
 *
 * The file will not be touched (not even locked) until commit time, where the
 * first count bytes at offset will be read into buf.
 *
 * Note that if there is not enough data in the file to read the specified
 * amount of bytes, the commit will fail, so do not attempt to read beyond EOF
 * (you can use jread() for that purpose).
 *
 * Operations will be applied in order, and overlapping operations are
 * permitted, in which case the latest one will prevail.
 *
 * In case of an error in jtrans_commit(), the contents of the buffer are

libjio/libjio/trans.c  view on Meta::CPAN

		for (op = start_op; op != NULL; op = op->next) {
			if (min_offset < op->offset)
				continue;
			min_offset = op->offset;
			start_op = op->next;

			if (mode == F_LOCKW) {
				lr = plockf(ts->fs->fd, F_LOCKW, op->offset, op->len);
				if (lr == -1)
					goto error;
				op->locked = 1;
			} else if (mode == F_UNLOCK && op->locked) {
				lr = plockf(ts->fs->fd, F_UNLOCK, op->offset,
						op->len);
				if (lr == -1)
					goto error;
				op->locked = 0;
			}
		}

		nops++;
	}

	return 0;

error:
	return -1;

libjio/libjio/trans.c  view on Meta::CPAN

		tmpop->next = op;
		op->prev = tmpop;
	}

	pthread_mutex_unlock(&(ts->lock));

	op->len = count;
	op->offset = offset;
	op->plen = 0;
	op->pdata = NULL;
	op->locked = 0;
	op->direction = direction;

	if (direction == D_WRITE) {
		memcpy(op->buf, buf, count);

		if (!(ts->flags & J_NOROLLBACK)) {
			/* jtrans_commit() will want to read the current data,
			 * so we tell the kernel about that */
			posix_fadvise(ts->fs->fd, offset, count,
					POSIX_FADV_WILLNEED);

libjio/libjio/trans.c  view on Meta::CPAN

			rv = -1;
			goto exit;
		}

		curop->offset = op->offset;
		curop->len = op->plen;
		curop->buf = op->pdata;
		curop->plen = op->plen;
		curop->pdata = op->pdata;
		curop->direction = op->direction;
		curop->locked = 0;

		newts->numops_w++;
		newts->len_w += curop->len;

		/* add the new transaction to the list */
		if (newts->op == NULL) {
			newts->op = curop;
			curop->prev = NULL;
			curop->next = NULL;
		} else {

libjio/libjio/trans.h  view on Meta::CPAN

};

/** Possible operation directions */
enum op_direction {
	D_READ = 1,
	D_WRITE = 2,
};

/** A single operation */
struct operation {
	/** Is the region locked? */
	int locked;

	/** Operation's offset */
	off_t offset;

	/** Data length, in bytes */
	size_t len;

	/** Data buffer */
	void *buf;

libjio/tests/stress/jiostress  view on Meta::CPAN

		# public
		self.start, self.end = randfrange(fsize, maxlen)
		self.new_data = None
		self.type = 'r'

		# private
		self.prev_data = None
		self.new_data_ctx = None
		self.read_buf = None
		self.lockmgr = lockmgr
		self.locked = False

		# read an extended range so we can check we
		# only wrote what we were supposed to
		self.ext_start = max(0, self.start - 32)
		self.ext_end = min(fsize, self.end + 32)

	def __lt__(self, other):
		return self.ext_start < other.ext_start

	def __del__(self):
		if self.locked:
			self.lockmgr.unlock(self.ext_start, self.ext_end)

	def overlaps(self, other):
		if (other.ext_start <= self.ext_start <= other.ext_end) or \
		   (other.ext_start <= self.ext_end <= other.ext_end) or \
		   (self.ext_start <= other.ext_start <= self.ext_end) or \
		   (self.ext_start <= other.ext_end <= self.ext_end):
			return True
		return False

	def prepare_r(self):
		self.type = 'r'
		self.read_buf = bytearray(self.end - self.start)
		self.lockmgr.lock(self.ext_start, self.ext_end)
		self.locked = True

	def verify_r(self, fd):
		real_data = pread(fd, self.start, self.end)
		if real_data != self.read_buf:
			print('Corruption detected')
			self.show(fd)
			raise ConsistencyError

	def prepare_w(self, fd):
		self.type = 'w'
		self.lockmgr.lock(self.ext_start, self.ext_end)
		self.locked = True

		self.prev_data = pread(fd, self.ext_start, self.ext_end)

		self.new_data = getbytes(self.end - self.start)
		self.new_data_ctx = \
			self.prev_data[:self.start - self.ext_start] \
			+ self.new_data \
			+ self.prev_data[- (self.ext_end - self.end):]

		return self.new_data, self.start



( run in 0.506 second using v1.01-cache-2.11-cpan-49f99fa48dc )