]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
Added CephMount.flock()
authorXavier Roche <roche@httrack.com>
Sun, 15 Feb 2015 09:53:23 +0000 (10:53 +0100)
committerXavier Roche <roche@httrack.com>
Sun, 15 Feb 2015 09:53:23 +0000 (10:53 +0100)
Also added corresponding unit tests

src/java/java/com/ceph/fs/CephMount.java
src/java/native/libcephfs_jni.cc
src/java/test/com/ceph/fs/CephMountTest.java

index 79a48b3d9b8f1396c7607906f4e86f4818e3eeeb..07819efa68f81d7798b901c9c3653850d39073db 100644 (file)
@@ -79,6 +79,15 @@ public class CephMount {
   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
@@ -685,6 +694,27 @@ public class CephMount {
 
   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.
    *
index 99ab3f48c10e961529240ec22466f5c4f626425b..050acc3f8a0a3c34c09ea5d1d61b0485068e1469 100644 (file)
 #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)
 {
@@ -1765,6 +1773,49 @@ JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1fsync
        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
index 82c3f1b64579e14f14af32a8def5dce05bc6154f..9315c4b9191fbb6dfce6418b4299c4597e2bd764 100644 (file)
@@ -790,6 +790,35 @@ public class CephMountTest {
     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
    *