2 * Permission is hereby granted, free of charge, to any person obtaining a
3 * copy of this software and associated documentation files (the "Software"),
4 * to deal in the Software without restriction, including without limitation
5 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
6 * and/or sell copies of the Software, and to permit persons to whom the
7 * Software is furnished to do so, subject to the following conditions:
9 * The above copyright notice and this permission notice shall be included in
10 * all copies or substantial portions of the Software.
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18 * DEALINGS IN THE SOFTWARE.
20 #include <sys/types.h>
29 #include "ScopedLocalRef.h"
30 #include "JniConstants.h"
32 #include "include/cephfs/libcephfs.h"
33 #include "common/dout.h"
35 #define dout_subsys ceph_subsys_javaclient
37 #include "com_ceph_fs_CephMount.h"
39 #define CEPH_STAT_CP "com/ceph/fs/CephStat"
40 #define CEPH_STAT_VFS_CP "com/ceph/fs/CephStatVFS"
41 #define CEPH_FILE_EXTENT_CP "com/ceph/fs/CephFileExtent"
42 #define CEPH_MOUNT_CP "com/ceph/fs/CephMount"
43 #define CEPH_NOTMOUNTED_CP "com/ceph/fs/CephNotMountedException"
44 #define CEPH_FILEEXISTS_CP "com/ceph/fs/CephFileAlreadyExistsException"
45 #define CEPH_ALREADYMOUNTED_CP "com/ceph/fs/CephAlreadyMountedException"
46 #define CEPH_NOTDIR_CP "com/ceph/fs/CephNotDirectoryException"
49 * Flags to open(). must be synchronized with CephMount.java
51 * There are two versions of flags: the version in Java and the version in the
52 * target library (e.g. libc or libcephfs). We control the Java values and map
53 * to the target value with fixup_* functions below. This is much faster than
54 * keeping the values in Java and making a cross-JNI up-call to retrieve them,
55 * and makes it easy to keep any platform specific value changes in this file.
57 #define JAVA_O_RDONLY 1
59 #define JAVA_O_APPEND 4
60 #define JAVA_O_CREAT 8
61 #define JAVA_O_TRUNC 16
62 #define JAVA_O_EXCL 32
63 #define JAVA_O_WRONLY 64
64 #define JAVA_O_DIRECTORY 128
67 * Whence flags for seek(). sync with CephMount.java if changed.
69 * Mapping of SEEK_* done in seek function.
71 #define JAVA_SEEK_SET 1
72 #define JAVA_SEEK_CUR 2
73 #define JAVA_SEEK_END 3
76 * File attribute flags. sync with CephMount.java if changed.
78 #define JAVA_SETATTR_MODE 1
79 #define JAVA_SETATTR_UID 2
80 #define JAVA_SETATTR_GID 4
81 #define JAVA_SETATTR_MTIME 8
82 #define JAVA_SETATTR_ATIME 16
85 * Setxattr flags. sync with CephMount.java if changed.
87 #define JAVA_XATTR_CREATE 1
88 #define JAVA_XATTR_REPLACE 2
89 #define JAVA_XATTR_NONE 3
92 * flock flags. sync with CephMount.java if changed.
94 #define JAVA_LOCK_SH 1
95 #define JAVA_LOCK_EX 2
96 #define JAVA_LOCK_NB 4
97 #define JAVA_LOCK_UN 8
99 /* Map JAVA_O_* open flags to values in libc */
100 static inline int fixup_open_flags(jint jflags)
104 #define FIXUP_OPEN_FLAG(name) \
105 if (jflags & JAVA_##name) \
108 FIXUP_OPEN_FLAG(O_RDONLY)
109 FIXUP_OPEN_FLAG(O_RDWR)
110 FIXUP_OPEN_FLAG(O_APPEND)
111 FIXUP_OPEN_FLAG(O_CREAT)
112 FIXUP_OPEN_FLAG(O_TRUNC)
113 FIXUP_OPEN_FLAG(O_EXCL)
114 FIXUP_OPEN_FLAG(O_WRONLY)
115 FIXUP_OPEN_FLAG(O_DIRECTORY)
117 #undef FIXUP_OPEN_FLAG
122 /* Map JAVA_SETATTR_* to values in ceph lib */
123 static inline int fixup_attr_mask(jint jmask)
127 #define FIXUP_ATTR_MASK(name) \
128 if (jmask & JAVA_##name) \
131 FIXUP_ATTR_MASK(SETATTR_MODE)
132 FIXUP_ATTR_MASK(SETATTR_UID)
133 FIXUP_ATTR_MASK(SETATTR_GID)
134 FIXUP_ATTR_MASK(SETATTR_MTIME)
135 FIXUP_ATTR_MASK(SETATTR_ATIME)
137 #undef FIXUP_ATTR_MASK
142 /* Cached field IDs for com.ceph.fs.CephStat */
143 static jfieldID cephstat_mode_fid;
144 static jfieldID cephstat_uid_fid;
145 static jfieldID cephstat_gid_fid;
146 static jfieldID cephstat_size_fid;
147 static jfieldID cephstat_blksize_fid;
148 static jfieldID cephstat_blocks_fid;
149 static jfieldID cephstat_a_time_fid;
150 static jfieldID cephstat_m_time_fid;
151 static jfieldID cephstat_is_file_fid;
152 static jfieldID cephstat_is_directory_fid;
153 static jfieldID cephstat_is_symlink_fid;
155 /* Cached field IDs for com.ceph.fs.CephStatVFS */
156 static jfieldID cephstatvfs_bsize_fid;
157 static jfieldID cephstatvfs_frsize_fid;
158 static jfieldID cephstatvfs_blocks_fid;
159 static jfieldID cephstatvfs_bavail_fid;
160 static jfieldID cephstatvfs_files_fid;
161 static jfieldID cephstatvfs_fsid_fid;
162 static jfieldID cephstatvfs_namemax_fid;
164 /* Cached field IDs for com.ceph.fs.CephMount */
165 static jfieldID cephmount_instance_ptr_fid;
167 /* Cached field IDs for com.ceph.fs.CephFileExtent */
168 static jclass cephfileextent_cls;
169 static jmethodID cephfileextent_ctor_fid;
172 * Exception throwing helper. Adapted from Apache Hadoop header
173 * org_apache_hadoop.h by adding the do {} while (0) construct.
175 #define THROW(env, exception_name, message) \
177 jclass ecls = env->FindClass(exception_name); \
179 int ret = env->ThrowNew(ecls, message); \
181 printf("(CephFS) Fatal Error\n"); \
183 env->DeleteLocalRef(ecls); \
188 static void cephThrowNullArg(JNIEnv *env, const char *msg)
190 THROW(env, "java/lang/NullPointerException", msg);
193 static void cephThrowOutOfMemory(JNIEnv *env, const char *msg)
195 THROW(env, "java/lang/OutOfMemoryError", msg);
198 static void cephThrowInternal(JNIEnv *env, const char *msg)
200 THROW(env, "java/lang/InternalError", msg);
203 static void cephThrowIndexBounds(JNIEnv *env, const char *msg)
205 THROW(env, "java/lang/IndexOutOfBoundsException", msg);
208 static void cephThrowIllegalArg(JNIEnv *env, const char *msg)
210 THROW(env, "java/lang/IllegalArgumentException", msg);
213 static void cephThrowFNF(JNIEnv *env, const char *msg)
215 THROW(env, "java/io/FileNotFoundException", msg);
218 static void cephThrowFileExists(JNIEnv *env, const char *msg)
220 THROW(env, CEPH_FILEEXISTS_CP, msg);
223 static void cephThrowNotDir(JNIEnv *env, const char *msg)
225 THROW(env, CEPH_NOTDIR_CP, msg);
228 static void handle_error(JNIEnv *env, int rc)
232 cephThrowFNF(env, "");
235 cephThrowFileExists(env, "");
238 cephThrowNotDir(env, "");
244 THROW(env, "java/io/IOException", strerror(-rc));
247 #define CHECK_ARG_NULL(v, m, r) do { \
249 cephThrowNullArg(env, (m)); \
253 #define CHECK_ARG_BOUNDS(c, m, r) do { \
255 cephThrowIndexBounds(env, (m)); \
259 #define CHECK_MOUNTED(_c, _r) do { \
260 if (!ceph_is_mounted((_c))) { \
261 THROW(env, CEPH_NOTMOUNTED_CP, "not mounted"); \
266 * Cast a jlong to ceph_mount_info. Each JNI function is expected to pass in
267 * the class instance variable instance_ptr. Passing a parameter is faster
268 * than reaching back into Java via an upcall to retreive this pointer.
270 static inline struct ceph_mount_info *get_ceph_mount(jlong j_mntp)
272 return (struct ceph_mount_info *)j_mntp;
276 * Setup cached field IDs
278 static void setup_field_ids(JNIEnv *env, jclass clz)
281 jclass cephstatvfs_cls;
282 jclass tmp_cephfileextent_cls;
285 * Get a fieldID from a class with a specific type
288 * field: field in clz
289 * type: integer, long, etc..
291 * This macro assumes some naming convention that is used
294 * GETFID(cephstat, mode, I) gets translated into
295 * cephstat_mode_fid = env->GetFieldID(cephstat_cls, "mode", "I");
297 #define GETFID(clz, field, type) do { \
298 clz ## _ ## field ## _fid = env->GetFieldID(clz ## _cls, #field, #type); \
299 if ( ! clz ## _ ## field ## _fid ) \
303 /* Cache CephStat fields */
305 cephstat_cls = env->FindClass(CEPH_STAT_CP);
309 GETFID(cephstat, mode, I);
310 GETFID(cephstat, uid, I);
311 GETFID(cephstat, gid, I);
312 GETFID(cephstat, size, J);
313 GETFID(cephstat, blksize, J);
314 GETFID(cephstat, blocks, J);
315 GETFID(cephstat, a_time, J);
316 GETFID(cephstat, m_time, J);
317 GETFID(cephstat, is_file, Z);
318 GETFID(cephstat, is_directory, Z);
319 GETFID(cephstat, is_symlink, Z);
321 /* Cache CephStatVFS fields */
323 cephstatvfs_cls = env->FindClass(CEPH_STAT_VFS_CP);
324 if (!cephstatvfs_cls)
327 GETFID(cephstatvfs, bsize, J);
328 GETFID(cephstatvfs, frsize, J);
329 GETFID(cephstatvfs, blocks, J);
330 GETFID(cephstatvfs, bavail, J);
331 GETFID(cephstatvfs, files, J);
332 GETFID(cephstatvfs, fsid, J);
333 GETFID(cephstatvfs, namemax, J);
335 /* Cache CephFileExtent fields */
337 tmp_cephfileextent_cls = env->FindClass(CEPH_FILE_EXTENT_CP);
338 if (!tmp_cephfileextent_cls)
341 cephfileextent_cls = (jclass)env->NewGlobalRef(tmp_cephfileextent_cls);
342 env->DeleteLocalRef(tmp_cephfileextent_cls);
344 cephfileextent_ctor_fid = env->GetMethodID(cephfileextent_cls, "<init>", "(JJ[I)V");
345 if (!cephfileextent_ctor_fid)
348 JniConstants::init(env);
352 cephmount_instance_ptr_fid = env->GetFieldID(clz, "instance_ptr", "J");
357 * Class: com_ceph_fs_CephMount
358 * Method: native_initialize
361 JNIEXPORT void JNICALL Java_com_ceph_fs_CephMount_native_1initialize
362 (JNIEnv *env, jclass clz)
364 setup_field_ids(env, clz);
368 * Class: com_ceph_fs_CephMount
369 * Method: native_ceph_create
370 * Signature: (Lcom/ceph/fs/CephMount;Ljava/lang/String;)I
372 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1create
373 (JNIEnv *env, jclass clz, jobject j_cephmount, jstring j_id)
375 struct ceph_mount_info *cmount;
376 const char *c_id = NULL;
379 CHECK_ARG_NULL(j_cephmount, "@mount is null", -1);
382 c_id = env->GetStringUTFChars(j_id, NULL);
384 cephThrowInternal(env, "Failed to pin memory");
389 ret = ceph_create(&cmount, c_id);
392 env->ReleaseStringUTFChars(j_id, c_id);
395 THROW(env, "java/lang/RuntimeException", "failed to create Ceph mount object");
399 env->SetLongField(j_cephmount, cephmount_instance_ptr_fid, (long)cmount);
405 * Class: com_ceph_fs_CephMount
406 * Method: native_ceph_mount
407 * Signature: (JLjava/lang/String;)I
409 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1mount
410 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_root)
412 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
413 CephContext *cct = ceph_get_mount_context(cmount);
414 const char *c_root = NULL;
418 * Toss a message up if we are already mounted.
420 if (ceph_is_mounted(cmount)) {
421 THROW(env, CEPH_ALREADYMOUNTED_CP, "");
426 c_root = env->GetStringUTFChars(j_root, NULL);
428 cephThrowInternal(env, "Failed to pin memory");
433 ldout(cct, 10) << "jni: ceph_mount: " << (c_root ? c_root : "<NULL>") << dendl;
435 ret = ceph_mount(cmount, c_root);
437 ldout(cct, 10) << "jni: ceph_mount: exit ret " << ret << dendl;
440 env->ReleaseStringUTFChars(j_root, c_root);
443 handle_error(env, ret);
449 * Class: com_ceph_fs_CephMount
450 * Method: native_ceph_unmount
453 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1unmount
454 (JNIEnv *env, jclass clz, jlong j_mntp)
456 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
457 CephContext *cct = ceph_get_mount_context(cmount);
460 ldout(cct, 10) << "jni: ceph_unmount enter" << dendl;
462 CHECK_MOUNTED(cmount, -1);
464 ret = ceph_unmount(cmount);
466 ldout(cct, 10) << "jni: ceph_unmount exit ret " << ret << dendl;
469 handle_error(env, ret);
475 * Class: com_ceph_fs_CephMount
476 * Method: native_ceph_release
479 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1release
480 (JNIEnv *env, jclass clz, jlong j_mntp)
482 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
483 CephContext *cct = ceph_get_mount_context(cmount);
486 ldout(cct, 10) << "jni: ceph_release called" << dendl;
488 ret = ceph_release(cmount);
491 handle_error(env, ret);
497 * Class: com_ceph_fs_CephMount
498 * Method: native_ceph_conf_set
499 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
501 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1conf_1set
502 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_opt, jstring j_val)
504 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
505 CephContext *cct = ceph_get_mount_context(cmount);
506 const char *c_opt, *c_val;
509 CHECK_ARG_NULL(j_opt, "@option is null", -1);
510 CHECK_ARG_NULL(j_val, "@value is null", -1);
512 c_opt = env->GetStringUTFChars(j_opt, NULL);
514 cephThrowInternal(env, "failed to pin memory");
518 c_val = env->GetStringUTFChars(j_val, NULL);
520 env->ReleaseStringUTFChars(j_opt, c_opt);
521 cephThrowInternal(env, "failed to pin memory");
525 ldout(cct, 10) << "jni: conf_set: opt " << c_opt << " val " << c_val << dendl;
527 ret = ceph_conf_set(cmount, c_opt, c_val);
529 ldout(cct, 10) << "jni: conf_set: exit ret " << ret << dendl;
531 env->ReleaseStringUTFChars(j_opt, c_opt);
532 env->ReleaseStringUTFChars(j_val, c_val);
535 handle_error(env, ret);
541 * Class: com_ceph_fs_CephMount
542 * Method: native_ceph_conf_get
543 * Signature: (JLjava/lang/String;)Ljava/lang/String;
545 JNIEXPORT jstring JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1conf_1get
546 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_opt)
548 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
549 CephContext *cct = ceph_get_mount_context(cmount);
551 jstring value = NULL;
555 CHECK_ARG_NULL(j_opt, "@option is null", NULL);
557 c_opt = env->GetStringUTFChars(j_opt, NULL);
559 cephThrowInternal(env, "failed to pin memory");
564 buf = new (std::nothrow) char[buflen];
566 cephThrowOutOfMemory(env, "head allocation failed");
571 memset(buf, 0, sizeof(char)*buflen);
572 ldout(cct, 10) << "jni: conf_get: opt " << c_opt << " len " << buflen << dendl;
573 ret = ceph_conf_get(cmount, c_opt, buf, buflen);
574 if (ret == -ENAMETOOLONG) {
577 buf = new (std::nothrow) char[buflen];
579 cephThrowOutOfMemory(env, "head allocation failed");
586 ldout(cct, 10) << "jni: conf_get: ret " << ret << dendl;
589 value = env->NewStringUTF(buf);
590 else if (ret != -ENOENT)
591 handle_error(env, ret);
596 env->ReleaseStringUTFChars(j_opt, c_opt);
601 * Class: com_ceph_fs_CephMount
602 * Method: native_ceph_conf_read_file
603 * Signature: (JLjava/lang/String;)I
605 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1conf_1read_1file
606 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
608 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
609 CephContext *cct = ceph_get_mount_context(cmount);
613 CHECK_ARG_NULL(j_path, "@path is null", -1);
615 c_path = env->GetStringUTFChars(j_path, NULL);
617 cephThrowInternal(env, "failed to pin memory");
621 ldout(cct, 10) << "jni: conf_read_file: path " << c_path << dendl;
623 ret = ceph_conf_read_file(cmount, c_path);
625 ldout(cct, 10) << "jni: conf_read_file: exit ret " << ret << dendl;
627 env->ReleaseStringUTFChars(j_path, c_path);
630 handle_error(env, ret);
636 * Class: com_ceph_fs_CephMount
637 * Method: native_ceph_statfs
638 * Signature: (JLjava/lang/String;Lcom/ceph/fs/CephStatVFS;)I
640 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1statfs
641 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jobject j_cephstatvfs)
643 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
644 CephContext *cct = ceph_get_mount_context(cmount);
649 CHECK_ARG_NULL(j_path, "@path is null", -1);
650 CHECK_ARG_NULL(j_cephstatvfs, "@stat is null", -1);
651 CHECK_MOUNTED(cmount, -1);
653 c_path = env->GetStringUTFChars(j_path, NULL);
655 cephThrowInternal(env, "Failed to pin memory");
659 ldout(cct, 10) << "jni: statfs: path " << c_path << dendl;
661 ret = ceph_statfs(cmount, c_path, &st);
663 ldout(cct, 10) << "jni: statfs: exit ret " << ret << dendl;
665 env->ReleaseStringUTFChars(j_path, c_path);
668 handle_error(env, ret);
672 env->SetLongField(j_cephstatvfs, cephstatvfs_bsize_fid, st.f_bsize);
673 env->SetLongField(j_cephstatvfs, cephstatvfs_frsize_fid, st.f_frsize);
674 env->SetLongField(j_cephstatvfs, cephstatvfs_blocks_fid, st.f_blocks);
675 env->SetLongField(j_cephstatvfs, cephstatvfs_bavail_fid, st.f_bavail);
676 env->SetLongField(j_cephstatvfs, cephstatvfs_files_fid, st.f_files);
677 env->SetLongField(j_cephstatvfs, cephstatvfs_fsid_fid, st.f_fsid);
678 env->SetLongField(j_cephstatvfs, cephstatvfs_namemax_fid, st.f_namemax);
684 * Class: com_ceph_fs_CephMount
685 * Method: native_ceph_getcwd
686 * Signature: (J)Ljava/lang/String;
688 JNIEXPORT jstring JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1getcwd
689 (JNIEnv *env, jclass clz, jlong j_mntp)
691 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
692 CephContext *cct = ceph_get_mount_context(cmount);
695 CHECK_MOUNTED(cmount, NULL);
697 ldout(cct, 10) << "jni: getcwd: enter" << dendl;
699 c_cwd = ceph_getcwd(cmount);
701 cephThrowOutOfMemory(env, "ceph_getcwd");
705 ldout(cct, 10) << "jni: getcwd: exit ret " << c_cwd << dendl;
707 return env->NewStringUTF(c_cwd);
711 * Class: com_ceph_fs_CephMount
712 * Method: native_ceph_chdir
713 * Signature: (JLjava/lang/String;)I
715 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1chdir
716 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
718 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
719 CephContext *cct = ceph_get_mount_context(cmount);
723 CHECK_ARG_NULL(j_path, "@path is null", -1);
724 CHECK_MOUNTED(cmount, -1);
726 c_path = env->GetStringUTFChars(j_path, NULL);
728 cephThrowInternal(env, "failed to pin memory");
732 ldout(cct, 10) << "jni: chdir: path " << c_path << dendl;
734 ret = ceph_chdir(cmount, c_path);
736 ldout(cct, 10) << "jni: chdir: exit ret " << ret << dendl;
738 env->ReleaseStringUTFChars(j_path, c_path);
741 handle_error(env, ret);
747 * Class: com_ceph_fs_CephMount
748 * Method: native_ceph_listdir
749 * Signature: (JLjava/lang/String;)[Ljava/lang/String;
751 JNIEXPORT jobjectArray JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1listdir
752 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
754 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
755 CephContext *cct = ceph_get_mount_context(cmount);
756 struct ceph_dir_result *dirp;
757 list<string>::iterator it;
758 list<string> contents;
760 jobjectArray dirlist;
762 int ret, buflen, bufpos, i;
766 CHECK_ARG_NULL(j_path, "@path is null", NULL);
767 CHECK_MOUNTED(cmount, NULL);
769 c_path = env->GetStringUTFChars(j_path, NULL);
771 cephThrowInternal(env, "failed to pin memory");
775 ldout(cct, 10) << "jni: listdir: opendir: path " << c_path << dendl;
777 /* ret < 0 also includes -ENOTDIR which should return NULL */
778 ret = ceph_opendir(cmount, c_path, &dirp);
780 env->ReleaseStringUTFChars(j_path, c_path);
781 handle_error(env, ret);
785 ldout(cct, 10) << "jni: listdir: opendir: exit ret " << ret << dendl;
787 /* buffer for ceph_getdnames() results */
789 buf = new (std::nothrow) char[buflen];
791 cephThrowOutOfMemory(env, "heap allocation failed");
796 ldout(cct, 10) << "jni: listdir: getdnames: enter" << dendl;
797 ret = ceph_getdnames(cmount, dirp, buf, buflen);
798 if (ret == -ERANGE) {
801 buf = new (std::nothrow) char[buflen];
803 cephThrowOutOfMemory(env, "heap allocation failed");
809 ldout(cct, 10) << "jni: listdir: getdnames: exit ret " << ret << dendl;
814 /* got at least one name */
816 while (bufpos < ret) {
817 ent = new (std::nothrow) string(buf + bufpos);
820 cephThrowOutOfMemory(env, "heap allocation failed");
824 /* filter out dot files: xref: java.io.File::list() */
825 if (ent->compare(".") && ent->compare("..")) {
826 contents.push_back(*ent);
827 ldout(cct, 20) << "jni: listdir: take path " << *ent << dendl;
830 bufpos += ent->size() + 1;
838 handle_error(env, ret);
843 dirlist = env->NewObjectArray(contents.size(), env->FindClass("java/lang/String"), NULL);
848 * Fill directory listing array.
850 * FIXME: how should a partially filled array be cleaned-up properly?
852 for (i = 0, it = contents.begin(); it != contents.end(); ++it) {
853 name = env->NewStringUTF(it->c_str());
856 env->SetObjectArrayElement(dirlist, i++, name);
857 if (env->ExceptionOccurred())
859 env->DeleteLocalRef(name);
862 env->ReleaseStringUTFChars(j_path, c_path);
863 ceph_closedir(cmount, dirp);
868 env->ReleaseStringUTFChars(j_path, c_path);
869 ceph_closedir(cmount, dirp);
874 * Class: com_ceph_fs_CephMount
875 * Method: native_ceph_link
876 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
878 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1link
879 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_oldpath, jstring j_newpath)
881 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
882 CephContext *cct = ceph_get_mount_context(cmount);
883 const char *c_oldpath, *c_newpath;
886 CHECK_ARG_NULL(j_oldpath, "@oldpath is null", -1);
887 CHECK_ARG_NULL(j_newpath, "@newpath is null", -1);
888 CHECK_MOUNTED(cmount, -1);
890 c_oldpath = env->GetStringUTFChars(j_oldpath, NULL);
892 cephThrowInternal(env, "failed to pin memory");
896 c_newpath = env->GetStringUTFChars(j_newpath, NULL);
898 env->ReleaseStringUTFChars(j_oldpath, c_oldpath);
899 cephThrowInternal(env, "failed to pin memory");
903 ldout(cct, 10) << "jni: link: oldpath " << c_oldpath <<
904 " newpath " << c_newpath << dendl;
906 ret = ceph_link(cmount, c_oldpath, c_newpath);
908 ldout(cct, 10) << "jni: link: exit ret " << ret << dendl;
910 env->ReleaseStringUTFChars(j_oldpath, c_oldpath);
911 env->ReleaseStringUTFChars(j_newpath, c_newpath);
914 handle_error(env, ret);
920 * Class: com_ceph_fs_CephMount
921 * Method: native_ceph_unlink
922 * Signature: (JLjava/lang/String;)I
924 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1unlink
925 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
927 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
928 CephContext *cct = ceph_get_mount_context(cmount);
932 CHECK_ARG_NULL(j_path, "@path is null", -1);
933 CHECK_MOUNTED(cmount, -1);
935 c_path = env->GetStringUTFChars(j_path, NULL);
937 cephThrowInternal(env, "failed to pin memory");
941 ldout(cct, 10) << "jni: unlink: path " << c_path << dendl;
943 ret = ceph_unlink(cmount, c_path);
945 ldout(cct, 10) << "jni: unlink: exit ret " << ret << dendl;
947 env->ReleaseStringUTFChars(j_path, c_path);
950 handle_error(env, ret);
956 * Class: com_ceph_fs_CephMount
957 * Method: native_ceph_rename
958 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
960 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1rename
961 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_from, jstring j_to)
963 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
964 CephContext *cct = ceph_get_mount_context(cmount);
965 const char *c_from, *c_to;
968 CHECK_ARG_NULL(j_from, "@from is null", -1);
969 CHECK_ARG_NULL(j_to, "@to is null", -1);
970 CHECK_MOUNTED(cmount, -1);
972 c_from = env->GetStringUTFChars(j_from, NULL);
974 cephThrowInternal(env, "Failed to pin memory!");
978 c_to = env->GetStringUTFChars(j_to, NULL);
980 env->ReleaseStringUTFChars(j_from, c_from);
981 cephThrowInternal(env, "Failed to pin memory.");
985 ldout(cct, 10) << "jni: rename: from " << c_from << " to " << c_to << dendl;
987 ret = ceph_rename(cmount, c_from, c_to);
989 ldout(cct, 10) << "jni: rename: exit ret " << ret << dendl;
991 env->ReleaseStringUTFChars(j_from, c_from);
992 env->ReleaseStringUTFChars(j_to, c_to);
995 handle_error(env, ret);
1001 * Class: com_ceph_fs_CephMount
1002 * Method: native_ceph_mkdir
1003 * Signature: (JLjava/lang/String;I)I
1005 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1mkdir
1006 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jint j_mode)
1008 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1009 CephContext *cct = ceph_get_mount_context(cmount);
1013 CHECK_ARG_NULL(j_path, "@path is null", -1);
1014 CHECK_MOUNTED(cmount, -1);
1016 c_path = env->GetStringUTFChars(j_path, NULL);
1018 cephThrowInternal(env, "failed to pin memory");
1022 ldout(cct, 10) << "jni: mkdir: path " << c_path << " mode " << (int)j_mode << dendl;
1024 ret = ceph_mkdir(cmount, c_path, (int)j_mode);
1026 ldout(cct, 10) << "jni: mkdir: exit ret " << ret << dendl;
1028 env->ReleaseStringUTFChars(j_path, c_path);
1031 handle_error(env, ret);
1037 * Class: com_ceph_fs_CephMount
1038 * Method: native_ceph_mkdirs
1039 * Signature: (JLjava/lang/String;I)I
1041 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1mkdirs
1042 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jint j_mode)
1044 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1045 CephContext *cct = ceph_get_mount_context(cmount);
1049 CHECK_ARG_NULL(j_path, "@path is null", -1);
1050 CHECK_MOUNTED(cmount, -1);
1052 c_path = env->GetStringUTFChars(j_path, NULL);
1054 cephThrowInternal(env, "failed to pin memory");
1058 ldout(cct, 10) << "jni: mkdirs: path " << c_path << " mode " << (int)j_mode << dendl;
1060 ret = ceph_mkdirs(cmount, c_path, (int)j_mode);
1062 ldout(cct, 10) << "jni: mkdirs: exit ret " << ret << dendl;
1064 env->ReleaseStringUTFChars(j_path, c_path);
1067 handle_error(env, ret);
1073 * Class: com_ceph_fs_CephMount
1074 * Method: native_ceph_rmdir
1075 * Signature: (JLjava/lang/String;)I
1077 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1rmdir
1078 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
1080 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1081 CephContext *cct = ceph_get_mount_context(cmount);
1085 CHECK_ARG_NULL(j_path, "@path is null", -1);
1086 CHECK_MOUNTED(cmount, -1);
1088 c_path = env->GetStringUTFChars(j_path, NULL);
1090 cephThrowInternal(env, "failed to pin memory");
1094 ldout(cct, 10) << "jni: rmdir: path " << c_path << dendl;
1096 ret = ceph_rmdir(cmount, c_path);
1098 ldout(cct, 10) << "jni: rmdir: exit ret " << ret << dendl;
1100 env->ReleaseStringUTFChars(j_path, c_path);
1103 handle_error(env, ret);
1109 * Class: com_ceph_fs_CephMount
1110 * Method: native_ceph_readlink
1111 * Signature: (JLjava/lang/String;)Ljava/lang/String;
1113 JNIEXPORT jstring JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1readlink
1114 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
1116 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1117 CephContext *cct = ceph_get_mount_context(cmount);
1120 struct ceph_statx stx;
1123 CHECK_ARG_NULL(j_path, "@path is null", NULL);
1124 CHECK_MOUNTED(cmount, NULL);
1126 c_path = env->GetStringUTFChars(j_path, NULL);
1128 cephThrowInternal(env, "failed to pin memory");
1133 ldout(cct, 10) << "jni: readlink: lstatx " << c_path << dendl;
1134 int ret = ceph_statx(cmount, c_path, &stx, CEPH_STATX_SIZE,
1135 AT_SYMLINK_NOFOLLOW);
1136 ldout(cct, 10) << "jni: readlink: lstat exit ret " << ret << dendl;
1138 env->ReleaseStringUTFChars(j_path, c_path);
1139 handle_error(env, ret);
1143 linkname = new (std::nothrow) char[stx.stx_size + 1];
1145 env->ReleaseStringUTFChars(j_path, c_path);
1146 cephThrowOutOfMemory(env, "head allocation failed");
1150 ldout(cct, 10) << "jni: readlink: size " << stx.stx_size << " path " << c_path << dendl;
1152 ret = ceph_readlink(cmount, c_path, linkname, stx.stx_size + 1);
1154 ldout(cct, 10) << "jni: readlink: exit ret " << ret << dendl;
1158 env->ReleaseStringUTFChars(j_path, c_path);
1159 handle_error(env, ret);
1163 /* re-stat and try again */
1164 if (ret > (int)stx.stx_size) {
1169 linkname[ret] = '\0';
1173 env->ReleaseStringUTFChars(j_path, c_path);
1175 j_linkname = env->NewStringUTF(linkname);
1182 * Class: com_ceph_fs_CephMount
1183 * Method: native_ceph_symlink
1184 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
1186 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1symlink
1187 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_oldpath, jstring j_newpath)
1189 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1190 CephContext *cct = ceph_get_mount_context(cmount);
1191 const char *c_oldpath, *c_newpath;
1194 CHECK_ARG_NULL(j_oldpath, "@oldpath is null", -1);
1195 CHECK_ARG_NULL(j_newpath, "@newpath is null", -1);
1196 CHECK_MOUNTED(cmount, -1);
1198 c_oldpath = env->GetStringUTFChars(j_oldpath, NULL);
1200 cephThrowInternal(env, "failed to pin memory");
1204 c_newpath = env->GetStringUTFChars(j_newpath, NULL);
1206 env->ReleaseStringUTFChars(j_oldpath, c_oldpath);
1207 cephThrowInternal(env, "failed to pin memory");
1211 ldout(cct, 10) << "jni: symlink: oldpath " << c_oldpath <<
1212 " newpath " << c_newpath << dendl;
1214 ret = ceph_symlink(cmount, c_oldpath, c_newpath);
1216 ldout(cct, 10) << "jni: symlink: exit ret " << ret << dendl;
1218 env->ReleaseStringUTFChars(j_oldpath, c_oldpath);
1219 env->ReleaseStringUTFChars(j_newpath, c_newpath);
1222 handle_error(env, ret);
1227 #define CEPH_J_CEPHSTAT_MASK (CEPH_STATX_UID|CEPH_STATX_GID|CEPH_STATX_SIZE|CEPH_STATX_BLOCKS|CEPH_STATX_MTIME|CEPH_STATX_ATIME)
1229 static void fill_cephstat(JNIEnv *env, jobject j_cephstat, struct ceph_statx *stx)
1231 env->SetIntField(j_cephstat, cephstat_mode_fid, stx->stx_mode);
1232 env->SetIntField(j_cephstat, cephstat_uid_fid, stx->stx_uid);
1233 env->SetIntField(j_cephstat, cephstat_gid_fid, stx->stx_gid);
1234 env->SetLongField(j_cephstat, cephstat_size_fid, stx->stx_size);
1235 env->SetLongField(j_cephstat, cephstat_blksize_fid, stx->stx_blksize);
1236 env->SetLongField(j_cephstat, cephstat_blocks_fid, stx->stx_blocks);
1238 long long time = stx->stx_mtime.tv_sec;
1240 time += stx->stx_mtime.tv_nsec / 1000000;
1241 env->SetLongField(j_cephstat, cephstat_m_time_fid, time);
1243 time = stx->stx_atime.tv_sec;
1245 time += stx->stx_atime.tv_nsec / 1000000;
1246 env->SetLongField(j_cephstat, cephstat_a_time_fid, time);
1248 env->SetBooleanField(j_cephstat, cephstat_is_file_fid,
1249 S_ISREG(stx->stx_mode) ? JNI_TRUE : JNI_FALSE);
1251 env->SetBooleanField(j_cephstat, cephstat_is_directory_fid,
1252 S_ISDIR(stx->stx_mode) ? JNI_TRUE : JNI_FALSE);
1254 env->SetBooleanField(j_cephstat, cephstat_is_symlink_fid,
1255 S_ISLNK(stx->stx_mode) ? JNI_TRUE : JNI_FALSE);
1259 * Class: com_ceph_fs_CephMount
1260 * Method: native_ceph_lstat
1261 * Signature: (JLjava/lang/String;Lcom/ceph/fs/CephStat;)I
1263 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1lstat
1264 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jobject j_cephstat)
1266 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1267 CephContext *cct = ceph_get_mount_context(cmount);
1269 struct ceph_statx stx;
1272 CHECK_ARG_NULL(j_path, "@path is null", -1);
1273 CHECK_ARG_NULL(j_cephstat, "@stat is null", -1);
1274 CHECK_MOUNTED(cmount, -1);
1276 c_path = env->GetStringUTFChars(j_path, NULL);
1278 cephThrowInternal(env, "Failed to pin memory");
1282 ldout(cct, 10) << "jni: lstat: path " << c_path << dendl;
1284 ret = ceph_statx(cmount, c_path, &stx, CEPH_J_CEPHSTAT_MASK, AT_SYMLINK_NOFOLLOW);
1286 ldout(cct, 10) << "jni: lstat exit ret " << ret << dendl;
1288 env->ReleaseStringUTFChars(j_path, c_path);
1291 handle_error(env, ret);
1295 fill_cephstat(env, j_cephstat, &stx);
1301 * Class: com_ceph_fs_CephMount
1302 * Method: native_ceph_stat
1303 * Signature: (JLjava/lang/String;Lcom/ceph/fs/CephStat;)I
1305 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1stat
1306 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jobject j_cephstat)
1308 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1309 CephContext *cct = ceph_get_mount_context(cmount);
1311 struct ceph_statx stx;
1314 CHECK_ARG_NULL(j_path, "@path is null", -1);
1315 CHECK_ARG_NULL(j_cephstat, "@stat is null", -1);
1316 CHECK_MOUNTED(cmount, -1);
1318 c_path = env->GetStringUTFChars(j_path, NULL);
1320 cephThrowInternal(env, "Failed to pin memory");
1324 ldout(cct, 10) << "jni: lstat: path " << c_path << dendl;
1326 ret = ceph_statx(cmount, c_path, &stx, CEPH_J_CEPHSTAT_MASK, 0);
1328 ldout(cct, 10) << "jni: lstat exit ret " << ret << dendl;
1330 env->ReleaseStringUTFChars(j_path, c_path);
1333 handle_error(env, ret);
1337 fill_cephstat(env, j_cephstat, &stx);
1343 * Class: com_ceph_fs_CephMount
1344 * Method: native_ceph_setattr
1345 * Signature: (JLjava/lang/String;Lcom/ceph/fs/CephStat;I)I
1347 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1setattr
1348 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jobject j_cephstat, jint j_mask)
1350 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1351 CephContext *cct = ceph_get_mount_context(cmount);
1353 struct ceph_statx stx;
1354 int ret, mask = fixup_attr_mask(j_mask);
1356 CHECK_ARG_NULL(j_path, "@path is null", -1);
1357 CHECK_ARG_NULL(j_cephstat, "@stat is null", -1);
1358 CHECK_MOUNTED(cmount, -1);
1360 c_path = env->GetStringUTFChars(j_path, NULL);
1362 cephThrowInternal(env, "Failed to pin memory");
1366 memset(&stx, 0, sizeof(stx));
1368 stx.stx_mode = env->GetIntField(j_cephstat, cephstat_mode_fid);
1369 stx.stx_uid = env->GetIntField(j_cephstat, cephstat_uid_fid);
1370 stx.stx_gid = env->GetIntField(j_cephstat, cephstat_gid_fid);
1371 stx.stx_mtime.tv_sec = env->GetLongField(j_cephstat, cephstat_m_time_fid);
1372 stx.stx_atime.tv_sec = env->GetLongField(j_cephstat, cephstat_a_time_fid);
1374 ldout(cct, 10) << "jni: setattr: path " << c_path << " mask " << mask << dendl;
1376 ret = ceph_setattrx(cmount, c_path, &stx, mask, 0);
1378 ldout(cct, 10) << "jni: setattr: exit ret " << ret << dendl;
1380 env->ReleaseStringUTFChars(j_path, c_path);
1383 handle_error(env, ret);
1389 * Class: com_ceph_fs_CephMount
1390 * Method: native_ceph_chmod
1391 * Signature: (JLjava/lang/String;I)I
1393 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1chmod
1394 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jint j_mode)
1396 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1397 CephContext *cct = ceph_get_mount_context(cmount);
1401 CHECK_ARG_NULL(j_path, "@path is null", -1);
1402 CHECK_MOUNTED(cmount, -1);
1404 c_path = env->GetStringUTFChars(j_path, NULL);
1406 cephThrowInternal(env, "Failed to pin memory");
1410 ldout(cct, 10) << "jni: chmod: path " << c_path << " mode " << (int)j_mode << dendl;
1412 ret = ceph_chmod(cmount, c_path, (int)j_mode);
1414 ldout(cct, 10) << "jni: chmod: exit ret " << ret << dendl;
1416 env->ReleaseStringUTFChars(j_path, c_path);
1419 handle_error(env, ret);
1425 * Class: com_ceph_fs_CephMount
1426 * Method: native_ceph_fchmod
1429 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1fchmod
1430 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jint j_mode)
1432 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1433 CephContext *cct = ceph_get_mount_context(cmount);
1436 CHECK_MOUNTED(cmount, -1);
1438 ldout(cct, 10) << "jni: fchmod: fd " << (int)j_fd << " mode " << (int)j_mode << dendl;
1440 ret = ceph_fchmod(cmount, (int)j_fd, (int)j_mode);
1442 ldout(cct, 10) << "jni: fchmod: exit ret " << ret << dendl;
1445 handle_error(env, ret);
1451 * Class: com_ceph_fs_CephMount
1452 * Method: native_ceph_truncate
1453 * Signature: (JLjava/lang/String;J)I
1455 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1truncate
1456 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jlong j_size)
1458 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1459 CephContext *cct = ceph_get_mount_context(cmount);
1463 CHECK_ARG_NULL(j_path, "@path is null", -1);
1464 CHECK_MOUNTED(cmount, -1);
1466 c_path = env->GetStringUTFChars(j_path, NULL);
1468 cephThrowInternal(env, "Failed to pin memory");
1472 ldout(cct, 10) << "jni: truncate: path " << c_path << " size " << (loff_t)j_size << dendl;
1474 ret = ceph_truncate(cmount, c_path, (loff_t)j_size);
1476 ldout(cct, 10) << "jni: truncate: exit ret " << ret << dendl;
1478 env->ReleaseStringUTFChars(j_path, c_path);
1481 handle_error(env, ret);
1487 * Class: com_ceph_fs_CephMount
1488 * Method: native_ceph_open
1489 * Signature: (JLjava/lang/String;II)I
1491 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1open
1492 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jint j_flags, jint j_mode)
1494 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1495 CephContext *cct = ceph_get_mount_context(cmount);
1497 int ret, flags = fixup_open_flags(j_flags);
1499 CHECK_ARG_NULL(j_path, "@path is null", -1);
1500 CHECK_MOUNTED(cmount, -1);
1502 c_path = env->GetStringUTFChars(j_path, NULL);
1504 cephThrowInternal(env, "Failed to pin memory");
1508 ldout(cct, 10) << "jni: open: path " << c_path << " flags " << flags
1509 << " mode " << (int)j_mode << dendl;
1511 ret = ceph_open(cmount, c_path, flags, (int)j_mode);
1513 ldout(cct, 10) << "jni: open: exit ret " << ret << dendl;
1515 env->ReleaseStringUTFChars(j_path, c_path);
1518 handle_error(env, ret);
1524 * Class: com_ceph_fs_CephMount
1525 * Method: native_ceph_open_layout
1526 * Signature: (JLjava/lang/String;IIIIILjava/lang/String;)I
1528 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1open_1layout
1529 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jint j_flags, jint j_mode,
1530 jint stripe_unit, jint stripe_count, jint object_size, jstring j_data_pool)
1532 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1533 CephContext *cct = ceph_get_mount_context(cmount);
1534 const char *c_path, *c_data_pool = NULL;
1535 int ret, flags = fixup_open_flags(j_flags);
1537 CHECK_ARG_NULL(j_path, "@path is null", -1);
1538 CHECK_MOUNTED(cmount, -1);
1540 c_path = env->GetStringUTFChars(j_path, NULL);
1542 cephThrowInternal(env, "Failed to pin memory");
1547 c_data_pool = env->GetStringUTFChars(j_data_pool, NULL);
1549 env->ReleaseStringUTFChars(j_path, c_path);
1550 cephThrowInternal(env, "Failed to pin memory");
1555 ldout(cct, 10) << "jni: open_layout: path " << c_path << " flags " << flags
1556 << " mode " << (int)j_mode << " stripe_unit " << stripe_unit
1557 << " stripe_count " << stripe_count << " object_size " << object_size
1558 << " data_pool " << (c_data_pool ? c_data_pool : "<NULL>") << dendl;
1560 ret = ceph_open_layout(cmount, c_path, flags, (int)j_mode,
1561 (int)stripe_unit, (int)stripe_count, (int)object_size, c_data_pool);
1563 ldout(cct, 10) << "jni: open_layout: exit ret " << ret << dendl;
1565 env->ReleaseStringUTFChars(j_path, c_path);
1567 env->ReleaseStringUTFChars(j_data_pool, c_data_pool);
1570 handle_error(env, ret);
1576 * Class: com_ceph_fs_CephMount
1577 * Method: native_ceph_close
1580 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1close
1581 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd)
1583 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1584 CephContext *cct = ceph_get_mount_context(cmount);
1587 CHECK_MOUNTED(cmount, -1);
1589 ldout(cct, 10) << "jni: close: fd " << (int)j_fd << dendl;
1591 ret = ceph_close(cmount, (int)j_fd);
1593 ldout(cct, 10) << "jni: close: ret " << ret << dendl;
1596 handle_error(env, ret);
1602 * Class: com_ceph_fs_CephMount
1603 * Method: native_ceph_lseek
1604 * Signature: (JIJI)J
1606 JNIEXPORT jlong JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1lseek
1607 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jlong j_offset, jint j_whence)
1609 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1610 CephContext *cct = ceph_get_mount_context(cmount);
1614 CHECK_MOUNTED(cmount, -1);
1627 cephThrowIllegalArg(env, "Unknown whence value");
1631 ldout(cct, 10) << "jni: lseek: fd " << (int)j_fd << " offset "
1632 << (long)j_offset << " whence " << whence << dendl;
1634 ret = ceph_lseek(cmount, (int)j_fd, (long)j_offset, whence);
1636 ldout(cct, 10) << "jni: lseek: exit ret " << ret << dendl;
1639 handle_error(env, ret);
1645 * Class: com_ceph_fs_CephMount
1646 * Method: native_ceph_read
1647 * Signature: (JI[BJJ)J
1649 JNIEXPORT jlong JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1read
1650 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jbyteArray j_buf, jlong j_size, jlong j_offset)
1652 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1653 CephContext *cct = ceph_get_mount_context(cmount);
1658 CHECK_ARG_NULL(j_buf, "@buf is null", -1);
1659 CHECK_ARG_BOUNDS(j_size < 0, "@size is negative", -1);
1660 CHECK_MOUNTED(cmount, -1);
1662 buf_size = env->GetArrayLength(j_buf);
1663 CHECK_ARG_BOUNDS(j_size > buf_size, "@size > @buf.length", -1);
1665 c_buf = env->GetByteArrayElements(j_buf, NULL);
1667 cephThrowInternal(env, "failed to pin memory");
1671 ldout(cct, 10) << "jni: read: fd " << (int)j_fd << " len " << (long)j_size <<
1672 " offset " << (long)j_offset << dendl;
1674 ret = ceph_read(cmount, (int)j_fd, (char*)c_buf, (long)j_size, (long)j_offset);
1676 ldout(cct, 10) << "jni: read: exit ret " << ret << dendl;
1679 handle_error(env, (int)ret);
1681 env->ReleaseByteArrayElements(j_buf, c_buf, 0);
1687 * Class: com_ceph_fs_CephMount
1688 * Method: native_ceph_write
1689 * Signature: (JI[BJJ)J
1691 JNIEXPORT jlong JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1write
1692 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jbyteArray j_buf, jlong j_size, jlong j_offset)
1694 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1695 CephContext *cct = ceph_get_mount_context(cmount);
1700 CHECK_ARG_NULL(j_buf, "@buf is null", -1);
1701 CHECK_ARG_BOUNDS(j_size < 0, "@size is negative", -1);
1702 CHECK_MOUNTED(cmount, -1);
1704 buf_size = env->GetArrayLength(j_buf);
1705 CHECK_ARG_BOUNDS(j_size > buf_size, "@size > @buf.length", -1);
1707 c_buf = env->GetByteArrayElements(j_buf, NULL);
1709 cephThrowInternal(env, "failed to pin memory");
1713 ldout(cct, 10) << "jni: write: fd " << (int)j_fd << " len " << (long)j_size <<
1714 " offset " << (long)j_offset << dendl;
1716 ret = ceph_write(cmount, (int)j_fd, (char*)c_buf, (long)j_size, (long)j_offset);
1718 ldout(cct, 10) << "jni: write: exit ret " << ret << dendl;
1721 handle_error(env, (int)ret);
1723 env->ReleaseByteArrayElements(j_buf, c_buf, JNI_ABORT);
1730 * Class: com_ceph_fs_CephMount
1731 * Method: native_ceph_ftruncate
1734 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1ftruncate
1735 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jlong j_size)
1737 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1738 CephContext *cct = ceph_get_mount_context(cmount);
1741 CHECK_MOUNTED(cmount, -1);
1743 ldout(cct, 10) << "jni: ftruncate: fd " << (int)j_fd <<
1744 " size " << (loff_t)j_size << dendl;
1746 ret = ceph_ftruncate(cmount, (int)j_fd, (loff_t)j_size);
1748 ldout(cct, 10) << "jni: ftruncate: exit ret " << ret << dendl;
1751 handle_error(env, ret);
1757 * Class: com_ceph_fs_CephMount
1758 * Method: native_ceph_fsync
1761 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1fsync
1762 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jboolean j_dataonly)
1764 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1765 CephContext *cct = ceph_get_mount_context(cmount);
1768 ldout(cct, 10) << "jni: fsync: fd " << (int)j_fd <<
1769 " dataonly " << (j_dataonly ? 1 : 0) << dendl;
1771 ret = ceph_fsync(cmount, (int)j_fd, j_dataonly ? 1 : 0);
1773 ldout(cct, 10) << "jni: fsync: exit ret " << ret << dendl;
1776 handle_error(env, ret);
1782 * Class: com_ceph_fs_CephMount
1783 * Method: native_ceph_flock
1786 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1flock
1787 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jint j_operation, jlong j_owner)
1789 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1790 CephContext *cct = ceph_get_mount_context(cmount);
1793 ldout(cct, 10) << "jni: flock: fd " << (int)j_fd <<
1794 " operation " << j_operation << " owner " << j_owner << dendl;
1798 #define MAP_FLOCK_FLAG(JNI_MASK, NATIVE_MASK) do { \
1799 if ((j_operation & JNI_MASK) != 0) { \
1800 operation |= NATIVE_MASK; \
1801 j_operation &= ~JNI_MASK; \
1804 MAP_FLOCK_FLAG(JAVA_LOCK_SH, LOCK_SH);
1805 MAP_FLOCK_FLAG(JAVA_LOCK_EX, LOCK_EX);
1806 MAP_FLOCK_FLAG(JAVA_LOCK_NB, LOCK_NB);
1807 MAP_FLOCK_FLAG(JAVA_LOCK_UN, LOCK_UN);
1808 if (j_operation != 0) {
1809 cephThrowIllegalArg(env, "flock flags");
1812 #undef MAP_FLOCK_FLAG
1814 ret = ceph_flock(cmount, (int)j_fd, operation, (uint64_t) j_owner);
1816 ldout(cct, 10) << "jni: flock: exit ret " << ret << dendl;
1819 handle_error(env, ret);
1825 * Class: com_ceph_fs_CephMount
1826 * Method: native_ceph_fstat
1827 * Signature: (JILcom/ceph/fs/CephStat;)I
1829 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1fstat
1830 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jobject j_cephstat)
1832 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1833 CephContext *cct = ceph_get_mount_context(cmount);
1834 struct ceph_statx stx;
1837 CHECK_ARG_NULL(j_cephstat, "@stat is null", -1);
1838 CHECK_MOUNTED(cmount, -1);
1840 ldout(cct, 10) << "jni: fstat: fd " << (int)j_fd << dendl;
1842 ret = ceph_fstatx(cmount, (int)j_fd, &stx, CEPH_J_CEPHSTAT_MASK, 0);
1844 ldout(cct, 10) << "jni: fstat exit ret " << ret << dendl;
1847 handle_error(env, ret);
1851 fill_cephstat(env, j_cephstat, &stx);
1857 * Class: com_ceph_fs_CephMount
1858 * Method: native_ceph_sync_fs
1861 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1sync_1fs
1862 (JNIEnv *env, jclass clz, jlong j_mntp)
1864 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1865 CephContext *cct = ceph_get_mount_context(cmount);
1868 ldout(cct, 10) << "jni: sync_fs: enter" << dendl;
1870 ret = ceph_sync_fs(cmount);
1872 ldout(cct, 10) << "jni: sync_fs: exit ret " << ret << dendl;
1875 handle_error(env, ret);
1881 * Class: com_ceph_fs_CephMount
1882 * Method: native_ceph_getxattr
1883 * Signature: (JLjava/lang/String;Ljava/lang/String;[B)J
1885 JNIEXPORT jlong JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1getxattr
1886 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name, jbyteArray j_buf)
1888 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1889 CephContext *cct = ceph_get_mount_context(cmount);
1893 jbyte *c_buf = NULL; /* please gcc with goto */
1896 CHECK_ARG_NULL(j_path, "@path is null", -1);
1897 CHECK_ARG_NULL(j_name, "@name is null", -1);
1898 CHECK_MOUNTED(cmount, -1);
1900 c_path = env->GetStringUTFChars(j_path, NULL);
1902 cephThrowInternal(env, "Failed to pin memory");
1906 c_name = env->GetStringUTFChars(j_name, NULL);
1908 env->ReleaseStringUTFChars(j_path, c_path);
1909 cephThrowInternal(env, "Failed to pin memory");
1913 /* just lookup the size if buf is null */
1919 c_buf = env->GetByteArrayElements(j_buf, NULL);
1921 env->ReleaseStringUTFChars(j_path, c_path);
1922 env->ReleaseStringUTFChars(j_name, c_name);
1923 cephThrowInternal(env, "failed to pin memory");
1927 buf_size = env->GetArrayLength(j_buf);
1931 ldout(cct, 10) << "jni: getxattr: path " << c_path << " name " << c_name <<
1932 " len " << buf_size << dendl;
1934 ret = ceph_getxattr(cmount, c_path, c_name, c_buf, buf_size);
1936 ret = ceph_getxattr(cmount, c_path, c_name, c_buf, 0);
1938 ldout(cct, 10) << "jni: getxattr: exit ret " << ret << dendl;
1940 env->ReleaseStringUTFChars(j_path, c_path);
1941 env->ReleaseStringUTFChars(j_name, c_name);
1943 env->ReleaseByteArrayElements(j_buf, c_buf, 0);
1946 handle_error(env, (int)ret);
1952 * Class: com_ceph_fs_CephMount
1953 * Method: native_ceph_lgetxattr
1954 * Signature: (JLjava/lang/String;Ljava/lang/String;[B)I
1956 JNIEXPORT jlong JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1lgetxattr
1957 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name, jbyteArray j_buf)
1959 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1960 CephContext *cct = ceph_get_mount_context(cmount);
1964 jbyte *c_buf = NULL; /* please gcc with goto */
1967 CHECK_ARG_NULL(j_path, "@path is null", -1);
1968 CHECK_ARG_NULL(j_name, "@name is null", -1);
1969 CHECK_MOUNTED(cmount, -1);
1971 c_path = env->GetStringUTFChars(j_path, NULL);
1973 cephThrowInternal(env, "Failed to pin memory");
1977 c_name = env->GetStringUTFChars(j_name, NULL);
1979 env->ReleaseStringUTFChars(j_path, c_path);
1980 cephThrowInternal(env, "Failed to pin memory");
1984 /* just lookup the size if buf is null */
1990 c_buf = env->GetByteArrayElements(j_buf, NULL);
1992 env->ReleaseStringUTFChars(j_path, c_path);
1993 env->ReleaseStringUTFChars(j_name, c_name);
1994 cephThrowInternal(env, "failed to pin memory");
1998 buf_size = env->GetArrayLength(j_buf);
2002 ldout(cct, 10) << "jni: lgetxattr: path " << c_path << " name " << c_name <<
2003 " len " << buf_size << dendl;
2005 ret = ceph_lgetxattr(cmount, c_path, c_name, c_buf, buf_size);
2007 ret = ceph_lgetxattr(cmount, c_path, c_name, c_buf, 0);
2009 ldout(cct, 10) << "jni: lgetxattr: exit ret " << ret << dendl;
2011 env->ReleaseStringUTFChars(j_path, c_path);
2012 env->ReleaseStringUTFChars(j_name, c_name);
2014 env->ReleaseByteArrayElements(j_buf, c_buf, 0);
2017 handle_error(env, (int)ret);
2023 * Class: com_ceph_fs_CephMount
2024 * Method: native_ceph_listxattr
2025 * Signature: (JLjava/lang/String;)[Ljava/lang/String;
2027 JNIEXPORT jobjectArray JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1listxattr
2028 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
2030 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2031 CephContext *cct = ceph_get_mount_context(cmount);
2032 jobjectArray xattrlist;
2036 list<string>::iterator it;
2037 list<string> contents;
2038 int ret, buflen, bufpos, i;
2041 CHECK_ARG_NULL(j_path, "@path is null", NULL);
2042 CHECK_MOUNTED(cmount, NULL);
2044 c_path = env->GetStringUTFChars(j_path, NULL);
2046 cephThrowInternal(env, "Failed to pin memory");
2051 buf = new (std::nothrow) char[buflen];
2053 cephThrowOutOfMemory(env, "head allocation failed");
2058 ldout(cct, 10) << "jni: listxattr: path " << c_path << " len " << buflen << dendl;
2059 ret = ceph_listxattr(cmount, c_path, buf, buflen);
2060 if (ret == -ERANGE) {
2063 buf = new (std::nothrow) char[buflen];
2065 cephThrowOutOfMemory(env, "heap allocation failed");
2073 ldout(cct, 10) << "jni: listxattr: ret " << ret << dendl;
2077 handle_error(env, ret);
2082 while (bufpos < ret) {
2083 ent = new (std::nothrow) string(buf + bufpos);
2086 cephThrowOutOfMemory(env, "heap allocation failed");
2089 contents.push_back(*ent);
2090 bufpos += ent->size() + 1;
2096 xattrlist = env->NewObjectArray(contents.size(), env->FindClass("java/lang/String"), NULL);
2100 for (i = 0, it = contents.begin(); it != contents.end(); ++it) {
2101 name = env->NewStringUTF(it->c_str());
2104 env->SetObjectArrayElement(xattrlist, i++, name);
2105 if (env->ExceptionOccurred())
2107 env->DeleteLocalRef(name);
2110 env->ReleaseStringUTFChars(j_path, c_path);
2114 env->ReleaseStringUTFChars(j_path, c_path);
2119 * Class: com_ceph_fs_CephMount
2120 * Method: native_ceph_llistxattr
2121 * Signature: (JLjava/lang/String;)[Ljava/lang/String;
2123 JNIEXPORT jobjectArray JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1llistxattr
2124 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
2126 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2127 CephContext *cct = ceph_get_mount_context(cmount);
2128 jobjectArray xattrlist;
2132 list<string>::iterator it;
2133 list<string> contents;
2134 int ret, buflen, bufpos, i;
2137 CHECK_ARG_NULL(j_path, "@path is null", NULL);
2138 CHECK_MOUNTED(cmount, NULL);
2140 c_path = env->GetStringUTFChars(j_path, NULL);
2142 cephThrowInternal(env, "Failed to pin memory");
2147 buf = new (std::nothrow) char[buflen];
2149 cephThrowOutOfMemory(env, "head allocation failed");
2154 ldout(cct, 10) << "jni: llistxattr: path " << c_path << " len " << buflen << dendl;
2155 ret = ceph_llistxattr(cmount, c_path, buf, buflen);
2156 if (ret == -ERANGE) {
2159 buf = new (std::nothrow) char[buflen];
2161 cephThrowOutOfMemory(env, "heap allocation failed");
2169 ldout(cct, 10) << "jni: llistxattr: ret " << ret << dendl;
2173 handle_error(env, ret);
2178 while (bufpos < ret) {
2179 ent = new (std::nothrow) string(buf + bufpos);
2182 cephThrowOutOfMemory(env, "heap allocation failed");
2185 contents.push_back(*ent);
2186 bufpos += ent->size() + 1;
2192 xattrlist = env->NewObjectArray(contents.size(), env->FindClass("java/lang/String"), NULL);
2196 for (i = 0, it = contents.begin(); it != contents.end(); ++it) {
2197 name = env->NewStringUTF(it->c_str());
2200 env->SetObjectArrayElement(xattrlist, i++, name);
2201 if (env->ExceptionOccurred())
2203 env->DeleteLocalRef(name);
2206 env->ReleaseStringUTFChars(j_path, c_path);
2210 env->ReleaseStringUTFChars(j_path, c_path);
2215 * Class: com_ceph_fs_CephMount
2216 * Method: native_ceph_removexattr
2217 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
2219 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1removexattr
2220 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name)
2222 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2223 CephContext *cct = ceph_get_mount_context(cmount);
2228 CHECK_ARG_NULL(j_path, "@path is null", -1);
2229 CHECK_ARG_NULL(j_name, "@name is null", -1);
2230 CHECK_MOUNTED(cmount, -1);
2232 c_path = env->GetStringUTFChars(j_path, NULL);
2234 cephThrowInternal(env, "Failed to pin memory");
2238 c_name = env->GetStringUTFChars(j_name, NULL);
2240 env->ReleaseStringUTFChars(j_path, c_path);
2241 cephThrowInternal(env, "Failed to pin memory");
2245 ldout(cct, 10) << "jni: removexattr: path " << c_path << " name " << c_name << dendl;
2247 ret = ceph_removexattr(cmount, c_path, c_name);
2249 ldout(cct, 10) << "jni: removexattr: exit ret " << ret << dendl;
2251 env->ReleaseStringUTFChars(j_path, c_path);
2252 env->ReleaseStringUTFChars(j_name, c_name);
2255 handle_error(env, ret);
2261 * Class: com_ceph_fs_CephMount
2262 * Method: native_ceph_lremovexattr
2263 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
2265 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1lremovexattr
2266 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name)
2268 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2269 CephContext *cct = ceph_get_mount_context(cmount);
2274 CHECK_ARG_NULL(j_path, "@path is null", -1);
2275 CHECK_ARG_NULL(j_name, "@name is null", -1);
2276 CHECK_MOUNTED(cmount, -1);
2278 c_path = env->GetStringUTFChars(j_path, NULL);
2280 cephThrowInternal(env, "Failed to pin memory");
2284 c_name = env->GetStringUTFChars(j_name, NULL);
2286 env->ReleaseStringUTFChars(j_path, c_path);
2287 cephThrowInternal(env, "Failed to pin memory");
2291 ldout(cct, 10) << "jni: lremovexattr: path " << c_path << " name " << c_name << dendl;
2293 ret = ceph_lremovexattr(cmount, c_path, c_name);
2295 ldout(cct, 10) << "jni: lremovexattr: exit ret " << ret << dendl;
2297 env->ReleaseStringUTFChars(j_path, c_path);
2298 env->ReleaseStringUTFChars(j_name, c_name);
2301 handle_error(env, ret);
2307 * Class: com_ceph_fs_CephMount
2308 * Method: native_ceph_setxattr
2309 * Signature: (JLjava/lang/String;Ljava/lang/String;[BJI)I
2311 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1setxattr
2312 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name,
2313 jbyteArray j_buf, jlong j_size, jint j_flags)
2315 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2316 CephContext *cct = ceph_get_mount_context(cmount);
2323 CHECK_ARG_NULL(j_path, "@path is null", -1);
2324 CHECK_ARG_NULL(j_name, "@name is null", -1);
2325 CHECK_ARG_NULL(j_buf, "@buf is null", -1);
2326 CHECK_ARG_BOUNDS(j_size < 0, "@size is negative", -1);
2327 CHECK_MOUNTED(cmount, -1);
2329 buf_size = env->GetArrayLength(j_buf);
2330 CHECK_ARG_BOUNDS(j_size > buf_size, "@size > @buf.length", -1);
2332 c_path = env->GetStringUTFChars(j_path, NULL);
2334 cephThrowInternal(env, "Failed to pin memory");
2338 c_name = env->GetStringUTFChars(j_name, NULL);
2340 env->ReleaseStringUTFChars(j_path, c_path);
2341 cephThrowInternal(env, "Failed to pin memory");
2345 c_buf = env->GetByteArrayElements(j_buf, NULL);
2347 env->ReleaseStringUTFChars(j_path, c_path);
2348 env->ReleaseStringUTFChars(j_name, c_name);
2349 cephThrowInternal(env, "failed to pin memory");
2354 case JAVA_XATTR_CREATE:
2355 flags = CEPH_XATTR_CREATE;
2357 case JAVA_XATTR_REPLACE:
2358 flags = CEPH_XATTR_REPLACE;
2360 case JAVA_XATTR_NONE:
2364 env->ReleaseStringUTFChars(j_path, c_path);
2365 env->ReleaseStringUTFChars(j_name, c_name);
2366 env->ReleaseByteArrayElements(j_buf, c_buf, JNI_ABORT);
2367 cephThrowIllegalArg(env, "setxattr flag");
2371 ldout(cct, 10) << "jni: setxattr: path " << c_path << " name " << c_name
2372 << " len " << j_size << " flags " << flags << dendl;
2374 ret = ceph_setxattr(cmount, c_path, c_name, c_buf, j_size, flags);
2376 ldout(cct, 10) << "jni: setxattr: exit ret " << ret << dendl;
2378 env->ReleaseStringUTFChars(j_path, c_path);
2379 env->ReleaseStringUTFChars(j_name, c_name);
2380 env->ReleaseByteArrayElements(j_buf, c_buf, JNI_ABORT);
2383 handle_error(env, ret);
2389 * Class: com_ceph_fs_CephMount
2390 * Method: native_ceph_lsetxattr
2391 * Signature: (JLjava/lang/String;Ljava/lang/String;[BJI)I
2393 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1lsetxattr
2394 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name,
2395 jbyteArray j_buf, jlong j_size, jint j_flags)
2397 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2398 CephContext *cct = ceph_get_mount_context(cmount);
2405 CHECK_ARG_NULL(j_path, "@path is null", -1);
2406 CHECK_ARG_NULL(j_name, "@name is null", -1);
2407 CHECK_ARG_NULL(j_buf, "@buf is null", -1);
2408 CHECK_ARG_BOUNDS(j_size < 0, "@size is negative", -1);
2409 CHECK_MOUNTED(cmount, -1);
2411 buf_size = env->GetArrayLength(j_buf);
2412 CHECK_ARG_BOUNDS(j_size > buf_size, "@size > @buf.length", -1);
2414 c_path = env->GetStringUTFChars(j_path, NULL);
2416 cephThrowInternal(env, "Failed to pin memory");
2420 c_name = env->GetStringUTFChars(j_name, NULL);
2422 env->ReleaseStringUTFChars(j_path, c_path);
2423 cephThrowInternal(env, "Failed to pin memory");
2427 c_buf = env->GetByteArrayElements(j_buf, NULL);
2429 env->ReleaseStringUTFChars(j_path, c_path);
2430 env->ReleaseStringUTFChars(j_name, c_name);
2431 cephThrowInternal(env, "failed to pin memory");
2436 case JAVA_XATTR_CREATE:
2437 flags = CEPH_XATTR_CREATE;
2439 case JAVA_XATTR_REPLACE:
2440 flags = CEPH_XATTR_REPLACE;
2442 case JAVA_XATTR_NONE:
2446 env->ReleaseStringUTFChars(j_path, c_path);
2447 env->ReleaseStringUTFChars(j_name, c_name);
2448 env->ReleaseByteArrayElements(j_buf, c_buf, JNI_ABORT);
2449 cephThrowIllegalArg(env, "lsetxattr flag");
2453 ldout(cct, 10) << "jni: lsetxattr: path " << c_path << " name " << c_name
2454 << " len " << j_size << " flags " << flags << dendl;
2456 ret = ceph_lsetxattr(cmount, c_path, c_name, c_buf, j_size, flags);
2458 ldout(cct, 10) << "jni: lsetxattr: exit ret " << ret << dendl;
2460 env->ReleaseStringUTFChars(j_path, c_path);
2461 env->ReleaseStringUTFChars(j_name, c_name);
2462 env->ReleaseByteArrayElements(j_buf, c_buf, JNI_ABORT);
2465 handle_error(env, ret);
2471 * Class: com_ceph_fs_CephMount
2472 * Method: native_ceph_get_file_stripe_unit
2475 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1file_1stripe_1unit
2476 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd)
2478 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2479 CephContext *cct = ceph_get_mount_context(cmount);
2482 CHECK_MOUNTED(cmount, -1);
2484 ldout(cct, 10) << "jni: get_file_stripe_unit: fd " << (int)j_fd << dendl;
2486 ret = ceph_get_file_stripe_unit(cmount, (int)j_fd);
2488 ldout(cct, 10) << "jni: get_file_stripe_unit: exit ret " << ret << dendl;
2491 handle_error(env, ret);
2497 * Class: com_ceph_fs_CephMount
2498 * Method: native_ceph_get_file_replication
2501 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1file_1replication
2502 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd)
2504 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2505 CephContext *cct = ceph_get_mount_context(cmount);
2508 CHECK_MOUNTED(cmount, -1);
2510 ldout(cct, 10) << "jni: get_file_replication: fd " << (int)j_fd << dendl;
2512 ret = ceph_get_file_replication(cmount, (int)j_fd);
2514 ldout(cct, 10) << "jni: get_file_replication: exit ret " << ret << dendl;
2517 handle_error(env, ret);
2523 * Class: com_ceph_fs_CephMount
2524 * Method: native_ceph_get_file_pool_name
2525 * Signature: (JI)Ljava/lang/String;
2527 JNIEXPORT jstring JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1file_1pool_1name
2528 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd)
2530 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2531 CephContext *cct = ceph_get_mount_context(cmount);
2532 jstring pool = NULL;
2533 int ret, buflen = 0;
2536 CHECK_MOUNTED(cmount, NULL);
2538 ldout(cct, 10) << "jni: get_file_pool_name: fd " << (int)j_fd << dendl;
2541 /* get pool name length (len==0) */
2542 ret = ceph_get_file_pool_name(cmount, (int)j_fd, NULL, 0);
2546 /* allocate buffer */
2550 buf = new (std::nothrow) char[buflen+1]; /* +1 for '\0' */
2552 cephThrowOutOfMemory(env, "head allocation failed");
2555 memset(buf, 0, (buflen+1)*sizeof(*buf));
2557 /* handle zero-length pool name!? */
2562 ret = ceph_get_file_pool_name(cmount, (int)j_fd, buf, buflen);
2563 if (ret == -ERANGE) /* size changed! */
2569 ldout(cct, 10) << "jni: get_file_pool_name: ret " << ret << dendl;
2572 handle_error(env, ret);
2574 pool = env->NewStringUTF(buf);
2584 * Class: com_ceph_fs_CephMount
2585 * Method: native_ceph_get_default_data_pool_name
2586 * Signature: (J)Ljava/lang/String;
2588 JNIEXPORT jstring JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1default_1data_1pool_1name
2589 (JNIEnv *env, jclass clz, jlong j_mntp)
2591 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2592 CephContext *cct = ceph_get_mount_context(cmount);
2593 jstring pool = NULL;
2594 int ret, buflen = 0;
2597 CHECK_MOUNTED(cmount, NULL);
2599 ldout(cct, 10) << "jni: get_default_data_pool_name" << dendl;
2601 ret = ceph_get_default_data_pool_name(cmount, NULL, 0);
2605 buf = new (std::nothrow) char[buflen+1]; /* +1 for '\0' */
2607 cephThrowOutOfMemory(env, "head allocation failed");
2610 memset(buf, 0, (buflen+1)*sizeof(*buf));
2611 ret = ceph_get_default_data_pool_name(cmount, buf, buflen);
2613 ldout(cct, 10) << "jni: get_default_data_pool_name: ret " << ret << dendl;
2616 handle_error(env, ret);
2618 pool = env->NewStringUTF(buf);
2629 * Class: com_ceph_fs_CephMount
2630 * Method: native_ceph_localize_reads
2633 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1localize_1reads
2634 (JNIEnv *env, jclass clz, jlong j_mntp, jboolean j_on)
2636 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2637 CephContext *cct = ceph_get_mount_context(cmount);
2638 int ret, val = j_on ? 1 : 0;
2640 CHECK_MOUNTED(cmount, -1);
2642 ldout(cct, 10) << "jni: localize_reads: val " << val << dendl;
2644 ret = ceph_localize_reads(cmount, val);
2646 ldout(cct, 10) << "jni: localize_reads: exit ret " << ret << dendl;
2649 handle_error(env, ret);
2655 * Class: com_ceph_fs_CephMount
2656 * Method: native_ceph_get_stripe_unit_granularity
2659 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1stripe_1unit_1granularity
2660 (JNIEnv *env, jclass clz, jlong j_mntp)
2662 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2663 CephContext *cct = ceph_get_mount_context(cmount);
2666 CHECK_MOUNTED(cmount, -1);
2668 ldout(cct, 10) << "jni: get_stripe_unit_granularity" << dendl;
2670 ret = ceph_get_stripe_unit_granularity(cmount);
2672 ldout(cct, 10) << "jni: get_stripe_unit_granularity: exit ret " << ret << dendl;
2675 handle_error(env, ret);
2681 * Class: com_ceph_fs_CephMount
2682 * Method: native_ceph_get_pool_id
2683 * Signature: (JLjava/lang/String;)I
2685 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1pool_1id
2686 (JNIEnv *env, jclass clz, jlong j_mntp, jstring jname)
2688 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2689 CephContext *cct = ceph_get_mount_context(cmount);
2693 CHECK_MOUNTED(cmount, -1);
2694 CHECK_ARG_NULL(jname, "@name is null", -1);
2696 c_name = env->GetStringUTFChars(jname, NULL);
2698 cephThrowInternal(env, "failed to pin memory");
2702 ldout(cct, 10) << "jni: get_pool_id: name " << c_name << dendl;
2704 ret = ceph_get_pool_id(cmount, c_name);
2706 handle_error(env, ret);
2708 ldout(cct, 10) << "jni: get_pool_id: ret " << ret << dendl;
2710 env->ReleaseStringUTFChars(jname, c_name);
2716 * Class: com_ceph_fs_CephMount
2717 * Method: native_ceph_get_pool_replication
2720 JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1pool_1replication
2721 (JNIEnv *env, jclass clz, jlong j_mntp, jint jpoolid)
2723 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2724 CephContext *cct = ceph_get_mount_context(cmount);
2727 CHECK_MOUNTED(cmount, -1);
2729 ldout(cct, 10) << "jni: get_pool_replication: poolid " << jpoolid << dendl;
2731 ret = ceph_get_pool_replication(cmount, jpoolid);
2733 handle_error(env, ret);
2735 ldout(cct, 10) << "jni: get_pool_replication: ret " << ret << dendl;
2741 * Class: com_ceph_fs_CephMount
2742 * Method: native_ceph_get_file_extent_osds
2743 * Signature: (JIJ)Lcom/ceph/fs/CephFileExtent;
2745 JNIEXPORT jobject JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1file_1extent_1osds
2746 (JNIEnv *env, jclass clz, jlong mntp, jint fd, jlong off)
2748 struct ceph_mount_info *cmount = get_ceph_mount(mntp);
2749 CephContext *cct = ceph_get_mount_context(cmount);
2750 jobject extent = NULL;
2751 int ret, nosds, *osds = NULL;
2752 jintArray osd_array;
2755 CHECK_MOUNTED(cmount, NULL);
2757 ldout(cct, 10) << "jni: get_file_extent_osds: fd " << fd << " off " << off << dendl;
2761 ret = ceph_get_file_extent_osds(cmount, fd, off, NULL, NULL, 0);
2765 /* alloc osd id array */
2769 osds = new int[nosds];
2772 ret = ceph_get_file_extent_osds(cmount, fd, off, &len, osds, nosds);
2779 ldout(cct, 10) << "jni: get_file_extent_osds: ret " << ret << dendl;
2782 handle_error(env, ret);
2788 osd_array = env->NewIntArray(nosds);
2792 env->SetIntArrayRegion(osd_array, 0, nosds, osds);
2793 if (env->ExceptionOccurred())
2796 extent = env->NewObject(cephfileextent_cls, cephfileextent_ctor_fid, off, len, osd_array);
2808 * Class: com_ceph_fs_CephMount
2809 * Method: native_ceph_get_osd_crush_location
2810 * Signature: (JI)[Ljava/lang/String;
2812 JNIEXPORT jobjectArray JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1osd_1crush_1location
2813 (JNIEnv *env, jclass clz, jlong j_mntp, jint osdid)
2815 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2816 CephContext *cct = ceph_get_mount_context(cmount);
2817 jobjectArray path = NULL;
2818 vector<string> str_path;
2819 int ret, bufpos, buflen = 0;
2822 CHECK_MOUNTED(cmount, NULL);
2824 ldout(cct, 10) << "jni: osd loc: osd " << osdid << dendl;
2827 /* get length of the location path */
2828 ret = ceph_get_osd_crush_location(cmount, osdid, NULL, 0);
2832 /* alloc path buffer */
2836 buf = new char[buflen+1];
2837 memset(buf, 0, buflen*sizeof(*buf));
2844 ret = ceph_get_osd_crush_location(cmount, osdid, buf, buflen);
2851 ldout(cct, 10) << "jni: osd loc: osd " << osdid << " ret " << ret << dendl;
2854 handle_error(env, ret);
2859 while (bufpos < ret) {
2860 string type(buf + bufpos);
2861 bufpos += type.size() + 1;
2862 string name(buf + bufpos);
2863 bufpos += name.size() + 1;
2864 str_path.push_back(type);
2865 str_path.push_back(name);
2868 path = env->NewObjectArray(str_path.size(), env->FindClass("java/lang/String"), NULL);
2872 for (unsigned i = 0; i < str_path.size(); i++) {
2873 jstring ent = env->NewStringUTF(str_path[i].c_str());
2876 env->SetObjectArrayElement(path, i, ent);
2877 if (env->ExceptionOccurred())
2879 env->DeleteLocalRef(ent);
2890 * sockaddrToInetAddress uses with the following license, and is adapted for
2891 * use in this project by using Ceph JNI exception utilities.
2895 * Copyright (C) 2010 The Android Open Source Project
2897 * Licensed under the Apache License, Version 2.0 (the "License");
2898 * you may not use this file except in compliance with the License.
2899 * You may obtain a copy of the License at
2901 * http://www.apache.org/licenses/LICENSE-2.0
2903 * Unless required by applicable law or agreed to in writing, software
2904 * distributed under the License is distributed on an "AS IS" BASIS,
2905 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2906 * See the License for the specific language governing permissions and
2907 * limitations under the License.
2909 jobject sockaddrToInetAddress(JNIEnv* env, const sockaddr_storage& ss, jint* port) {
2910 // Convert IPv4-mapped IPv6 addresses to IPv4 addresses.
2911 // The RI states "Java will never return an IPv4-mapped address".
2912 const sockaddr_in6& sin6 = reinterpret_cast<const sockaddr_in6&>(ss);
2913 if (ss.ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
2914 // Copy the IPv6 address into the temporary sockaddr_storage.
2915 sockaddr_storage tmp;
2916 memset(&tmp, 0, sizeof(tmp));
2917 memcpy(&tmp, &ss, sizeof(sockaddr_in6));
2918 // Unmap it into an IPv4 address.
2919 sockaddr_in& sin = reinterpret_cast<sockaddr_in&>(tmp);
2920 sin.sin_family = AF_INET;
2921 sin.sin_port = sin6.sin6_port;
2922 memcpy(&sin.sin_addr.s_addr, &sin6.sin6_addr.s6_addr[12], 4);
2923 // Do the regular conversion using the unmapped address.
2924 return sockaddrToInetAddress(env, tmp, port);
2927 const void* rawAddress;
2928 size_t addressLength;
2931 if (ss.ss_family == AF_INET) {
2932 const sockaddr_in& sin = reinterpret_cast<const sockaddr_in&>(ss);
2933 rawAddress = &sin.sin_addr.s_addr;
2935 sin_port = ntohs(sin.sin_port);
2936 } else if (ss.ss_family == AF_INET6) {
2937 const sockaddr_in6& sin6 = reinterpret_cast<const sockaddr_in6&>(ss);
2938 rawAddress = &sin6.sin6_addr.s6_addr;
2940 sin_port = ntohs(sin6.sin6_port);
2941 scope_id = sin6.sin6_scope_id;
2942 } else if (ss.ss_family == AF_UNIX) {
2943 const sockaddr_un& sun = reinterpret_cast<const sockaddr_un&>(ss);
2944 rawAddress = &sun.sun_path;
2945 addressLength = strlen(sun.sun_path);
2947 // We can't throw SocketException. We aren't meant to see bad addresses, so seeing one
2948 // really does imply an internal error.
2949 //jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
2950 // "sockaddrToInetAddress unsupported ss_family: %i", ss.ss_family);
2951 cephThrowIllegalArg(env, "sockaddrToInetAddress unsupposed ss_family");
2958 ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(addressLength));
2959 if (byteArray.get() == NULL) {
2962 env->SetByteArrayRegion(byteArray.get(), 0, addressLength,
2963 reinterpret_cast<jbyte*>(const_cast<void*>(rawAddress)));
2965 if (ss.ss_family == AF_UNIX) {
2966 // Note that we get here for AF_UNIX sockets on accept(2). The unix(7) man page claims
2967 // that the peer's sun_path will contain the path, but in practice it doesn't, and the
2968 // peer length is returned as 2 (meaning only the sun_family field was set).
2970 // Ceph Note: this isn't supported. inetUnixAddress appears to just be
2971 // something in Dalvik/Android stuff.
2972 cephThrowInternal(env, "OSD address should never be a UNIX socket");
2974 //static jmethodID ctor = env->GetMethodID(JniConstants::inetUnixAddressClass, "<init>", "([B)V");
2975 //return env->NewObject(JniConstants::inetUnixAddressClass, ctor, byteArray.get());
2978 if (addressLength == 4) {
2979 static jmethodID getByAddressMethod = env->GetStaticMethodID(JniConstants::inetAddressClass,
2980 "getByAddress", "(Ljava/lang/String;[B)Ljava/net/InetAddress;");
2981 if (getByAddressMethod == NULL) {
2984 return env->CallStaticObjectMethod(JniConstants::inetAddressClass, getByAddressMethod,
2985 NULL, byteArray.get());
2986 } else if (addressLength == 16) {
2987 static jmethodID getByAddressMethod = env->GetStaticMethodID(JniConstants::inet6AddressClass,
2988 "getByAddress", "(Ljava/lang/String;[BI)Ljava/net/Inet6Address;");
2989 if (getByAddressMethod == NULL) {
2992 return env->CallStaticObjectMethod(JniConstants::inet6AddressClass, getByAddressMethod,
2993 NULL, byteArray.get(), scope_id);
3001 * Class: com_ceph_fs_CephMount
3002 * Method: native_ceph_get_osd_addr
3003 * Signature: (JI)Ljava/net/InetAddress;
3005 JNIEXPORT jobject JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1osd_1addr
3006 (JNIEnv *env, jclass clz, jlong j_mntp, jint osd)
3008 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
3009 CephContext *cct = ceph_get_mount_context(cmount);
3010 struct sockaddr_storage addr;
3013 CHECK_MOUNTED(cmount, NULL);
3015 ldout(cct, 10) << "jni: get_osd_addr: osd " << osd << dendl;
3017 ret = ceph_get_osd_addr(cmount, osd, &addr);
3019 ldout(cct, 10) << "jni: get_osd_addr: ret " << ret << dendl;
3022 handle_error(env, ret);
3026 return sockaddrToInetAddress(env, addr, NULL);