]> git.proxmox.com Git - ceph.git/blame - ceph/src/java/native/libcephfs_jni.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / java / native / libcephfs_jni.cc
CommitLineData
7c673cae
FG
1/*
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:
8 *
9 * The above copyright notice and this permission notice shall be included in
10 * all copies or substantial portions of the Software.
11 *
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.
19 */
20#include <sys/types.h>
21#include <sys/stat.h>
22#include <string.h>
23#include <errno.h>
24#include <unistd.h>
25#include <fcntl.h>
26#include <sys/un.h>
27#include <jni.h>
28
29#include "ScopedLocalRef.h"
30#include "JniConstants.h"
31
32#include "include/cephfs/libcephfs.h"
33#include "common/dout.h"
34
35#define dout_subsys ceph_subsys_javaclient
36
37#include "com_ceph_fs_CephMount.h"
38
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"
47
48/*
49 * Flags to open(). must be synchronized with CephMount.java
50 *
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.
56 */
57#define JAVA_O_RDONLY 1
58#define JAVA_O_RDWR 2
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
65
66/*
67 * Whence flags for seek(). sync with CephMount.java if changed.
68 *
69 * Mapping of SEEK_* done in seek function.
70 */
71#define JAVA_SEEK_SET 1
72#define JAVA_SEEK_CUR 2
73#define JAVA_SEEK_END 3
74
75/*
76 * File attribute flags. sync with CephMount.java if changed.
77 */
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
83
84/*
85 * Setxattr flags. sync with CephMount.java if changed.
86 */
87#define JAVA_XATTR_CREATE 1
88#define JAVA_XATTR_REPLACE 2
89#define JAVA_XATTR_NONE 3
90
91/*
92 * flock flags. sync with CephMount.java if changed.
93 */
94#define JAVA_LOCK_SH 1
95#define JAVA_LOCK_EX 2
96#define JAVA_LOCK_NB 4
97#define JAVA_LOCK_UN 8
98
20effc67
TL
99using namespace std;
100
7c673cae
FG
101/* Map JAVA_O_* open flags to values in libc */
102static inline int fixup_open_flags(jint jflags)
103{
104 int ret = 0;
105
106#define FIXUP_OPEN_FLAG(name) \
107 if (jflags & JAVA_##name) \
108 ret |= name;
109
110 FIXUP_OPEN_FLAG(O_RDONLY)
111 FIXUP_OPEN_FLAG(O_RDWR)
112 FIXUP_OPEN_FLAG(O_APPEND)
113 FIXUP_OPEN_FLAG(O_CREAT)
114 FIXUP_OPEN_FLAG(O_TRUNC)
115 FIXUP_OPEN_FLAG(O_EXCL)
116 FIXUP_OPEN_FLAG(O_WRONLY)
117 FIXUP_OPEN_FLAG(O_DIRECTORY)
118
119#undef FIXUP_OPEN_FLAG
120
121 return ret;
122}
123
124/* Map JAVA_SETATTR_* to values in ceph lib */
125static inline int fixup_attr_mask(jint jmask)
126{
127 int mask = 0;
128
129#define FIXUP_ATTR_MASK(name) \
130 if (jmask & JAVA_##name) \
131 mask |= CEPH_##name;
132
133 FIXUP_ATTR_MASK(SETATTR_MODE)
134 FIXUP_ATTR_MASK(SETATTR_UID)
135 FIXUP_ATTR_MASK(SETATTR_GID)
136 FIXUP_ATTR_MASK(SETATTR_MTIME)
137 FIXUP_ATTR_MASK(SETATTR_ATIME)
138
139#undef FIXUP_ATTR_MASK
140
141 return mask;
142}
143
144/* Cached field IDs for com.ceph.fs.CephStat */
145static jfieldID cephstat_mode_fid;
146static jfieldID cephstat_uid_fid;
147static jfieldID cephstat_gid_fid;
148static jfieldID cephstat_size_fid;
149static jfieldID cephstat_blksize_fid;
150static jfieldID cephstat_blocks_fid;
151static jfieldID cephstat_a_time_fid;
152static jfieldID cephstat_m_time_fid;
153static jfieldID cephstat_is_file_fid;
154static jfieldID cephstat_is_directory_fid;
155static jfieldID cephstat_is_symlink_fid;
156
157/* Cached field IDs for com.ceph.fs.CephStatVFS */
158static jfieldID cephstatvfs_bsize_fid;
159static jfieldID cephstatvfs_frsize_fid;
160static jfieldID cephstatvfs_blocks_fid;
161static jfieldID cephstatvfs_bavail_fid;
162static jfieldID cephstatvfs_files_fid;
163static jfieldID cephstatvfs_fsid_fid;
164static jfieldID cephstatvfs_namemax_fid;
165
166/* Cached field IDs for com.ceph.fs.CephMount */
167static jfieldID cephmount_instance_ptr_fid;
168
169/* Cached field IDs for com.ceph.fs.CephFileExtent */
170static jclass cephfileextent_cls;
171static jmethodID cephfileextent_ctor_fid;
172
173/*
174 * Exception throwing helper. Adapted from Apache Hadoop header
175 * org_apache_hadoop.h by adding the do {} while (0) construct.
176 */
177#define THROW(env, exception_name, message) \
178 do { \
179 jclass ecls = env->FindClass(exception_name); \
180 if (ecls) { \
181 int ret = env->ThrowNew(ecls, message); \
182 if (ret < 0) { \
183 printf("(CephFS) Fatal Error\n"); \
184 } \
185 env->DeleteLocalRef(ecls); \
186 } \
187 } while (0)
188
189
190static void cephThrowNullArg(JNIEnv *env, const char *msg)
191{
192 THROW(env, "java/lang/NullPointerException", msg);
193}
194
195static void cephThrowOutOfMemory(JNIEnv *env, const char *msg)
196{
197 THROW(env, "java/lang/OutOfMemoryError", msg);
198}
199
200static void cephThrowInternal(JNIEnv *env, const char *msg)
201{
202 THROW(env, "java/lang/InternalError", msg);
203}
204
205static void cephThrowIndexBounds(JNIEnv *env, const char *msg)
206{
207 THROW(env, "java/lang/IndexOutOfBoundsException", msg);
208}
209
210static void cephThrowIllegalArg(JNIEnv *env, const char *msg)
211{
212 THROW(env, "java/lang/IllegalArgumentException", msg);
213}
214
215static void cephThrowFNF(JNIEnv *env, const char *msg)
216{
217 THROW(env, "java/io/FileNotFoundException", msg);
218}
219
220static void cephThrowFileExists(JNIEnv *env, const char *msg)
221{
222 THROW(env, CEPH_FILEEXISTS_CP, msg);
223}
224
225static void cephThrowNotDir(JNIEnv *env, const char *msg)
226{
227 THROW(env, CEPH_NOTDIR_CP, msg);
228}
229
230static void handle_error(JNIEnv *env, int rc)
231{
232 switch (rc) {
233 case -ENOENT:
234 cephThrowFNF(env, "");
235 return;
236 case -EEXIST:
237 cephThrowFileExists(env, "");
238 return;
239 case -ENOTDIR:
240 cephThrowNotDir(env, "");
241 return;
242 default:
243 break;
244 }
245
246 THROW(env, "java/io/IOException", strerror(-rc));
247}
248
249#define CHECK_ARG_NULL(v, m, r) do { \
250 if (!(v)) { \
251 cephThrowNullArg(env, (m)); \
252 return (r); \
253 } } while (0)
254
255#define CHECK_ARG_BOUNDS(c, m, r) do { \
256 if ((c)) { \
257 cephThrowIndexBounds(env, (m)); \
258 return (r); \
259 } } while (0)
260
261#define CHECK_MOUNTED(_c, _r) do { \
262 if (!ceph_is_mounted((_c))) { \
263 THROW(env, CEPH_NOTMOUNTED_CP, "not mounted"); \
264 return (_r); \
265 } } while (0)
266
267/*
268 * Cast a jlong to ceph_mount_info. Each JNI function is expected to pass in
269 * the class instance variable instance_ptr. Passing a parameter is faster
11fdf7f2 270 * than reaching back into Java via an upcall to retrieve this pointer.
7c673cae
FG
271 */
272static inline struct ceph_mount_info *get_ceph_mount(jlong j_mntp)
273{
274 return (struct ceph_mount_info *)j_mntp;
275}
276
277/*
278 * Setup cached field IDs
279 */
280static void setup_field_ids(JNIEnv *env, jclass clz)
281{
282 jclass cephstat_cls;
283 jclass cephstatvfs_cls;
284 jclass tmp_cephfileextent_cls;
285
286/*
287 * Get a fieldID from a class with a specific type
288 *
289 * clz: jclass
290 * field: field in clz
291 * type: integer, long, etc..
292 *
293 * This macro assumes some naming convention that is used
294 * only in this file:
295 *
296 * GETFID(cephstat, mode, I) gets translated into
297 * cephstat_mode_fid = env->GetFieldID(cephstat_cls, "mode", "I");
298 */
299#define GETFID(clz, field, type) do { \
300 clz ## _ ## field ## _fid = env->GetFieldID(clz ## _cls, #field, #type); \
301 if ( ! clz ## _ ## field ## _fid ) \
302 return; \
303 } while (0)
304
305 /* Cache CephStat fields */
306
307 cephstat_cls = env->FindClass(CEPH_STAT_CP);
308 if (!cephstat_cls)
309 return;
310
311 GETFID(cephstat, mode, I);
312 GETFID(cephstat, uid, I);
313 GETFID(cephstat, gid, I);
314 GETFID(cephstat, size, J);
315 GETFID(cephstat, blksize, J);
316 GETFID(cephstat, blocks, J);
317 GETFID(cephstat, a_time, J);
318 GETFID(cephstat, m_time, J);
319 GETFID(cephstat, is_file, Z);
320 GETFID(cephstat, is_directory, Z);
321 GETFID(cephstat, is_symlink, Z);
322
323 /* Cache CephStatVFS fields */
324
325 cephstatvfs_cls = env->FindClass(CEPH_STAT_VFS_CP);
326 if (!cephstatvfs_cls)
327 return;
328
329 GETFID(cephstatvfs, bsize, J);
330 GETFID(cephstatvfs, frsize, J);
331 GETFID(cephstatvfs, blocks, J);
332 GETFID(cephstatvfs, bavail, J);
333 GETFID(cephstatvfs, files, J);
334 GETFID(cephstatvfs, fsid, J);
335 GETFID(cephstatvfs, namemax, J);
336
337 /* Cache CephFileExtent fields */
338
339 tmp_cephfileextent_cls = env->FindClass(CEPH_FILE_EXTENT_CP);
340 if (!tmp_cephfileextent_cls)
341 return;
342
343 cephfileextent_cls = (jclass)env->NewGlobalRef(tmp_cephfileextent_cls);
344 env->DeleteLocalRef(tmp_cephfileextent_cls);
345
346 cephfileextent_ctor_fid = env->GetMethodID(cephfileextent_cls, "<init>", "(JJ[I)V");
347 if (!cephfileextent_ctor_fid)
348 return;
349
350 JniConstants::init(env);
351
352#undef GETFID
353
354 cephmount_instance_ptr_fid = env->GetFieldID(clz, "instance_ptr", "J");
355}
356
357
358/*
359 * Class: com_ceph_fs_CephMount
360 * Method: native_initialize
361 * Signature: ()V
362 */
363JNIEXPORT void JNICALL Java_com_ceph_fs_CephMount_native_1initialize
364 (JNIEnv *env, jclass clz)
365{
366 setup_field_ids(env, clz);
367}
368
369/*
370 * Class: com_ceph_fs_CephMount
371 * Method: native_ceph_create
372 * Signature: (Lcom/ceph/fs/CephMount;Ljava/lang/String;)I
373 */
374JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1create
375 (JNIEnv *env, jclass clz, jobject j_cephmount, jstring j_id)
376{
377 struct ceph_mount_info *cmount;
378 const char *c_id = NULL;
379 int ret;
380
381 CHECK_ARG_NULL(j_cephmount, "@mount is null", -1);
382
383 if (j_id) {
384 c_id = env->GetStringUTFChars(j_id, NULL);
385 if (!c_id) {
386 cephThrowInternal(env, "Failed to pin memory");
387 return -1;
388 }
389 }
390
391 ret = ceph_create(&cmount, c_id);
392
393 if (c_id)
394 env->ReleaseStringUTFChars(j_id, c_id);
395
396 if (ret) {
397 THROW(env, "java/lang/RuntimeException", "failed to create Ceph mount object");
398 return ret;
399 }
400
401 env->SetLongField(j_cephmount, cephmount_instance_ptr_fid, (long)cmount);
402
403 return ret;
404}
405
406/*
407 * Class: com_ceph_fs_CephMount
408 * Method: native_ceph_mount
409 * Signature: (JLjava/lang/String;)I
410 */
411JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1mount
412 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_root)
413{
414 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
415 CephContext *cct = ceph_get_mount_context(cmount);
416 const char *c_root = NULL;
417 int ret;
418
419 /*
420 * Toss a message up if we are already mounted.
421 */
422 if (ceph_is_mounted(cmount)) {
423 THROW(env, CEPH_ALREADYMOUNTED_CP, "");
424 return -1;
425 }
426
427 if (j_root) {
428 c_root = env->GetStringUTFChars(j_root, NULL);
429 if (!c_root) {
430 cephThrowInternal(env, "Failed to pin memory");
431 return -1;
432 }
433 }
434
435 ldout(cct, 10) << "jni: ceph_mount: " << (c_root ? c_root : "<NULL>") << dendl;
436
437 ret = ceph_mount(cmount, c_root);
438
439 ldout(cct, 10) << "jni: ceph_mount: exit ret " << ret << dendl;
440
441 if (c_root)
442 env->ReleaseStringUTFChars(j_root, c_root);
443
444 if (ret)
445 handle_error(env, ret);
446
447 return ret;
448}
449
450/*
451 * Class: com_ceph_fs_CephMount
452 * Method: native_ceph_unmount
453 * Signature: (J)I
454 */
455JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1unmount
456 (JNIEnv *env, jclass clz, jlong j_mntp)
457{
458 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
459 CephContext *cct = ceph_get_mount_context(cmount);
460 int ret;
461
462 ldout(cct, 10) << "jni: ceph_unmount enter" << dendl;
463
464 CHECK_MOUNTED(cmount, -1);
465
466 ret = ceph_unmount(cmount);
467
468 ldout(cct, 10) << "jni: ceph_unmount exit ret " << ret << dendl;
469
470 if (ret)
471 handle_error(env, ret);
472
473 return ret;
474}
475
476/*
477 * Class: com_ceph_fs_CephMount
478 * Method: native_ceph_release
479 * Signature: (J)I
480 */
481JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1release
482 (JNIEnv *env, jclass clz, jlong j_mntp)
483{
484 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
485 CephContext *cct = ceph_get_mount_context(cmount);
486 int ret;
487
488 ldout(cct, 10) << "jni: ceph_release called" << dendl;
489
490 ret = ceph_release(cmount);
491
492 if (ret)
493 handle_error(env, ret);
494
495 return ret;
496}
497
498/*
499 * Class: com_ceph_fs_CephMount
500 * Method: native_ceph_conf_set
501 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
502 */
503JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1conf_1set
504 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_opt, jstring j_val)
505{
506 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
507 CephContext *cct = ceph_get_mount_context(cmount);
508 const char *c_opt, *c_val;
509 int ret;
510
511 CHECK_ARG_NULL(j_opt, "@option is null", -1);
512 CHECK_ARG_NULL(j_val, "@value is null", -1);
513
514 c_opt = env->GetStringUTFChars(j_opt, NULL);
515 if (!c_opt) {
516 cephThrowInternal(env, "failed to pin memory");
517 return -1;
518 }
519
520 c_val = env->GetStringUTFChars(j_val, NULL);
521 if (!c_val) {
522 env->ReleaseStringUTFChars(j_opt, c_opt);
523 cephThrowInternal(env, "failed to pin memory");
524 return -1;
525 }
526
527 ldout(cct, 10) << "jni: conf_set: opt " << c_opt << " val " << c_val << dendl;
528
529 ret = ceph_conf_set(cmount, c_opt, c_val);
530
531 ldout(cct, 10) << "jni: conf_set: exit ret " << ret << dendl;
532
533 env->ReleaseStringUTFChars(j_opt, c_opt);
534 env->ReleaseStringUTFChars(j_val, c_val);
535
536 if (ret)
537 handle_error(env, ret);
538
539 return ret;
540}
541
542/*
543 * Class: com_ceph_fs_CephMount
544 * Method: native_ceph_conf_get
545 * Signature: (JLjava/lang/String;)Ljava/lang/String;
546 */
547JNIEXPORT jstring JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1conf_1get
548 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_opt)
549{
550 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
551 CephContext *cct = ceph_get_mount_context(cmount);
552 const char *c_opt;
553 jstring value = NULL;
554 int ret, buflen;
555 char *buf;
556
557 CHECK_ARG_NULL(j_opt, "@option is null", NULL);
558
559 c_opt = env->GetStringUTFChars(j_opt, NULL);
560 if (!c_opt) {
561 cephThrowInternal(env, "failed to pin memory");
562 return NULL;
563 }
564
565 buflen = 128;
566 buf = new (std::nothrow) char[buflen];
567 if (!buf) {
568 cephThrowOutOfMemory(env, "head allocation failed");
569 goto out;
570 }
571
572 while (1) {
573 memset(buf, 0, sizeof(char)*buflen);
574 ldout(cct, 10) << "jni: conf_get: opt " << c_opt << " len " << buflen << dendl;
575 ret = ceph_conf_get(cmount, c_opt, buf, buflen);
576 if (ret == -ENAMETOOLONG) {
577 buflen *= 2;
578 delete [] buf;
579 buf = new (std::nothrow) char[buflen];
580 if (!buf) {
581 cephThrowOutOfMemory(env, "head allocation failed");
582 goto out;
583 }
584 } else
585 break;
586 }
587
588 ldout(cct, 10) << "jni: conf_get: ret " << ret << dendl;
589
590 if (ret == 0)
591 value = env->NewStringUTF(buf);
592 else if (ret != -ENOENT)
593 handle_error(env, ret);
594
595 delete [] buf;
596
597out:
598 env->ReleaseStringUTFChars(j_opt, c_opt);
599 return value;
600}
601
602/*
603 * Class: com_ceph_fs_CephMount
604 * Method: native_ceph_conf_read_file
605 * Signature: (JLjava/lang/String;)I
606 */
607JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1conf_1read_1file
608 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
609{
610 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
611 CephContext *cct = ceph_get_mount_context(cmount);
612 const char *c_path;
613 int ret;
614
615 CHECK_ARG_NULL(j_path, "@path is null", -1);
616
617 c_path = env->GetStringUTFChars(j_path, NULL);
618 if (!c_path) {
619 cephThrowInternal(env, "failed to pin memory");
620 return -1;
621 }
622
623 ldout(cct, 10) << "jni: conf_read_file: path " << c_path << dendl;
624
625 ret = ceph_conf_read_file(cmount, c_path);
626
627 ldout(cct, 10) << "jni: conf_read_file: exit ret " << ret << dendl;
628
629 env->ReleaseStringUTFChars(j_path, c_path);
630
631 if (ret)
632 handle_error(env, ret);
633
634 return ret;
635}
636
637/*
638 * Class: com_ceph_fs_CephMount
639 * Method: native_ceph_statfs
640 * Signature: (JLjava/lang/String;Lcom/ceph/fs/CephStatVFS;)I
641 */
642JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1statfs
643 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jobject j_cephstatvfs)
644{
645 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
646 CephContext *cct = ceph_get_mount_context(cmount);
647 const char *c_path;
648 struct statvfs st;
649 int ret;
650
651 CHECK_ARG_NULL(j_path, "@path is null", -1);
652 CHECK_ARG_NULL(j_cephstatvfs, "@stat is null", -1);
653 CHECK_MOUNTED(cmount, -1);
654
655 c_path = env->GetStringUTFChars(j_path, NULL);
656 if (!c_path) {
657 cephThrowInternal(env, "Failed to pin memory");
658 return -1;
659 }
660
661 ldout(cct, 10) << "jni: statfs: path " << c_path << dendl;
662
663 ret = ceph_statfs(cmount, c_path, &st);
664
665 ldout(cct, 10) << "jni: statfs: exit ret " << ret << dendl;
666
667 env->ReleaseStringUTFChars(j_path, c_path);
668
669 if (ret) {
670 handle_error(env, ret);
671 return ret;
672 }
673
674 env->SetLongField(j_cephstatvfs, cephstatvfs_bsize_fid, st.f_bsize);
675 env->SetLongField(j_cephstatvfs, cephstatvfs_frsize_fid, st.f_frsize);
676 env->SetLongField(j_cephstatvfs, cephstatvfs_blocks_fid, st.f_blocks);
677 env->SetLongField(j_cephstatvfs, cephstatvfs_bavail_fid, st.f_bavail);
678 env->SetLongField(j_cephstatvfs, cephstatvfs_files_fid, st.f_files);
679 env->SetLongField(j_cephstatvfs, cephstatvfs_fsid_fid, st.f_fsid);
680 env->SetLongField(j_cephstatvfs, cephstatvfs_namemax_fid, st.f_namemax);
681
682 return ret;
683}
684
685/*
686 * Class: com_ceph_fs_CephMount
687 * Method: native_ceph_getcwd
688 * Signature: (J)Ljava/lang/String;
689 */
690JNIEXPORT jstring JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1getcwd
691 (JNIEnv *env, jclass clz, jlong j_mntp)
692{
693 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
694 CephContext *cct = ceph_get_mount_context(cmount);
695 const char *c_cwd;
696
697 CHECK_MOUNTED(cmount, NULL);
698
699 ldout(cct, 10) << "jni: getcwd: enter" << dendl;
700
701 c_cwd = ceph_getcwd(cmount);
702 if (!c_cwd) {
703 cephThrowOutOfMemory(env, "ceph_getcwd");
704 return NULL;
705 }
706
707 ldout(cct, 10) << "jni: getcwd: exit ret " << c_cwd << dendl;
708
709 return env->NewStringUTF(c_cwd);
710}
711
712/*
713 * Class: com_ceph_fs_CephMount
714 * Method: native_ceph_chdir
715 * Signature: (JLjava/lang/String;)I
716 */
717JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1chdir
718 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
719{
720 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
721 CephContext *cct = ceph_get_mount_context(cmount);
722 const char *c_path;
723 int ret;
724
725 CHECK_ARG_NULL(j_path, "@path is null", -1);
726 CHECK_MOUNTED(cmount, -1);
727
728 c_path = env->GetStringUTFChars(j_path, NULL);
729 if (!c_path) {
730 cephThrowInternal(env, "failed to pin memory");
731 return -1;
732 }
733
734 ldout(cct, 10) << "jni: chdir: path " << c_path << dendl;
735
736 ret = ceph_chdir(cmount, c_path);
737
738 ldout(cct, 10) << "jni: chdir: exit ret " << ret << dendl;
739
740 env->ReleaseStringUTFChars(j_path, c_path);
741
742 if (ret)
743 handle_error(env, ret);
744
745 return ret;
746}
747
748/*
749 * Class: com_ceph_fs_CephMount
750 * Method: native_ceph_listdir
751 * Signature: (JLjava/lang/String;)[Ljava/lang/String;
752 */
753JNIEXPORT jobjectArray JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1listdir
754 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
755{
756 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
757 CephContext *cct = ceph_get_mount_context(cmount);
758 struct ceph_dir_result *dirp;
759 list<string>::iterator it;
760 list<string> contents;
761 const char *c_path;
762 jobjectArray dirlist;
763 string *ent;
764 int ret, buflen, bufpos, i;
765 jstring name;
766 char *buf;
767
768 CHECK_ARG_NULL(j_path, "@path is null", NULL);
769 CHECK_MOUNTED(cmount, NULL);
770
771 c_path = env->GetStringUTFChars(j_path, NULL);
772 if (!c_path) {
773 cephThrowInternal(env, "failed to pin memory");
774 return NULL;
775 }
776
777 ldout(cct, 10) << "jni: listdir: opendir: path " << c_path << dendl;
778
779 /* ret < 0 also includes -ENOTDIR which should return NULL */
780 ret = ceph_opendir(cmount, c_path, &dirp);
781 if (ret) {
782 env->ReleaseStringUTFChars(j_path, c_path);
783 handle_error(env, ret);
784 return NULL;
785 }
786
787 ldout(cct, 10) << "jni: listdir: opendir: exit ret " << ret << dendl;
788
789 /* buffer for ceph_getdnames() results */
790 buflen = 256;
791 buf = new (std::nothrow) char[buflen];
792 if (!buf) {
793 cephThrowOutOfMemory(env, "heap allocation failed");
794 goto out;
795 }
796
797 while (1) {
798 ldout(cct, 10) << "jni: listdir: getdnames: enter" << dendl;
799 ret = ceph_getdnames(cmount, dirp, buf, buflen);
800 if (ret == -ERANGE) {
801 delete [] buf;
802 buflen *= 2;
803 buf = new (std::nothrow) char[buflen];
804 if (!buf) {
805 cephThrowOutOfMemory(env, "heap allocation failed");
806 goto out;
807 }
808 continue;
809 }
810
811 ldout(cct, 10) << "jni: listdir: getdnames: exit ret " << ret << dendl;
812
813 if (ret <= 0)
814 break;
815
816 /* got at least one name */
817 bufpos = 0;
818 while (bufpos < ret) {
819 ent = new (std::nothrow) string(buf + bufpos);
820 if (!ent) {
821 delete [] buf;
822 cephThrowOutOfMemory(env, "heap allocation failed");
823 goto out;
824 }
825
826 /* filter out dot files: xref: java.io.File::list() */
827 if (ent->compare(".") && ent->compare("..")) {
828 contents.push_back(*ent);
829 ldout(cct, 20) << "jni: listdir: take path " << *ent << dendl;
830 }
831
832 bufpos += ent->size() + 1;
833 delete ent;
834 }
835 }
836
837 delete [] buf;
838
839 if (ret < 0) {
840 handle_error(env, ret);
841 goto out;
842 }
843
844 /* directory list */
845 dirlist = env->NewObjectArray(contents.size(), env->FindClass("java/lang/String"), NULL);
846 if (!dirlist)
847 goto out;
848
849 /*
850 * Fill directory listing array.
851 *
852 * FIXME: how should a partially filled array be cleaned-up properly?
853 */
854 for (i = 0, it = contents.begin(); it != contents.end(); ++it) {
855 name = env->NewStringUTF(it->c_str());
856 if (!name)
857 goto out;
858 env->SetObjectArrayElement(dirlist, i++, name);
859 if (env->ExceptionOccurred())
860 goto out;
861 env->DeleteLocalRef(name);
862 }
863
864 env->ReleaseStringUTFChars(j_path, c_path);
865 ceph_closedir(cmount, dirp);
866
867 return dirlist;
868
869out:
870 env->ReleaseStringUTFChars(j_path, c_path);
871 ceph_closedir(cmount, dirp);
872 return NULL;
873}
874
875/*
876 * Class: com_ceph_fs_CephMount
877 * Method: native_ceph_link
878 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
879 */
880JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1link
881 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_oldpath, jstring j_newpath)
882{
883 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
884 CephContext *cct = ceph_get_mount_context(cmount);
885 const char *c_oldpath, *c_newpath;
886 int ret;
887
888 CHECK_ARG_NULL(j_oldpath, "@oldpath is null", -1);
889 CHECK_ARG_NULL(j_newpath, "@newpath is null", -1);
890 CHECK_MOUNTED(cmount, -1);
891
892 c_oldpath = env->GetStringUTFChars(j_oldpath, NULL);
893 if (!c_oldpath) {
894 cephThrowInternal(env, "failed to pin memory");
895 return -1;
896 }
897
898 c_newpath = env->GetStringUTFChars(j_newpath, NULL);
899 if (!c_newpath) {
900 env->ReleaseStringUTFChars(j_oldpath, c_oldpath);
901 cephThrowInternal(env, "failed to pin memory");
902 return -1;
903 }
904
905 ldout(cct, 10) << "jni: link: oldpath " << c_oldpath <<
906 " newpath " << c_newpath << dendl;
907
908 ret = ceph_link(cmount, c_oldpath, c_newpath);
909
910 ldout(cct, 10) << "jni: link: exit ret " << ret << dendl;
911
912 env->ReleaseStringUTFChars(j_oldpath, c_oldpath);
913 env->ReleaseStringUTFChars(j_newpath, c_newpath);
914
915 if (ret)
916 handle_error(env, ret);
917
918 return ret;
919}
920
921/*
922 * Class: com_ceph_fs_CephMount
923 * Method: native_ceph_unlink
924 * Signature: (JLjava/lang/String;)I
925 */
926JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1unlink
927 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
928{
929 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
930 CephContext *cct = ceph_get_mount_context(cmount);
931 const char *c_path;
932 int ret;
933
934 CHECK_ARG_NULL(j_path, "@path is null", -1);
935 CHECK_MOUNTED(cmount, -1);
936
937 c_path = env->GetStringUTFChars(j_path, NULL);
938 if (!c_path) {
939 cephThrowInternal(env, "failed to pin memory");
940 return -1;
941 }
942
943 ldout(cct, 10) << "jni: unlink: path " << c_path << dendl;
944
945 ret = ceph_unlink(cmount, c_path);
946
947 ldout(cct, 10) << "jni: unlink: exit ret " << ret << dendl;
948
949 env->ReleaseStringUTFChars(j_path, c_path);
950
951 if (ret)
952 handle_error(env, ret);
953
954 return ret;
955}
956
957/*
958 * Class: com_ceph_fs_CephMount
959 * Method: native_ceph_rename
960 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
961 */
962JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1rename
963 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_from, jstring j_to)
964{
965 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
966 CephContext *cct = ceph_get_mount_context(cmount);
967 const char *c_from, *c_to;
968 int ret;
969
970 CHECK_ARG_NULL(j_from, "@from is null", -1);
971 CHECK_ARG_NULL(j_to, "@to is null", -1);
972 CHECK_MOUNTED(cmount, -1);
973
974 c_from = env->GetStringUTFChars(j_from, NULL);
975 if (!c_from) {
976 cephThrowInternal(env, "Failed to pin memory!");
977 return -1;
978 }
979
980 c_to = env->GetStringUTFChars(j_to, NULL);
981 if (!c_to) {
982 env->ReleaseStringUTFChars(j_from, c_from);
983 cephThrowInternal(env, "Failed to pin memory.");
984 return -1;
985 }
986
987 ldout(cct, 10) << "jni: rename: from " << c_from << " to " << c_to << dendl;
988
989 ret = ceph_rename(cmount, c_from, c_to);
990
991 ldout(cct, 10) << "jni: rename: exit ret " << ret << dendl;
992
993 env->ReleaseStringUTFChars(j_from, c_from);
994 env->ReleaseStringUTFChars(j_to, c_to);
995
996 if (ret)
997 handle_error(env, ret);
998
999 return ret;
1000}
1001
1002/*
1003 * Class: com_ceph_fs_CephMount
1004 * Method: native_ceph_mkdir
1005 * Signature: (JLjava/lang/String;I)I
1006 */
1007JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1mkdir
1008 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jint j_mode)
1009{
1010 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1011 CephContext *cct = ceph_get_mount_context(cmount);
1012 const char *c_path;
1013 int ret;
1014
1015 CHECK_ARG_NULL(j_path, "@path is null", -1);
1016 CHECK_MOUNTED(cmount, -1);
1017
1018 c_path = env->GetStringUTFChars(j_path, NULL);
1019 if (!c_path) {
1020 cephThrowInternal(env, "failed to pin memory");
1021 return -1;
1022 }
1023
1024 ldout(cct, 10) << "jni: mkdir: path " << c_path << " mode " << (int)j_mode << dendl;
1025
1026 ret = ceph_mkdir(cmount, c_path, (int)j_mode);
1027
1028 ldout(cct, 10) << "jni: mkdir: exit ret " << ret << dendl;
1029
1030 env->ReleaseStringUTFChars(j_path, c_path);
1031
1032 if (ret)
1033 handle_error(env, ret);
1034
1035 return ret;
1036}
1037
1038/*
1039 * Class: com_ceph_fs_CephMount
1040 * Method: native_ceph_mkdirs
1041 * Signature: (JLjava/lang/String;I)I
1042 */
1043JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1mkdirs
1044 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jint j_mode)
1045{
1046 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1047 CephContext *cct = ceph_get_mount_context(cmount);
1048 const char *c_path;
1049 int ret;
1050
1051 CHECK_ARG_NULL(j_path, "@path is null", -1);
1052 CHECK_MOUNTED(cmount, -1);
1053
1054 c_path = env->GetStringUTFChars(j_path, NULL);
1055 if (!c_path) {
1056 cephThrowInternal(env, "failed to pin memory");
1057 return -1;
1058 }
1059
1060 ldout(cct, 10) << "jni: mkdirs: path " << c_path << " mode " << (int)j_mode << dendl;
1061
1062 ret = ceph_mkdirs(cmount, c_path, (int)j_mode);
1063
1064 ldout(cct, 10) << "jni: mkdirs: exit ret " << ret << dendl;
1065
1066 env->ReleaseStringUTFChars(j_path, c_path);
1067
1068 if (ret)
1069 handle_error(env, ret);
1070
1071 return ret;
1072}
1073
1074/*
1075 * Class: com_ceph_fs_CephMount
1076 * Method: native_ceph_rmdir
1077 * Signature: (JLjava/lang/String;)I
1078 */
1079JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1rmdir
1080 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
1081{
1082 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1083 CephContext *cct = ceph_get_mount_context(cmount);
1084 const char *c_path;
1085 int ret;
1086
1087 CHECK_ARG_NULL(j_path, "@path is null", -1);
1088 CHECK_MOUNTED(cmount, -1);
1089
1090 c_path = env->GetStringUTFChars(j_path, NULL);
1091 if (!c_path) {
1092 cephThrowInternal(env, "failed to pin memory");
1093 return -1;
1094 }
1095
1096 ldout(cct, 10) << "jni: rmdir: path " << c_path << dendl;
1097
1098 ret = ceph_rmdir(cmount, c_path);
1099
1100 ldout(cct, 10) << "jni: rmdir: exit ret " << ret << dendl;
1101
1102 env->ReleaseStringUTFChars(j_path, c_path);
1103
1104 if (ret)
1105 handle_error(env, ret);
1106
1107 return ret;
1108}
1109
1110/*
1111 * Class: com_ceph_fs_CephMount
1112 * Method: native_ceph_readlink
1113 * Signature: (JLjava/lang/String;)Ljava/lang/String;
1114 */
1115JNIEXPORT jstring JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1readlink
1116 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
1117{
1118 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1119 CephContext *cct = ceph_get_mount_context(cmount);
1120 const char *c_path;
1121 char *linkname;
1122 struct ceph_statx stx;
1123 jstring j_linkname;
1124
1125 CHECK_ARG_NULL(j_path, "@path is null", NULL);
1126 CHECK_MOUNTED(cmount, NULL);
1127
1128 c_path = env->GetStringUTFChars(j_path, NULL);
1129 if (!c_path) {
1130 cephThrowInternal(env, "failed to pin memory");
1131 return NULL;
1132 }
1133
1134 for (;;) {
1135 ldout(cct, 10) << "jni: readlink: lstatx " << c_path << dendl;
1136 int ret = ceph_statx(cmount, c_path, &stx, CEPH_STATX_SIZE,
1137 AT_SYMLINK_NOFOLLOW);
1138 ldout(cct, 10) << "jni: readlink: lstat exit ret " << ret << dendl;
1139 if (ret) {
1140 env->ReleaseStringUTFChars(j_path, c_path);
1141 handle_error(env, ret);
1142 return NULL;
1143 }
1144
1145 linkname = new (std::nothrow) char[stx.stx_size + 1];
1146 if (!linkname) {
1147 env->ReleaseStringUTFChars(j_path, c_path);
1148 cephThrowOutOfMemory(env, "head allocation failed");
1149 return NULL;
1150 }
1151
1152 ldout(cct, 10) << "jni: readlink: size " << stx.stx_size << " path " << c_path << dendl;
1153
1154 ret = ceph_readlink(cmount, c_path, linkname, stx.stx_size + 1);
1155
1156 ldout(cct, 10) << "jni: readlink: exit ret " << ret << dendl;
1157
1158 if (ret < 0) {
1159 delete [] linkname;
1160 env->ReleaseStringUTFChars(j_path, c_path);
1161 handle_error(env, ret);
1162 return NULL;
1163 }
1164
1165 /* re-stat and try again */
1166 if (ret > (int)stx.stx_size) {
1167 delete [] linkname;
1168 continue;
1169 }
1170
1171 linkname[ret] = '\0';
1172 break;
1173 }
1174
1175 env->ReleaseStringUTFChars(j_path, c_path);
1176
1177 j_linkname = env->NewStringUTF(linkname);
1178 delete [] linkname;
1179
1180 return j_linkname;
1181}
1182
1183/*
1184 * Class: com_ceph_fs_CephMount
1185 * Method: native_ceph_symlink
1186 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
1187 */
1188JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1symlink
1189 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_oldpath, jstring j_newpath)
1190{
1191 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1192 CephContext *cct = ceph_get_mount_context(cmount);
1193 const char *c_oldpath, *c_newpath;
1194 int ret;
1195
1196 CHECK_ARG_NULL(j_oldpath, "@oldpath is null", -1);
1197 CHECK_ARG_NULL(j_newpath, "@newpath is null", -1);
1198 CHECK_MOUNTED(cmount, -1);
1199
1200 c_oldpath = env->GetStringUTFChars(j_oldpath, NULL);
1201 if (!c_oldpath) {
1202 cephThrowInternal(env, "failed to pin memory");
1203 return -1;
1204 }
1205
1206 c_newpath = env->GetStringUTFChars(j_newpath, NULL);
1207 if (!c_newpath) {
1208 env->ReleaseStringUTFChars(j_oldpath, c_oldpath);
1209 cephThrowInternal(env, "failed to pin memory");
1210 return -1;
1211 }
1212
1213 ldout(cct, 10) << "jni: symlink: oldpath " << c_oldpath <<
1214 " newpath " << c_newpath << dendl;
1215
1216 ret = ceph_symlink(cmount, c_oldpath, c_newpath);
1217
1218 ldout(cct, 10) << "jni: symlink: exit ret " << ret << dendl;
1219
1220 env->ReleaseStringUTFChars(j_oldpath, c_oldpath);
1221 env->ReleaseStringUTFChars(j_newpath, c_newpath);
1222
1223 if (ret)
1224 handle_error(env, ret);
1225
1226 return ret;
1227}
1228
1229#define CEPH_J_CEPHSTAT_MASK (CEPH_STATX_UID|CEPH_STATX_GID|CEPH_STATX_SIZE|CEPH_STATX_BLOCKS|CEPH_STATX_MTIME|CEPH_STATX_ATIME)
1230
1231static void fill_cephstat(JNIEnv *env, jobject j_cephstat, struct ceph_statx *stx)
1232{
1233 env->SetIntField(j_cephstat, cephstat_mode_fid, stx->stx_mode);
1234 env->SetIntField(j_cephstat, cephstat_uid_fid, stx->stx_uid);
1235 env->SetIntField(j_cephstat, cephstat_gid_fid, stx->stx_gid);
1236 env->SetLongField(j_cephstat, cephstat_size_fid, stx->stx_size);
1237 env->SetLongField(j_cephstat, cephstat_blksize_fid, stx->stx_blksize);
1238 env->SetLongField(j_cephstat, cephstat_blocks_fid, stx->stx_blocks);
1239
1240 long long time = stx->stx_mtime.tv_sec;
1241 time *= 1000;
1242 time += stx->stx_mtime.tv_nsec / 1000000;
1243 env->SetLongField(j_cephstat, cephstat_m_time_fid, time);
1244
1245 time = stx->stx_atime.tv_sec;
1246 time *= 1000;
1247 time += stx->stx_atime.tv_nsec / 1000000;
1248 env->SetLongField(j_cephstat, cephstat_a_time_fid, time);
1249
1250 env->SetBooleanField(j_cephstat, cephstat_is_file_fid,
1251 S_ISREG(stx->stx_mode) ? JNI_TRUE : JNI_FALSE);
1252
1253 env->SetBooleanField(j_cephstat, cephstat_is_directory_fid,
1254 S_ISDIR(stx->stx_mode) ? JNI_TRUE : JNI_FALSE);
1255
1256 env->SetBooleanField(j_cephstat, cephstat_is_symlink_fid,
1257 S_ISLNK(stx->stx_mode) ? JNI_TRUE : JNI_FALSE);
1258}
1259
1260/*
1261 * Class: com_ceph_fs_CephMount
1262 * Method: native_ceph_lstat
1263 * Signature: (JLjava/lang/String;Lcom/ceph/fs/CephStat;)I
1264 */
1265JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1lstat
1266 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jobject j_cephstat)
1267{
1268 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1269 CephContext *cct = ceph_get_mount_context(cmount);
1270 const char *c_path;
1271 struct ceph_statx stx;
1272 int ret;
1273
1274 CHECK_ARG_NULL(j_path, "@path is null", -1);
1275 CHECK_ARG_NULL(j_cephstat, "@stat is null", -1);
1276 CHECK_MOUNTED(cmount, -1);
1277
1278 c_path = env->GetStringUTFChars(j_path, NULL);
1279 if (!c_path) {
1280 cephThrowInternal(env, "Failed to pin memory");
1281 return -1;
1282 }
1283
1284 ldout(cct, 10) << "jni: lstat: path " << c_path << dendl;
1285
1286 ret = ceph_statx(cmount, c_path, &stx, CEPH_J_CEPHSTAT_MASK, AT_SYMLINK_NOFOLLOW);
1287
1288 ldout(cct, 10) << "jni: lstat exit ret " << ret << dendl;
1289
1290 env->ReleaseStringUTFChars(j_path, c_path);
1291
1292 if (ret) {
1293 handle_error(env, ret);
1294 return ret;
1295 }
1296
1297 fill_cephstat(env, j_cephstat, &stx);
1298
1299 return ret;
1300}
1301
1302/*
1303 * Class: com_ceph_fs_CephMount
1304 * Method: native_ceph_stat
1305 * Signature: (JLjava/lang/String;Lcom/ceph/fs/CephStat;)I
1306 */
1307JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1stat
1308 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jobject j_cephstat)
1309{
1310 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1311 CephContext *cct = ceph_get_mount_context(cmount);
1312 const char *c_path;
1313 struct ceph_statx stx;
1314 int ret;
1315
1316 CHECK_ARG_NULL(j_path, "@path is null", -1);
1317 CHECK_ARG_NULL(j_cephstat, "@stat is null", -1);
1318 CHECK_MOUNTED(cmount, -1);
1319
1320 c_path = env->GetStringUTFChars(j_path, NULL);
1321 if (!c_path) {
1322 cephThrowInternal(env, "Failed to pin memory");
1323 return -1;
1324 }
1325
11fdf7f2 1326 ldout(cct, 10) << "jni: stat: path " << c_path << dendl;
7c673cae
FG
1327
1328 ret = ceph_statx(cmount, c_path, &stx, CEPH_J_CEPHSTAT_MASK, 0);
1329
11fdf7f2 1330 ldout(cct, 10) << "jni: stat exit ret " << ret << dendl;
7c673cae
FG
1331
1332 env->ReleaseStringUTFChars(j_path, c_path);
1333
1334 if (ret) {
1335 handle_error(env, ret);
1336 return ret;
1337 }
1338
1339 fill_cephstat(env, j_cephstat, &stx);
1340
1341 return ret;
1342}
1343
1344/*
1345 * Class: com_ceph_fs_CephMount
1346 * Method: native_ceph_setattr
1347 * Signature: (JLjava/lang/String;Lcom/ceph/fs/CephStat;I)I
1348 */
1349JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1setattr
1350 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jobject j_cephstat, jint j_mask)
1351{
1352 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1353 CephContext *cct = ceph_get_mount_context(cmount);
1354 const char *c_path;
1355 struct ceph_statx stx;
1356 int ret, mask = fixup_attr_mask(j_mask);
1357
1358 CHECK_ARG_NULL(j_path, "@path is null", -1);
1359 CHECK_ARG_NULL(j_cephstat, "@stat is null", -1);
1360 CHECK_MOUNTED(cmount, -1);
1361
1362 c_path = env->GetStringUTFChars(j_path, NULL);
1363 if (!c_path) {
1364 cephThrowInternal(env, "Failed to pin memory");
1365 return -1;
1366 }
1367
1368 memset(&stx, 0, sizeof(stx));
1369
1370 stx.stx_mode = env->GetIntField(j_cephstat, cephstat_mode_fid);
1371 stx.stx_uid = env->GetIntField(j_cephstat, cephstat_uid_fid);
1372 stx.stx_gid = env->GetIntField(j_cephstat, cephstat_gid_fid);
11fdf7f2
TL
1373 long mtime_msec = env->GetLongField(j_cephstat, cephstat_m_time_fid);
1374 long atime_msec = env->GetLongField(j_cephstat, cephstat_a_time_fid);
1375 stx.stx_mtime.tv_sec = mtime_msec / 1000;
1376 stx.stx_mtime.tv_nsec = (mtime_msec % 1000) * 1000000;
1377 stx.stx_atime.tv_sec = atime_msec / 1000;
1378 stx.stx_atime.tv_nsec = (atime_msec % 1000) * 1000000;
1379
7c673cae
FG
1380 ldout(cct, 10) << "jni: setattr: path " << c_path << " mask " << mask << dendl;
1381
1382 ret = ceph_setattrx(cmount, c_path, &stx, mask, 0);
1383
1384 ldout(cct, 10) << "jni: setattr: exit ret " << ret << dendl;
1385
1386 env->ReleaseStringUTFChars(j_path, c_path);
1387
1388 if (ret)
1389 handle_error(env, ret);
1390
1391 return ret;
1392}
1393
1394/*
1395 * Class: com_ceph_fs_CephMount
1396 * Method: native_ceph_chmod
1397 * Signature: (JLjava/lang/String;I)I
1398 */
1399JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1chmod
1400 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jint j_mode)
1401{
1402 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1403 CephContext *cct = ceph_get_mount_context(cmount);
1404 const char *c_path;
1405 int ret;
1406
1407 CHECK_ARG_NULL(j_path, "@path is null", -1);
1408 CHECK_MOUNTED(cmount, -1);
1409
1410 c_path = env->GetStringUTFChars(j_path, NULL);
1411 if (!c_path) {
1412 cephThrowInternal(env, "Failed to pin memory");
1413 return -1;
1414 }
1415
1416 ldout(cct, 10) << "jni: chmod: path " << c_path << " mode " << (int)j_mode << dendl;
1417
1418 ret = ceph_chmod(cmount, c_path, (int)j_mode);
1419
1420 ldout(cct, 10) << "jni: chmod: exit ret " << ret << dendl;
1421
1422 env->ReleaseStringUTFChars(j_path, c_path);
1423
1424 if (ret)
1425 handle_error(env, ret);
1426
1427 return ret;
1428}
1429
1430/*
1431 * Class: com_ceph_fs_CephMount
1432 * Method: native_ceph_fchmod
1433 * Signature: (JII)I
1434 */
1435JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1fchmod
1436 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jint j_mode)
1437{
1438 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1439 CephContext *cct = ceph_get_mount_context(cmount);
1440 int ret;
1441
1442 CHECK_MOUNTED(cmount, -1);
1443
1444 ldout(cct, 10) << "jni: fchmod: fd " << (int)j_fd << " mode " << (int)j_mode << dendl;
1445
1446 ret = ceph_fchmod(cmount, (int)j_fd, (int)j_mode);
1447
1448 ldout(cct, 10) << "jni: fchmod: exit ret " << ret << dendl;
1449
1450 if (ret)
1451 handle_error(env, ret);
1452
1453 return ret;
1454}
1455
1456/*
1457 * Class: com_ceph_fs_CephMount
1458 * Method: native_ceph_truncate
1459 * Signature: (JLjava/lang/String;J)I
1460 */
1461JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1truncate
1462 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jlong j_size)
1463{
1464 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1465 CephContext *cct = ceph_get_mount_context(cmount);
1466 const char *c_path;
1467 int ret;
1468
1469 CHECK_ARG_NULL(j_path, "@path is null", -1);
1470 CHECK_MOUNTED(cmount, -1);
1471
1472 c_path = env->GetStringUTFChars(j_path, NULL);
1473 if (!c_path) {
1474 cephThrowInternal(env, "Failed to pin memory");
1475 return -1;
1476 }
1477
1478 ldout(cct, 10) << "jni: truncate: path " << c_path << " size " << (loff_t)j_size << dendl;
1479
1480 ret = ceph_truncate(cmount, c_path, (loff_t)j_size);
1481
1482 ldout(cct, 10) << "jni: truncate: exit ret " << ret << dendl;
1483
1484 env->ReleaseStringUTFChars(j_path, c_path);
1485
1486 if (ret)
1487 handle_error(env, ret);
1488
1489 return ret;
1490}
1491
1492/*
1493 * Class: com_ceph_fs_CephMount
1494 * Method: native_ceph_open
1495 * Signature: (JLjava/lang/String;II)I
1496 */
1497JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1open
1498 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jint j_flags, jint j_mode)
1499{
1500 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1501 CephContext *cct = ceph_get_mount_context(cmount);
1502 const char *c_path;
1503 int ret, flags = fixup_open_flags(j_flags);
1504
1505 CHECK_ARG_NULL(j_path, "@path is null", -1);
1506 CHECK_MOUNTED(cmount, -1);
1507
1508 c_path = env->GetStringUTFChars(j_path, NULL);
1509 if (!c_path) {
1510 cephThrowInternal(env, "Failed to pin memory");
1511 return -1;
1512 }
1513
1514 ldout(cct, 10) << "jni: open: path " << c_path << " flags " << flags
1515 << " mode " << (int)j_mode << dendl;
1516
1517 ret = ceph_open(cmount, c_path, flags, (int)j_mode);
1518
1519 ldout(cct, 10) << "jni: open: exit ret " << ret << dendl;
1520
1521 env->ReleaseStringUTFChars(j_path, c_path);
1522
1523 if (ret < 0)
1524 handle_error(env, ret);
1525
1526 return ret;
1527}
1528
1529/*
1530 * Class: com_ceph_fs_CephMount
1531 * Method: native_ceph_open_layout
1532 * Signature: (JLjava/lang/String;IIIIILjava/lang/String;)I
1533 */
1534JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1open_1layout
1535 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jint j_flags, jint j_mode,
1536 jint stripe_unit, jint stripe_count, jint object_size, jstring j_data_pool)
1537{
1538 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1539 CephContext *cct = ceph_get_mount_context(cmount);
1540 const char *c_path, *c_data_pool = NULL;
1541 int ret, flags = fixup_open_flags(j_flags);
1542
1543 CHECK_ARG_NULL(j_path, "@path is null", -1);
1544 CHECK_MOUNTED(cmount, -1);
1545
1546 c_path = env->GetStringUTFChars(j_path, NULL);
1547 if (!c_path) {
1548 cephThrowInternal(env, "Failed to pin memory");
1549 return -1;
1550 }
1551
1552 if (j_data_pool) {
1553 c_data_pool = env->GetStringUTFChars(j_data_pool, NULL);
1554 if (!c_data_pool) {
1555 env->ReleaseStringUTFChars(j_path, c_path);
1556 cephThrowInternal(env, "Failed to pin memory");
1557 return -1;
1558 }
1559 }
1560
1561 ldout(cct, 10) << "jni: open_layout: path " << c_path << " flags " << flags
1562 << " mode " << (int)j_mode << " stripe_unit " << stripe_unit
1563 << " stripe_count " << stripe_count << " object_size " << object_size
1564 << " data_pool " << (c_data_pool ? c_data_pool : "<NULL>") << dendl;
1565
1566 ret = ceph_open_layout(cmount, c_path, flags, (int)j_mode,
1567 (int)stripe_unit, (int)stripe_count, (int)object_size, c_data_pool);
1568
1569 ldout(cct, 10) << "jni: open_layout: exit ret " << ret << dendl;
1570
1571 env->ReleaseStringUTFChars(j_path, c_path);
1572 if (j_data_pool)
1573 env->ReleaseStringUTFChars(j_data_pool, c_data_pool);
1574
1575 if (ret < 0)
1576 handle_error(env, ret);
1577
1578 return ret;
1579}
1580
1581/*
1582 * Class: com_ceph_fs_CephMount
1583 * Method: native_ceph_close
1584 * Signature: (JI)I
1585 */
1586JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1close
1587 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd)
1588{
1589 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1590 CephContext *cct = ceph_get_mount_context(cmount);
1591 int ret;
1592
1593 CHECK_MOUNTED(cmount, -1);
1594
1595 ldout(cct, 10) << "jni: close: fd " << (int)j_fd << dendl;
1596
1597 ret = ceph_close(cmount, (int)j_fd);
1598
1599 ldout(cct, 10) << "jni: close: ret " << ret << dendl;
1600
1601 if (ret)
1602 handle_error(env, ret);
1603
1604 return ret;
1605}
1606
1607/*
1608 * Class: com_ceph_fs_CephMount
1609 * Method: native_ceph_lseek
1610 * Signature: (JIJI)J
1611 */
1612JNIEXPORT jlong JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1lseek
1613 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jlong j_offset, jint j_whence)
1614{
1615 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1616 CephContext *cct = ceph_get_mount_context(cmount);
1617 int whence;
1618 jlong ret;
1619
1620 CHECK_MOUNTED(cmount, -1);
1621
1622 switch (j_whence) {
1623 case JAVA_SEEK_SET:
1624 whence = SEEK_SET;
1625 break;
1626 case JAVA_SEEK_CUR:
1627 whence = SEEK_CUR;
1628 break;
1629 case JAVA_SEEK_END:
1630 whence = SEEK_END;
1631 break;
1632 default:
1633 cephThrowIllegalArg(env, "Unknown whence value");
1634 return -1;
1635 }
1636
1637 ldout(cct, 10) << "jni: lseek: fd " << (int)j_fd << " offset "
1638 << (long)j_offset << " whence " << whence << dendl;
1639
1640 ret = ceph_lseek(cmount, (int)j_fd, (long)j_offset, whence);
1641
1642 ldout(cct, 10) << "jni: lseek: exit ret " << ret << dendl;
1643
1644 if (ret < 0)
1645 handle_error(env, ret);
1646
1647 return ret;
1648}
1649
1650/*
1651 * Class: com_ceph_fs_CephMount
1652 * Method: native_ceph_read
1653 * Signature: (JI[BJJ)J
1654 */
1655JNIEXPORT jlong JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1read
1656 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jbyteArray j_buf, jlong j_size, jlong j_offset)
1657{
1658 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1659 CephContext *cct = ceph_get_mount_context(cmount);
1660 jsize buf_size;
1661 jbyte *c_buf;
1662 long ret;
1663
1664 CHECK_ARG_NULL(j_buf, "@buf is null", -1);
1665 CHECK_ARG_BOUNDS(j_size < 0, "@size is negative", -1);
1666 CHECK_MOUNTED(cmount, -1);
1667
1668 buf_size = env->GetArrayLength(j_buf);
1669 CHECK_ARG_BOUNDS(j_size > buf_size, "@size > @buf.length", -1);
1670
1671 c_buf = env->GetByteArrayElements(j_buf, NULL);
1672 if (!c_buf) {
1673 cephThrowInternal(env, "failed to pin memory");
1674 return -1;
1675 }
1676
1677 ldout(cct, 10) << "jni: read: fd " << (int)j_fd << " len " << (long)j_size <<
1678 " offset " << (long)j_offset << dendl;
1679
1680 ret = ceph_read(cmount, (int)j_fd, (char*)c_buf, (long)j_size, (long)j_offset);
1681
1682 ldout(cct, 10) << "jni: read: exit ret " << ret << dendl;
1683
1684 if (ret < 0)
1685 handle_error(env, (int)ret);
1686 else
1687 env->ReleaseByteArrayElements(j_buf, c_buf, 0);
1688
1689 return (jlong)ret;
1690}
1691
1692/*
1693 * Class: com_ceph_fs_CephMount
1694 * Method: native_ceph_write
1695 * Signature: (JI[BJJ)J
1696 */
1697JNIEXPORT jlong JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1write
1698 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jbyteArray j_buf, jlong j_size, jlong j_offset)
1699{
1700 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1701 CephContext *cct = ceph_get_mount_context(cmount);
1702 jsize buf_size;
1703 jbyte *c_buf;
1704 long ret;
1705
1706 CHECK_ARG_NULL(j_buf, "@buf is null", -1);
1707 CHECK_ARG_BOUNDS(j_size < 0, "@size is negative", -1);
1708 CHECK_MOUNTED(cmount, -1);
1709
1710 buf_size = env->GetArrayLength(j_buf);
1711 CHECK_ARG_BOUNDS(j_size > buf_size, "@size > @buf.length", -1);
1712
1713 c_buf = env->GetByteArrayElements(j_buf, NULL);
1714 if (!c_buf) {
1715 cephThrowInternal(env, "failed to pin memory");
1716 return -1;
1717 }
1718
1719 ldout(cct, 10) << "jni: write: fd " << (int)j_fd << " len " << (long)j_size <<
1720 " offset " << (long)j_offset << dendl;
1721
1722 ret = ceph_write(cmount, (int)j_fd, (char*)c_buf, (long)j_size, (long)j_offset);
1723
1724 ldout(cct, 10) << "jni: write: exit ret " << ret << dendl;
1725
1726 if (ret < 0)
1727 handle_error(env, (int)ret);
1728 else
1729 env->ReleaseByteArrayElements(j_buf, c_buf, JNI_ABORT);
1730
1731 return ret;
1732}
1733
1734
1735/*
1736 * Class: com_ceph_fs_CephMount
1737 * Method: native_ceph_ftruncate
1738 * Signature: (JIJ)I
1739 */
1740JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1ftruncate
1741 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jlong j_size)
1742{
1743 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1744 CephContext *cct = ceph_get_mount_context(cmount);
1745 int ret;
1746
1747 CHECK_MOUNTED(cmount, -1);
1748
1749 ldout(cct, 10) << "jni: ftruncate: fd " << (int)j_fd <<
1750 " size " << (loff_t)j_size << dendl;
1751
1752 ret = ceph_ftruncate(cmount, (int)j_fd, (loff_t)j_size);
1753
1754 ldout(cct, 10) << "jni: ftruncate: exit ret " << ret << dendl;
1755
1756 if (ret)
1757 handle_error(env, ret);
1758
1759 return ret;
1760}
1761
1762/*
1763 * Class: com_ceph_fs_CephMount
1764 * Method: native_ceph_fsync
1765 * Signature: (JIZ)I
1766 */
1767JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1fsync
1768 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jboolean j_dataonly)
1769{
1770 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1771 CephContext *cct = ceph_get_mount_context(cmount);
1772 int ret;
1773
1774 ldout(cct, 10) << "jni: fsync: fd " << (int)j_fd <<
1775 " dataonly " << (j_dataonly ? 1 : 0) << dendl;
1776
1777 ret = ceph_fsync(cmount, (int)j_fd, j_dataonly ? 1 : 0);
1778
1779 ldout(cct, 10) << "jni: fsync: exit ret " << ret << dendl;
1780
1781 if (ret)
1782 handle_error(env, ret);
1783
1784 return ret;
1785}
1786
1787/*
1788 * Class: com_ceph_fs_CephMount
1789 * Method: native_ceph_flock
1790 * Signature: (JIZ)I
1791 */
1792JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1flock
1793 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jint j_operation, jlong j_owner)
1794{
1795 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1796 CephContext *cct = ceph_get_mount_context(cmount);
1797 int ret;
1798
1799 ldout(cct, 10) << "jni: flock: fd " << (int)j_fd <<
1800 " operation " << j_operation << " owner " << j_owner << dendl;
1801
1802 int operation = 0;
1803
1804#define MAP_FLOCK_FLAG(JNI_MASK, NATIVE_MASK) do { \
1805 if ((j_operation & JNI_MASK) != 0) { \
1806 operation |= NATIVE_MASK; \
1807 j_operation &= ~JNI_MASK; \
1808 } \
1809 } while(0)
1810 MAP_FLOCK_FLAG(JAVA_LOCK_SH, LOCK_SH);
1811 MAP_FLOCK_FLAG(JAVA_LOCK_EX, LOCK_EX);
1812 MAP_FLOCK_FLAG(JAVA_LOCK_NB, LOCK_NB);
1813 MAP_FLOCK_FLAG(JAVA_LOCK_UN, LOCK_UN);
1814 if (j_operation != 0) {
1815 cephThrowIllegalArg(env, "flock flags");
1816 return -EINVAL;
1817 }
1818#undef MAP_FLOCK_FLAG
1819
1820 ret = ceph_flock(cmount, (int)j_fd, operation, (uint64_t) j_owner);
1821
1822 ldout(cct, 10) << "jni: flock: exit ret " << ret << dendl;
1823
1824 if (ret)
1825 handle_error(env, ret);
1826
1827 return ret;
1828}
1829
1830/*
1831 * Class: com_ceph_fs_CephMount
1832 * Method: native_ceph_fstat
1833 * Signature: (JILcom/ceph/fs/CephStat;)I
1834 */
1835JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1fstat
1836 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd, jobject j_cephstat)
1837{
1838 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1839 CephContext *cct = ceph_get_mount_context(cmount);
1840 struct ceph_statx stx;
1841 int ret;
1842
1843 CHECK_ARG_NULL(j_cephstat, "@stat is null", -1);
1844 CHECK_MOUNTED(cmount, -1);
1845
1846 ldout(cct, 10) << "jni: fstat: fd " << (int)j_fd << dendl;
1847
1848 ret = ceph_fstatx(cmount, (int)j_fd, &stx, CEPH_J_CEPHSTAT_MASK, 0);
1849
1850 ldout(cct, 10) << "jni: fstat exit ret " << ret << dendl;
1851
1852 if (ret) {
1853 handle_error(env, ret);
1854 return ret;
1855 }
1856
1857 fill_cephstat(env, j_cephstat, &stx);
1858
1859 return ret;
1860}
1861
1862/*
1863 * Class: com_ceph_fs_CephMount
1864 * Method: native_ceph_sync_fs
1865 * Signature: (J)I
1866 */
1867JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1sync_1fs
1868 (JNIEnv *env, jclass clz, jlong j_mntp)
1869{
1870 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1871 CephContext *cct = ceph_get_mount_context(cmount);
1872 int ret;
1873
1874 ldout(cct, 10) << "jni: sync_fs: enter" << dendl;
1875
1876 ret = ceph_sync_fs(cmount);
1877
1878 ldout(cct, 10) << "jni: sync_fs: exit ret " << ret << dendl;
1879
1880 if (ret)
1881 handle_error(env, ret);
1882
1883 return ret;
1884}
1885
1886/*
1887 * Class: com_ceph_fs_CephMount
1888 * Method: native_ceph_getxattr
1889 * Signature: (JLjava/lang/String;Ljava/lang/String;[B)J
1890 */
1891JNIEXPORT jlong JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1getxattr
1892 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name, jbyteArray j_buf)
1893{
1894 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1895 CephContext *cct = ceph_get_mount_context(cmount);
1896 const char *c_path;
1897 const char *c_name;
1898 jsize buf_size;
1899 jbyte *c_buf = NULL; /* please gcc with goto */
1900 long ret;
1901
1902 CHECK_ARG_NULL(j_path, "@path is null", -1);
1903 CHECK_ARG_NULL(j_name, "@name is null", -1);
1904 CHECK_MOUNTED(cmount, -1);
1905
1906 c_path = env->GetStringUTFChars(j_path, NULL);
1907 if (!c_path) {
1908 cephThrowInternal(env, "Failed to pin memory");
1909 return -1;
1910 }
1911
1912 c_name = env->GetStringUTFChars(j_name, NULL);
1913 if (!c_name) {
1914 env->ReleaseStringUTFChars(j_path, c_path);
1915 cephThrowInternal(env, "Failed to pin memory");
1916 return -1;
1917 }
1918
1919 /* just lookup the size if buf is null */
1920 if (!j_buf) {
1921 buf_size = 0;
1922 goto do_getxattr;
1923 }
1924
1925 c_buf = env->GetByteArrayElements(j_buf, NULL);
1926 if (!c_buf) {
1927 env->ReleaseStringUTFChars(j_path, c_path);
1928 env->ReleaseStringUTFChars(j_name, c_name);
1929 cephThrowInternal(env, "failed to pin memory");
1930 return -1;
1931 }
1932
1933 buf_size = env->GetArrayLength(j_buf);
1934
1935do_getxattr:
1936
1937 ldout(cct, 10) << "jni: getxattr: path " << c_path << " name " << c_name <<
1938 " len " << buf_size << dendl;
1939
1940 ret = ceph_getxattr(cmount, c_path, c_name, c_buf, buf_size);
1941 if (ret == -ERANGE)
1942 ret = ceph_getxattr(cmount, c_path, c_name, c_buf, 0);
1943
1944 ldout(cct, 10) << "jni: getxattr: exit ret " << ret << dendl;
1945
1946 env->ReleaseStringUTFChars(j_path, c_path);
1947 env->ReleaseStringUTFChars(j_name, c_name);
1948 if (j_buf)
1949 env->ReleaseByteArrayElements(j_buf, c_buf, 0);
1950
1951 if (ret < 0)
1952 handle_error(env, (int)ret);
1953
1954 return (jlong)ret;
1955}
1956
1957/*
1958 * Class: com_ceph_fs_CephMount
1959 * Method: native_ceph_lgetxattr
1960 * Signature: (JLjava/lang/String;Ljava/lang/String;[B)I
1961 */
1962JNIEXPORT jlong JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1lgetxattr
1963 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name, jbyteArray j_buf)
1964{
1965 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
1966 CephContext *cct = ceph_get_mount_context(cmount);
1967 const char *c_path;
1968 const char *c_name;
1969 jsize buf_size;
1970 jbyte *c_buf = NULL; /* please gcc with goto */
1971 long ret;
1972
1973 CHECK_ARG_NULL(j_path, "@path is null", -1);
1974 CHECK_ARG_NULL(j_name, "@name is null", -1);
1975 CHECK_MOUNTED(cmount, -1);
1976
1977 c_path = env->GetStringUTFChars(j_path, NULL);
1978 if (!c_path) {
1979 cephThrowInternal(env, "Failed to pin memory");
1980 return -1;
1981 }
1982
1983 c_name = env->GetStringUTFChars(j_name, NULL);
1984 if (!c_name) {
1985 env->ReleaseStringUTFChars(j_path, c_path);
1986 cephThrowInternal(env, "Failed to pin memory");
1987 return -1;
1988 }
1989
1990 /* just lookup the size if buf is null */
1991 if (!j_buf) {
1992 buf_size = 0;
1993 goto do_lgetxattr;
1994 }
1995
1996 c_buf = env->GetByteArrayElements(j_buf, NULL);
1997 if (!c_buf) {
1998 env->ReleaseStringUTFChars(j_path, c_path);
1999 env->ReleaseStringUTFChars(j_name, c_name);
2000 cephThrowInternal(env, "failed to pin memory");
2001 return -1;
2002 }
2003
2004 buf_size = env->GetArrayLength(j_buf);
2005
2006do_lgetxattr:
2007
2008 ldout(cct, 10) << "jni: lgetxattr: path " << c_path << " name " << c_name <<
2009 " len " << buf_size << dendl;
2010
2011 ret = ceph_lgetxattr(cmount, c_path, c_name, c_buf, buf_size);
2012 if (ret == -ERANGE)
2013 ret = ceph_lgetxattr(cmount, c_path, c_name, c_buf, 0);
2014
2015 ldout(cct, 10) << "jni: lgetxattr: exit ret " << ret << dendl;
2016
2017 env->ReleaseStringUTFChars(j_path, c_path);
2018 env->ReleaseStringUTFChars(j_name, c_name);
2019 if (j_buf)
2020 env->ReleaseByteArrayElements(j_buf, c_buf, 0);
2021
2022 if (ret < 0)
2023 handle_error(env, (int)ret);
2024
2025 return (jlong)ret;
2026}
2027
2028/*
2029 * Class: com_ceph_fs_CephMount
2030 * Method: native_ceph_listxattr
2031 * Signature: (JLjava/lang/String;)[Ljava/lang/String;
2032 */
2033JNIEXPORT jobjectArray JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1listxattr
2034 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
2035{
2036 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2037 CephContext *cct = ceph_get_mount_context(cmount);
2038 jobjectArray xattrlist;
2039 const char *c_path;
2040 string *ent;
2041 jstring name;
2042 list<string>::iterator it;
2043 list<string> contents;
2044 int ret, buflen, bufpos, i;
2045 char *buf;
2046
2047 CHECK_ARG_NULL(j_path, "@path is null", NULL);
2048 CHECK_MOUNTED(cmount, NULL);
2049
2050 c_path = env->GetStringUTFChars(j_path, NULL);
2051 if (!c_path) {
2052 cephThrowInternal(env, "Failed to pin memory");
2053 return NULL;
2054 }
2055
2056 buflen = 1024;
2057 buf = new (std::nothrow) char[buflen];
2058 if (!buf) {
2059 cephThrowOutOfMemory(env, "head allocation failed");
2060 goto out;
2061 }
2062
2063 while (1) {
2064 ldout(cct, 10) << "jni: listxattr: path " << c_path << " len " << buflen << dendl;
2065 ret = ceph_listxattr(cmount, c_path, buf, buflen);
2066 if (ret == -ERANGE) {
2067 delete [] buf;
2068 buflen *= 2;
2069 buf = new (std::nothrow) char[buflen];
2070 if (!buf) {
2071 cephThrowOutOfMemory(env, "heap allocation failed");
2072 goto out;
2073 }
2074 continue;
2075 }
2076 break;
2077 }
2078
2079 ldout(cct, 10) << "jni: listxattr: ret " << ret << dendl;
2080
2081 if (ret < 0) {
2082 delete [] buf;
2083 handle_error(env, ret);
2084 goto out;
2085 }
2086
2087 bufpos = 0;
2088 while (bufpos < ret) {
2089 ent = new (std::nothrow) string(buf + bufpos);
2090 if (!ent) {
2091 delete [] buf;
2092 cephThrowOutOfMemory(env, "heap allocation failed");
2093 goto out;
2094 }
2095 contents.push_back(*ent);
2096 bufpos += ent->size() + 1;
2097 delete ent;
2098 }
2099
2100 delete [] buf;
2101
2102 xattrlist = env->NewObjectArray(contents.size(), env->FindClass("java/lang/String"), NULL);
2103 if (!xattrlist)
2104 goto out;
2105
2106 for (i = 0, it = contents.begin(); it != contents.end(); ++it) {
2107 name = env->NewStringUTF(it->c_str());
2108 if (!name)
2109 goto out;
2110 env->SetObjectArrayElement(xattrlist, i++, name);
2111 if (env->ExceptionOccurred())
2112 goto out;
2113 env->DeleteLocalRef(name);
2114 }
2115
2116 env->ReleaseStringUTFChars(j_path, c_path);
2117 return xattrlist;
2118
2119out:
2120 env->ReleaseStringUTFChars(j_path, c_path);
2121 return NULL;
2122}
2123
2124/*
2125 * Class: com_ceph_fs_CephMount
2126 * Method: native_ceph_llistxattr
2127 * Signature: (JLjava/lang/String;)[Ljava/lang/String;
2128 */
2129JNIEXPORT jobjectArray JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1llistxattr
2130 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path)
2131{
2132 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2133 CephContext *cct = ceph_get_mount_context(cmount);
2134 jobjectArray xattrlist;
2135 const char *c_path;
2136 string *ent;
2137 jstring name;
2138 list<string>::iterator it;
2139 list<string> contents;
2140 int ret, buflen, bufpos, i;
2141 char *buf;
2142
2143 CHECK_ARG_NULL(j_path, "@path is null", NULL);
2144 CHECK_MOUNTED(cmount, NULL);
2145
2146 c_path = env->GetStringUTFChars(j_path, NULL);
2147 if (!c_path) {
2148 cephThrowInternal(env, "Failed to pin memory");
2149 return NULL;
2150 }
2151
2152 buflen = 1024;
2153 buf = new (std::nothrow) char[buflen];
2154 if (!buf) {
2155 cephThrowOutOfMemory(env, "head allocation failed");
2156 goto out;
2157 }
2158
2159 while (1) {
2160 ldout(cct, 10) << "jni: llistxattr: path " << c_path << " len " << buflen << dendl;
2161 ret = ceph_llistxattr(cmount, c_path, buf, buflen);
2162 if (ret == -ERANGE) {
2163 delete [] buf;
2164 buflen *= 2;
2165 buf = new (std::nothrow) char[buflen];
2166 if (!buf) {
2167 cephThrowOutOfMemory(env, "heap allocation failed");
2168 goto out;
2169 }
2170 continue;
2171 }
2172 break;
2173 }
2174
2175 ldout(cct, 10) << "jni: llistxattr: ret " << ret << dendl;
2176
2177 if (ret < 0) {
2178 delete [] buf;
2179 handle_error(env, ret);
2180 goto out;
2181 }
2182
2183 bufpos = 0;
2184 while (bufpos < ret) {
2185 ent = new (std::nothrow) string(buf + bufpos);
2186 if (!ent) {
2187 delete [] buf;
2188 cephThrowOutOfMemory(env, "heap allocation failed");
2189 goto out;
2190 }
2191 contents.push_back(*ent);
2192 bufpos += ent->size() + 1;
2193 delete ent;
2194 }
2195
2196 delete [] buf;
2197
2198 xattrlist = env->NewObjectArray(contents.size(), env->FindClass("java/lang/String"), NULL);
2199 if (!xattrlist)
2200 goto out;
2201
2202 for (i = 0, it = contents.begin(); it != contents.end(); ++it) {
2203 name = env->NewStringUTF(it->c_str());
2204 if (!name)
2205 goto out;
2206 env->SetObjectArrayElement(xattrlist, i++, name);
2207 if (env->ExceptionOccurred())
2208 goto out;
2209 env->DeleteLocalRef(name);
2210 }
2211
2212 env->ReleaseStringUTFChars(j_path, c_path);
2213 return xattrlist;
2214
2215out:
2216 env->ReleaseStringUTFChars(j_path, c_path);
2217 return NULL;
2218}
2219
2220/*
2221 * Class: com_ceph_fs_CephMount
2222 * Method: native_ceph_removexattr
2223 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
2224 */
2225JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1removexattr
2226 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name)
2227{
2228 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2229 CephContext *cct = ceph_get_mount_context(cmount);
2230 const char *c_path;
2231 const char *c_name;
2232 int ret;
2233
2234 CHECK_ARG_NULL(j_path, "@path is null", -1);
2235 CHECK_ARG_NULL(j_name, "@name is null", -1);
2236 CHECK_MOUNTED(cmount, -1);
2237
2238 c_path = env->GetStringUTFChars(j_path, NULL);
2239 if (!c_path) {
2240 cephThrowInternal(env, "Failed to pin memory");
2241 return -1;
2242 }
2243
2244 c_name = env->GetStringUTFChars(j_name, NULL);
2245 if (!c_name) {
2246 env->ReleaseStringUTFChars(j_path, c_path);
2247 cephThrowInternal(env, "Failed to pin memory");
2248 return -1;
2249 }
2250
2251 ldout(cct, 10) << "jni: removexattr: path " << c_path << " name " << c_name << dendl;
2252
2253 ret = ceph_removexattr(cmount, c_path, c_name);
2254
2255 ldout(cct, 10) << "jni: removexattr: exit ret " << ret << dendl;
2256
2257 env->ReleaseStringUTFChars(j_path, c_path);
2258 env->ReleaseStringUTFChars(j_name, c_name);
2259
2260 if (ret)
2261 handle_error(env, ret);
2262
2263 return ret;
2264}
2265
2266/*
2267 * Class: com_ceph_fs_CephMount
2268 * Method: native_ceph_lremovexattr
2269 * Signature: (JLjava/lang/String;Ljava/lang/String;)I
2270 */
2271JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1lremovexattr
2272 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name)
2273{
2274 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2275 CephContext *cct = ceph_get_mount_context(cmount);
2276 const char *c_path;
2277 const char *c_name;
2278 int ret;
2279
2280 CHECK_ARG_NULL(j_path, "@path is null", -1);
2281 CHECK_ARG_NULL(j_name, "@name is null", -1);
2282 CHECK_MOUNTED(cmount, -1);
2283
2284 c_path = env->GetStringUTFChars(j_path, NULL);
2285 if (!c_path) {
2286 cephThrowInternal(env, "Failed to pin memory");
2287 return -1;
2288 }
2289
2290 c_name = env->GetStringUTFChars(j_name, NULL);
2291 if (!c_name) {
2292 env->ReleaseStringUTFChars(j_path, c_path);
2293 cephThrowInternal(env, "Failed to pin memory");
2294 return -1;
2295 }
2296
2297 ldout(cct, 10) << "jni: lremovexattr: path " << c_path << " name " << c_name << dendl;
2298
2299 ret = ceph_lremovexattr(cmount, c_path, c_name);
2300
2301 ldout(cct, 10) << "jni: lremovexattr: exit ret " << ret << dendl;
2302
2303 env->ReleaseStringUTFChars(j_path, c_path);
2304 env->ReleaseStringUTFChars(j_name, c_name);
2305
2306 if (ret)
2307 handle_error(env, ret);
2308
2309 return ret;
2310}
2311
2312/*
2313 * Class: com_ceph_fs_CephMount
2314 * Method: native_ceph_setxattr
2315 * Signature: (JLjava/lang/String;Ljava/lang/String;[BJI)I
2316 */
2317JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1setxattr
2318 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name,
2319 jbyteArray j_buf, jlong j_size, jint j_flags)
2320{
2321 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2322 CephContext *cct = ceph_get_mount_context(cmount);
2323 const char *c_path;
2324 const char *c_name;
2325 jsize buf_size;
2326 jbyte *c_buf;
2327 int ret, flags;
2328
2329 CHECK_ARG_NULL(j_path, "@path is null", -1);
2330 CHECK_ARG_NULL(j_name, "@name is null", -1);
2331 CHECK_ARG_NULL(j_buf, "@buf is null", -1);
2332 CHECK_ARG_BOUNDS(j_size < 0, "@size is negative", -1);
2333 CHECK_MOUNTED(cmount, -1);
2334
2335 buf_size = env->GetArrayLength(j_buf);
2336 CHECK_ARG_BOUNDS(j_size > buf_size, "@size > @buf.length", -1);
2337
2338 c_path = env->GetStringUTFChars(j_path, NULL);
2339 if (!c_path) {
2340 cephThrowInternal(env, "Failed to pin memory");
2341 return -1;
2342 }
2343
2344 c_name = env->GetStringUTFChars(j_name, NULL);
2345 if (!c_name) {
2346 env->ReleaseStringUTFChars(j_path, c_path);
2347 cephThrowInternal(env, "Failed to pin memory");
2348 return -1;
2349 }
2350
2351 c_buf = env->GetByteArrayElements(j_buf, NULL);
2352 if (!c_buf) {
2353 env->ReleaseStringUTFChars(j_path, c_path);
2354 env->ReleaseStringUTFChars(j_name, c_name);
2355 cephThrowInternal(env, "failed to pin memory");
2356 return -1;
2357 }
2358
2359 switch (j_flags) {
2360 case JAVA_XATTR_CREATE:
2361 flags = CEPH_XATTR_CREATE;
2362 break;
2363 case JAVA_XATTR_REPLACE:
2364 flags = CEPH_XATTR_REPLACE;
2365 break;
2366 case JAVA_XATTR_NONE:
2367 flags = 0;
2368 break;
2369 default:
2370 env->ReleaseStringUTFChars(j_path, c_path);
2371 env->ReleaseStringUTFChars(j_name, c_name);
2372 env->ReleaseByteArrayElements(j_buf, c_buf, JNI_ABORT);
2373 cephThrowIllegalArg(env, "setxattr flag");
2374 return -1;
2375 }
2376
2377 ldout(cct, 10) << "jni: setxattr: path " << c_path << " name " << c_name
2378 << " len " << j_size << " flags " << flags << dendl;
2379
2380 ret = ceph_setxattr(cmount, c_path, c_name, c_buf, j_size, flags);
2381
2382 ldout(cct, 10) << "jni: setxattr: exit ret " << ret << dendl;
2383
2384 env->ReleaseStringUTFChars(j_path, c_path);
2385 env->ReleaseStringUTFChars(j_name, c_name);
2386 env->ReleaseByteArrayElements(j_buf, c_buf, JNI_ABORT);
2387
2388 if (ret)
2389 handle_error(env, ret);
2390
2391 return ret;
2392}
2393
2394/*
2395 * Class: com_ceph_fs_CephMount
2396 * Method: native_ceph_lsetxattr
2397 * Signature: (JLjava/lang/String;Ljava/lang/String;[BJI)I
2398 */
2399JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1lsetxattr
2400 (JNIEnv *env, jclass clz, jlong j_mntp, jstring j_path, jstring j_name,
2401 jbyteArray j_buf, jlong j_size, jint j_flags)
2402{
2403 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2404 CephContext *cct = ceph_get_mount_context(cmount);
2405 const char *c_path;
2406 const char *c_name;
2407 jsize buf_size;
2408 jbyte *c_buf;
2409 int ret, flags;
2410
2411 CHECK_ARG_NULL(j_path, "@path is null", -1);
2412 CHECK_ARG_NULL(j_name, "@name is null", -1);
2413 CHECK_ARG_NULL(j_buf, "@buf is null", -1);
2414 CHECK_ARG_BOUNDS(j_size < 0, "@size is negative", -1);
2415 CHECK_MOUNTED(cmount, -1);
2416
2417 buf_size = env->GetArrayLength(j_buf);
2418 CHECK_ARG_BOUNDS(j_size > buf_size, "@size > @buf.length", -1);
2419
2420 c_path = env->GetStringUTFChars(j_path, NULL);
2421 if (!c_path) {
2422 cephThrowInternal(env, "Failed to pin memory");
2423 return -1;
2424 }
2425
2426 c_name = env->GetStringUTFChars(j_name, NULL);
2427 if (!c_name) {
2428 env->ReleaseStringUTFChars(j_path, c_path);
2429 cephThrowInternal(env, "Failed to pin memory");
2430 return -1;
2431 }
2432
2433 c_buf = env->GetByteArrayElements(j_buf, NULL);
2434 if (!c_buf) {
2435 env->ReleaseStringUTFChars(j_path, c_path);
2436 env->ReleaseStringUTFChars(j_name, c_name);
2437 cephThrowInternal(env, "failed to pin memory");
2438 return -1;
2439 }
2440
2441 switch (j_flags) {
2442 case JAVA_XATTR_CREATE:
2443 flags = CEPH_XATTR_CREATE;
2444 break;
2445 case JAVA_XATTR_REPLACE:
2446 flags = CEPH_XATTR_REPLACE;
2447 break;
2448 case JAVA_XATTR_NONE:
2449 flags = 0;
2450 break;
2451 default:
2452 env->ReleaseStringUTFChars(j_path, c_path);
2453 env->ReleaseStringUTFChars(j_name, c_name);
2454 env->ReleaseByteArrayElements(j_buf, c_buf, JNI_ABORT);
2455 cephThrowIllegalArg(env, "lsetxattr flag");
2456 return -1;
2457 }
2458
2459 ldout(cct, 10) << "jni: lsetxattr: path " << c_path << " name " << c_name
2460 << " len " << j_size << " flags " << flags << dendl;
2461
2462 ret = ceph_lsetxattr(cmount, c_path, c_name, c_buf, j_size, flags);
2463
2464 ldout(cct, 10) << "jni: lsetxattr: exit ret " << ret << dendl;
2465
2466 env->ReleaseStringUTFChars(j_path, c_path);
2467 env->ReleaseStringUTFChars(j_name, c_name);
2468 env->ReleaseByteArrayElements(j_buf, c_buf, JNI_ABORT);
2469
2470 if (ret)
2471 handle_error(env, ret);
2472
2473 return ret;
2474}
2475
2476/*
2477 * Class: com_ceph_fs_CephMount
2478 * Method: native_ceph_get_file_stripe_unit
2479 * Signature: (JI)I
2480 */
2481JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1file_1stripe_1unit
2482 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd)
2483{
2484 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2485 CephContext *cct = ceph_get_mount_context(cmount);
2486 int ret;
2487
2488 CHECK_MOUNTED(cmount, -1);
2489
2490 ldout(cct, 10) << "jni: get_file_stripe_unit: fd " << (int)j_fd << dendl;
2491
2492 ret = ceph_get_file_stripe_unit(cmount, (int)j_fd);
2493
2494 ldout(cct, 10) << "jni: get_file_stripe_unit: exit ret " << ret << dendl;
2495
2496 if (ret < 0)
2497 handle_error(env, ret);
2498
2499 return ret;
2500}
2501
2502/*
2503 * Class: com_ceph_fs_CephMount
2504 * Method: native_ceph_get_file_replication
2505 * Signature: (JI)I
2506 */
2507JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1file_1replication
2508 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd)
2509{
2510 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2511 CephContext *cct = ceph_get_mount_context(cmount);
2512 int ret;
2513
2514 CHECK_MOUNTED(cmount, -1);
2515
2516 ldout(cct, 10) << "jni: get_file_replication: fd " << (int)j_fd << dendl;
2517
2518 ret = ceph_get_file_replication(cmount, (int)j_fd);
2519
2520 ldout(cct, 10) << "jni: get_file_replication: exit ret " << ret << dendl;
2521
2522 if (ret < 0)
2523 handle_error(env, ret);
2524
2525 return ret;
2526}
2527
2528/*
2529 * Class: com_ceph_fs_CephMount
2530 * Method: native_ceph_get_file_pool_name
2531 * Signature: (JI)Ljava/lang/String;
2532 */
2533JNIEXPORT jstring JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1file_1pool_1name
2534 (JNIEnv *env, jclass clz, jlong j_mntp, jint j_fd)
2535{
2536 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2537 CephContext *cct = ceph_get_mount_context(cmount);
2538 jstring pool = NULL;
2539 int ret, buflen = 0;
2540 char *buf = NULL;
2541
2542 CHECK_MOUNTED(cmount, NULL);
2543
2544 ldout(cct, 10) << "jni: get_file_pool_name: fd " << (int)j_fd << dendl;
2545
2546 for (;;) {
2547 /* get pool name length (len==0) */
2548 ret = ceph_get_file_pool_name(cmount, (int)j_fd, NULL, 0);
2549 if (ret < 0)
2550 break;
2551
2552 /* allocate buffer */
2553 if (buf)
2554 delete [] buf;
2555 buflen = ret;
2556 buf = new (std::nothrow) char[buflen+1]; /* +1 for '\0' */
2557 if (!buf) {
2558 cephThrowOutOfMemory(env, "head allocation failed");
2559 goto out;
2560 }
2561 memset(buf, 0, (buflen+1)*sizeof(*buf));
2562
2563 /* handle zero-length pool name!? */
2564 if (buflen == 0)
2565 break;
2566
2567 /* fill buffer */
2568 ret = ceph_get_file_pool_name(cmount, (int)j_fd, buf, buflen);
2569 if (ret == -ERANGE) /* size changed! */
2570 continue;
2571 else
2572 break;
2573 }
2574
2575 ldout(cct, 10) << "jni: get_file_pool_name: ret " << ret << dendl;
2576
2577 if (ret < 0)
2578 handle_error(env, ret);
2579 else
2580 pool = env->NewStringUTF(buf);
2581
2582out:
2583 if (buf)
2584 delete [] buf;
2585
2586 return pool;
2587}
2588
d2e6a577
FG
2589/**
2590 * Class: com_ceph_fs_CephMount
2591 * Method: native_ceph_get_default_data_pool_name
2592 * Signature: (J)Ljava/lang/String;
2593 */
2594JNIEXPORT jstring JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1default_1data_1pool_1name
2595 (JNIEnv *env, jclass clz, jlong j_mntp)
2596{
2597 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2598 CephContext *cct = ceph_get_mount_context(cmount);
2599 jstring pool = NULL;
2600 int ret, buflen = 0;
2601 char *buf = NULL;
2602
2603 CHECK_MOUNTED(cmount, NULL);
2604
2605 ldout(cct, 10) << "jni: get_default_data_pool_name" << dendl;
2606
2607 ret = ceph_get_default_data_pool_name(cmount, NULL, 0);
2608 if (ret < 0)
2609 goto out;
2610 buflen = ret;
2611 buf = new (std::nothrow) char[buflen+1]; /* +1 for '\0' */
2612 if (!buf) {
2613 cephThrowOutOfMemory(env, "head allocation failed");
2614 goto out;
2615 }
2616 memset(buf, 0, (buflen+1)*sizeof(*buf));
2617 ret = ceph_get_default_data_pool_name(cmount, buf, buflen);
2618
2619 ldout(cct, 10) << "jni: get_default_data_pool_name: ret " << ret << dendl;
2620
2621 if (ret < 0)
2622 handle_error(env, ret);
2623 else
2624 pool = env->NewStringUTF(buf);
2625
2626out:
2627 if (buf)
2628 delete [] buf;
2629
2630 return pool;
2631}
2632
2633
7c673cae
FG
2634/*
2635 * Class: com_ceph_fs_CephMount
2636 * Method: native_ceph_localize_reads
2637 * Signature: (JZ)I
2638 */
2639JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1localize_1reads
2640 (JNIEnv *env, jclass clz, jlong j_mntp, jboolean j_on)
2641{
2642 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2643 CephContext *cct = ceph_get_mount_context(cmount);
2644 int ret, val = j_on ? 1 : 0;
2645
2646 CHECK_MOUNTED(cmount, -1);
2647
2648 ldout(cct, 10) << "jni: localize_reads: val " << val << dendl;
2649
2650 ret = ceph_localize_reads(cmount, val);
2651
2652 ldout(cct, 10) << "jni: localize_reads: exit ret " << ret << dendl;
2653
2654 if (ret)
2655 handle_error(env, ret);
2656
2657 return ret;
2658}
2659
2660/*
2661 * Class: com_ceph_fs_CephMount
2662 * Method: native_ceph_get_stripe_unit_granularity
2663 * Signature: (J)I
2664 */
2665JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1stripe_1unit_1granularity
2666 (JNIEnv *env, jclass clz, jlong j_mntp)
2667{
2668 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2669 CephContext *cct = ceph_get_mount_context(cmount);
2670 int ret;
2671
2672 CHECK_MOUNTED(cmount, -1);
2673
2674 ldout(cct, 10) << "jni: get_stripe_unit_granularity" << dendl;
2675
2676 ret = ceph_get_stripe_unit_granularity(cmount);
2677
2678 ldout(cct, 10) << "jni: get_stripe_unit_granularity: exit ret " << ret << dendl;
2679
2680 if (ret < 0)
2681 handle_error(env, ret);
2682
2683 return ret;
2684}
2685
2686/*
2687 * Class: com_ceph_fs_CephMount
2688 * Method: native_ceph_get_pool_id
2689 * Signature: (JLjava/lang/String;)I
2690 */
2691JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1pool_1id
2692 (JNIEnv *env, jclass clz, jlong j_mntp, jstring jname)
2693{
2694 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2695 CephContext *cct = ceph_get_mount_context(cmount);
2696 const char *c_name;
2697 int ret;
2698
2699 CHECK_MOUNTED(cmount, -1);
2700 CHECK_ARG_NULL(jname, "@name is null", -1);
2701
2702 c_name = env->GetStringUTFChars(jname, NULL);
2703 if (!c_name) {
2704 cephThrowInternal(env, "failed to pin memory");
2705 return -1;
2706 }
2707
2708 ldout(cct, 10) << "jni: get_pool_id: name " << c_name << dendl;
2709
2710 ret = ceph_get_pool_id(cmount, c_name);
2711 if (ret < 0)
2712 handle_error(env, ret);
2713
2714 ldout(cct, 10) << "jni: get_pool_id: ret " << ret << dendl;
2715
2716 env->ReleaseStringUTFChars(jname, c_name);
2717
2718 return ret;
2719}
2720
2721/*
2722 * Class: com_ceph_fs_CephMount
2723 * Method: native_ceph_get_pool_replication
2724 * Signature: (JI)I
2725 */
2726JNIEXPORT jint JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1pool_1replication
2727 (JNIEnv *env, jclass clz, jlong j_mntp, jint jpoolid)
2728{
2729 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2730 CephContext *cct = ceph_get_mount_context(cmount);
2731 int ret;
2732
2733 CHECK_MOUNTED(cmount, -1);
2734
2735 ldout(cct, 10) << "jni: get_pool_replication: poolid " << jpoolid << dendl;
2736
2737 ret = ceph_get_pool_replication(cmount, jpoolid);
2738 if (ret < 0)
2739 handle_error(env, ret);
2740
2741 ldout(cct, 10) << "jni: get_pool_replication: ret " << ret << dendl;
2742
2743 return ret;
2744}
2745
2746/*
2747 * Class: com_ceph_fs_CephMount
2748 * Method: native_ceph_get_file_extent_osds
2749 * Signature: (JIJ)Lcom/ceph/fs/CephFileExtent;
2750 */
2751JNIEXPORT jobject JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1file_1extent_1osds
2752 (JNIEnv *env, jclass clz, jlong mntp, jint fd, jlong off)
2753{
2754 struct ceph_mount_info *cmount = get_ceph_mount(mntp);
2755 CephContext *cct = ceph_get_mount_context(cmount);
2756 jobject extent = NULL;
2757 int ret, nosds, *osds = NULL;
2758 jintArray osd_array;
2759 loff_t len;
2760
2761 CHECK_MOUNTED(cmount, NULL);
2762
2763 ldout(cct, 10) << "jni: get_file_extent_osds: fd " << fd << " off " << off << dendl;
2764
2765 for (;;) {
2766 /* get pg size */
2767 ret = ceph_get_file_extent_osds(cmount, fd, off, NULL, NULL, 0);
2768 if (ret < 0)
2769 break;
2770
2771 /* alloc osd id array */
2772 if (osds)
2773 delete [] osds;
2774 nosds = ret;
2775 osds = new int[nosds];
2776
2777 /* get osd ids */
2778 ret = ceph_get_file_extent_osds(cmount, fd, off, &len, osds, nosds);
2779 if (ret == -ERANGE)
2780 continue;
2781 else
2782 break;
2783 }
2784
2785 ldout(cct, 10) << "jni: get_file_extent_osds: ret " << ret << dendl;
2786
2787 if (ret < 0) {
2788 handle_error(env, ret);
2789 goto out;
2790 }
2791
2792 nosds = ret;
2793
2794 osd_array = env->NewIntArray(nosds);
2795 if (!osd_array)
2796 goto out;
2797
2798 env->SetIntArrayRegion(osd_array, 0, nosds, osds);
2799 if (env->ExceptionOccurred())
2800 goto out;
2801
2802 extent = env->NewObject(cephfileextent_cls, cephfileextent_ctor_fid, off, len, osd_array);
2803 if (!extent)
2804 goto out;
2805
2806out:
2807 if (osds)
2808 delete [] osds;
2809
2810 return extent;
2811}
2812
2813/*
2814 * Class: com_ceph_fs_CephMount
2815 * Method: native_ceph_get_osd_crush_location
2816 * Signature: (JI)[Ljava/lang/String;
2817 */
2818JNIEXPORT jobjectArray JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1osd_1crush_1location
2819 (JNIEnv *env, jclass clz, jlong j_mntp, jint osdid)
2820{
2821 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
2822 CephContext *cct = ceph_get_mount_context(cmount);
2823 jobjectArray path = NULL;
2824 vector<string> str_path;
2825 int ret, bufpos, buflen = 0;
2826 char *buf = NULL;
2827
2828 CHECK_MOUNTED(cmount, NULL);
2829
2830 ldout(cct, 10) << "jni: osd loc: osd " << osdid << dendl;
2831
2832 for (;;) {
2833 /* get length of the location path */
2834 ret = ceph_get_osd_crush_location(cmount, osdid, NULL, 0);
2835 if (ret < 0)
2836 break;
2837
2838 /* alloc path buffer */
2839 if (buf)
2840 delete [] buf;
2841 buflen = ret;
2842 buf = new char[buflen+1];
2843 memset(buf, 0, buflen*sizeof(*buf));
2844
2845 /* empty path */
2846 if (buflen == 0)
2847 break;
2848
2849 /* get the path */
2850 ret = ceph_get_osd_crush_location(cmount, osdid, buf, buflen);
2851 if (ret == -ERANGE)
2852 continue;
2853 else
2854 break;
2855 }
2856
2857 ldout(cct, 10) << "jni: osd loc: osd " << osdid << " ret " << ret << dendl;
2858
2859 if (ret < 0) {
2860 handle_error(env, ret);
2861 goto out;
2862 }
2863
2864 bufpos = 0;
2865 while (bufpos < ret) {
2866 string type(buf + bufpos);
2867 bufpos += type.size() + 1;
2868 string name(buf + bufpos);
2869 bufpos += name.size() + 1;
2870 str_path.push_back(type);
2871 str_path.push_back(name);
2872 }
2873
2874 path = env->NewObjectArray(str_path.size(), env->FindClass("java/lang/String"), NULL);
2875 if (!path)
2876 goto out;
2877
2878 for (unsigned i = 0; i < str_path.size(); i++) {
2879 jstring ent = env->NewStringUTF(str_path[i].c_str());
2880 if (!ent)
2881 goto out;
2882 env->SetObjectArrayElement(path, i, ent);
2883 if (env->ExceptionOccurred())
2884 goto out;
2885 env->DeleteLocalRef(ent);
2886 }
2887
2888out:
2889 if (buf)
2890 delete [] buf;
2891
2892 return path;
2893}
2894
2895/*
2896 * sockaddrToInetAddress uses with the following license, and is adapted for
2897 * use in this project by using Ceph JNI exception utilities.
2898 *
2899 * ----
2900 *
2901 * Copyright (C) 2010 The Android Open Source Project
2902 *
2903 * Licensed under the Apache License, Version 2.0 (the "License");
2904 * you may not use this file except in compliance with the License.
2905 * You may obtain a copy of the License at
2906 *
2907 * http://www.apache.org/licenses/LICENSE-2.0
2908 *
2909 * Unless required by applicable law or agreed to in writing, software
2910 * distributed under the License is distributed on an "AS IS" BASIS,
2911 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2912 * See the License for the specific language governing permissions and
2913 * limitations under the License.
2914 */
2915jobject sockaddrToInetAddress(JNIEnv* env, const sockaddr_storage& ss, jint* port) {
2916 // Convert IPv4-mapped IPv6 addresses to IPv4 addresses.
2917 // The RI states "Java will never return an IPv4-mapped address".
2918 const sockaddr_in6& sin6 = reinterpret_cast<const sockaddr_in6&>(ss);
2919 if (ss.ss_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
2920 // Copy the IPv6 address into the temporary sockaddr_storage.
2921 sockaddr_storage tmp;
2922 memset(&tmp, 0, sizeof(tmp));
2923 memcpy(&tmp, &ss, sizeof(sockaddr_in6));
2924 // Unmap it into an IPv4 address.
2925 sockaddr_in& sin = reinterpret_cast<sockaddr_in&>(tmp);
2926 sin.sin_family = AF_INET;
2927 sin.sin_port = sin6.sin6_port;
2928 memcpy(&sin.sin_addr.s_addr, &sin6.sin6_addr.s6_addr[12], 4);
2929 // Do the regular conversion using the unmapped address.
2930 return sockaddrToInetAddress(env, tmp, port);
2931 }
2932
2933 const void* rawAddress;
2934 size_t addressLength;
2935 int sin_port = 0;
2936 int scope_id = 0;
2937 if (ss.ss_family == AF_INET) {
2938 const sockaddr_in& sin = reinterpret_cast<const sockaddr_in&>(ss);
2939 rawAddress = &sin.sin_addr.s_addr;
2940 addressLength = 4;
2941 sin_port = ntohs(sin.sin_port);
2942 } else if (ss.ss_family == AF_INET6) {
2943 const sockaddr_in6& sin6 = reinterpret_cast<const sockaddr_in6&>(ss);
2944 rawAddress = &sin6.sin6_addr.s6_addr;
2945 addressLength = 16;
2946 sin_port = ntohs(sin6.sin6_port);
2947 scope_id = sin6.sin6_scope_id;
2948 } else if (ss.ss_family == AF_UNIX) {
2949 const sockaddr_un& sun = reinterpret_cast<const sockaddr_un&>(ss);
2950 rawAddress = &sun.sun_path;
2951 addressLength = strlen(sun.sun_path);
2952 } else {
2953 // We can't throw SocketException. We aren't meant to see bad addresses, so seeing one
2954 // really does imply an internal error.
2955 //jniThrowExceptionFmt(env, "java/lang/IllegalArgumentException",
2956 // "sockaddrToInetAddress unsupported ss_family: %i", ss.ss_family);
2957 cephThrowIllegalArg(env, "sockaddrToInetAddress unsupposed ss_family");
2958 return NULL;
2959 }
2960 if (port != NULL) {
2961 *port = sin_port;
2962 }
2963
2964 ScopedLocalRef<jbyteArray> byteArray(env, env->NewByteArray(addressLength));
2965 if (byteArray.get() == NULL) {
2966 return NULL;
2967 }
2968 env->SetByteArrayRegion(byteArray.get(), 0, addressLength,
2969 reinterpret_cast<jbyte*>(const_cast<void*>(rawAddress)));
2970
2971 if (ss.ss_family == AF_UNIX) {
2972 // Note that we get here for AF_UNIX sockets on accept(2). The unix(7) man page claims
2973 // that the peer's sun_path will contain the path, but in practice it doesn't, and the
2974 // peer length is returned as 2 (meaning only the sun_family field was set).
2975 //
2976 // Ceph Note: this isn't supported. inetUnixAddress appears to just be
2977 // something in Dalvik/Android stuff.
2978 cephThrowInternal(env, "OSD address should never be a UNIX socket");
2979 return NULL;
2980 //static jmethodID ctor = env->GetMethodID(JniConstants::inetUnixAddressClass, "<init>", "([B)V");
2981 //return env->NewObject(JniConstants::inetUnixAddressClass, ctor, byteArray.get());
2982 }
2983
2984 if (addressLength == 4) {
2985 static jmethodID getByAddressMethod = env->GetStaticMethodID(JniConstants::inetAddressClass,
2986 "getByAddress", "(Ljava/lang/String;[B)Ljava/net/InetAddress;");
2987 if (getByAddressMethod == NULL) {
2988 return NULL;
2989 }
2990 return env->CallStaticObjectMethod(JniConstants::inetAddressClass, getByAddressMethod,
2991 NULL, byteArray.get());
2992 } else if (addressLength == 16) {
2993 static jmethodID getByAddressMethod = env->GetStaticMethodID(JniConstants::inet6AddressClass,
2994 "getByAddress", "(Ljava/lang/String;[BI)Ljava/net/Inet6Address;");
2995 if (getByAddressMethod == NULL) {
2996 return NULL;
2997 }
2998 return env->CallStaticObjectMethod(JniConstants::inet6AddressClass, getByAddressMethod,
2999 NULL, byteArray.get(), scope_id);
3000 } else {
3001 abort();
3002 return NULL;
3003 }
3004}
3005
3006/*
3007 * Class: com_ceph_fs_CephMount
3008 * Method: native_ceph_get_osd_addr
3009 * Signature: (JI)Ljava/net/InetAddress;
3010 */
3011JNIEXPORT jobject JNICALL Java_com_ceph_fs_CephMount_native_1ceph_1get_1osd_1addr
3012 (JNIEnv *env, jclass clz, jlong j_mntp, jint osd)
3013{
3014 struct ceph_mount_info *cmount = get_ceph_mount(j_mntp);
3015 CephContext *cct = ceph_get_mount_context(cmount);
3016 struct sockaddr_storage addr;
3017 int ret;
3018
3019 CHECK_MOUNTED(cmount, NULL);
3020
3021 ldout(cct, 10) << "jni: get_osd_addr: osd " << osd << dendl;
3022
3023 ret = ceph_get_osd_addr(cmount, osd, &addr);
3024
3025 ldout(cct, 10) << "jni: get_osd_addr: ret " << ret << dendl;
3026
3027 if (ret < 0) {
3028 handle_error(env, ret);
3029 return NULL;
3030 }
3031
3032 return sockaddrToInetAddress(env, addr, NULL);
3033}