public static final int XATTR_REPLACE = 2;
public static final int XATTR_NONE = 3;
+ /*
+ * Flags for flock();
+ *
+ * Must be synchronized with JNI if changed.
+ */
+ public static final int LOCK_SH = 1;
+ public static final int LOCK_EX = 2;
+ public static final int LOCK_NB = 4;
+ public static final int LOCK_UN = 8;
/*
* This is run by the class loader and will report early any problems
private static native int native_ceph_fsync(long mountp, int fd, boolean dataonly);
+ /**
+ * Apply or remove an advisory lock.
+ *
+ * @param fd File descriptor to synchronize.
+ * @param operation the advisory lock operation to be performed on the file
+ * descriptor among LOCK_SH (shared lock), LOCK_EX (exclusive lock),
+ * or LOCK_UN (remove lock). The LOCK_NB value can be ORed to perform a
+ * non-blocking operation.
+ * @param owner the user-supplied owner identifier (an arbitrary integer)
+ */
+ public void flock(int fd, int operation, long owner) throws IOException {
+ rlock.lock();
+ try {
+ native_ceph_flock(instance_ptr, fd, operation, owner);
+ } finally {
+ rlock.unlock();
+ }
+ }
+
+ private static native int native_ceph_flock(long mountp, int fd, int operation, long owner);
+
/**
* Get file status.
*
#define JAVA_XATTR_REPLACE 2
#define JAVA_XATTR_NONE 3
+/*
+ * flock flags. sync with CephMount.java if changed.
+ */
+#define JAVA_LOCK_SH 1
+#define JAVA_LOCK_EX 2
+#define JAVA_LOCK_NB 4
+#define JAVA_LOCK_UN 8
+
/* Map JAVA_O_* open flags to values in libc */
static inline int fixup_open_flags(jint jflags)
{
return ret;
}
+/*
+ * Class: com_ceph_fs_CephMount
+ * Method: native_ceph_flock
+ * Signature: (JIZ)I
+ */
+JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1flock
+ (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jint j_operation, jlong j_owner)
+{
+ struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
+ CephContext *cct = ceph_get_mount_context(cmount);
+ int ret;
+
+ ldout(cct, 10) << "jni: flock: fd " << (int)j_fd <<
+ " operation " << j_operation << " owner " << j_owner << dendl;
+
+ int operation = 0;
+
+#define MAP_FLOCK_FLAG(JNI_MASK, NATIVE_MASK) do { \
+ if ((j_operation & JNI_MASK) != 0) { \
+ operation |= NATIVE_MASK; \
+ j_operation &= ~JNI_MASK; \
+ } \
+ } while(0)
+ MAP_FLOCK_FLAG(JAVA_LOCK_SH, LOCK_SH);
+ MAP_FLOCK_FLAG(JAVA_LOCK_EX, LOCK_EX);
+ MAP_FLOCK_FLAG(JAVA_LOCK_NB, LOCK_NB);
+ MAP_FLOCK_FLAG(JAVA_LOCK_UN, LOCK_UN);
+ if (j_operation != 0) {
+ cephThrowIllegalArg(env, "flock flags");
+ return -EINVAL;
+ }
+#undef MAP_FLOCK_FLAG
+
+ ret = ceph_flock(cmount, (int)j_fd, operation, (uint64_t) j_owner);
+
+ ldout(cct, 10) << "jni: flock: exit ret " << ret << dendl;
+
+ if (ret)
+ handle_error(env, ret);
+
+ return ret;
+}
+
/*
* Class: com_ceph_fs_CephMount
* Method: native_ceph_fstat
mount.unlink(path);
}
+ /*
+ * flock
+ */
+
+ @Test
+ public void test_flock() throws Exception {
+ String path = makePath();
+ int fd = createFile(path, 123);
+ mount.flock(fd, CephMount.LOCK_SH | CephMount.LOCK_NB, 42);
+ mount.flock(fd, CephMount.LOCK_SH | CephMount.LOCK_NB, 43);
+ mount.flock(fd, CephMount.LOCK_UN, 42);
+ mount.flock(fd, CephMount.LOCK_UN, 43);
+ mount.flock(fd, CephMount.LOCK_EX | CephMount.LOCK_NB, 42);
+ try {
+ mount.flock(fd, CephMount.LOCK_SH | CephMount.LOCK_NB, 43);
+ assertTrue(false);
+ } catch(IOException io) {}
+ try {
+ mount.flock(fd, CephMount.LOCK_EX | CephMount.LOCK_NB, 43);
+ assertTrue(false);
+ } catch(IOException io) {}
+ mount.flock(fd, CephMount.LOCK_SH, 42); // downgrade
+ mount.flock(fd, CephMount.LOCK_SH, 43);
+ mount.flock(fd, CephMount.LOCK_UN, 42);
+ mount.flock(fd, CephMount.LOCK_UN, 43);
+ mount.close(fd);
+ mount.unlink(path);
+ }
+
/*
* fstat
*