--- /dev/null
+.TH llapi_group_lock 3 "2014 Oct 03" "Lustre User API"
+.SH NAME
+llapi_group_lock, llapi_group_unlock \- get and put a Lustre group lock.
+.SH SYNOPSIS
+.nf
+.B #include <lustre/lustreapi.h>
+.PP
+.BI "int llapi_group_lock(int "fd ", int "gid );
+
+.BI "int llapi_group_unlock(int "fd ", int "gid );
+.fi
+.SH DESCRIPTION
+.PP
+The function
+.BR llapi_group_lock()
+takes a group lock on the file descriptor
+.I fd
+with group identifier
+.IR gid .
+
+The function
+.BR llapi_group_unlock()
+releases a group lock identified by group identifier
+.I gid
+on the file descriptor
+.IR fd .
+
+The group lock is a whole file lock that blocks concurrent I/O originating from descriptors that have not been locked. Multiple processes can acquire a lock by specifying the same group identifier.
+
+.SH RETURN VALUES
+.LP
+.B llapi_group_lock(\|)
+and
+.B llapi_group_unlock(\|)
+return 0 on success or a negative errno value on failure.
+.SH ERRORS
+.TP 15
+.SM -EBADF
+.I fd
+is not a valid file descriptor.
+.TP
+.SM -ENOTTY
+.I fd
+does not describe an object suitable for this request.
+.TP
+.SM -EINVAL
+.I fd
+is already group locked with a different group identifier.
+.TP
+.SH "SEE ALSO"
+.BR liblustreapi (7)
{ 0, 0, 0, NULL }
};
+/* Generate a random id for the grouplock */
+static int random_group_id(int *gid)
+{
+ int fd;
+ int rc;
+ size_t sz = sizeof(*gid);
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd < 0) {
+ rc = -errno;
+ fprintf(stderr, "cannot open /dev/urandom: %s\n",
+ strerror(-rc));
+ goto out;
+ }
+
+ rc = read(fd, gid, sz);
+ if (rc < sz) {
+ rc = -errno;
+ fprintf(stderr, "cannot read %zu bytes from /dev/urandom: %s\n",
+ sz, strerror(-rc));
+ goto out;
+ }
+
+out:
+ if (fd >= 0)
+ close(fd);
+
+ return rc;
+}
+
#define MIGRATION_BLOCKS 1
static int lfs_migrate(char *name, unsigned long long stripe_size,
void *buf = NULL;
int rsize, wsize;
__u64 rpos, wpos, bufoff;
- int gid = 0, sz;
+ int gid;
int have_gl = 0;
struct stat st, stv;
}
if (migration_flags & MIGRATION_BLOCKS) {
- /* generate a random id for the grouplock */
- fd = open("/dev/urandom", O_RDONLY);
- if (fd == -1) {
- rc = -errno;
- fprintf(stderr, "cannot open /dev/urandom (%s)\n",
- strerror(-rc));
- goto free;
- }
- sz = sizeof(gid);
- rc = read(fd, &gid, sz);
- close(fd);
- if (rc < sz) {
- rc = -errno;
- fprintf(stderr, "cannot read %d bytes from"
- " /dev/urandom (%s)\n", sz, strerror(-rc));
+ rc = random_group_id(&gid);
+ if (rc < 0) {
+ fprintf(stderr, "%s: cannot get random group ID: %s\n",
+ name, strerror(-rc));
goto free;
}
}
* be implemented (see LU-2919) */
/* group lock is taken after data version read because it
* blocks data version call */
- if (ioctl(fd, LL_IOC_GROUP_LOCK, gid) == -1) {
- rc = -errno;
+ rc = llapi_group_lock(fd, gid);
+ if (rc < 0) {
fprintf(stderr, "cannot get group lock on %s (%s)\n",
name, strerror(-rc));
goto error;
if (migration_flags & MIGRATION_BLOCKS) {
/* give back group lock */
- if (ioctl(fd, LL_IOC_GROUP_UNLOCK, gid) == -1) {
- rc = -errno;
+ rc = llapi_group_unlock(fd, gid);
+ if (rc < 0)
fprintf(stderr, "cannot put group lock on %s (%s)\n",
name, strerror(-rc));
- }
have_gl = 0;
}
error:
/* give back group lock */
- if ((migration_flags & MIGRATION_BLOCKS) && have_gl &&
- (ioctl(fd, LL_IOC_GROUP_UNLOCK, gid) == -1)) {
- /* we keep in rc the original error */
- fprintf(stderr, "cannot put group lock on %s (%s)\n",
- name, strerror(-errno));
+ if ((migration_flags & MIGRATION_BLOCKS) && have_gl) {
+ int rc2;
+
+ /* we keep the original error in rc */
+ rc2 = llapi_group_unlock(fd, gid);
+ if (rc2 < 0)
+ fprintf(stderr, "cannot put group lock on %s (%s)\n",
+ name, strerror(-rc2));
}
close(fdv);
snprintf(path, sizeof(path), "%s/.lustre/fid/"DFID, mntdir, PFID(fid));
return open(path, flags);
}
+
+/**
+ * Take group lock.
+ *
+ * \param fd File to lock.
+ * \param gid Group Identifier.
+ *
+ * \retval 0 on success.
+ * \retval -errno on failure.
+ */
+int llapi_group_lock(int fd, int gid)
+{
+ int rc;
+
+ rc = ioctl(fd, LL_IOC_GROUP_LOCK, gid);
+ if (rc < 0) {
+ rc = -errno;
+ llapi_error(LLAPI_MSG_ERROR, rc, "cannot get group lock");
+ }
+ return rc;
+}
+
+/**
+ * Put group lock.
+ *
+ * \param fd File to unlock.
+ * \param gid Group Identifier.
+ *
+ * \retval 0 on success.
+ * \retval -errno on failure.
+ */
+int llapi_group_unlock(int fd, int gid)
+{
+ int rc;
+
+ rc = ioctl(fd, LL_IOC_GROUP_UNLOCK, gid);
+ if (rc < 0) {
+ rc = -errno;
+ llapi_error(LLAPI_MSG_ERROR, rc, "cannot put group lock");
+ }
+ return rc;
+}