Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / java / java / com / ceph / fs / CephMount.java
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 package com.ceph.fs;
21
22 import java.io.IOException;
23 import java.io.FileNotFoundException;
24 import java.net.InetAddress;
25 import java.util.concurrent.locks.Lock;
26 import java.util.concurrent.locks.ReentrantReadWriteLock;
27 import java.lang.String;
28
29 import com.ceph.crush.Bucket;
30
31 public class CephMount {
32
33   /*
34    * Set via JNI callback in native_ceph_create
35    *
36    * Do not touch!
37    */
38   private long instance_ptr;
39
40   /*
41    * Flags for open().
42    *
43    * Must be synchronized with JNI if changed.
44    */
45   public static final int O_RDONLY    = 1;
46   public static final int O_RDWR      = 2;
47   public static final int O_APPEND    = 4;
48   public static final int O_CREAT     = 8;
49   public static final int O_TRUNC     = 16;
50   public static final int O_EXCL      = 32;
51   public static final int O_WRONLY    = 64;
52   public static final int O_DIRECTORY = 128;
53
54   /*
55    * Whence flags for seek().
56    *
57    * Must be synchronized with JNI if changed.
58    */
59   public static final int SEEK_SET = 1;
60   public static final int SEEK_CUR = 2;
61   public static final int SEEK_END = 3;
62
63   /*
64    * Attribute flags for setattr().
65    *
66    * Must be synchronized with JNI if changed.
67    */
68   public static final int SETATTR_MODE  = 1;
69   public static final int SETATTR_UID   = 2;
70   public static final int SETATTR_GID   = 4;
71   public static final int SETATTR_MTIME = 8;
72   public static final int SETATTR_ATIME = 16;
73
74   /*
75    * Flags for setxattr();
76    *
77    * Must be synchronized with JNI if changed.
78    */
79   public static final int XATTR_CREATE  = 1;
80   public static final int XATTR_REPLACE = 2;
81   public static final int XATTR_NONE    = 3;
82
83   /*
84    * Flags for flock();
85    *
86    * Must be synchronized with JNI if changed.
87    */
88   public static final int LOCK_SH       = 1;
89   public static final int LOCK_EX       = 2;
90   public static final int LOCK_NB       = 4;
91   public static final int LOCK_UN       = 8;
92
93   /*
94    * This is run by the class loader and will report early any problems
95    * finding or linking in the shared JNI library.
96    */
97   static {
98     loadLibrary();
99   }
100
101   static synchronized void loadLibrary() {
102     CephNativeLoader.getInstance().loadLibrary();
103   }
104
105   /*
106    * Package-private: called from CephNativeLoader
107    */
108   static native void native_initialize();
109
110   /*
111    * RW lock used for fine grained synchronization to native
112    */
113   private final ReentrantReadWriteLock rwlock = new ReentrantReadWriteLock();
114   private final Lock rlock = rwlock.readLock();
115   private final Lock wlock = rwlock.writeLock();
116
117   /*
118    * Controls clean-up synchronization between the constructor and finalize().
119    * If native_ceph_create fails, then we want a call to finalize() to not
120    * attempt to clean-up native context, because there is none.
121    */
122   private boolean initialized = false;
123
124   /*
125    * Try to clean-up. First, unmount() will catch users who forget to do the
126    * unmount manually. Second, release() will destroy the entire context. It
127    * is safe to call release after a failure in unmount.
128    */
129   protected void finalize() throws Throwable {
130     if (initialized) {
131       try {
132         unmount();
133       } catch (Exception e) {}
134       try {
135         native_ceph_release(instance_ptr);
136       } catch (Exception e) {}
137     }
138     super.finalize();
139   }
140
141   /**
142    * Create a new CephMount with specific client id.
143    *
144    * @param id client id.
145    */
146   public CephMount(String id) {
147     native_ceph_create(this, id);
148     initialized = true;
149   }
150
151   private static native int native_ceph_create(CephMount mount, String id);
152
153   /**
154    * Create a new CephMount with default client id.
155    */
156   public CephMount() {
157     this(null);
158   }
159
160   /**
161    * Activate the mount with a given root path.
162    *
163    * @param root The path to use as the root (pass null for "/").
164    */
165   public void mount(String root) {
166     wlock.lock();
167     try {
168       native_ceph_mount(instance_ptr, root);
169     } finally {
170       wlock.unlock();
171     }
172   }
173
174   private static native int native_ceph_mount(long mountp, String root);
175
176   /**
177    * Deactivate the mount.
178    *
179    * The mount can be reactivated using mount(). Configuration parameters
180    * previously set are not reset.
181    */
182   public void unmount() {
183     wlock.lock();
184     try {
185       native_ceph_unmount(instance_ptr);
186     } finally {
187       wlock.unlock();
188     }
189   }
190
191   private static native int native_ceph_unmount(long mountp);
192
193   /*
194    * Private access to low-level ceph_release.
195    */
196   private static native int native_ceph_release(long mountp);
197
198   /**
199    * Load configuration from a file.
200    *
201    * @param path The path to the configuration file.
202    */
203   public void conf_read_file(String path) throws FileNotFoundException {
204     rlock.lock();
205     try {
206       native_ceph_conf_read_file(instance_ptr, path);
207     } finally {
208       rlock.unlock();
209     }
210   }
211
212   private static native int native_ceph_conf_read_file(long mountp, String path);
213
214   /**
215    * Set the value of a configuration option.
216    *
217    * @param option The configuration option to modify.
218    * @param value The new value of the option.
219    */
220   public void conf_set(String option, String value) {
221     rlock.lock();
222     try {
223       native_ceph_conf_set(instance_ptr, option, value);
224     } finally {
225       rlock.unlock();
226     }
227   }
228
229   private static native int native_ceph_conf_set(long mountp, String option, String value);
230
231   /**
232    * Get the value of a configuration option.
233    *
234    * @param option The name of the configuration option.
235    * @return The value of the option or null if option not found
236    */
237   public String conf_get(String option) {
238     rlock.lock();
239     try {
240       return native_ceph_conf_get(instance_ptr, option);
241     } finally {
242       rlock.unlock();
243     }
244   }
245
246   private static native String native_ceph_conf_get(long mountp, String option);
247
248   /**
249    * Get file system status.
250    *
251    * @param path Path to file in file system.
252    * @param statvfs CephStatVFS structure to hold status.
253    */
254   public void statfs(String path, CephStatVFS statvfs) throws FileNotFoundException {
255     rlock.lock();
256     try {
257       native_ceph_statfs(instance_ptr, path, statvfs);
258     } finally {
259       rlock.unlock();
260     }
261   }
262
263   private static native int native_ceph_statfs(long mountp, String path, CephStatVFS statvfs);
264
265   /**
266    * Get the current working directory.
267    *
268    * @return The current working directory in Ceph.
269    */
270   public String getcwd() {
271     rlock.lock();
272     try {
273       return native_ceph_getcwd(instance_ptr);
274     } finally {
275       rlock.unlock();
276     }
277   }
278
279   private static native String native_ceph_getcwd(long mountp);
280
281   /**
282    * Set the current working directory.
283    *
284    * @param path The directory set as the cwd.
285    */
286   public void chdir(String path) throws FileNotFoundException {
287     rlock.lock();
288     try {
289       native_ceph_chdir(instance_ptr, path);
290     } finally {
291       rlock.unlock();
292     }
293   }
294
295   private static native int native_ceph_chdir(long mountp, String cwd);
296
297   /**
298    * List the contents of a directory.
299    *
300    * @param dir The directory.
301    * @return List of files and directories excluding "." and "..".
302    */
303   public String[] listdir(String dir) throws FileNotFoundException {
304     rlock.lock();
305     try {
306       return native_ceph_listdir(instance_ptr, dir);
307     } finally {
308       rlock.unlock();
309     }
310   }
311
312   private static native String[] native_ceph_listdir(long mountp, String path);
313
314   /**
315    * Create a hard link to an existing file.
316    *
317    * @param oldpath The target path of the link.
318    * @param newpath The name of the link.
319    */
320   public void link(String oldpath, String newpath) throws FileNotFoundException {
321     rlock.lock();
322     try {
323       native_ceph_link(instance_ptr, oldpath, newpath);
324     } finally {
325       rlock.unlock();
326     }
327   }
328
329   private static native int native_ceph_link(long mountp, String existing, String newname);
330
331   /**
332    * Unlink/delete a name from the file system.
333    *
334    * @param path The name to unlink/delete.
335    */
336   public void unlink(String path) throws FileNotFoundException {
337     rlock.lock();
338     try {
339       native_ceph_unlink(instance_ptr, path);
340     } finally {
341       rlock.unlock();
342     }
343   }
344
345   private static native int native_ceph_unlink(long mountp, String path);
346
347   /**
348    * Rename a file or directory.
349    *
350    * @param from The current path.
351    * @param to The new path.
352    */
353   public void rename(String from, String to) throws FileNotFoundException {
354     rlock.lock();
355     try {
356       native_ceph_rename(instance_ptr, from, to);
357     } finally {
358       rlock.unlock();
359     }
360   }
361
362   private static native int native_ceph_rename(long mountp, String from, String to);
363
364   /**
365    * Create a directory.
366    *
367    * @param path The directory to create.
368    * @param mode The mode of the new directory.
369    */
370   public void mkdir(String path, int mode) {
371     rlock.lock();
372     try {
373       native_ceph_mkdir(instance_ptr, path, mode);
374     } finally {
375       rlock.unlock();
376     }
377   }
378
379   private static native int native_ceph_mkdir(long mountp, String path, int mode);
380
381   /**
382    * Create a directory and all parents.
383    *
384    * @param path The directory to create.
385    * @param mode The mode of the new directory.
386    */
387   public void mkdirs(String path, int mode) throws IOException {
388     rlock.lock();
389     try {
390       native_ceph_mkdirs(instance_ptr, path, mode);
391     } finally {
392       rlock.unlock();
393     }
394   }
395
396   private static native int native_ceph_mkdirs(long mountp, String path, int mode);
397
398   /**
399    * Delete a directory.
400    *
401    * @param path The directory to delete.
402    */
403   public void rmdir(String path) throws FileNotFoundException {
404     rlock.lock();
405     try {
406       native_ceph_rmdir(instance_ptr, path);
407     } finally {
408       rlock.unlock();
409     }
410   }
411
412   private static native int native_ceph_rmdir(long mountp, String path);
413
414   /**
415    * Read the value of a symbolic link.
416    */
417   public String readlink(String path) throws FileNotFoundException {
418     rlock.lock();
419     try {
420       return native_ceph_readlink(instance_ptr, path);
421     } finally {
422       rlock.unlock();
423     }
424   }
425
426   private static native String native_ceph_readlink(long mountp, String path);
427
428   /**
429    * Create a symbolic link.
430    *
431    * @param oldpath Target of the symbolic link.
432    * @param newpath Name of the link.
433    */
434   public void symlink(String oldpath, String newpath) {
435     rlock.lock();
436     try {
437       native_ceph_symlink(instance_ptr, oldpath, newpath);
438     } finally {
439       rlock.unlock();
440     }
441   }
442
443   private static native int native_ceph_symlink(long mountp, String existing, String newname);
444
445   /**
446    * Get file status.
447    *
448    * @param path Path of file to stat.
449    * @param stat CephStat structure to hold file status.
450    */
451   public void stat(String path, CephStat stat) throws FileNotFoundException, CephNotDirectoryException {
452     rlock.lock();
453     try {
454       native_ceph_stat(instance_ptr, path, stat);
455     } finally {
456       rlock.unlock();
457     }
458   }
459
460   private static native int native_ceph_stat(long mountp, String path, CephStat stat);
461
462   /**
463    * Get file status, without following symlinks.
464    *
465    * @param path Path of file to stat.
466    * @param stat CephStat structure to hold file status.
467    */
468   public void lstat(String path, CephStat stat) throws FileNotFoundException, CephNotDirectoryException {
469     rlock.lock();
470     try {
471       native_ceph_lstat(instance_ptr, path, stat);
472     } finally {
473       rlock.unlock();
474     }
475   }
476
477   private static native int native_ceph_lstat(long mountp, String path, CephStat stat);
478
479   /**
480    * Set file attributes.
481    *
482    * @param path Path to file.
483    * @param stat CephStat structure holding attributes.
484    * @param mask Mask specifying which attributes to set.
485    */
486   public void setattr(String path, CephStat stat, int mask) throws FileNotFoundException {
487     rlock.lock();
488     try {
489       native_ceph_setattr(instance_ptr, path, stat, mask);
490     } finally {
491       rlock.unlock();
492     }
493   }
494
495   private static native int native_ceph_setattr(long mountp, String relpath, CephStat stat, int mask);
496
497   /**
498    * Change file mode.
499    * 
500    * @param path Path to file.
501    * @param mode New mode bits.
502    */
503   public void chmod(String path, int mode) throws FileNotFoundException {
504     rlock.lock();
505     try {
506       native_ceph_chmod(instance_ptr, path, mode);
507     } finally {
508       rlock.unlock();
509     }
510   }
511
512   private static native int native_ceph_chmod(long mountp, String path, int mode);
513
514   /**
515    * Change file mode of an open file.
516    *
517    * @param fd The open file descriptor to change the mode bits on.
518    * @param mode New mode bits.
519    */
520   public void fchmod(int fd, int mode) {
521     rlock.lock();
522     try {
523       native_ceph_fchmod(instance_ptr, fd, mode);
524     } finally {
525       rlock.unlock();
526     }
527   }
528
529   private static native int native_ceph_fchmod(long mountp, int fd, int mode);
530
531   /**
532    * Truncate a file to a specified length.
533    *
534    * @param path Path of the file.
535    * @param size New file length.
536    */
537   public void truncate(String path, long size) throws FileNotFoundException {
538     rlock.lock();
539     try {
540       native_ceph_truncate(instance_ptr, path, size);
541     } finally {
542       rlock.unlock();
543     }
544   }
545
546   private static native int native_ceph_truncate(long mountp, String path, long size);
547
548   /**
549    * Open a file.
550    *
551    * @param path Path of file to open or create.
552    * @param flags Open flags.
553    * @param mode Permission mode.
554    * @return File descriptor.
555    */
556   public int open(String path, int flags, int mode) throws FileNotFoundException {
557     rlock.lock();
558     try {
559       return native_ceph_open(instance_ptr, path, flags, mode);
560     } finally {
561       rlock.unlock();
562     }
563   }
564
565   private static native int native_ceph_open(long mountp, String path, int flags, int mode);
566
567   /**
568    * Open a file with a specific file layout.
569    *
570    * @param path Path of file to open or create.
571    * @param flags Open flags.
572    * @param mode Permission mode.
573    * @param stripe_unit File layout stripe unit size.
574    * @param stripe_count File layout stripe count.
575    * @param object_size Size of each object.
576    * @param data_pool The target data pool.
577    * @return File descriptor.
578    */
579   public int open(String path, int flags, int mode, int stripe_unit, int stripe_count,
580       int object_size, String data_pool) throws FileNotFoundException {
581     rlock.lock();
582     try {
583       return native_ceph_open_layout(instance_ptr, path, flags, mode, stripe_unit,
584           stripe_count, object_size, data_pool);
585     } finally {
586       rlock.unlock();
587     }
588   }
589
590   private static native int native_ceph_open_layout(long mountp, String path,
591       int flags, int mode, int stripe_unit, int stripe_count, int object_size, String data_pool);
592
593   /**
594    * Close an open file.
595    *
596    * @param fd The file descriptor.
597    */
598   public void close(int fd) {
599     rlock.lock();
600     try {
601       native_ceph_close(instance_ptr, fd);
602     } finally {
603       rlock.unlock();
604     }
605   }
606
607   private static native int native_ceph_close(long mountp, int fd);
608
609   /**
610    * Seek to a position in a file.
611    *
612    * @param fd File descriptor.
613    * @param offset New offset.
614    * @param whence Whence value.
615    * @return The new offset.
616    */
617   public long lseek(int fd, long offset, int whence) {
618     rlock.lock();
619     try {
620       return native_ceph_lseek(instance_ptr, fd, offset, whence);
621     } finally {
622       rlock.unlock();
623     }
624   }
625
626   private static native long native_ceph_lseek(long mountp, int fd, long offset, int whence);
627
628   /**
629    * Read from a file.
630    *
631    * @param fd The file descriptor.
632    * @param buf Buffer to for data read.
633    * @param size Amount of data to read into the buffer.
634    * @param offset Offset to read from (-1 for current position).
635    * @return The number of bytes read.
636    */
637   public long read(int fd, byte[] buf, long size, long offset) {
638     rlock.lock();
639     try {
640       return native_ceph_read(instance_ptr, fd, buf, size, offset);
641     } finally {
642       rlock.unlock();
643     }
644   }
645
646   private static native long native_ceph_read(long mountp, int fd, byte[] buf, long size, long offset);
647
648   /**
649    * Write to a file at a specific offset.
650    *
651    * @param fd The file descriptor.
652    * @param buf Buffer to write.
653    * @param size Amount of data to write.
654    * @param offset Offset to write from (-1 for current position).
655    * @return The number of bytes written.
656    */
657   public long write(int fd, byte[] buf, long size, long offset) {
658     rlock.lock();
659     try {
660       return native_ceph_write(instance_ptr, fd, buf, size, offset);
661     } finally {
662       rlock.unlock();
663     }
664   }
665
666   private static native long native_ceph_write(long mountp, int fd, byte[] buf, long size, long offset);
667
668   /**
669    * Truncate a file.
670    *
671    * @param fd File descriptor of the file to truncate.
672    * @param size New file size.
673    */
674   public void ftruncate(int fd, long size) {
675     rlock.lock();
676     try {
677       native_ceph_ftruncate(instance_ptr, fd, size);
678     } finally {
679       rlock.unlock();
680     }
681   }
682
683   private static native int native_ceph_ftruncate(long mountp, int fd, long size);
684
685   /**
686    * Synchronize a file with the file system.
687    *
688    * @param fd File descriptor to synchronize.
689    * @param dataonly Synchronize only data.
690    */
691   public void fsync(int fd, boolean dataonly) {
692     rlock.lock();
693     try {
694       native_ceph_fsync(instance_ptr, fd, dataonly);
695     } finally {
696       rlock.unlock();
697     }
698   }
699
700   private static native int native_ceph_fsync(long mountp, int fd, boolean dataonly);
701
702   /**
703    * Apply or remove an advisory lock.
704    *
705    * @param fd File descriptor to lock or unlock.
706    * @param operation the advisory lock operation to be performed on the file
707    * descriptor among LOCK_SH (shared lock), LOCK_EX (exclusive lock),
708    * or LOCK_UN (remove lock). The LOCK_NB value can be ORed to perform a
709    * non-blocking operation.
710    * @param owner the user-supplied owner identifier (an arbitrary integer)
711    */
712   public void flock(int fd, int operation, long owner) throws IOException {
713     rlock.lock();
714     try {
715       native_ceph_flock(instance_ptr, fd, operation, owner);
716     } finally {
717       rlock.unlock();
718     }
719   }
720
721   private static native int native_ceph_flock(long mountp, int fd, int operation, long owner);
722
723   /**
724    * Get file status.
725    *
726    * @param fd The file descriptor.
727    * @param stat The object in which to store the status.
728    */
729   public void fstat(int fd, CephStat stat) {
730     rlock.lock();
731     try {
732       native_ceph_fstat(instance_ptr, fd, stat);
733     } finally {
734       rlock.unlock();
735     }
736   }
737
738   private static native int native_ceph_fstat(long mountp, int fd, CephStat stat);
739
740   /**
741    * Synchronize the client with the file system.
742    */
743   public void sync_fs() {
744     rlock.lock();
745     try {
746       native_ceph_sync_fs(instance_ptr);
747     } finally {
748       rlock.unlock();
749     }
750   }
751
752   private static native int native_ceph_sync_fs(long mountp);
753
754   /**
755    * Get an extended attribute value.
756    *
757    * If the buffer is large enough to hold the entire attribute value, or
758    * buf is null, the size of the value is returned.
759    *
760    * @param path File path.
761    * @param name Name of the attribute.
762    * @param buf Buffer to store attribute value.
763    * @return The length of the attribute value. See description for more
764    * details.
765    */
766   public long getxattr(String path, String name, byte[] buf) throws FileNotFoundException {
767     rlock.lock();
768     try {
769       return native_ceph_getxattr(instance_ptr, path, name, buf);
770     } finally {
771       rlock.unlock();
772     }
773   }
774
775   private static native long native_ceph_getxattr(long mountp, String path, String name, byte[] buf);
776
777   /**
778    * Get an extended attribute value of a symbolic link.
779    *
780    * If the buffer is large enough to hold the entire attribute value, or
781    * buf is null, the size of the value is returned.
782    *
783    * @param path File path.
784    * @param name Name of attribute.
785    * @param buf Buffer to store attribute value.
786    * @return The length of the attribute value. See description for more
787    * details.
788    */
789   public long lgetxattr(String path, String name, byte[] buf) throws FileNotFoundException {
790     rlock.lock();
791     try {
792       return native_ceph_lgetxattr(instance_ptr, path, name, buf);
793     } finally {
794       rlock.unlock();
795     }
796   }
797
798   private static native long native_ceph_lgetxattr(long mountp, String path, String name, byte[] buf);
799
800   /**
801    * List extended attributes.
802    *
803    * @param path File path.
804    * @return List of attribute names.
805    */
806   public String[] listxattr(String path) throws FileNotFoundException {
807     rlock.lock();
808     try {
809       return native_ceph_listxattr(instance_ptr, path);
810     } finally {
811       rlock.unlock();
812     }
813   }
814
815   private static native String[] native_ceph_listxattr(long mountp, String path);
816
817   /**
818    * List extended attributes of a symbolic link.
819    *
820    * @param path File path.
821    * @return List of attribute names.
822    */
823   public String[] llistxattr(String path) throws FileNotFoundException {
824     rlock.lock();
825     try {
826       return native_ceph_llistxattr(instance_ptr, path);
827     } finally {
828       rlock.unlock();
829     }
830   }
831
832   private static native String[] native_ceph_llistxattr(long mountp, String path);
833
834   /**
835    * Remove an extended attribute.
836    *
837    * @param path File path.
838    * @param name Name of attribute.
839    */
840   public void removexattr(String path, String name) throws FileNotFoundException {
841     rlock.lock();
842     try {
843       native_ceph_removexattr(instance_ptr, path, name);
844     } finally {
845       rlock.unlock();
846     }
847   }
848
849   private static native int native_ceph_removexattr(long mountp, String path, String name);
850
851   /**
852    * Remove an extended attribute from a symbolic link.
853    *
854    * @param path File path.
855    * @param name Name of attribute.
856    */
857   public void lremovexattr(String path, String name) throws FileNotFoundException {
858     rlock.lock();
859     try {
860       native_ceph_lremovexattr(instance_ptr, path, name);
861     } finally {
862       rlock.unlock();
863     }
864   }
865
866   private static native int native_ceph_lremovexattr(long mountp, String path, String name);
867
868   /**
869    * Set the value of an extended attribute.
870    *
871    * @param path The file path.
872    * @param name The attribute name.
873    * @param buf The attribute value.
874    * @param size The size of the attribute value.
875    * @param flags Flag controlling behavior (XATTR_CREATE/REPLACE/NONE).
876    */
877   public void setxattr(String path, String name, byte[] buf, long size, int flags) throws FileNotFoundException {
878     rlock.lock();
879     try {
880       native_ceph_setxattr(instance_ptr, path, name, buf, size, flags);
881     } finally {
882       rlock.unlock();
883     }
884   }
885
886   private static native int native_ceph_setxattr(long mountp, String path, String name, byte[] buf, long size, int flags);
887
888   /**
889    * Set the value of an extended attribute on a symbolic link.
890    *
891    * @param path The file path.
892    * @param name The attribute name.
893    * @param buf The attribute value.
894    * @param size The size of the attribute value.
895    * @param flags Flag controlling behavior (XATTR_CREATE/REPLACE/NONE).
896    */
897   public void lsetxattr(String path, String name, byte[] buf, long size, int flags) throws FileNotFoundException {
898     rlock.lock();
899     try {
900       native_ceph_lsetxattr(instance_ptr, path, name, buf, size, flags);
901     } finally {
902       rlock.unlock();
903     }
904   }
905
906   private static native int native_ceph_lsetxattr(long mountp, String path, String name, byte[] buf, long size, int flags);
907
908   /**
909    * Get the stripe unit of a file.
910    *
911    * @param fd The file descriptor.
912    * @return The stripe unit.
913    */
914   public int get_file_stripe_unit(int fd) {
915     rlock.lock();
916     try {
917       return native_ceph_get_file_stripe_unit(instance_ptr, fd);
918     } finally {
919       rlock.unlock();
920     }
921   }
922
923   private static native int native_ceph_get_file_stripe_unit(long mountp, int fd);
924
925   /**
926    * Get the name of the pool a file is stored in.
927    *
928    * @param fd An open file descriptor.
929    * @return The pool name.
930    */
931   public String get_file_pool_name(int fd) {
932     rlock.lock();
933     try {
934       return native_ceph_get_file_pool_name(instance_ptr, fd);
935     } finally {
936       rlock.unlock();
937     }
938   }
939
940   private static native String native_ceph_get_file_pool_name(long mountp, int fd);
941   
942   /**
943    * Get the default data pool of cephfs.
944    * 
945    * @return The pool name.
946    */ 
947   public String get_default_data_pool_name() {
948     rlock.lock();
949     try {
950       return native_ceph_get_default_data_pool_name(instance_ptr);
951     } finally {
952       rlock.unlock();
953     }
954   }
955   
956   private static native String native_ceph_get_default_data_pool_name(long mountp);
957
958   /**
959    * Get the replication of a file.
960    *
961    * @param fd The file descriptor.
962    * @return The file replication.
963    */
964   public int get_file_replication(int fd) {
965     rlock.lock();
966     try {
967       return native_ceph_get_file_replication(instance_ptr, fd);
968     } finally {
969       rlock.unlock();
970     }
971   }
972
973   private static native int native_ceph_get_file_replication(long mountp, int fd);
974
975   /**
976    * Favor reading from local replicas when possible.
977    *
978    * @param state Enable or disable localized reads.
979    */
980   public void localize_reads(boolean state) {
981     rlock.lock();
982     try {
983       native_ceph_localize_reads(instance_ptr, state);
984     } finally {
985       rlock.unlock();
986     }
987   }
988
989   private static native int native_ceph_localize_reads(long mountp, boolean on);
990
991   /**
992    * Get file layout stripe unit granularity.
993    *
994    * @return Stripe unit granularity.
995    */
996   public int get_stripe_unit_granularity() {
997     rlock.lock();
998     try {
999       return native_ceph_get_stripe_unit_granularity(instance_ptr);
1000     } finally {
1001       rlock.unlock();
1002     }
1003   }
1004
1005   private static native int native_ceph_get_stripe_unit_granularity(long mountp);
1006
1007   /**
1008    * Get the pool id for the named pool.
1009    *
1010    * @param name The pool name.
1011    * @return The pool id.
1012    */
1013   public int get_pool_id(String name) throws CephPoolException {
1014     rlock.lock();
1015     try {
1016       return native_ceph_get_pool_id(instance_ptr, name);
1017     } catch (FileNotFoundException e) {
1018       throw new CephPoolException("pool name " + name + " not found");
1019     } finally {
1020       rlock.unlock();
1021     }
1022   }
1023
1024   private static native int native_ceph_get_pool_id(long mountp, String name) throws FileNotFoundException;
1025
1026   /**
1027    * Get the pool replication factor.
1028    *
1029    * @param pool_id The pool id.
1030    * @return Number of replicas stored in the pool.
1031    */
1032   public int get_pool_replication(int pool_id) throws CephPoolException {
1033     rlock.lock();
1034     try {
1035       return native_ceph_get_pool_replication(instance_ptr, pool_id);
1036     } catch (FileNotFoundException e) {
1037       throw new CephPoolException("pool id " + pool_id + " not found");
1038     } finally {
1039       rlock.unlock();
1040     }
1041   }
1042
1043   private static native int native_ceph_get_pool_replication(long mountp, int pool_id) throws FileNotFoundException;
1044
1045   /**
1046    * Get file extent containing a given offset.
1047    *
1048    * @param fd The file descriptor.
1049    * @param offset Offset in file.
1050    * @return A CephFileExtent object.
1051    */
1052   public CephFileExtent get_file_extent(int fd, long offset) {
1053     rlock.lock();
1054     try {
1055       return native_ceph_get_file_extent_osds(instance_ptr, fd, offset);
1056     } finally {
1057       rlock.unlock();
1058     }
1059   }
1060
1061   private static native CephFileExtent native_ceph_get_file_extent_osds(long mountp, int fd, long offset);
1062
1063   /**
1064    * Get the fully qualified CRUSH location of an OSD.
1065    *
1066    * Returns (type, name) string pairs for each device in the CRUSH bucket
1067    * hierarchy starting from the given OSD to the root.
1068    *
1069    * @param osd The OSD device id.
1070    * @return List of pairs.
1071    */
1072   public Bucket[] get_osd_crush_location(int osd) {
1073     rlock.lock();
1074     try {
1075       String[] parts = native_ceph_get_osd_crush_location(instance_ptr, osd);
1076       Bucket[] path = new Bucket[parts.length / 2];
1077       for (int i = 0; i < path.length; i++)
1078         path[i] = new Bucket(parts[i*2], parts[i*2+1]);
1079       return path;
1080     } finally {
1081       rlock.unlock();
1082     }
1083   }
1084
1085   private static native String[] native_ceph_get_osd_crush_location(long mountp, int osd);
1086
1087   /**
1088    * Get the network address of an OSD.
1089    *
1090    * @param osd The OSD device id.
1091    * @return The network address.
1092    */
1093   public InetAddress get_osd_address(int osd) {
1094     rlock.lock();
1095     try {
1096       return native_ceph_get_osd_addr(instance_ptr, osd);
1097     } finally {
1098       rlock.unlock();
1099     }
1100   }
1101
1102   private static native InetAddress native_ceph_get_osd_addr(long mountp, int osd);
1103 }