Hypertable: Change to use ceph_getdnames instead of getdir.
Hadoop: Minor updates to use the new C-style functions in libceph.
#include <sys/stat.h>
using namespace std;
+const static int IP_ADDR_LENGTH = 24;//a buffer size; may want to up for IPv6.
+static int path_size;
/*
* Class: org_apache_hadoop_fs_ceph_CephFileSystem
* Method: ceph_initializeClient
env->ReleaseStringUTFChars(j_debug_level, c_debug_level);
return false;
}
+ path_size = 64; //reasonable starting point?
//construct an arguments array
const char *argv[10];
int argc = 0;
{
dout(10) << "CephFSInterface: In getcwd" << dendl;
- string path;
- ceph_getcwd(path);
- return env->NewStringUTF(path.c_str());
+ char *path = new char[path_size];
+ int r = ceph_getcwd(path, path_size);
+ if (r==-ERANGE) { //path is too short
+ path_size = ceph_getcwd(path, 0) * 1.2; //leave some extra
+ delete path;
+ path = new char[path_size];
+ ceph_getcwd(path, path_size);
+ }
+ jstring j_path = env->NewStringUTF(path);
+ delete path;
+ return j_path;
}
/*
JNIEXPORT jboolean JNICALL Java_org_apache_hadoop_fs_ceph_CephFileSystem_ceph_1stat
(JNIEnv * env, jobject obj, jstring j_path, jobject j_stat) {
//setup variables
- struct Client::stat_precise st;
+ struct stat_precise st;
const char* c_path = env->GetStringUTFChars(j_path, 0);
if (c_path == NULL) return false;
jfieldID c_mode_id = env->GetFieldID(cls, "mode", "I");
if (c_mode_id == NULL) return false;
//do actual lstat
- int r = ceph_lstat(c_path, &st);
+ int r = ceph_lstat_precise(c_path, &st);
env->ReleaseStringUTFChars(j_path, c_path);
if (r < 0) return false; //fail out; file DNE or Ceph broke
JNIEXPORT jstring JNICALL Java_org_apache_hadoop_fs_ceph_CephFileSystem_ceph_1hosts
(JNIEnv * env, jobject obj, jint j_fh, jlong j_offset) {
//get the address
- string address;
- ceph_get_file_stripe_address(j_fh, j_offset, address);
+ char *address = new char[IP_ADDR_LENGTH];
+ int r = ceph_get_file_stripe_address(j_fh, j_offset, address, IP_ADDR_LENGTH);
+ if (r == -ERANGE) {//buffer's too small
+ delete address;
+ int size = ceph_get_file_stripe_address(j_fh, j_offset, address, 0);
+ address = new char[size];
+ r = ceph_get_file_stripe_address(j_fh, j_offset, address, size);
+ }
+ if (r != 0) { //some rather worse problem
+ if (r == -EINVAL) return NULL; //ceph thinks there are no OSDs
+ }
//make java String of address
- return env->NewStringUTF(address.c_str());
+ jstring j_addr = env->NewStringUTF(address);
+ delete address;
+ return j_addr;
}
/*
if (atime!=-1) mask |= CEPH_SETATTR_ATIME;
//build a struct stat and fill it in!
//remember to convert from millis to seconds and microseconds
- Client::stat_precise attr;
+ stat_precise attr;
attr.st_mtime_sec = mtime / 1000;
attr.st_mtime_micro = (mtime % 1000) * 1000;
attr.st_atime_sec = atime / 1000;
attr.st_atime_micro = (atime % 1000) * 1000;
- return ceph_setattr(c_path, &attr, mask);
+ return ceph_setattr_precise(c_path, &attr, mask);
}
/*
HT_DEBUGF("Readdir dir='%s'", dname);
- //get from ceph in list<string>
+ //get from ceph in a buffer
make_abs_path(dname, absdir);
- std::list<String> dir_con;
- ceph_getdir(absdir.c_str(), dir_con);
- //convert to vector<String>
- for (std::list<String>::iterator i = dir_con.begin(); i!=dir_con.end(); ++i) {
- if (!(i->compare(".")==0 || i->compare("..")==0))
- listing.push_back(*i);
+ DIR *dirp;
+ ceph_opendir(absdir.c_str(), &dirp);
+ int r;
+ int buflen = 100; //good default?
+ char *buf = new char[buflen];
+ string *ent;
+ int bufpos;
+ while (1) {
+ r = ceph_getdnames(dirp, buf, buflen);
+ if (r==-ERANGE) { //expand the buffer
+ delete buf;
+ buflen *= 2;
+ buf = new char[buflen];
+ continue;
+ }
+ if (r==0) break;
+ //if we make it here, we got at least one name, maybe more
+ bufpos = 0;
+ while (bufpos<r) {//make new strings and add them to listing
+ ent = new string(buf+bufpos);
+ listing.push_back(*ent);
+ bufpos+=ent->size()+1;
+ delete ent;
+ }
}
cb->response(listing);
}
#include "messages/MMonMap.h"
#include "common/common_init.h"
#include "msg/SimpleMessenger.h"
+#include "Client.h"
/* ************* ************* ************* *************
* C interface
{
return client->statfs(path, stbuf);
}
-
+
+extern "C" int ceph_getcwd(char *buf, int buflen)
+{
+ string cwd;
+ client->getcwd(cwd);
+ int size = cwd.size()+1; //need space for null character
+ if (size > buflen) {
+ if (buflen == 0) return size;
+ else return -ERANGE;
+ }
+ size = cwd.copy(buf, size);
+ buf[size] = '\0'; //fill in null character
+ return 0;
+}
+
extern "C" int ceph_chdir (const char *s)
{
return client->chdir(s);
}
// inode stuff
-extern "C" int ceph_lstat(const char *path, struct stat *stbuf, struct frag_info_t *dirstat)
+extern "C" int ceph_lstat(const char *path, struct stat *stbuf)
{
- return client->lstat(path, stbuf, dirstat);
+ return client->lstat(path, stbuf);
}
-int ceph_lstat(const char *path, Client::stat_precise *stbuf, frag_info_t *dirstat)
+extern "C" int ceph_lstat_precise(const char *path, stat_precise *stbuf)
{
- return client->lstat_precise(path, stbuf, dirstat);
+ return client->lstat_precise(path, (Client::stat_precise*)stbuf);
}
-extern "C" int ceph_setattr(const char *relpath, Client::stat_precise *attr, int mask)
+extern "C" int ceph_setattr(const char *relpath, struct stat *attr, int mask)
{
- return client->setattr(relpath, attr, mask);
+ Client::stat_precise p_attr = Client::stat_precise(*attr);
+ return client->setattr(relpath, &p_attr, mask);
+}
+
+extern "C" int ceph_setattr_precise(const char *relpath,
+ struct stat_precise *attr, int mask) {
+ return client->setattr(relpath, (Client::stat_precise*)attr, mask);
}
extern "C" int ceph_chmod(const char *path, mode_t mode)
return rep;
}
-int ceph_get_file_stripe_address(int fh, loff_t offset, std::string& address) {
- return client->get_file_stripe_address(fh, offset, address);
-}
-
-int ceph_getdir(const char *relpath, std::list<std::string>& names)
+int ceph_get_file_stripe_address(int fh, loff_t offset, char *buf, int buflen)
{
- return client->getdir(relpath, names);
+ string address;
+ int r = client->get_file_stripe_address(fh, offset, address);
+ if (r != 0) return r; //at time of writing, method ONLY returns
+ // 0 or -EINVAL if there are no known osds
+ int len = address.size()+1;
+ if (len > buflen) {
+ if (buflen == 0) return len;
+ else return -ERANGE;
+ }
+ len = address.copy(buf, len, 0);
+ buf[len] = '\0'; // write a null char to terminate c-style string
+ return 0;
}
#include <unistd.h>
#include <dirent.h>
-#ifdef __cplusplus
-#include <list>
-#include <string>
-#include "Client.h"
-extern "C" {
-#endif
-
- struct frag_info_t;
+struct frag_info_t;
+struct stat_precise {
+ ino_t st_ino;
+ dev_t st_dev;
+ mode_t st_mode;
+ nlink_t st_nlink;
+ uid_t st_uid;
+ gid_t st_gid;
+ dev_t st_rdev;
+ off_t st_size;
+ blksize_t st_blksize;
+ blkcnt_t st_blocks;
+ time_t st_atime_sec;
+ time_t st_atime_micro;
+ time_t st_mtime_sec;
+ time_t st_mtime_micro;
+ time_t st_ctime_sec;
+ time_t st_ctime_micro;
+};
int ceph_initialize(int argc, const char **argv);
void ceph_deinitialize();
int ceph_statfs(const char *path, struct statvfs *stbuf);
-int ceph_chdir (const char *s);
+int ceph_getcwd(char *buf, int buflen);
+int ceph_chdir(const char *s);
int ceph_opendir(const char *name, DIR **dirpp);
int ceph_closedir(DIR *dirp);
int ceph_symlink(const char *existing, const char *newname);
// inode stuff
-int ceph_lstat(const char *path, struct stat *stbuf, frag_info_t *dirstat=0);
+int ceph_lstat(const char *path, struct stat *stbuf);
+int ceph_lstat_precise(const char *path, struct stat_precise *stbuf);
-int ceph_setattr(const char *relpath, Client::stat_precise *attr, int mask);
+int ceph_setattr(const char *relpath, struct stat *attr, int mask);
+int ceph_setattr_precise (const char *relpath, struct stat_precise *stbuf, int mask);
int ceph_chmod(const char *path, mode_t mode);
int ceph_chown(const char *path, uid_t uid, gid_t gid);
int ceph_utime(const char *path, struct utimbuf *buf);
int ceph_sync_fs();
int ceph_get_file_stripe_unit(int fh);
int ceph_get_file_replication(const char *path);
-#ifdef __cplusplus
-}
-//not for C, sorry!
-int ceph_getdir(const char *relpath, std::list<std::string>& names);
-void ceph_getcwd(std::string& cwd);
-int ceph_get_file_stripe_address(int fd, loff_t offset, std::string& address);
-int ceph_lstat(const char *path, Client::stat_precise *stbuf, frag_info_t *dirstat=0);
-
-#endif
+int ceph_get_file_stripe_address(int fd, loff_t offset, char *buf, int buflen);
#endif