From 9aa15433810b879090d6fca1aaa1b0d8e24fe71d Mon Sep 17 00:00:00 2001 From: Wine93 Date: Wed, 20 Dec 2023 17:29:26 +0800 Subject: [PATCH] t Signed-off-by: Wine93 --- ..._opencurve_curve_fs_libfs_CurveFSMount.cpp | 411 +++++++----- .../curve/fs/hadoop/CurveFSProto.java | 57 -- .../curve/fs/hadoop/CurveFSTalker.java | 190 ------ .../curve/fs/hadoop/CurveFileSystem.java | 584 ++++++++++-------- ...putStream.java => CurveFsInputStream.java} | 23 +- ...utStream.java => CurveFsOutputStream.java} | 28 +- .../curve/fs/libfs/CurveFSMount.java | 232 ------- .../opencurve/curve/fs/libfs/CurveFSStat.java | 50 -- ...veFSStatVFS.java => CurveFsException.java} | 24 +- .../curve/fs/libfs/CurveFsMount.java | 274 ++++++++ ...veLoader.java => CurveFsNativeLoader.java} | 29 +- .../curve/fs/libfs/CurveFsProto.java | 60 ++ curvefs/sdk/libcurvefs/examples/Makefile | 3 +- curvefs/sdk/libcurvefs/examples/common.h | 18 +- curvefs/sdk/libcurvefs/examples/ls.c | 18 +- curvefs/sdk/libcurvefs/libcurvefs.cpp | 83 ++- curvefs/sdk/libcurvefs/libcurvefs.h | 36 +- curvefs/src/client/filesystem/dir_cache.cpp | 20 +- curvefs/src/client/filesystem/dir_cache.h | 4 +- curvefs/src/client/vfs/handlers.cpp | 9 +- curvefs/src/client/vfs/handlers.h | 37 +- curvefs/src/client/vfs/meta.h | 12 +- curvefs/src/client/vfs/vfs.cpp | 155 ++++- curvefs/src/client/vfs/vfs.h | 18 +- 24 files changed, 1240 insertions(+), 1135 deletions(-) delete mode 100644 curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSProto.java delete mode 100644 curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSTalker.java rename curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/{CurveFSInputStream.java => CurveFsInputStream.java} (92%) rename curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/{CurveFSOutputStream.java => CurveFsOutputStream.java} (87%) delete mode 100644 curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSMount.java delete mode 100644 curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSStat.java rename curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/{CurveFSStatVFS.java => CurveFsException.java} (67%) create mode 100644 curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsMount.java rename curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/{CurveFSNativeLoader.java => CurveFsNativeLoader.java} (86%) create mode 100644 curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsProto.java diff --git a/curvefs/sdk/java/native/io_opencurve_curve_fs_libfs_CurveFSMount.cpp b/curvefs/sdk/java/native/io_opencurve_curve_fs_libfs_CurveFSMount.cpp index d9c0abed81..f0205ba8ab 100644 --- a/curvefs/sdk/java/native/io_opencurve_curve_fs_libfs_CurveFSMount.cpp +++ b/curvefs/sdk/java/native/io_opencurve_curve_fs_libfs_CurveFSMount.cpp @@ -22,40 +22,51 @@ #include #include +#include #include "absl/cleanup/cleanup.h" #include "curvefs/sdk/libcurvefs/libcurvefs.h" -#include "curvefs/sdk/java/native/io_opencurve_curve_fs_libfs_CurveFSMount.h" - -/* Cached field IDs for io.opencurve.curve.fs.CurveStat */ -static jfieldID curvestat_mode_fid; -static jfieldID curvestat_uid_fid; -static jfieldID curvestat_gid_fid; -static jfieldID curvestat_size_fid; -static jfieldID curvestat_blksize_fid; -static jfieldID curvestat_blocks_fid; -static jfieldID curvestat_a_time_fid; -static jfieldID curvestat_m_time_fid; -static jfieldID curvestat_is_file_fid; -static jfieldID curvestat_is_directory_fid; -static jfieldID curvestat_is_symlink_fid; - -/* Cached field IDs for io.opencurve.curve.fs.CurveStatVFS */ -static jfieldID curvestatvfs_bsize_fid; -static jfieldID curvestatvfs_frsize_fid; -static jfieldID curvestatvfs_blocks_fid; -static jfieldID curvestatvfs_bavail_fid; -static jfieldID curvestatvfs_files_fid; -static jfieldID curvestatvfs_fsid_fid; -static jfieldID curvestatvfs_namemax_fid; - -/* - * Setup cached field IDs - */ +#include "curvefs/sdk/java/native/io_opencurve_curve_fs_libfs_CurveFsMount.h" + +// Cached for class +static jclass statvfs_cls; +static jclass stat_cls; +static jclass file_cls; +static jclass dirent_cls; + +// Cached field IDs for io.opencurve.curve.fs.CurveFsMount.StatVfs +static jfieldID statvfs_bsize_fid; +static jfieldID statvfs_frsize_fid; +static jfieldID statvfs_blocks_fid; +static jfieldID statvfs_bavail_fid; +static jfieldID statvfs_files_fid; +static jfieldID statvfs_fsid_fid; +static jfieldID statvfs_namemax_fid; + +// Cached field IDs for io.opencurve.curve.fs.CurveFsMount.Stat +static jfieldID stat_mode_fid; +static jfieldID stat_uid_fid; +static jfieldID stat_gid_fid; +static jfieldID stat_size_fid; +static jfieldID stat_blksize_fid; +static jfieldID stat_blocks_fid; +static jfieldID stat_a_time_fid; +static jfieldID stat_m_time_fid; +static jfieldID stat_is_file_fid; +static jfieldID stat_is_directory_fid; +static jfieldID stat_is_symlink_fid; + +// Cached field IDs for io.opencurve.curve.fs.CurveFsMount.File +static jfieldID file_fd_fid; +static jfieldID file_length_fd; + +// Cached field IDs for io.opencurve.curve.fs.CurveFsMount.Dirent +static jfieldID dirent_name_fid; +static jfieldID dirent_stat_fid; + + +// Setup cached field IDs static void setup_field_ids(JNIEnv* env) { - jclass curvestat_cls; - jclass curvestatvfs_cls; - /* * Get a fieldID from a class with a specific type * @@ -75,94 +86,125 @@ static void setup_field_ids(JNIEnv* env) { return; \ } while (0) - /* Cache CurveStat fields */ + // Cache StatVfs fields + statvfs_cls = + env->FindClass("io/opencurve/curve/fs/libfs/CurveFsMount$StatVfs"); + if (!statvfs_cls) { + return; + } - curvestat_cls = env->FindClass("io/opencurve/curve/fs/libfs/CurveFSStat"); - if (!curvestat_cls) { + GETFID(statvfs, bsize, J); + GETFID(statvfs, frsize, J); + GETFID(statvfs, blocks, J); + GETFID(statvfs, bavail, J); + GETFID(statvfs, files, J); + GETFID(statvfs, fsid, J); + GETFID(statvfs, namemax, J); + + // Cache Stat fields + stat_cls = env->FindClass("io/opencurve/curve/fs/libfs/CurveFsMount$Stat"); + if (!stat_cls) { return; } - GETFID(curvestat, mode, I); - GETFID(curvestat, uid, I); - GETFID(curvestat, gid, I); - GETFID(curvestat, size, J); - GETFID(curvestat, blksize, J); - GETFID(curvestat, blocks, J); - GETFID(curvestat, a_time, J); - GETFID(curvestat, m_time, J); - GETFID(curvestat, is_file, Z); - GETFID(curvestat, is_directory, Z); - GETFID(curvestat, is_symlink, Z); - - /* Cache CurveStatVFS fields */ - - curvestatvfs_cls = - env->FindClass("io/opencurve/curve/fs/libfs/CurveFSStatVFS"); - if (!curvestatvfs_cls) { + GETFID(stat, mode, I); + GETFID(stat, uid, I); + GETFID(stat, gid, I); + GETFID(stat, size, J); + GETFID(stat, blksize, J); + GETFID(stat, blocks, J); + GETFID(stat, a_time, J); + GETFID(stat, m_time, J); + GETFID(stat, is_file, Z); + GETFID(stat, is_directory, Z); + GETFID(stat, is_symlink, Z); + + // Cache File fields + file_cls = env->FindClass("io/opencurve/curve/fs/libfs/CurveFsMount$File"); + if (!file_cls) { return; } - GETFID(curvestatvfs, bsize, J); - GETFID(curvestatvfs, frsize, J); - GETFID(curvestatvfs, blocks, J); - GETFID(curvestatvfs, bavail, J); - GETFID(curvestatvfs, files, J); - GETFID(curvestatvfs, fsid, J); - GETFID(curvestatvfs, namemax, J); + GETFID(file, fd, I); + GETFID(file, length, J); + + // Cache Dirent fields + dirent_cls = + env->FindClass("io/opencurve/curve/fs/libfs/CurveFsMount$Dirent"); + if (!dirent_cls) { + return; + } + + GETFID(dirent, name, "Ljava/lang/String;"); + GETFID(dirent, stat, + "Lio/opencurve/curve/fs/libfs/CurveFsMount$Stat;"); #undef GETFID } -static void fill_curvestat(JNIEnv* env, - jobject j_curvestat, - struct stat* stat) { - env->SetIntField(j_curvestat, curvestat_mode_fid, stat->st_mode); - env->SetIntField(j_curvestat, curvestat_uid_fid, stat->st_uid); - env->SetIntField(j_curvestat, curvestat_gid_fid, stat->st_gid); - env->SetLongField(j_curvestat, curvestat_size_fid, stat->st_size); - env->SetLongField(j_curvestat, curvestat_blksize_fid, stat->st_blksize); - env->SetLongField(j_curvestat, curvestat_blocks_fid, stat->st_blocks); +static void fill_statvfs(JNIEnv* env, jobject j_statvfs, struct statvfs* st) { + env->SetLongField(j_statvfs, statvfs_bsize_fid, st->f_bsize); + env->SetLongField(j_statvfs, statvfs_frsize_fid, st->f_frsize); + env->SetLongField(j_statvfs, statvfs_blocks_fid, st->f_blocks); + env->SetLongField(j_statvfs, statvfs_bavail_fid, st->f_bavail); + env->SetLongField(j_statvfs, statvfs_files_fid, st->f_files); + env->SetLongField(j_statvfs, statvfs_fsid_fid, st->f_fsid); + env->SetLongField(j_statvfs, statvfs_namemax_fid, st->f_namemax); +} + +static void fill_stat(JNIEnv* env, jobject j_stat, struct stat* stat) { + env->SetIntField(j_stat, stat_mode_fid, stat->st_mode); + env->SetIntField(j_stat, stat_uid_fid, stat->st_uid); + env->SetIntField(j_stat, stat_gid_fid, stat->st_gid); + env->SetLongField(j_stat, stat_size_fid, stat->st_size); + env->SetLongField(j_stat, stat_blksize_fid, stat->st_blksize); + env->SetLongField(j_stat, stat_blocks_fid, stat->st_blocks); // mtime uint64_t time = stat->st_mtim.tv_sec; time *= 1000; time += stat->st_mtim.tv_nsec / 1000000; - env->SetLongField(j_curvestat, curvestat_m_time_fid, time); + env->SetLongField(j_stat, stat_m_time_fid, time); // atime time = stat->st_atim.tv_sec; time *= 1000; time += stat->st_atim.tv_nsec / 1000000; - env->SetLongField(j_curvestat, curvestat_a_time_fid, time); + env->SetLongField(j_stat, stat_a_time_fid, time); - env->SetBooleanField(j_curvestat, curvestat_is_file_fid, + env->SetBooleanField(j_stat, stat_is_file_fid, S_ISREG(stat->st_mode) ? JNI_TRUE : JNI_FALSE); - env->SetBooleanField(j_curvestat, curvestat_is_directory_fid, + env->SetBooleanField(j_stat, stat_is_directory_fid, S_ISDIR(stat->st_mode) ? JNI_TRUE : JNI_FALSE); - env->SetBooleanField(j_curvestat, curvestat_is_symlink_fid, + env->SetBooleanField(j_stat, stat_is_symlink_fid, S_ISLNK(stat->st_mode) ? JNI_TRUE : JNI_FALSE); } -static void fill_curvestatvfs(JNIEnv* env, - jobject j_curvestatvfs, - struct statvfs st) { - env->SetLongField(j_curvestatvfs, curvestatvfs_bsize_fid, st.f_bsize); - env->SetLongField(j_curvestatvfs, curvestatvfs_frsize_fid, st.f_frsize); - env->SetLongField(j_curvestatvfs, curvestatvfs_blocks_fid, st.f_blocks); - env->SetLongField(j_curvestatvfs, curvestatvfs_bavail_fid, st.f_bavail); - env->SetLongField(j_curvestatvfs, curvestatvfs_files_fid, st.f_files); - env->SetLongField(j_curvestatvfs, curvestatvfs_fsid_fid, st.f_fsid); - env->SetLongField(j_curvestatvfs, curvestatvfs_namemax_fid, st.f_namemax); +static void fill_file(JNIEnv* env, jobject j_file, file_t* file) { + env->SetIntField(j_file, file_fd_fid, file->fd); + env->SetLongField(j_file, file_length_fid, file->length); +} + +static void fill_dirent(JNIEnv* env, jobject j_dirent, dirent_t* dirent) { + jstring j_name = env->NewStringUTF(dirent->name); + jclass j_stat = env->AllocObject(stat_cls); + fill_curvestat(env, j_stat, &dirent->stat); + + env->SetObjectField(j_dirent, dirent_name_fid, j_name); + env->SetObjectField(j_dirent, dirent_stat_fid, j_stat); + + env->DeleteLocalRef(j_name); + env->DeleteLocalRef(j_stat); } -/* Map io_opencurve_curve_fs_libfs_CurveFSMount_O_* open flags to values in libc */ +// Map io_opencurve_curve_fs_libfs_CurveFsMount_O_* open flags to values in libc static inline uint32_t fixup_open_flags(jint jflags) { uint32_t flags = 0; #define FIXUP_OPEN_FLAG(name) \ - if (jflags & io_opencurve_curve_fs_libfs_CurveFSMount_##name) \ + if (jflags & io_opencurve_curve_fs_libfs_CurveFsMount_##name) \ flags |= name; FIXUP_OPEN_FLAG(O_RDONLY) @@ -189,12 +231,12 @@ static inline uint32_t fixup_open_flags(jint jflags) { #define CURVEFS_SETATTR_MTIME_NOW (1 << 8) #define CURVEFS_SETATTR_CTIME (1 << 10) -/* Map JAVA_SETATTR_* to values in curve lib */ +// Map JAVA_SETATTR_* to values in curve lib static inline int fixup_attr_mask(jint jmask) { int mask = 0; #define FIXUP_ATTR_MASK(name) \ - if (jmask & io_opencurve_curve_fs_libfs_CurveFSMount_##name) \ + if (jmask & io_opencurve_curve_fs_libfs_CurveFsMount_##name) \ mask |= CURVEFS_##name; FIXUP_ATTR_MASK(SETATTR_MODE) @@ -207,17 +249,15 @@ static inline int fixup_attr_mask(jint jmask) { return mask; } -/* - * Exception throwing helper. Adapted from Apache Hadoop header - * org_apache_hadoop.h by adding the do {} while (0) construct. - */ +// Exception throwing helper. Adapted from Apache Hadoop header +// org_apache_hadoop.h by adding the do {} while (0) construct. #define THROW(env, exception_name, message) \ do { \ jclass ecls = env->FindClass(exception_name); \ if (ecls) { \ int ret = env->ThrowNew(ecls, message); \ if (ret < 0) { \ - printf("(CurveFS) Fatal Error\n"); \ + printf("(CurveFs) Fatal Error\n"); \ } \ env->DeleteLocalRef(ecls); \ } \ @@ -232,7 +272,7 @@ static void handle_error(JNIEnv* env, int rc) { THROW(env, "org/apache/hadoop/fs/FileAlreadyExistsException", ""); return; case ENOTDIR: - THROW(env, "org/apache/hadoop/fs/ParentNotDirectoryException", ""); + THROW(env, "io/opencurve/curve/fs/libfs/CurveFsException$NotADirectoryException", ""); // NOLINT return; default: break; @@ -241,26 +281,26 @@ static void handle_error(JNIEnv* env, int rc) { THROW(env, "java/io/IOException", strerror(rc)); } -// nativeCurveFSCreate: curvefs_create +// nativeCurveFsCreate: curvefs_create JNIEXPORT jlong -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSCreate +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsCreate (JNIEnv* env, jobject) { setup_field_ids(env); uintptr_t instance = curvefs_create(); return reinterpret_cast(instance); } -// nativeCurveFSRelease: curvefs_release +// nativeCurveFsRelease: curvefs_release JNIEXPORT void -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSRelease +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsRelease (JNIEnv* env, jobject, jlong j_instance) { uintptr_t instance = static_cast(j_instance); return curvefs_release(instance); } -// nativeCurveFSConfSet: curvefs_conf_set +// nativeCurveFsConfSet: curvefs_conf_set JNIEXPORT void -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSConfSet +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsConfSet (JNIEnv* env, jclass, jlong j_instance, jstring j_key, jstring j_value) { uintptr_t instance = static_cast(j_instance); const char* key = env->GetStringUTFChars(j_key, NULL); @@ -273,9 +313,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSConfSet return curvefs_conf_set(instance, key, value); } -// nativeCurveFSMount: curvefs_mount +// nativeCurveFsMount: curvefs_mount JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSMount +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsMount (JNIEnv* env, jclass, jlong j_instance, jstring j_fsname, jstring j_mountpoint) { uintptr_t instance = static_cast(j_instance); @@ -293,9 +333,10 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSMount return rc; } -// nativeCurveFSUmount: curvefs_umount +// nativeCurveFsUmount: curvefs_umount +p JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSUmount +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsUmount (JNIEnv* env, jclass, jlong j_instance, jstring j_fsname, jstring j_mountpoint) { uintptr_t instance = static_cast(j_instance); @@ -313,9 +354,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSUmount return rc; } -// nativeCurveFSMkDirs: curvefs_mkdirs +// nativeCurveFsMkDirs: curvefs_mkdirs JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSMkDirs +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsMkDirs (JNIEnv* env, jclass, jlong j_instance, jstring j_path, jint j_mode) { uintptr_t instance = static_cast(j_instance); const char* path = env->GetStringUTFChars(j_path, NULL); @@ -333,9 +374,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSMkDirs return rc; } -// nativeCurveFSRmDir: curvefs_rmdir +// nativeCurveFsRmDir: curvefs_rmdir JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSRmDir +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsRmDir (JNIEnv* env, jclass, jlong j_instance, jstring j_path) { uintptr_t instance = static_cast(j_instance); const char* path = env->GetStringUTFChars(j_path, NULL); @@ -350,9 +391,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSRmDir return rc; } -// nativeCurveFSListDir: curvefs_opendir/curvefs_readdir/curvefs_closedir +// nativeCurveFsListDir: curvefs_opendir/curvefs_readdir/curvefs_closedir JNIEXPORT jobjectArray -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSListDir +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsListDir (JNIEnv* env, jclass, jlong j_instance, jstring j_path) { uintptr_t instance = static_cast(j_instance); const char* path = env->GetStringUTFChars(j_path, NULL); @@ -361,51 +402,70 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSListDir }); // curvefs_opendir - dir_stream_t dir_stream; - auto rc = curvefs_opendir(instance, path, &dir_stream); + uint64_t fd; + auto rc = curvefs_opendir(instance, path, &fd); if (rc != 0) { handle_error(env, rc); return NULL; } // curvefs_readdir - std::vector dirents; - dirent_t dirent; - for ( ;; ) { - ssize_t n = curvefs_readdir(instance, &dir_stream, &dirent); + size_t count = 1 << 13; // 8192 + std::vector dirents, buffer(count); + for ( ; ; ) { + ssize_t n = curvefs_readdir(instance, fd, buffer.data(), count); if (n < 0) { handle_error(env, rc); return NULL; } else if (n == 0) { break; } - dirents.push_back(dirent); + dirents.insert(dirents.end(), buffer.begin(), buffer.end()); } // closedir - rc = curvefs_closedir(instance, &dir_stream); + rc = curvefs_closedir(instance, fd); if (rc != 0) { handle_error(env, rc); return NULL; } - // extract entry name - jobjectArray j_names = env->NewObjectArray( - dirents.size(), env->FindClass("java/lang/String"), NULL); + jobjectArray j_dirents = + env->NewObjectArray(dirents.size(), dirent_cls, NULL); + for (int i = 0; i < n; i++) { + jclass j_dirent = env->AllocObject(dirent_cls); + fill_dirent(env, j_dirent, &dirents[i]); + env->SetObjectArrayElement(j_dirents, i, j_dirent); + env->DeleteLocalRef(j_dirent); + } + return j_dirents; +} - for (int i = 0; i < dirents.size(); i++) { - jstring j_name = env->NewStringUTF(dirents[i].name); - env->SetObjectArrayElement(j_names, i, j_name); - env->DeleteLocalRef(j_name); +// nativeCurveFsOpen: curvefs_create +JNIEXPORT jint +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsCreate + (JNIEnv* env, jclass, + jlong j_instance, jstring j_path, jint j_mode, jobject j_file) { + uintptr_t instance = static_cast(j_instance); + const char* path = env->GetStringUTFChars(j_path, NULL); + uint16_t mode = static_cast(j_mode); + auto defer = absl::MakeCleanup([&]() { + env->ReleaseStringUTFChars(j_path, path); + }); + + file_t file; + int rc = curvefs_create(instance, path, mode, &file); + if (rc < 0) { + handle_error(env, rc); } - return j_names; + return rc; } -// nativeCurveFSOpen: curvefs_open +// nativeCurveFsOpen: curvefs_open JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSOpen +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsOpen (JNIEnv* env, jclass, - jlong j_instance, jstring j_path, jint j_flags, jint j_mode) { + jlong j_instance, jstring j_path, jint j_flags, jobject j_file) { uintptr_t instance = static_cast(j_instance); const char* path = env->GetStringUTFChars(j_path, NULL); uint32_t flags = fixup_open_flags(j_flags); @@ -414,16 +474,17 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSOpen env->ReleaseStringUTFChars(j_path, path); }); - int fd = curvefs_open(instance, path, flags, mode); - if (fd < 0) { - handle_error(env, fd); + file_t file; + int rc = curvefs_open(instance, path, flags, &file); + if (rc < 0) { + handle_error(env, rc); } return fd; } -// nativeCurveFSLSeek: curvefs_lseek +// nativeCurveFsLSeek: curvefs_lseek JNIEXPORT jlong -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSLSeek +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsLSeek (JNIEnv* env, jclass, jlong j_instance, jint j_fd, jlong j_offset, jint j_whence) { uintptr_t instance = static_cast(j_instance); @@ -432,13 +493,13 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSLSeek int whence; switch (j_whence) { - case io_opencurve_curve_fs_libfs_CurveFSMount_SEEK_SET: + case io_opencurve_curve_fs_libfs_CurveFsMount_SEEK_SET: whence = SEEK_SET; break; - case io_opencurve_curve_fs_libfs_CurveFSMount_SEEK_CUR: + case io_opencurve_curve_fs_libfs_CurveFsMount_SEEK_CUR: whence = SEEK_CUR; break; - case io_opencurve_curve_fs_libfs_CurveFSMount_SEEK_END: + case io_opencurve_curve_fs_libfs_CurveFsMount_SEEK_END: whence = SEEK_END; break; default: @@ -452,9 +513,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSLSeek return rc; } -// nativieCurveFSRead: curvefs_read +// nativieCurveFsRead: curvefs_read JNIEXPORT jlong -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativieCurveFSRead +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativieCurveFsRead (JNIEnv* env, jclass, jlong j_instance, jint j_fd, jbyteArray j_buffer, jlong j_size, jlong j_offset) { uintptr_t instance = static_cast(j_instance); @@ -473,9 +534,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativieCurveFSRead return static_cast(n); } -// nativieCurveFSWrite: curvefs_write +// nativieCurveFsWrite: curvefs_write JNIEXPORT jlong -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativieCurveFSWrite +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativieCurveFsWrite (JNIEnv* env, jclass, jlong j_instance, jint j_fd, jbyteArray j_buffer, jlong j_size, jlong j_offset) { uintptr_t instance = static_cast(j_instance); @@ -494,9 +555,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativieCurveFSWrite return static_cast(n); } -// nativeCurveFSFSync: curvefs_fsync +// nativeCurveFsFSync: curvefs_fsync JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSFSync +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsFSync (JNIEnv* env, jclass, jlong j_instance, jint j_fd) { uintptr_t instance = static_cast(j_instance); int fd = static_cast(j_fd); @@ -508,9 +569,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSFSync return rc; } -// nativeCurveFSClose: curvefs_close +// nativeCurveFsClose: curvefs_close JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSClose +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsClose (JNIEnv* env, jclass, jlong j_instance, jint j_fd) { uintptr_t instance = static_cast(j_instance); int fd = static_cast(j_fd); @@ -522,9 +583,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSClose return rc; } -// nativeCurveFSUnlink: curvefs_unlink +// nativeCurveFsUnlink: curvefs_unlink JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSUnlink +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsUnlink (JNIEnv* env, jclass, jlong j_instance, jstring j_path) { uintptr_t instance = static_cast(j_instance); const char* path = env->GetStringUTFChars(j_path, NULL); @@ -539,9 +600,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSUnlink return rc; } -// nativeCurveFSStatFs: curvefs_statfs +// nativeCurveFsStatFs: curvefs_statfs JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSStatFs +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsStatFs (JNIEnv* env, jclass, jlong j_instance, jobject j_curvestatvfs) { uintptr_t instance = static_cast(j_instance); @@ -557,9 +618,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSStatFs return rc; } -// nativeCurveFSLstat: curvefs_lstat +// nativeCurveFsLstat: curvefs_lstat JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSLstat +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsLstat (JNIEnv* env, jclass, jlong j_instance, jstring j_path, jobject j_curvestat) { uintptr_t instance = static_cast(j_instance); @@ -580,9 +641,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSLstat return rc; } -// nativeCurveFSFStat: curvefs_fstat +// nativeCurveFsFStat: curvefs_fstat JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSFStat +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsFStat (JNIEnv* env, jclass, jlong j_instance, jint j_fd, jobject j_curvestat) { uintptr_t instance = static_cast(j_instance); int fd = static_cast(j_fd); @@ -599,9 +660,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSFStat return rc; } -// nativeCurveFSSetAttr: curvefs_setattr +// nativeCurveFsSetAttr: curvefs_setattr JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSSetAttr +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsSetAttr (JNIEnv* env, jclass, jlong j_instance, jstring j_path, jobject j_curvestat, jint j_mask) { uintptr_t instance = static_cast(j_instance); @@ -630,9 +691,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSSetAttr return rc; } -// nativeCurveFSChmod: curvefs_chmod +// nativeCurveFsChmod: curvefs_chmod JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSChmod +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsChmod (JNIEnv* env, jclass, jlong j_instance, jstring j_path, jint j_mode) { uintptr_t instance = static_cast(j_instance); uint16_t mode = static_cast(j_mode); @@ -648,9 +709,9 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSChmod return rc; } -// nativeCurveFSChown: curvefs_chown +// nativeCurveFsChown: curvefs_chown JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSChown +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsChown (JNIEnv* env, jclass, jlong j_instance, jstring j_path, jint j_uid, jint j_gid) { uintptr_t instance = static_cast(j_instance); @@ -668,9 +729,43 @@ JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSChown return rc; } -// nativeCurveFSRename: curvefs_rename +// nativeCurveFsRemove: curvefs_remove +JNIEXPORT jint +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsRemove + (JNIEnv* env, jclass, jlong j_instance, jstring j_path) { + uintptr_t instance = static_cast(j_instance); + const char* path = env->GetStringUTFChars(j_path, NULL); + auto defer = absl::MakeCleanup([&]() { + env->ReleaseStringUTFChars(j_path, path); + }); + + int rc = curvefs_remove(instance, src, dst); + if (rc != 0) { + handle_error(env, rc); + } + return rc; +} + +// nativeCurveFsRemoveAll: curvefs_removeall +JNIEXPORT jint +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsRemoveAll + (JNIEnv* env, jclass, jlong j_instance, jstring j_path) { + uintptr_t instance = static_cast(j_instance); + const char* path = env->GetStringUTFChars(j_path, NULL); + auto defer = absl::MakeCleanup([&]() { + env->ReleaseStringUTFChars(j_path, path); + }); + + int rc = curvefs_removeall(instance, src, dst); + if (rc != 0) { + handle_error(env, rc); + } + return rc; +} + +// nativeCurveFsRename: curvefs_rename JNIEXPORT jint -JNICALL Java_io_opencurve_curve_fs_libfs_CurveFSMount_nativeCurveFSRename +JNICALL Java_io_opencurve_curve_fs_libfs_CurveFsMount_nativeCurveFsRename (JNIEnv* env, jclass, jlong j_instance, jstring j_src, jstring j_dst) { uintptr_t instance = static_cast(j_instance); const char* src = env->GetStringUTFChars(j_src, NULL); diff --git a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSProto.java b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSProto.java deleted file mode 100644 index df8ab69b21..0000000000 --- a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSProto.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2023 NetEase Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Project: Curve - * Created Date: 2023-08-01 - * Author: NetEase Media Bigdata - */ - -package io.opencurve.curve.fs.hadoop; - -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.Path; -import io.opencurve.curve.fs.libfs.CurveFSStat; -import io.opencurve.curve.fs.libfs.CurveFSStatVFS; - -import java.io.IOException; -import java.net.URI; - -abstract class CurveFSProto { - // init* - abstract void initialize(URI uri, Configuration conf) throws IOException; - abstract void shutdown() throws IOException; - // directory* - abstract void mkdirs(Path path, int mode) throws IOException; - abstract void rmdir(Path path) throws IOException; - abstract String[] listdir(Path path) throws IOException; - // file* - abstract int open(Path path, int flags, int mode) throws IOException; - abstract long lseek(int fd, long offset, int whence) throws IOException; - abstract int write(int fd, byte[] buf, long size, long offset) throws IOException; - abstract int read(int fd, byte[] buf, long size, long offset) throws IOException; - abstract void fsync(int fd) throws IOException; - abstract void close(int fd) throws IOException; - abstract void unlink(Path path) throws IOException; - // others - abstract void statfs(Path path, CurveFSStatVFS stat) throws IOException; - abstract void lstat(Path path, CurveFSStat stat) throws IOException; - abstract void fstat(int fd, CurveFSStat stat) throws IOException; - abstract void setattr(Path path, CurveFSStat stat, int mask) throws IOException; - abstract void chmod(Path path, int mode) throws IOException; - abstract void chown(Path path, int uid, int gid) throws IOException; - abstract void rename(Path src, Path dst) throws IOException; -} diff --git a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSTalker.java b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSTalker.java deleted file mode 100644 index 714a6182cb..0000000000 --- a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSTalker.java +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (c) 2023 NetEase Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Project: Curve - * Created Date: 2023-08-01 - * Author: NetEase Media Bigdata - */ - -package io.opencurve.curve.fs.hadoop; - -import org.apache.commons.logging.Log; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.fs.Path; -import io.opencurve.curve.fs.libfs.CurveFSMount; -import io.opencurve.curve.fs.libfs.CurveFSStat; -import io.opencurve.curve.fs.libfs.CurveFSStatVFS; - -import java.util.UUID; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.net.URI; -import java.util.Map; - -class CurveFSTalker extends CurveFSProto { - private CurveFSMount mount; - private String fsname = null; - private String mountpoint = null; - private boolean inited = false; - - private static final String PREFIX_KEY = "curvefs"; - - CurveFSTalker(Configuration conf, Log log) { - mount = null; - } - - private String tostr(Path path) { - if (null == path) { - return "/"; - } - return path.toUri().getPath(); - } - - private void loadCfg(Configuration conf) { - Map m = conf.getValByRegex("^" + PREFIX_KEY + "\\..*"); - for (Map.Entry entry : m.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue(); - if (key.equals(PREFIX_KEY + ".name")) { - fsname = value; - } else { - mount.confSet(key.substring(PREFIX_KEY.length() + 1), value); - } - } - } - - @Override - void initialize(URI uri, Configuration conf) throws IOException { - if (inited) { - return; - } - - mount = new CurveFSMount(); - loadCfg(conf); - if (null == fsname || fsname.isEmpty()) { - throw new IOException("curvefs.name is not set"); - } - mountpoint = UUID.randomUUID().toString(); - mount.mount(fsname, mountpoint); - inited = true; - } - - @Override - void shutdown() throws IOException { - if (inited) { - mount.umount(fsname, mountpoint); - mount.release(); - mount = null; - inited = false; - } - } - - @Override - void mkdirs(Path path, int mode) throws IOException { - mount.mkdirs(tostr(path), mode); - } - - @Override - void rmdir(Path path) throws IOException { - mount.rmdir(tostr(path)); - } - - @Override - String[] listdir(Path path) throws IOException { - CurveFSStat stat = new CurveFSStat(); - try { - mount.lstat(tostr(path), stat); - } catch (FileNotFoundException e) { - return null; - } - if (!stat.isDir()) { - return null; - } - - return mount.listdir(tostr(path)); - } - - @Override - int open(Path path, int flags, int mode) throws IOException { - return mount.open(tostr(path), flags, mode); - } - - @Override - long lseek(int fd, long offset, int whence) throws IOException { - return mount.lseek(fd, offset, whence); - } - - @Override - int write(int fd, byte[] buf, long size, long offset) throws IOException { - return mount.write(fd, buf, size, offset); - } - - @Override - int read(int fd, byte[] buf, long size, long offset) throws IOException { - return mount.read(fd, buf, size, offset); - } - - @Override - void fsync(int fd) throws IOException { - mount.fsync(fd); - } - - @Override - void close(int fd) throws IOException { - mount.close(fd); - } - - @Override - void unlink(Path path) throws IOException { - mount.unlink(tostr(path)); - } - - @Override - void statfs(Path path, CurveFSStatVFS stat) throws IOException { - mount.statfs(tostr(path), stat); - } - - @Override - void lstat(Path path, CurveFSStat stat) throws IOException { - mount.lstat(tostr(path), stat); - } - - @Override - void fstat(int fd, CurveFSStat stat) throws IOException { - mount.fstat(fd, stat); - } - - @Override - void setattr(Path path, CurveFSStat stat, int mask) throws IOException { - mount.setattr(tostr(path), stat, mask); - } - - @Override - void chmod(Path path, int mode) throws IOException { - mount.chmod(tostr(path), mode); - } - - @Override - void chown(Path path, int uid, int gid) throws IOException { - mount.chown(tostr(path), uid, gid); - } - - @Override - void rename(Path src, Path dst) throws IOException { - mount.rename(tostr(src), tostr(dst)); - } -} \ No newline at end of file diff --git a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFileSystem.java b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFileSystem.java index fc031d38d8..8f1239afcf 100644 --- a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFileSystem.java +++ b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFileSystem.java @@ -22,368 +22,446 @@ package io.opencurve.curve.fs.hadoop; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import java.net.URI; +import java.io.IOException; +import java.io.OutputStream; +import java.io.FileNotFoundException; + import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.*; import org.apache.hadoop.fs.permission.FsPermission; import org.apache.hadoop.util.Progressable; -import io.opencurve.curve.fs.libfs.CurveFSMount; -import io.opencurve.curve.fs.libfs.CurveFSStat; -import io.opencurve.curve.fs.libfs.CurveFSStatVFS; -import io.opencurve.curve.fs.hadoop.permission.Permission; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.OutputStream; -import java.net.URI; +import io.opencurve.curve.fs.hadoop.permission.Permission; +import io.opencurve.curve.fs.libfs.CurveFsProto; +import io.opencurve.curve.fs.libfs.CurveFsMount; +import io.opencurve.curve.fs.libfs.CurveFsMount.StatVfs; +import io.opencurve.curve.fs.libfs.CurveFsMount.Stat; +import io.opencurve.curve.fs.libfs.CurveFsMount.File; +import io.opencurve.curve.fs.libfs.CurveFsMount.Dirent; +import io.opencurve.curve.fs.libfs.CurveFsException.NotADirectoryException; public class CurveFileSystem extends FileSystem { - private static final Log LOG = LogFactory.getLog(CurveFileSystem.class); + private static final int O_RDONLY = CurveFsMount.O_RDONLY; + private static final int O_WRONLY = CurveFsMount.O_WRONLY; + private static final int O_APPEND = CurveFsMount.O_APPEND; + private static final int SETATTR_MTIME = CurveFsMount.SETATTR_MTIME; + private static final int SETATTR_ATIME = CurveFsMount.SETATTR_ATIME; private URI uri; private Path workingDir; - private CurveFSProto curve = null; - private Permission perm = null; + private CurveFsProto curvefs = null; + private Permission permission = null; public CurveFileSystem() {} - public CurveFileSystem(Configuration conf) { - setConf(conf); - } + public CurveFileSystem(Configuration conf) { setConf(conf); } - private Path makeAbsolute(Path path) { - if (path.isAbsolute()) { - return path; - } - return new Path(workingDir, path); + // e.g. /my/dir1 + private String makeAbsolute(Path path) { + return makeQualified(path).toUri().getPath(); } + /** + * Get the current working directory for the given FileSystem + * @return the directory pathname + */ @Override - public URI getUri() { - return uri; + public Path getWorkingDirectory() { + return workingDir; } + /** + * Set the current working directory for the given FileSystem. All relative + * paths will be resolved relative to it. + * + * @param new_dir Path of new working directory + */ @Override - public String getScheme() { - return "hdfs"; + public void setWorkingDirectory(Path new_dir) { + workingDir = fixRelativePart(new_dir); + checkPath(workingDir); } + /** Called after a new FileSystem instance is constructed. + * @param name a uri whose authority section names the host, port, etc. + * for this FileSystem + * @param conf the configuration + */ @Override public void initialize(URI uri, Configuration conf) throws IOException { super.initialize(uri, conf); - if (curve == null) { - curve = new CurveFSTalker(conf, LOG); + if (curvefs == null) { + curvefs = new CurveFsMount(); } - if (perm == null) { - perm = new Permission(); + if (permission == null) { + permission = new Permission(); } - perm.initialize(conf); - curve.initialize(uri, conf); + curvefs.initialize(uri, conf); + permission.initialize(conf); setConf(conf); this.uri = URI.create(uri.getScheme() + "://" + uri.getAuthority()); this.workingDir = getHomeDirectory(); } - @Override - public FSDataInputStream open(Path path, int bufferSize) throws IOException { - path = makeAbsolute(path); - - int fd = curve.open(path, CurveFSMount.O_RDONLY, 0); - - CurveFSStat stat = new CurveFSStat(); - curve.fstat(fd, stat); - - CurveFSInputStream istream = new CurveFSInputStream(getConf(), curve, fd, stat.size, bufferSize); - return new FSDataInputStream(istream); - } - + /** + * No more filesystem operations are needed. Will + * release any held locks. + */ @Override public void close() throws IOException { super.close(); - curve.shutdown(); + curvefs.shutdown(); } + /** + * Return the protocol scheme for the FileSystem. + *

+ * This implementation throws an UnsupportedOperationException. + * + * @return the protocol scheme for the FileSystem. + */ @Override - public FSDataOutputStream append(Path path, int bufferSize, Progressable progress) throws IOException { - path = makeAbsolute(path); - - if (progress != null) { - progress.progress(); - } - - int fd = curve.open(path, CurveFSMount.O_WRONLY | CurveFSMount.O_APPEND, 0); - if (progress != null) { - progress.progress(); - } - - CurveFSOutputStream ostream = new CurveFSOutputStream(getConf(), curve, fd, bufferSize); - return new FSDataOutputStream(ostream, statistics); + public String getScheme() { + return "hdfs"; } + /** Returns a URI whose scheme and authority identify this FileSystem.*/ @Override - public Path getWorkingDirectory() { - return workingDir; + public URI getUri() { + return uri; } + /** + * Call {@link #mkdirs(Path, FsPermission)} with default permission. + */ @Override - public void setWorkingDirectory(Path dir) { - workingDir = makeAbsolute(dir); + public boolean mkdirs(Path f) throws IOException { + FsPermission perms = FsPermission.getDirDefault().applyUMask(FsPermission.getUMask(getConf())); + return mkdirs(f, perms); } + /** + * Make the given file and all non-existent parents into + * directories. Has the semantics of Unix 'mkdir -p'. + * Existence of the directory hierarchy is not an error. + * @param f path to create + * @param permission to apply to f + */ @Override - public boolean mkdirs(Path path, FsPermission perms) throws IOException { - path = makeAbsolute(path); - curve.mkdirs(path, (int) perms.toShort()); + public boolean mkdirs(Path f, FsPermission perms) throws IOException { + try { + curvefs.mkdirs(makeAbsolute(f), perms.toShort()); + } catch (IOException e) { + return false; + } return true; } - @Override - public boolean mkdirs(Path f) throws IOException { - FsPermission perms = FsPermission.getDirDefault().applyUMask(FsPermission.getUMask(getConf()));; - return mkdirs(f, perms); + private FileStatus newFileStatus(Path f, Stat stat) { + return new FileStatus(stat.size, + stat.isDirectory, + 1, + stat.blksize, + stat.mtime, + stat.atime, + new FsPermission((short) stat.mode), + permission.getUsername(stat.uid), + permission.getGroupname(stat.gid), + makeQualified(f)); // e.g. curvefs://my/dir1 } + /** + * Return a file status object that represents the path. + * @param f The path we want information from + * @return a FileStatus object + * @throws FileNotFoundException when the path does not exist; + * IOException see specific implementation + */ @Override - public FileStatus getFileStatus(Path path) throws IOException { - path = makeAbsolute(path); - - CurveFSStat stat = new CurveFSStat(); - curve.lstat(path, stat); - String owner = perm.getUsername(stat.uid);; - String group = perm.getGroupname(stat.gid);; - - FileStatus status = new FileStatus( - stat.size, stat.isDir(), 1, stat.blksize, - stat.m_time, stat.a_time, - new FsPermission((short) stat.mode), owner, group, - path.makeQualified(this)); - return status; + public FileStatus getFileStatus(Path f) throws IOException { + Stat stat = new Stat(); + curvefs.lstat(makeAbsolute(f), stat); + return newFileStatus(f, stat); } + /** + * List the statuses of the files/directories in the given path if the path is + * a directory. + * + * @param f given path + * @return the statuses of the files/directories in the given patch + * @throws FileNotFoundException when the path does not exist; + * IOException see specific implementation + */ @Override - public FileStatus[] listStatus(Path path) throws IOException { - path = makeAbsolute(path); - - if (isFile(path)) { - return new FileStatus[]{getFileStatus(path)}; + public FileStatus[] listStatus(Path f) throws IOException { + Dirent[] dirents; + try { + dirents = curvefs.listdir(makeAbsolute(f)); + } catch(NotADirectoryException e) { + return new FileStatus[]{ getFileStatus(f) }; } - String[] dirlist = curve.listdir(path); - if (dirlist != null) { - FileStatus[] status = new FileStatus[dirlist.length]; - for (int i = 0; i < status.length; i++) { - status[i] = getFileStatus(new Path(path, dirlist[i])); - } - return status; - } else { - throw new FileNotFoundException("File " + path + " does not exist."); + FileStatus[] statuses = new FileStatus[dirents.length]; + for (int i = 0; i < dirents.length; i++) { + Path p = makeQualified(new Path(f, new String(dirents[i].name))); + statuses[i] = newFileStatus(p, dirents[i].stat); } + return statuses; } - @Override - public void setPermission(Path path, FsPermission permission) throws IOException { - path = makeAbsolute(path); - curve.chmod(path, permission.toShort()); + private FSDataInputStream createFsDataInputStream(File file, + int bufferSize) throws IOException { + CurveFsInputStream istream = + new CurveFsInputStream(getConf(), curvefs, file.fd, file.length, bufferSize); + return new FSDataInputStream(istream); } - @Override - public void setTimes(Path path, long mtime, long atime) throws IOException { - path = makeAbsolute(path); - - CurveFSStat stat = new CurveFSStat(); - - int mask = 0; - if (mtime != -1) { - stat.m_time = mtime; - mask |= CurveFSMount.SETATTR_MTIME; - } - - if (atime != -1) { - stat.a_time = atime; - mask |= CurveFSMount.SETATTR_ATIME; - } - - curve.setattr(path, stat, mask); + private FSDataOutputStream createFsDataOutputStream(File file, + int bufferSize) throws IOException { + OutputStream ostream = + new CurveFsOutputStream(getConf(), curvefs, file.fd, bufferSize); + return new FSDataOutputStream(ostream, statistics); } + /** + * Opens an FSDataInputStream at the indicated Path. + * @param f the file name to open + * @param bufferSize the size of the buffer to be used. + */ @Override - public FSDataOutputStream create(Path path, FsPermission permission, boolean overwrite, int bufferSize, - short replication, long blockSize, Progressable progress) throws IOException { - path = makeAbsolute(path); - - boolean exists = exists(path); - - if (progress != null) { - progress.progress(); - } - - int flags = CurveFSMount.O_WRONLY | CurveFSMount.O_CREAT; - - if (exists) { - if (overwrite) { - flags |= CurveFSMount.O_TRUNC; - } else { - throw new FileAlreadyExistsException(); - } - } else { - Path parent = path.getParent(); - if (parent != null) { - if (!mkdirs(parent)) { - throw new IOException("mkdirs failed for " + parent.toString()); - } - } - } - - if (progress != null) { - progress.progress(); - } - - int fd = curve.open(path, flags, (int) permission.toShort()); - - if (progress != null) { - progress.progress(); - } - - OutputStream ostream = new CurveFSOutputStream(getConf(), curve, fd, bufferSize); - return new FSDataOutputStream(ostream, statistics); + public FSDataInputStream open(Path f, int bufferSize) throws IOException { + File file = new File(); + curvefs.open(makeAbsolute(f), O_RDONLY, file); + return createFsDataInputStream(file, bufferSize); } + /** + * Create an FSDataOutputStream at the indicated Path with write-progress + * reporting. + * @param f the file name to open + * @param permission + * @param overwrite if a file with this name already exists, then if true, + * the file will be overwritten, and if false an error will be thrown. + * @param bufferSize the size of the buffer to be used. + * @param replication required block replication for the file. + * @param blockSize + * @param progress + * @throws IOException + * @see #setPermission(Path, FsPermission) + */ @Override - public void setOwner(Path path, String username, String groupname) throws IOException { - CurveFSStat stat = new CurveFSStat(); - curve.lstat(path, stat); - - int uid = stat.uid; - int gid = stat.gid; - if (username != null) { - uid = perm.getUid(username); - } - if (groupname != null) { - gid = perm.getGid(groupname); + public FSDataOutputStream create(Path f, + FsPermission permission, + boolean overwrite, + int bufferSize, + short replication, + long blockSize, + Progressable progress) throws IOException { + File file = new File(); + for ( ; ; ) { + try { + curvefs.create(makeAbsolute(f), permission.toShort(), file); + } catch(FileNotFoundException e) { // parent directorty not exist + Path parent = makeQualified(f).getParent(); + try { + mkdirs(parent, FsPermission.getDirDefault()); + } catch (FileAlreadyExistsException ignored) {} + continue; // create file again + } catch(FileAlreadyExistsException e) { + if (!overwrite || isDirectory(f)) { + throw new FileAlreadyExistsException("File already exists: " + f); + } + delete(f, false); + continue; // create file again + } + break; } - - curve.chown(path, uid, gid); + return createFsDataOutputStream(file, bufferSize); } + /** + * Opens an FSDataOutputStream at the indicated Path with write-progress + * reporting. Same as create(), except fails if parent directory doesn't + * already exist. + * @param f the file name to open + * @param permission + * @param overwrite if a file with this name already exists, then if true, + * the file will be overwritten, and if false an error will be thrown. + * @param bufferSize the size of the buffer to be used. + * @param replication required block replication for the file. + * @param blockSize + * @param progress + * @throws IOException + * @see #setPermission(Path, FsPermission) + * @deprecated API only for 0.20-append + */ @Deprecated @Override - public FSDataOutputStream createNonRecursive(Path path, FsPermission permission, + public FSDataOutputStream createNonRecursive(Path f, + FsPermission permission, boolean overwrite, - int bufferSize, short replication, long blockSize, + int bufferSize, + short replication, + long blockSize, Progressable progress) throws IOException { - path = makeAbsolute(path); - - Path parent = path.getParent(); - - if (parent != null) { - CurveFSStat stat = new CurveFSStat(); - curve.lstat(parent, stat); - if (stat.isFile()) { - throw new FileAlreadyExistsException(parent.toString()); + File file = new File(); + for ( ; ; ) { + try { + curvefs.create(makeAbsolute(f), permission.toShort(), file); + } catch(FileAlreadyExistsException e) { + if (!overwrite || isDirectory(f)) { + throw new FileAlreadyExistsException("File already exists: " + f); + } + delete(f, false); + continue; // create file again } + break; } + return createFsDataOutputStream(file, bufferSize); + } - return this.create(path, permission, overwrite, - bufferSize, replication, blockSize, progress); + /** + * Append to an existing file (optional operation). + * Same as append(f, getConf().getInt("io.file.buffer.size", 4096), null) + * @param f the existing file to be appended. + * @throws IOException + */ + @Override + public FSDataOutputStream append(Path f, + int bufferSize, + Progressable progress) throws IOException { + File file = new File(); + curvefs.open(makeAbsolute(f), O_WRONLY | O_APPEND, file); + return createFsDataOutputStream(file, bufferSize); } + /** + * Renames Path src to Path dst. Can take place on local fs + * or remote DFS. + * @param src path to be renamed + * @param dst new path after rename + * @throws IOException on failure + * @return true if rename is successful + */ @Override public boolean rename(Path src, Path dst) throws IOException { - src = makeAbsolute(src); - dst = makeAbsolute(dst); - try { - CurveFSStat stat = new CurveFSStat(); - curve.lstat(dst, stat); - if (stat.isDir()) { - return rename(src, new Path(dst, src.getName())); - } + curvefs.rename(makeAbsolute(src), makeAbsolute(dst)); + } catch(FileNotFoundException e) { // src path not exist return false; - } catch (FileNotFoundException e) { + } catch (FileAlreadyExistsException e) { + FileStatus status = getFileStatus(dst); + if (!status.isDirectory()) { + return false; + } + // FIXME: } - try { - curve.rename(src, dst); - } catch (FileNotFoundException e) { - throw e; - } catch (Exception e) { - return false; - } return true; } - @Deprecated + /** Delete a file. + * + * @param f the path to delete. + * @param recursive if path is a directory and set to + * true, the directory is deleted else throws an exception. In + * case of a file the recursive can be set to either true or false. + * @return true if delete is successful else false. + * @throws IOException + */ @Override - public boolean delete(Path path) throws IOException { - return delete(path, false); - } - - @Override - public boolean delete(Path path, boolean recursive) throws IOException { - path = makeAbsolute(path); - - FileStatus status; + public boolean delete(Path f, boolean recursive) throws IOException { try { - status = getFileStatus(path); - } catch (FileNotFoundException e) { - return false; - } - - if (status.isFile()) { - curve.unlink(path); - return true; - } - - FileStatus[] dirlist = listStatus(path); - if (dirlist == null) { - return false; - } - - if (!recursive && dirlist.length > 0) { - throw new IOException("Directory " + path.toString() + "is not empty."); - } - - for (FileStatus fs : dirlist) { - if (!delete(fs.getPath(), recursive)) { - return false; + if (recursive) { + curvefs.removeall(makeAbsolute(f)); + } else { + curvefs.remove(makeAbsolute(f)); } + } catch (IOException e) { + return false; } - - curve.rmdir(path); return true; } + /** + * Returns a status object describing the use and capacity of the + * file system. If the file system has multiple partitions, the + * use and capacity of the partition pointed to by the specified + * path is reflected. + * @param p Path for which status should be obtained. null means + * the default partition. + * @return a FsStatus object + * @throws IOException + * see specific implementation + */ @Override public FsStatus getStatus(Path p) throws IOException { - CurveFSStatVFS stat = new CurveFSStatVFS(); - curve.statfs(p, stat); - - FsStatus status = new FsStatus(stat.bsize * stat.blocks, - stat.bsize * (stat.blocks - stat.bavail), - stat.bsize * stat.bavail); - return status; + StatVfs statvfs = new StatVfs(); + curvefs.statfs(makeAbsolute(p), statvfs); + return new FsStatus(statvfs.bsize * statvfs.blocks, // capacity + statvfs.bsize * (statvfs.blocks - statvfs.bavail), // used + statvfs.bsize * statvfs.bavail); // remaining } + /** + * Set permission of a path. + * @param p + * @param permission + */ @Override - public short getDefaultReplication() { - return 1; + public void setPermission(Path p, FsPermission permission) throws IOException { + curvefs.chmod(makeAbsolute(p), permission.toShort()); } + /** + * Set owner of a path (i.e. a file or a directory). + * The parameters username and groupname cannot both be null. + * @param p The path + * @param username If it is null, the original username remains unchanged. + * @param groupname If it is null, the original groupname remains unchanged. + */ @Override - public long getDefaultBlockSize() { - return super.getDefaultBlockSize(); - } + public void setOwner(Path p, String username, String groupname) throws IOException { + Stat stat = new Stat(); + curvefs.lstat(makeAbsolute(p), stat); // TODO(Wine93): remove this operation - @Override - protected int getDefaultPort() { - return super.getDefaultPort(); + int uid = stat.uid; + int gid = stat.gid; + if (username != null) { + uid = permission.getUid(username); + } + if (groupname != null) { + gid = permission.getGid(groupname); + } + curvefs.chown(makeAbsolute(p), uid, gid); } + /** + * Set access time of a file + * @param p The path + * @param mtime Set the modification time of this file. + * The number of milliseconds since Jan 1, 1970. + * A value of -1 means that this call should not set modification time. + * @param atime Set the access time of this file. + * The number of milliseconds since Jan 1, 1970. + * A value of -1 means that this call should not set access time. + */ @Override - public String getCanonicalServiceName() { - return null; + public void setTimes(Path p, long mtime, long atime) throws IOException { + Stat stat = new Stat(); + int mask = 0; + if (mtime != -1) { + stat.mtime = mtime; + mask |= SETATTR_MTIME; + } + if (atime != -1) { + stat.atime = atime; + mask |= SETATTR_ATIME; + } + curvefs.setattr(makeAbsolute(p), stat, mask); } -} +} \ No newline at end of file diff --git a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSInputStream.java b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFsInputStream.java similarity index 92% rename from curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSInputStream.java rename to curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFsInputStream.java index 25ad56564f..eb40992bf7 100644 --- a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSInputStream.java +++ b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFsInputStream.java @@ -26,7 +26,8 @@ import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSInputStream; -import io.opencurve.curve.fs.libfs.CurveFSMount; +import io.opencurve.curve.fs.libfs.CurveFsMount; +import io.opencurve.curve.fs.libfs.CurveFsProto; import java.io.IOException; @@ -35,15 +36,15 @@ * An {@link FSInputStream} for a CurveFileSystem and corresponding * Curve instance. */ -public class CurveFSInputStream extends FSInputStream { - private static final Log LOG = LogFactory.getLog(CurveFSInputStream.class); +public class CurveFsInputStream extends FSInputStream { + private static final Log LOG = LogFactory.getLog(CurveFsInputStream.class); private boolean closed; private int fileHandle; private long fileLength; - private CurveFSProto curve; + private CurveFsProto curvefs; private byte[] buffer; private int bufPos = 0; @@ -57,12 +58,12 @@ public class CurveFSInputStream extends FSInputStream { * @param flength The current length of the file. If the length changes * you will need to close and re-open it to access the new data. */ - public CurveFSInputStream(Configuration conf, CurveFSProto curvefs, + public CurveFsInputStream(Configuration conf, CurveFsProto curve, int fh, long flength, int bufferSize) { fileLength = flength; fileHandle = fh; closed = false; - curve = curvefs; + curvefs = curve; buffer = new byte[1<<21]; LOG.debug("CurveInputStream constructor: initializing stream with fh " + fh + " and file length " + flength); @@ -83,14 +84,14 @@ protected void finalize() throws Throwable { } private synchronized boolean fillBuffer() throws IOException { - bufValid = curve.read(fileHandle, buffer, buffer.length, -1); + bufValid = curvefs.read(fileHandle, -1, buffer, buffer.length); bufPos = 0; if (bufValid < 0) { int err = bufValid; bufValid = 0; - curve.lseek(fileHandle, curvePos, CurveFSMount.SEEK_SET); + curvefs.lseek(fileHandle, curvePos, CurveFsMount.SEEK_SET); throw new IOException("Failed to fill read buffer! Error code:" + err); } curvePos += bufValid; @@ -127,7 +128,7 @@ public synchronized void seek(long targetPos) throws IOException { } long oldPos = curvePos; - curvePos = curve.lseek(fileHandle, targetPos, CurveFSMount.SEEK_SET); + curvePos = curvefs.lseek(fileHandle, targetPos, CurveFsMount.SEEK_SET); bufValid = 0; bufPos = 0; if (curvePos < 0) { @@ -244,9 +245,9 @@ public synchronized int read(byte buf[], int off, int len) throws IOException { public void close() throws IOException { LOG.trace("CurveOutputStream.close:enter"); if (!closed) { - curve.close(fileHandle); + curvefs.close(fileHandle); closed = true; LOG.trace("CurveOutputStream.close:exit"); } } -} +} \ No newline at end of file diff --git a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSOutputStream.java b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFsOutputStream.java similarity index 87% rename from curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSOutputStream.java rename to curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFsOutputStream.java index 06855bcd7d..8f24b3c7ca 100644 --- a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFSOutputStream.java +++ b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/hadoop/CurveFsOutputStream.java @@ -25,7 +25,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; -import io.opencurve.curve.fs.libfs.CurveFSMount; +import io.opencurve.curve.fs.libfs.CurveFsMount; +import io.opencurve.curve.fs.libfs.CurveFsProto; import java.io.IOException; import java.io.OutputStream; @@ -41,13 +42,10 @@ * libcurvefs. Currently it might be useful to reduce JNI crossings, but not * much more. */ -public class CurveFSOutputStream extends OutputStream { +public class CurveFsOutputStream extends OutputStream { private boolean closed; - - private CurveFSProto curve; - + private CurveFsProto curvefs; private int fileHandle; - private byte[] buffer; private int bufUsed = 0; @@ -56,9 +54,11 @@ public class CurveFSOutputStream extends OutputStream { * @param conf The FileSystem configuration. * @param fh The Curve filehandle to connect to. */ - public CurveFSOutputStream(Configuration conf, CurveFSProto curvefs, - int fh, int bufferSize) { - curve = curvefs; + public CurveFsOutputStream(Configuration conf, + CurveFsProto curve, + int fh, + int bufferSize) { + curvefs = curve; fileHandle = fh; closed = false; buffer = new byte[1<<21]; @@ -92,7 +92,7 @@ private synchronized void checkOpen() throws IOException { */ public synchronized long getPos() throws IOException { checkOpen(); - return curve.lseek(fileHandle, 0, CurveFSMount.SEEK_CUR); + return curvefs.lseek(fileHandle, 0, CurveFsMount.SEEK_CUR); } @Override @@ -129,7 +129,7 @@ private synchronized void flushBuffer() throws IOException { } while (bufUsed > 0) { - int ret = curve.write(fileHandle, buffer, bufUsed, -1); + int ret = curvefs.write(fileHandle, -1, buffer, bufUsed); if (ret < 0) { throw new IOException("curve.write: ret=" + ret); } @@ -161,14 +161,14 @@ private synchronized void flushBuffer() throws IOException { public synchronized void flush() throws IOException { checkOpen(); flushBuffer(); // buffer -> libcurvefs - curve.fsync(fileHandle); // libcurvefs -> cluster + curvefs.fsync(fileHandle); // libcurvefs -> cluster } @Override public synchronized void close() throws IOException { checkOpen(); flush(); - curve.close(fileHandle); + curvefs.close(fileHandle); closed = true; } -} +} \ No newline at end of file diff --git a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSMount.java b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSMount.java deleted file mode 100644 index 8abb9862b8..0000000000 --- a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSMount.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Copyright (c) 2023 NetEase Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Project: Curve - * Created Date: 2023-07-07 - * Author: Jingli Chen (Wine93) - */ -package io.opencurve.curve.fs.libfs; - -import java.io.IOException; - -public class CurveFSMount { - // init - private native long nativeCurveFSCreate(); - private native void nativeCurveFSRelease(long instancePtr); - private static native void nativeCurveFSConfSet(long instancePtr, String key, String value); - private static native int nativeCurveFSMount(long instancePtr, String fsname, String mountpoint); - private static native int nativeCurveFSUmount(long instancePtr, String fsname, String mountpoint); - // dir* - private static native int nativeCurveFSMkDirs(long instancePtr, String path, int mode); - private static native int nativeCurveFSRmDir(long instancePtr, String path); - private static native String[] nativeCurveFSListDir(long instancePtr, String path); - // file* - private static native int nativeCurveFSOpen(long instancePtr, String path, int flags, int mode); - private static native long nativeCurveFSLSeek(long instancePtr, int fd, long offset, int whence); - private static native long nativieCurveFSRead(long instancePtr, int fd, byte[] buffer, long size, long offset); - private static native long nativieCurveFSWrite(long instancePtr, int fd, byte[] buffer, long size, long offset); - private static native int nativeCurveFSFSync(long instancePtr, int fd); - private static native int nativeCurveFSClose(long instancePtr, int fd); - private static native int nativeCurveFSUnlink(long instancePtr, String path); - // others - private static native int nativeCurveFSStatFs(long instancePtr, CurveFSStatVFS statvfs); - private static native int nativeCurveFSLstat(long instancePtr, String path, CurveFSStat stat); - private static native int nativeCurveFSFStat(long instancePtr, int fd, CurveFSStat stat); - private static native int nativeCurveFSSetAttr(long instancePtr, String path, CurveFSStat stat, int mask); - private static native int nativeCurveFSChmod(long instancePtr, String path, int mode); - private static native int nativeCurveFSChown(long instancePtr, String path, int uid, int gid); - private static native int nativeCurveFSRename(long instancePtr, String src, String dst); - - /* - * Flags for open(). - * - * Must be synchronized with JNI if changed. - */ - public static final int O_RDONLY = 1; - public static final int O_RDWR = 2; - public static final int O_APPEND = 4; - public static final int O_CREAT = 8; - public static final int O_TRUNC = 16; - public static final int O_EXCL = 32; - public static final int O_WRONLY = 64; - public static final int O_DIRECTORY = 128; - - /* - * Whence flags for seek(). - * - * Must be synchronized with JNI if changed. - */ - public static final int SEEK_SET = 0; - public static final int SEEK_CUR = 1; - public static final int SEEK_END = 2; - - /* - * Attribute flags for setattr(). - * - * Must be synchronized with JNI if changed. - */ - public static final int SETATTR_MODE = 1; - public static final int SETATTR_UID = 2; - public static final int SETATTR_GID = 4; - public static final int SETATTR_MTIME = 8; - public static final int SETATTR_ATIME = 16; - - private static final String CURVEFS_DEBUG_ENV_VAR = "CURVEFS_DEBUG"; - private static final String CLASS_NAME = "io.opencurve.curve.fs.CurveFSMount"; - - private long instancePtr; - - private static void accessLog(String name, String... args) { - String value = System.getenv(CURVEFS_DEBUG_ENV_VAR); - if (!Boolean.valueOf(value)) { - return; - } - - String params = String.join(",", args); - String message = String.format("%s.%s(%s)", CLASS_NAME, name, params); - System.out.println(message); - } - - static { - accessLog("loadLibrary"); - try { - CurveFSNativeLoader.getInstance().loadLibrary(); - } catch(Exception e) {} - } - - protected void finalize() throws Throwable { - accessLog("finalize"); - } - - public CurveFSMount() { - accessLog("CurveMount"); - instancePtr = nativeCurveFSCreate(); - } - - public void release() throws IOException { - nativeCurveFSRelease(instancePtr); - } - - public void confSet(String key, String value) { - accessLog("confSet", key, value); - nativeCurveFSConfSet(instancePtr, key, value); - } - - public void mount(String fsname, String mountpoint) throws IOException { - accessLog("mount"); - nativeCurveFSMount(instancePtr, fsname, mountpoint); - } - - public void umount(String fsname, String mountpoint) throws IOException { - accessLog("umount"); - nativeCurveFSUmount(instancePtr, fsname, mountpoint); - } - - public void shutdown() throws IOException { - accessLog("shutdown"); - } - - // directory* - public void mkdirs(String path, int mode) throws IOException { - accessLog("mkdirs", path.toString()); - nativeCurveFSMkDirs(instancePtr, path, mode); - } - - public void rmdir(String path) throws IOException { - accessLog("rmdir", path.toString()); - nativeCurveFSRmDir(instancePtr, path); - } - - public String[] listdir(String path) throws IOException { - accessLog("listdir", path.toString()); - return nativeCurveFSListDir(instancePtr, path); - } - - // file* - public int open(String path, int flags, int mode) throws IOException { - accessLog("open", path.toString()); - return nativeCurveFSOpen(instancePtr, path, flags, mode); - } - - public long lseek(int fd, long offset, int whence) throws IOException { - accessLog("lseek", String.valueOf(fd), String.valueOf(offset), String.valueOf(whence)); - return nativeCurveFSLSeek(instancePtr, fd, offset, whence); - } - - public int read(int fd, byte[] buf, long size, long offset) throws IOException { - accessLog("read", String.valueOf(fd), String.valueOf(size), String.valueOf(size)); - long rc = nativieCurveFSRead(instancePtr, fd, buf, size, offset); - return (int) rc; - } - - public int write(int fd, byte[] buf, long size, long offset) throws IOException { - accessLog("write", String.valueOf(fd), String.valueOf(size), String.valueOf(size)); - long rc = nativieCurveFSWrite(instancePtr, fd, buf, size, offset); - return (int) rc; - } - - public void fsync(int fd) throws IOException { - accessLog("fsync", String.valueOf(fd)); - nativeCurveFSFSync(instancePtr, fd); - } - - public void close(int fd) throws IOException { - accessLog("close", String.valueOf(fd)); - nativeCurveFSClose(instancePtr, fd); - } - - public void unlink(String path) throws IOException { - accessLog("unlink", path.toString()); - nativeCurveFSUnlink(instancePtr, path); - } - - // others - public void statfs(String path, CurveFSStatVFS statvfs) throws IOException { - accessLog("statfs", path.toString()); - nativeCurveFSStatFs(instancePtr, statvfs); - } - - public void lstat(String path, CurveFSStat stat) throws IOException { - accessLog("lstat", path.toString()); - nativeCurveFSLstat(instancePtr, path, stat); - } - - public void fstat(int fd, CurveFSStat stat) throws IOException { - accessLog("fstat", String.valueOf(fd)); - nativeCurveFSFStat(instancePtr, fd, stat); - } - - public void setattr(String path, CurveFSStat stat, int mask) throws IOException { - accessLog("setattr", path.toString()); - nativeCurveFSSetAttr(instancePtr, path, stat, mask); - } - - public void chmod(String path, int mode) throws IOException { - accessLog("chmod", path.toString()); - nativeCurveFSChmod(instancePtr, path, mode); - } - - public void chown(String path, int uid, int gid) throws IOException { - accessLog("chown", path.toString(), String.valueOf(uid), String.valueOf(gid)); - nativeCurveFSChown(instancePtr, path, uid, gid); - } - - public void rename(String src, String dst) throws IOException { - accessLog("rename", src.toString(), dst.toString()); - nativeCurveFSRename(instancePtr, src, dst); - } -} diff --git a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSStat.java b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSStat.java deleted file mode 100644 index d188ca93f5..0000000000 --- a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSStat.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2023 NetEase Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Project: Curve - * Created Date: 2023-07-07 - * Author: Jingli Chen (Wine93) - */ - -package io.opencurve.curve.fs.libfs; - -public class CurveFSStat { - public boolean is_file; /* S_ISREG */ - public boolean is_directory; /* S_ISDIR */ - public boolean is_symlink; /* S_ISLNK */ - - public int mode; - public int uid; - public int gid; - public long size; - public long blksize; - public long blocks; - public long a_time; - public long m_time; - - public boolean isFile() { - return is_file; - } - - public boolean isDir() { - return is_directory; - } - - public boolean isSymlink() { - return is_symlink; - } -} diff --git a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSStatVFS.java b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsException.java similarity index 67% rename from curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSStatVFS.java rename to curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsException.java index 5ee2c1b8b0..175fd910eb 100644 --- a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSStatVFS.java +++ b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsException.java @@ -16,18 +16,22 @@ /* * Project: Curve - * Created Date: 2023-07-07 + * Created Date: 2023-12-19 * Author: Jingli Chen (Wine93) */ package io.opencurve.curve.fs.libfs; -public class CurveFSStatVFS { - public long bsize; - public long frsize; - public long blocks; - public long bavail; - public long files; - public long fsid; - public long namemax; -} +import java.io.IOException; + +public class CurveFsException extends IOException { + public static class NotADirectoryException extends IOException { + public NotADirectoryException() { + super(); + } + + public NotADirectoryException(String s) { + super(s); + } + } +} \ No newline at end of file diff --git a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsMount.java b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsMount.java new file mode 100644 index 0000000000..a273b366eb --- /dev/null +++ b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsMount.java @@ -0,0 +1,274 @@ +/* + * Copyright (c) 2023 NetEase Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Project: Curve + * Created Date: 2023-07-07 + * Author: Jingli Chen (Wine93) + */ + +package io.opencurve.curve.fs.libfs; + +import java.net.URI; +import java.util.Map; +import java.util.UUID; +import java.io.IOException; + +import org.apache.hadoop.conf.Configuration; + +public class CurveFsMount extends CurveFsProto { + // init + private native long nativeCurveFSNew(); + private native void nativeCurveFSDelete(long instancePtr); + private static native void nativeCurveFsConfSet(long instancePtr, String key, String value); + private static native int nativeCurveFsMount(long instancePtr, String fsname, String mountpoint); + private static native int nativeCurveFsUmount(long instancePtr, String fsname, String mountpoint); + // dir* + private static native int nativeCurveFsMkDirs(long instancePtr, String path, int mode); + private static native int nativeCurveFsRmDir(long instancePtr, String path); + private static native Dirent[] nativeCurveFsListDir(long instancePtr, String path); + // file* + private static native int nativeCurveFsCreate(long instancePtr, String path, int mode, File file); + private static native int nativeCurveFsOpen(long instancePtr, String path, int flags, File file); + private static native long nativeCurveFsLSeek(long instancePtr, int fd, long offset, int whence); + private static native int nativieCurveFsRead(long instancePtr, int fd, long offset, byte[] buffer, long size); + private static native int nativieCurveFsWrite(long instancePtr, int fd, long offset, byte[] buffer, long size); + private static native int nativeCurveFsFSync(long instancePtr, int fd); + private static native int nativeCurveFsClose(long instancePtr, int fd); + private static native int nativeCurveFsUnlink(long instancePtr, String path); + // others + private static native int nativeCurveFsStatFs(long instancePtr, StatVfs statvfs); + private static native int nativeCurveFsLStat(long instancePtr, String path, Stat stat); + private static native int nativeCurveFsFStat(long instancePtr, int fd, Stat stat); + private static native int nativeCurveFsSetAttr(long instancePtr, String path, Stat stat, int mask); + private static native int nativeCurveFsChmod(long instancePtr, String path, int mode); + private static native int nativeCurveFsChown(long instancePtr, String path, int uid, int gid); + private static native int nativeCurveFsRename(long instancePtr, String src, String dst); + private static native int nativeCurveFsRemove(long instancePtr, String path); + private static native int nativeCurveFsRemoveAll(long instancePtr, String path); + + // private static native int nativeCurveFsRemove(long instancePtr, String path); + // private static native int nativeCurveFsRemoveAll(long instancePtr, String path); + + public static class StatVfs { + public long bsize; + public long frsize; + public long blocks; + public long bavail; + public long files; + public long fsid; + public long namemax; + } + + public static class Stat { + public int mode; + public int uid; + public int gid; + public long size; + public long blksize; + public long blocks; + public long atime; + public long mtime; + + public boolean isFile; + public boolean isDirectory; + public boolean isSymlink; + } + + public static class File { + public int fd; + public long length; + }; + + public static class Dirent { + public String name; + public Stat stat; + }; + + // Flags for open(): must be synchronized with JNI if changed. + public static final int O_RDONLY = 1; + public static final int O_RDWR = 2; + public static final int O_APPEND = 4; + public static final int O_CREAT = 8; + public static final int O_TRUNC = 16; + public static final int O_EXCL = 32; + public static final int O_WRONLY = 64; + public static final int O_DIRECTORY = 128; + + // Whence flags for seek(): must be synchronized with JNI if changed. + public static final int SEEK_SET = 0; + public static final int SEEK_CUR = 1; + public static final int SEEK_END = 2; + + // Attribute flags for setattr(): must be synchronized with JNI if changed. + public static final int SETATTR_MODE = 1; + public static final int SETATTR_UID = 2; + public static final int SETATTR_GID = 4; + public static final int SETATTR_MTIME = 8; + public static final int SETATTR_ATIME = 16; + + public static final String REGEX_CURVEFS_CONF = "^curvefs\\..*"; + public static final String KEY_FSNAME = "curvefs.name"; + + private static long instancePtr; + private static String fsname; + private static String mountpoint; + private static boolean initialized = false; + + static { + try { + CurveFsNativeLoader.getInstance().loadLibrary(); + } catch(Exception e) {} + } + + public CurveFsMount() {} + + private void setConf(Configuration conf) throws IOException { + Map m = conf.getValByRegex(REGEX_CURVEFS_CONF); + for (Map.Entry entry : m.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + if (key.equals(KEY_FSNAME)) { + fsname = value; + continue; + } + nativeCurveFsConfSet(instancePtr, key, value); + } + + if (null == fsname || fsname.isEmpty()) { + throw new IOException(KEY_FSNAME + " is not set"); + } + mountpoint = UUID.randomUUID().toString(); + } + + @Override + public void initialize(URI uri, Configuration conf) throws IOException { + if (!initialized) { + instancePtr = nativeCurveFSNew(); + setConf(conf); + nativeCurveFsMount(instancePtr, fsname, mountpoint); + initialized = true; + } + } + + @Override + public void shutdown() throws IOException { + if (initialized) { + nativeCurveFsUmount(instancePtr, fsname, mountpoint); + nativeCurveFSDelete(instancePtr); + initialized = false; + } + } + + @Override + public void mkdirs(String path, int mode) throws IOException { + nativeCurveFsMkDirs(instancePtr, path, mode); + } + + @Override + public void rmdir(String path) throws IOException { + nativeCurveFsRmDir(instancePtr, path); + } + + @Override + public Dirent[] listdir(String path) throws IOException { + return nativeCurveFsListDir(instancePtr, path); + } + + @Override + public void create(String path, int mode, File file) throws IOException { + nativeCurveFsCreate(instancePtr, path, mode, file); + } + + public void open(String path, int flags, File file) throws IOException { + nativeCurveFsOpen(instancePtr, path, flags, file); + } + + @Override + public long lseek(int fd, long offset, int whence) throws IOException { + return nativeCurveFsLSeek(instancePtr, fd, offset, whence); + } + + @Override + public int read(int fd, long offset, byte[] buffer, long size) throws IOException { + return nativieCurveFsRead(instancePtr, fd, offset, buffer, size); + } + + @Override + public int write(int fd, long offset, byte[] buffer, long size) throws IOException { + return nativieCurveFsWrite(instancePtr, fd, offset, buffer, size); + } + + @Override + public void fsync(int fd) throws IOException { + nativeCurveFsFSync(instancePtr, fd); + } + + @Override + public void close(int fd) throws IOException { + nativeCurveFsClose(instancePtr, fd); + } + + @Override + public void unlink(String path) throws IOException { + nativeCurveFsUnlink(instancePtr, path); + } + + @Override + public void statfs(String path, StatVfs statvfs) throws IOException { + nativeCurveFsStatFs(instancePtr, statvfs); + } + + @Override + public void lstat(String path, Stat stat) throws IOException { + nativeCurveFsLStat(instancePtr, path, stat); + } + + @Override + public void fstat(int fd, Stat stat) throws IOException { + nativeCurveFsFStat(instancePtr, fd, stat); + } + + @Override + public void setattr(String path, Stat stat, int mask) throws IOException { + nativeCurveFsSetAttr(instancePtr, path, stat, mask); + } + + @Override + public void chmod(String path, int mode) throws IOException { + nativeCurveFsChmod(instancePtr, path, mode); + } + + @Override + public void chown(String path, int uid, int gid) throws IOException { + nativeCurveFsChown(instancePtr, path, uid, gid); + } + + @Override + public void rename(String src, String dst) throws IOException { + nativeCurveFsRename(instancePtr, src, dst); + } + + @Override + public void remove(String path) throws IOException { + nativeCurveFsRemove(instancePtr, path); + } + + @Override + public void removeall(String path) throws IOException { + nativeCurveFsRemoveAll(instancePtr, path); + } +} \ No newline at end of file diff --git a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSNativeLoader.java b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsNativeLoader.java similarity index 86% rename from curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSNativeLoader.java rename to curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsNativeLoader.java index 7ba7a535e8..95df921e51 100644 --- a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFSNativeLoader.java +++ b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsNativeLoader.java @@ -13,60 +13,53 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - /* * Project: Curve * Created Date: 2023-07-07 * Author: Jingli Chen (Wine93) */ - package io.opencurve.curve.fs.libfs; - import java.net.URL; import java.net.URLConnection; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; - import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; import org.apache.commons.compress.archivers.ArchiveEntry; import org.apache.commons.compress.utils.IOUtils; -public class CurveFSNativeLoader { +public class CurveFsNativeLoader { boolean initialized = false; - private static final CurveFSNativeLoader instance = new CurveFSNativeLoader(); + private static final CurveFsNativeLoader instance = new CurveFsNativeLoader(); private static final String TMP_DIR = "/tmp"; private static final String CURVEFS_LIBRARY_PATH = "/tmp/libcurvefs"; private static final String RESOURCE_TAR_NAME = "libcurvefs.tar"; private static final String JNI_LIBRARY_NAME = "libcurvefs_jni.so"; - private CurveFSNativeLoader() {} + private CurveFsNativeLoader() {} - public static CurveFSNativeLoader getInstance() { + public static CurveFsNativeLoader getInstance() { return instance; } public long getJarModifiedTime() throws IOException { - URL location = CurveFSNativeLoader.class.getProtectionDomain().getCodeSource().getLocation(); + URL location = CurveFsNativeLoader.class.getProtectionDomain().getCodeSource().getLocation(); URLConnection conn = location.openConnection(); return conn.getLastModified(); } - public void descompress(InputStream in, String dest) throws IOException { File dir = new File(dest); if (!dir.exists()) { dir.mkdirs(); } - ArchiveEntry entry; TarArchiveInputStream reader = new TarArchiveInputStream(in); while ((entry = reader.getNextTarEntry()) != null) { if (entry.isDirectory()) { continue; } - String path = TMP_DIR + File.separator + entry.getName(); File file = new File(path); IOUtils.copy(reader, new FileOutputStream(file)); @@ -74,25 +67,23 @@ public void descompress(InputStream in, String dest) throws IOException { reader.close(); } - public void loadJniLibrary() throws IOException { + public void loadJNILibrary() throws IOException { File libFile = new File(CURVEFS_LIBRARY_PATH, JNI_LIBRARY_NAME); System.load(libFile.getAbsolutePath()); } - public synchronized void loadLibrary() throws IOException { if (initialized) { return; } - long jarModifiedTime = getJarModifiedTime(); File libDir = new File(CURVEFS_LIBRARY_PATH); if (libDir.exists() && libDir.lastModified() == jarModifiedTime) { - loadJniLibrary(); + loadJNILibrary(); initialized = true; return; } - InputStream reader = CurveFSNativeLoader.class.getResourceAsStream("/" + RESOURCE_TAR_NAME); + InputStream reader = CurveFsNativeLoader.class.getResourceAsStream("/" + RESOURCE_TAR_NAME); if (reader == null) { throw new IOException("Cannot get resource " + RESOURCE_TAR_NAME + " from Jar file."); } @@ -100,7 +91,7 @@ public synchronized void loadLibrary() throws IOException { reader.close(); libDir.setLastModified(jarModifiedTime); - loadJniLibrary(); + loadJNILibrary(); initialized = true; } -} +} \ No newline at end of file diff --git a/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsProto.java b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsProto.java new file mode 100644 index 0000000000..c7cad8fd48 --- /dev/null +++ b/curvefs/sdk/java/src/main/java/io/opencurve/curve/fs/libfs/CurveFsProto.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2023 NetEase Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Project: Curve + * Created Date: 2023-12-19 + * Author: Jingli Chen (Wine93) + */ + +package io.opencurve.curve.fs.libfs; + +import java.net.URI; +import java.io.IOException; + +import org.apache.hadoop.conf.Configuration; +import io.opencurve.curve.fs.libfs.CurveFsMount.StatVfs; +import io.opencurve.curve.fs.libfs.CurveFsMount.Stat; +import io.opencurve.curve.fs.libfs.CurveFsMount.File; +import io.opencurve.curve.fs.libfs.CurveFsMount.Dirent; + +public abstract class CurveFsProto { + public abstract void initialize(URI uri, Configuration conf) throws IOException; + public abstract void shutdown() throws IOException; + + public abstract void mkdirs(String path, int mode) throws IOException; + public abstract void rmdir(String path) throws IOException; + public abstract Dirent[] listdir(String path) throws IOException; + + public abstract void create(String path, int mode, File file) throws IOException; + public abstract void open(String path, int flags, File file) throws IOException; + public abstract long lseek(int fd, long offset, int whence) throws IOException; + public abstract int write(int fd, long offset, byte[] buffer, long size) throws IOException; + public abstract int read(int fd, long offset, byte[] buffer, long size) throws IOException; + public abstract void fsync(int fd) throws IOException; + public abstract void close(int fd) throws IOException; + public abstract void unlink(String path) throws IOException; + + public abstract void statfs(String path, StatVfs statvfs) throws IOException; + public abstract void lstat(String path, Stat stat) throws IOException; + public abstract void fstat(int fd, Stat stat) throws IOException; + public abstract void setattr(String path, Stat stat, int mask) throws IOException; + public abstract void chmod(String path, int mode) throws IOException; + public abstract void chown(String path, int uid, int gid) throws IOException; + public abstract void remove(String path) throws IOException; + public abstract void removeall(String path) throws IOException; + public abstract void rename(String src, String dst) throws IOException; +} diff --git a/curvefs/sdk/libcurvefs/examples/Makefile b/curvefs/sdk/libcurvefs/examples/Makefile index 082e743f52..676f6334d2 100644 --- a/curvefs/sdk/libcurvefs/examples/Makefile +++ b/curvefs/sdk/libcurvefs/examples/Makefile @@ -6,7 +6,8 @@ hrd_opt?= -I/curve build_opt?= -L$(so_path) link_opt?= -Wl,-rpath=$(so_path) -Wall flags?= $(hrd_opt) $(build_opt) $(link_opt) -targets= mkdir rmdir ls touch read write unlink append rename stat statfs fstat chmod +#targets= mkdir rmdir ls touch read write unlink append rename stat statfs fstat chmod +targets= ls libcurvefs: mkdir -p bin diff --git a/curvefs/sdk/libcurvefs/examples/common.h b/curvefs/sdk/libcurvefs/examples/common.h index dc262eb0b2..a80acd97b1 100644 --- a/curvefs/sdk/libcurvefs/examples/common.h +++ b/curvefs/sdk/libcurvefs/examples/common.h @@ -23,11 +23,7 @@ #include "curvefs/sdk/libcurvefs/libcurvefs.h" -const char* KEY_FSNAME = "CURVEFS_FSNAME"; -const char* KEY_S3_AK = "s3.ak"; -const char* KEY_S3_SK = "s3.sk"; -const char* KEY_S3_ENDPOINT = "s3.endpoint"; -const char* KEY_S3_BUCKET = "s3.bucket_name"; +const char* KEY_FSNAME = "curvefs.name"; const char* KEY_MDS_ADDRS = "mdsOpt.rpcRetryOpt.addrs"; char* @@ -42,7 +38,8 @@ require_string(const char* name) { char* get_filesystem_name() { - return require_string(KEY_FSNAME); + //return require_string(KEY_FSNAME); + return "perf02"; } char* @@ -52,12 +49,9 @@ get_mountpoint() { void load_cfg_from_environ(uintptr_t instance) { - curvefs_conf_set(instance, KEY_S3_AK, require_string(KEY_S3_AK)); - curvefs_conf_set(instance, KEY_S3_SK, require_string(KEY_S3_SK)); - curvefs_conf_set(instance, KEY_S3_ENDPOINT, - require_string(KEY_S3_ENDPOINT)); - curvefs_conf_set(instance, KEY_S3_BUCKET, require_string(KEY_S3_BUCKET)); - curvefs_conf_set(instance, KEY_MDS_ADDRS, require_string(KEY_MDS_ADDRS)); + //curvefs_conf_set(instance, KEY_MDS_ADDRS, require_string(KEY_MDS_ADDRS)); + curvefs_conf_set(instance, KEY_MDS_ADDRS, "10.221.103.160:6700,10.221.103.160:6701,10.221.103.160:6702"); + curvefs_conf_set(instance, "client.common.logDir", "/tmp"); curvefs_conf_set(instance, "fs.accessLogging", "true"); curvefs_conf_set(instance, "client.loglevel", "6"); curvefs_conf_set(instance, "diskCache.diskCacheType", "0"); diff --git a/curvefs/sdk/libcurvefs/examples/ls.c b/curvefs/sdk/libcurvefs/examples/ls.c index 71df5f30be..30ddb9764f 100644 --- a/curvefs/sdk/libcurvefs/examples/ls.c +++ b/curvefs/sdk/libcurvefs/examples/ls.c @@ -17,17 +17,17 @@ main(int argc, char** argv) { } // opendir - dir_stream_t dir_stream; - rc = curvefs_opendir(instance, argv[1], &dir_stream); + uint64_t fd; + rc = curvefs_opendir(instance, argv[1], &fd); if (rc != 0) { fprintf(stderr, "opendir failed: retcode = %d\n", rc); return rc; } // readdir - dirent_t dirent; + dirent_t dirents[8192]; for ( ;; ) { - ssize_t n = curvefs_readdir(instance, &dir_stream, &dirent); + ssize_t n = curvefs_readdir(instance, fd, dirents, 8192); if (n < 0) { rc = n; fprintf(stderr, "readdir failed: retcode = %d\n", rc); @@ -36,12 +36,14 @@ main(int argc, char** argv) { break; } - printf("%s: ino=%d size=%d\n", dirent.name, - dirent.stat.st_ino, - dirent.stat.st_size); + for (int i = 0; i < n; i++) { + printf("%s: ino=%d size=%d\n", dirents[i].name, + dirents[i].stat.st_ino, + dirents[i].stat.st_size); + } } - rc = curvefs_closedir(instance, &dir_stream); + rc = curvefs_closedir(instance, fd); if (rc != 0) { fprintf(stderr, "closedir failed: retcode = %d\n", rc); } diff --git a/curvefs/sdk/libcurvefs/libcurvefs.cpp b/curvefs/sdk/libcurvefs/libcurvefs.cpp index aef8a0caac..65e1b98998 100644 --- a/curvefs/sdk/libcurvefs/libcurvefs.cpp +++ b/curvefs/sdk/libcurvefs/libcurvefs.cpp @@ -21,30 +21,24 @@ */ #include "curvefs/src/client/filesystem/error.h" +#include "curvefs/src/client/vfs/meta.h" #include "curvefs/sdk/libcurvefs/libcurvefs.h" using ::curvefs::client::filesystem::CURVEFS_ERROR; using ::curvefs::client::filesystem::SysErr; -using ::curvefs::client::vfs::DirStream; -using ::curvefs::client::vfs::DirEntry; +using ::curvefs::client::vfs::Dirent; static curvefs_mount_t* get_instance(uintptr_t instance_ptr) { return reinterpret_cast(instance_ptr); } -static void stream_cast(DirStream* stream, dir_stream_t* dir_stream) { - dir_stream->fh = stream->fh; - dir_stream->ino = stream->ino; - dir_stream->offset = stream->offset; -} - -uintptr_t curvefs_create() { +uintptr_t curvefs_new() { auto mount = new curvefs_mount_t(); mount->cfg = Configure::Default(); return reinterpret_cast(mount); } -void curvefs_release(uintptr_t instance_ptr) { +void curvefs_delete(uintptr_t instance_ptr) { auto mount = get_instance(instance_ptr); delete mount; mount = nullptr; @@ -94,61 +88,52 @@ int curvefs_rmdir(uintptr_t instance_ptr, const char* path) { int curvefs_opendir(uintptr_t instance_ptr, const char* path, - dir_stream_t* dir_stream) { - DirStream stream; + uint64_t* fd) { auto mount = get_instance(instance_ptr); - auto rc = mount->vfs->OpenDir(path, &stream); - if (rc == CURVEFS_ERROR::OK) { - stream_cast(&stream, dir_stream); - } + auto rc = mount->vfs->OpenDir(path, fd); return SysErr(rc); } ssize_t curvefs_readdir(uintptr_t instance_ptr, - dir_stream_t* dir_stream, - dirent_t* dirent) { - DirEntry dirEntry; + uint64_t fd, + dirent_t dirents[], + size_t count) { + size_t nread = 0; auto mount = get_instance(instance_ptr); - DirStream* stream = reinterpret_cast(dir_stream); - auto rc = mount->vfs->ReadDir(stream, &dirEntry); + auto rc = mount->vfs->ReadDir( + fd, reinterpret_cast(dirents), count, &nread); if (rc == CURVEFS_ERROR::OK) { - std::string name = dirEntry.name; - name.copy(dirent->name, name.size() ); - dirent->name[name.size()] = '\0'; - mount->vfs->Attr2Stat(&dirEntry.attr, &dirent->stat); - return 1; + return nread; } else if (rc == CURVEFS_ERROR::END_OF_FILE) { return 0; } return SysErr(rc); } -int curvefs_closedir(uintptr_t instance_ptr, dir_stream_t* dir_stream) { - DirStream* stream = reinterpret_cast(dir_stream); +int curvefs_closedir(uintptr_t instance_ptr, uint64_t fd) { + auto mount = get_instance(instance_ptr); + auto rc = mount->vfs->CloseDir(fd); + return SysErr(rc); +} + +int curvefs_create(uintptr_t instance_ptr, + const char* path, + uint16_t mode, + file_t* file) { + CURVEFS_ERROR rc; auto mount = get_instance(instance_ptr); - auto rc = mount->vfs->CloseDir(stream); + rc = mount->vfs->Create(path, mode, reinterpret_castfile); return SysErr(rc); } int curvefs_open(uintptr_t instance_ptr, const char* path, uint32_t flags, - uint16_t mode) { + file_t* file) { CURVEFS_ERROR rc; auto mount = get_instance(instance_ptr); - if (flags & O_CREAT) { - rc = mount->vfs->Create(path, mode); - if (rc != CURVEFS_ERROR::OK && rc != CURVEFS_ERROR::EXISTS) { - return SysErr(rc); - } - } - - uint64_t fd = 0; - rc = mount->vfs->Open(path, flags, mode, &fd); - if (rc != CURVEFS_ERROR::OK) { - return SysErr(rc); - } - return static_cast(fd); + rc = mount->vfs->Open(path, flags, reinterpret_castfile); + return SysErr(rc); } int curvefs_lseek(uintptr_t instance_ptr, @@ -247,6 +232,18 @@ int curvefs_chown(uintptr_t instance_ptr, return SysErr(rc); } +int curvefs_remove(uintptr_t instance_ptr, const char* path) { + auto mount = get_instance(instance_ptr); + auto rc = mount->vfs->Remove(path, path); + return SysErr(rc); +} + +int curvefs_removeall(uintptr_t instance_ptr, const char* path) { + auto mount = get_instance(instance_ptr); + auto rc = mount->vfs->RemoveAll(path, path); + return SysErr(rc); +} + int curvefs_rename(uintptr_t instance_ptr, const char* oldpath, const char* newpath) { diff --git a/curvefs/sdk/libcurvefs/libcurvefs.h b/curvefs/sdk/libcurvefs/libcurvefs.h index 35d2f743df..f78621aee7 100644 --- a/curvefs/sdk/libcurvefs/libcurvefs.h +++ b/curvefs/sdk/libcurvefs/libcurvefs.h @@ -46,25 +46,23 @@ typedef struct { #endif // __cplusplus -// Must be synchronized with DirStream if changed typedef struct { - uint64_t ino; - uint64_t fh; - uint64_t offset; -} dir_stream_t; + uint64_t fd; + uint64_t length; +} file_t; typedef struct { - struct stat stat; - char name[256]; + char name[256]; // TODO(Wine93): smaller buffer + struct stat stat; // sizeof(stat) = 144 } dirent_t; #ifdef __cplusplus extern "C" { #endif -uintptr_t curvefs_create(); +uintptr_t curvefs_new(); -void curvefs_release(uintptr_t instance_ptr); +void curvefs_delete(uintptr_t instance_ptr); // NOTE: instance_ptr is the pointer of curvefs_mount_t instance. void curvefs_conf_set(uintptr_t instance_ptr, @@ -88,19 +86,25 @@ int curvefs_rmdir(uintptr_t instance_ptr, const char* path); int curvefs_opendir(uintptr_t instance_ptr, const char* path, - dir_stream_t* dir_stream); + uint64_t* fd); ssize_t curvefs_readdir(uintptr_t instance_ptr, - dir_stream_t* dir_stream, - dirent_t* dirent); + uint64_t fd, + dirent_t dirents[], + size_t count); -int curvefs_closedir(uintptr_t instance_ptr, dir_stream_t* dir_stream); +int curvefs_closedir(uintptr_t instance_ptr, uint64_t fd); // file +int curvefs_create(uintptr_t instance_ptr, + const char* path, + uint16_t mode, + file_t* file); + int curvefs_open(uintptr_t instance_ptr, const char* path, uint32_t flags, - uint16_t mode); + file_t* file); int curvefs_lseek(uintptr_t instance_ptr, int fd, @@ -142,6 +146,10 @@ int curvefs_chown(uintptr_t instance_ptr, uint32_t uid, uint32_t gid); +int curvefs_remove(uintptr_t instance_ptr, const char* path); + +int curvefs_removeall(uintptr_t instance_ptr, const char* path); + int curvefs_rename(uintptr_t instance_ptr, const char* oldpath, const char* newpath); diff --git a/curvefs/src/client/filesystem/dir_cache.cpp b/curvefs/src/client/filesystem/dir_cache.cpp index f71a1651b8..b535d926e4 100644 --- a/curvefs/src/client/filesystem/dir_cache.cpp +++ b/curvefs/src/client/filesystem/dir_cache.cpp @@ -57,15 +57,6 @@ bool DirEntryList::Get(Ino ino, DirEntry* dirEntry) { return true; } -bool DirEntryList::At(uint32_t index, DirEntry* dirEntry) { - ReadLockGuard lk(rwlock_); - if (index >= entries_.size()) { - return false; - } - *dirEntry = entries_[index]; - return true; -} - bool DirEntryList::UpdateAttr(Ino ino, const InodeAttr& attr) { WriteLockGuard lk(rwlock_); auto iter = index_.find(ino); @@ -104,6 +95,17 @@ void DirEntryList::Iterate(IterateHandler handler) { } } +void DirEntryList::IterateRange(uint64_t offset, + uint64_t count, + IterateHandler handler) { + ReadLockGuard lk(rwlock_); + auto iter = entries_.begin() + offset; + while (count > 0 && iter != entries_.end()) { + handler(&(*iter++)); + count--; + } +} + void DirEntryList::Clear() { WriteLockGuard lk(rwlock_); entries_.clear(); diff --git a/curvefs/src/client/filesystem/dir_cache.h b/curvefs/src/client/filesystem/dir_cache.h index 6c07ae1221..2be4da8c8b 100644 --- a/curvefs/src/client/filesystem/dir_cache.h +++ b/curvefs/src/client/filesystem/dir_cache.h @@ -59,9 +59,9 @@ class DirEntryList { void Iterate(IterateHandler handler); - bool Get(Ino ino, DirEntry* dirEntry); + void IterateRange(uint64_t offset, uint64_t count, IterateHandler handler); - bool At(uint32_t index, DirEntry* dirEntry); + bool Get(Ino ino, DirEntry* dirEntry); bool UpdateAttr(Ino ino, const InodeAttr& attr); diff --git a/curvefs/src/client/vfs/handlers.cpp b/curvefs/src/client/vfs/handlers.cpp index 2c28f2fc14..b53995cda9 100644 --- a/curvefs/src/client/vfs/handlers.cpp +++ b/curvefs/src/client/vfs/handlers.cpp @@ -30,13 +30,10 @@ FileHandlers::FileHandlers() : nextHandler_(0), handlers_() {} -uint64_t FileHandlers::NextHandler(Ino ino, - uint64_t offset, - uint64_t length, - uint32_t flags) { + +uint64_t FileHandlers::NextHandler(const FileHandler& fh) { LockGuard lk(mutex_); - handlers_[nextHandler_] = - std::make_shared(ino, offset, length, flags); + handlers_[nextHandler_] = std::make_shared(fh); return nextHandler_++; } diff --git a/curvefs/src/client/vfs/handlers.h b/curvefs/src/client/vfs/handlers.h index 034a82588b..305bab177f 100644 --- a/curvefs/src/client/vfs/handlers.h +++ b/curvefs/src/client/vfs/handlers.h @@ -38,25 +38,48 @@ namespace vfs { using ::curve::common::Mutex; using ::curve::common::LockGuard; +enum HandlerType : uint8_t { + DIR = 0, + FILE = 1, +}; + struct FileHandler { - FileHandler() : ino(0), offset(0) {} - FileHandler(Ino ino, uint64_t offset, uint64_t length, uint32_t flags) - : ino(ino), offset(offset), length(length), flags(flags) {} + // for file + FileHandler(HandlerType type, Ino ino, uint64_t offset, + uint64_t length, uint32_t flags) + : type(type), + ino(ino), + offset(offset), + length(length), + flags(flags), + fh(0), + entries(nullptr) {} + // for directory + FileHandler(HandlerType type, Ino ino) + : type(type), + ino(ino), + offset(0), + length(0), + flags(0), + fh(0), + entries(nullptr) {} + + HandlerType type; Ino ino; uint64_t offset; uint64_t length; uint32_t flags; + + uint64_t fh; + std::shared_ptr entries; }; class FileHandlers { public: FileHandlers(); - uint64_t NextHandler(Ino ino, - uint64_t offset, - uint64_t length, - uint32_t flags); + uint64_t NextHandler(const FileHandler& fh); bool GetHandler(uint64_t fd, std::shared_ptr* handler); diff --git a/curvefs/src/client/vfs/meta.h b/curvefs/src/client/vfs/meta.h index 789e093bbd..6d08b44d5b 100644 --- a/curvefs/src/client/vfs/meta.h +++ b/curvefs/src/client/vfs/meta.h @@ -45,10 +45,14 @@ using Ino = uint64_t; const Ino ROOT_INO = ::curvefs::ROOTINODEID; -struct DirStream { - Ino ino; - uint64_t fh; - uint64_t offset; +struct File { + uint64_t fd; + uint64_t length; +}; + +struct Dirent { + char name[256]; // TODO(Wine93): smaller buffer + struct stat stat; // sizeof(stat) = 144 }; struct Entry { diff --git a/curvefs/src/client/vfs/vfs.cpp b/curvefs/src/client/vfs/vfs.cpp index 083c951af6..91463430c2 100644 --- a/curvefs/src/client/vfs/vfs.cpp +++ b/curvefs/src/client/vfs/vfs.cpp @@ -37,6 +37,7 @@ #include "curvefs/src/client/vfs/config.h" #include "curvefs/src/client/vfs/meta.h" #include "curvefs/src/client/vfs/utils.h" +#include "curvefs/src/client/vfs/handlers.h" #include "curvefs/src/client/vfs/vfs.h" namespace curvefs { @@ -185,17 +186,19 @@ CURVEFS_ERROR VFS::RmDir(const std::string& path) { return rc; } -CURVEFS_ERROR VFS::OpenDir(const std::string& path, DirStream* stream) { +CURVEFS_ERROR VFS::OpenDir(const std::string& path, uint64_t* fd) { Entry entry; CURVEFS_ERROR rc; AccessLogGuard log([&](){ return StrFormat("opendir (%s): %s [fh:%d]", - path, StrErr(rc), stream->fh); + path, StrErr(rc), *fd); }); rc = Lookup(path, true, &entry); if (rc != CURVEFS_ERROR::OK) { return rc; + } else if (!IsDir(entry.attr)) { + return CURVEFS_ERROR::NOT_A_DIRECTORY; } rc = permission_->Check(entry.attr, Permission::WANT_READ); @@ -203,57 +206,96 @@ CURVEFS_ERROR VFS::OpenDir(const std::string& path, DirStream* stream) { return rc; } - stream->ino = entry.ino; - stream->offset = 0; - rc = op_->OpenDir(entry.ino, &stream->fh); + FileHandler fh(HandlerType::DIR, entry.ino); + rc = op_->OpenDir(entry.ino, &fh.fh); + if (rc == CURVEFS_ERROR::OK) { + *fd = handlers_->NextHandler(fh); + } return rc; } -CURVEFS_ERROR VFS::ReadDir(DirStream* stream, DirEntry* dirEntry) { - uint64_t nread = 0; +CURVEFS_ERROR VFS::ReadDir(uint64_t fd, + Dirent dirents[], + size_t count, + uint64_t* nread) { + uint64_t offset = 0; CURVEFS_ERROR rc; AccessLogGuard log([&](){ - return StrFormat("readdir (%d,%d): %s (%d)", - stream->fh, stream->offset, StrErr(rc), nread); + return StrFormat("readdir (%d,%d,%d): %s (%d)", + fd, count, offset, StrErr(rc), *nread); }); - auto entries = std::make_shared(); - rc = op_->ReadDir(stream->ino, stream->fh, &entries); - if (rc != CURVEFS_ERROR::OK) { + std::shared_ptr fh; + bool yes = handlers_->GetHandler(fd, &fh); + if (!yes) { + rc = CURVEFS_ERROR::BAD_FD; return rc; } - if (stream->offset >= entries->Size()) { + if (nullptr == fh->entries) { + fh->entries = std::make_shared(); + rc = op_->ReadDir(fh->ino, fh->fh, &fh->entries); + if (rc != CURVEFS_ERROR::OK) { + return rc; + } + + fh->entries->Iterate([&](DirEntry* dirEntry) { + // TODO(Wine93): add entry&attr cache + }); + } + + offset = fh->offset; + size_t size = fh->entries->Size(); + if (offset >= size) { rc = CURVEFS_ERROR::END_OF_FILE; return rc; } + uint64_t i = 0; + fh->entries->IterateRange(offset, count, [&](DirEntry* dirEntry) { + const std::string& name = dirEntry->name; + name.copy(dirents[i].name, name.size()); + dirents[i].name[name.size()] = '\0'; + op_->Attr2Stat(&dirEntry->attr, &dirents[i].stat); + i++; + }); + + *nread = i; + fh->offset = fh->offset + *nread; rc = CURVEFS_ERROR::OK; - entries->At(stream->offset, dirEntry); - stream->offset++; - nread = 1; return rc; } -CURVEFS_ERROR VFS::CloseDir(DirStream* stream) { +CURVEFS_ERROR VFS::CloseDir(uint64_t fd) { CURVEFS_ERROR rc; AccessLogGuard log([&](){ - return StrFormat("closedir (%d): %s", - stream->fh, StrErr(rc)); + return StrFormat("closedir (%d): %s", fd, StrErr(rc)); }); - rc = op_->CloseDir(stream->ino); + std::shared_ptr fh; + bool yes = handlers_->GetHandler(fd, &fh); + if (!yes) { + rc = CURVEFS_ERROR::BAD_FD; + return rc; + } + + rc = op_->CloseDir(fh->ino); + if (rc == CURVEFS_ERROR::OK) { + handlers_->FreeHandler(fd); + } return rc; } -CURVEFS_ERROR VFS::Create(const std::string& path, uint16_t mode) { +CURVEFS_ERROR VFS::Create(const std::string& path, + uint16_t mode, + File* file) { Entry parent; EntryOut entryOut; CURVEFS_ERROR rc; AccessLogGuard log([&](){ - return StrFormat("create (%s,%s:0%04o): %s%s", + return StrFormat("create (%s,%s:0%04o): %s%s [fh:%d]", path, StrMode(mode), mode, - StrErr(rc), StrEntry(entryOut)); + StrErr(rc), StrEntry(entryOut), file->fd); }); rc = Lookup(filepath::ParentDir(path), true, &parent); @@ -268,20 +310,25 @@ CURVEFS_ERROR VFS::Create(const std::string& path, uint16_t mode) { mode = permission_->GetFileMode(S_IFREG, mode); rc = op_->Create(parent.ino, filepath::Filename(path), mode, &entryOut); - if (rc == CURVEFS_ERROR::OK) { - PurgeEntryCache(parent.ino, filepath::Filename(path)); + if (rc != CURVEFS_ERROR::OK) { + return rc; } + + PurgeEntryCache(parent.ino, filepath::Filename(path)); + FileHandler fh = FileHandler(HandlerType::FILE, entry.ino, + 0, 0, O_WRONLY); + file->fd = handlers_->NextHandler(fh); + file->length = 0; return rc; } CURVEFS_ERROR VFS::Open(const std::string& path, uint32_t flags, - uint16_t mode, - uint64_t* fd) { + File* file) { Entry entry; CURVEFS_ERROR rc; AccessLogGuard log([&](){ - return StrFormat("open (%s): %s [fh:%d]", path, StrErr(rc), *fd); + return StrFormat("open (%s): %s [fh:%d]", path, StrErr(rc), file->fd); }); rc = Lookup(path, true, &entry); @@ -313,7 +360,11 @@ CURVEFS_ERROR VFS::Open(const std::string& path, if (flags & O_APPEND) { offset = length; } - *fd = handlers_->NextHandler(entry.ino, offset, length, flags); + + auto fh = FileHandler(HandlerType::FILE, entry.ino, + offset, length, flags); + file->fd = handlers_->NextHandler(fh); + file->length = length; return CURVEFS_ERROR::OK; } @@ -629,6 +680,52 @@ CURVEFS_ERROR VFS::Chown(const std::string &path, uint32_t uid, uint32_t gid) { return rc; } +CURVEFS_ERROR VFS::Remove(const std::string& path) { + CURVEFS_ERROR rc; + AccessLogGuard log([&](){ + return StrFormat("remove (%s): %s", path, StrErr(rc)); + }); + + Entry parent; + rc = Lookup(filepath::ParentDir(path), true, &parent); + if (rc != CURVEFS_ERROR::OK) { + return rc; + } + + rc = permission_->Check(parent.attr, Permission::WANT_WRITE); + if (rc != CURVEFS_ERROR::OK) { + return rc; + } + + Entry entry; + rc = Lookup(path, true, &entry); + if (rc != CURVEFS_ERROR::OK) { + return rc; + } + + if (IsDir(entry.attr)) { + rc = op_->RmDir(parent.ino, filepath::Filename(path)); + } else { + rc = op_->Unlink(parent.ino, filepath::Filename(path)); + } + + rc = op_->Unlink(parent.ino, filepath::Filename(path)); + if (rc == CURVEFS_ERROR::OK) { + PurgeEntryCache(parent.ino, filepath::Filename(path)); + } + return rc; +} + +CURVEFS_ERROR VFS::RemoveAll(const std::string& path) { + CURVEFS_ERROR rc; + AccessLogGuard log([&](){ + return StrFormat("removeall (%s): %s", path, StrErr(rc)); + }); + + rc = CURVEFS_ERROR::NOT_SUPPORT; + return rc; +} + CURVEFS_ERROR VFS::Rename(const std::string& oldpath, const std::string& newpath) { Entry oldParent, newParent; diff --git a/curvefs/src/client/vfs/vfs.h b/curvefs/src/client/vfs/vfs.h index 0af8bbb304..dc63bcdfde 100644 --- a/curvefs/src/client/vfs/vfs.h +++ b/curvefs/src/client/vfs/vfs.h @@ -63,19 +63,21 @@ class VFS { CURVEFS_ERROR RmDir(const std::string& path); - CURVEFS_ERROR OpenDir(const std::string& path, DirStream* stream); + CURVEFS_ERROR OpenDir(const std::string& path, uint64_t* fd); - CURVEFS_ERROR ReadDir(DirStream* stream, DirEntry* dirEntry); + CURVEFS_ERROR ReadDir(uint64_t fd, + Dirent dirents[], + size_t count, + uint64_t* nread); - CURVEFS_ERROR CloseDir(DirStream* stream); + CURVEFS_ERROR CloseDir(uint64_t fd); // file* - CURVEFS_ERROR Create(const std::string& path, uint16_t mode); + CURVEFS_ERROR Create(const std::string& path, uint16_t mode, File* file); CURVEFS_ERROR Open(const std::string& path, uint32_t flags, - uint16_t mode, - uint64_t* fd); + File* file); CURVEFS_ERROR LSeek(uint64_t fd, uint64_t offset, int whence); @@ -107,6 +109,10 @@ class VFS { CURVEFS_ERROR Chown(const std::string& path, uint32_t uid, uint32_t gid); + CURVEFS_ERROR Remove(const std::string& path); + + CURVEFS_ERROR RemoveAll(const std::string& path); + CURVEFS_ERROR Rename(const std::string& oldpath, const std::string& newpath);