summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNoah Watkins <noahwatkins@gmail.com>2012-11-20 13:05:47 -0800
committerSage Weil <sage@inktank.com>2012-11-26 11:15:47 -0800
commitf0c608c0d674abed228b2bbf916e08b77afe1535 (patch)
tree52a1f52ee11245d999045bf893c11a65670a3b34
parent365ba0600bdaf28b9b71e7c6d5113cd531f95891 (diff)
downloadceph-f0c608c0d674abed228b2bbf916e08b77afe1535.tar.gz
client: add ceph_open_layout interface
Adds an interface identical to ceph_open() that takes additional parameters specifying a file layout to use on new files. Signed-off-by: Noah Watkins <noahwatkins@gmail.com> Reviewed-by: Sage Weil <sage@inktank.com>
-rw-r--r--src/client/Client.cc20
-rw-r--r--src/client/Client.h5
-rw-r--r--src/include/cephfs/libcephfs.h19
-rw-r--r--src/libcephfs.cc9
-rw-r--r--src/test/libcephfs/test.cc22
5 files changed, 69 insertions, 6 deletions
diff --git a/src/client/Client.cc b/src/client/Client.cc
index 8d4a5ac63d4..641aba170d7 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -5100,7 +5100,8 @@ int Client::getdir(const char *relpath, list<string>& contents)
/****** file i/o **********/
-int Client::open(const char *relpath, int flags, mode_t mode)
+int Client::open(const char *relpath, int flags, mode_t mode, int stripe_unit,
+ int stripe_count, int object_size, const char *data_pool)
{
ldout(cct, 3) << "open enter(" << relpath << ", " << flags << "," << mode << ") = " << dendl;
Mutex::Locker lock(client_lock);
@@ -5124,7 +5125,8 @@ int Client::open(const char *relpath, int flags, mode_t mode)
r = path_walk(dirpath, &dir);
if (r < 0)
return r;
- r = _create(dir, dname.c_str(), flags, mode, &in, &fh);
+ r = _create(dir, dname.c_str(), flags, mode, &in, &fh, stripe_unit,
+ stripe_count, object_size, data_pool);
created = true;
}
if (r < 0)
@@ -5156,6 +5158,13 @@ int Client::open(const char *relpath, int flags, mode_t mode)
return r;
}
+int Client::open(const char *relpath, int flags, mode_t mode)
+{
+ /* Use default file striping parameters */
+ return open(relpath, flags, mode, file_stripe_unit, file_stripe_count,
+ object_size, NULL);
+}
+
int Client::lookup_hash(inodeno_t ino, inodeno_t dirino, const char *name)
{
Mutex::Locker lock(client_lock);
@@ -6598,7 +6607,8 @@ int Client::ll_mknod(vinodeno_t parent, const char *name, mode_t mode, dev_t rde
return r;
}
-int Client::_create(Inode *dir, const char *name, int flags, mode_t mode, Inode **inp, Fh **fhp, int uid, int gid)
+int Client::_create(Inode *dir, const char *name, int flags, mode_t mode, Inode **inp, Fh **fhp,
+ int stripe_unit, int stripe_count, int object_size, const char *data_pool, int uid, int gid)
{
ldout(cct, 3) << "_create(" << dir->ino << " " << name << ", 0" << oct << mode << dec << ")" << dendl;
@@ -6622,8 +6632,8 @@ int Client::_create(Inode *dir, const char *name, int flags, mode_t mode, Inode
req->head.args.open.flags = flags | O_CREAT;
req->head.args.open.mode = mode;
- req->head.args.open.stripe_unit = file_stripe_unit;
- req->head.args.open.stripe_count = file_stripe_count;
+ req->head.args.open.stripe_unit = stripe_unit;
+ req->head.args.open.stripe_count = stripe_count;
req->head.args.open.object_size = object_size;
req->head.args.open.file_replication = file_replication;
req->dentry_drop = CEPH_CAP_FILE_SHARED;
diff --git a/src/client/Client.h b/src/client/Client.h
index f6f288a5bba..ae75d2df9fe 100644
--- a/src/client/Client.h
+++ b/src/client/Client.h
@@ -529,7 +529,9 @@ private:
int _setxattr(Inode *in, const char *name, const void *value, size_t len, int flags, int uid=-1, int gid=-1);
int _removexattr(Inode *in, const char *nm, int uid=-1, int gid=-1);
int _open(Inode *in, int flags, mode_t mode, Fh **fhp, int uid=-1, int gid=-1);
- int _create(Inode *in, const char *name, int flags, mode_t mode, Inode **inp, Fh **fhp, int uid=-1, int gid=-1);
+ int _create(Inode *in, const char *name, int flags, mode_t mode, Inode **inp, Fh **fhp,
+ int stripe_unit, int stripe_count, int object_size, const char *data_pool,
+ int uid=-1, int gid=-1);
loff_t _lseek(Fh *fh, loff_t offset, int whence);
int _read(Fh *fh, int64_t offset, uint64_t size, bufferlist *bl);
int _write(Fh *fh, int64_t offset, uint64_t size, const char *buf);
@@ -620,6 +622,7 @@ public:
// file ops
int mknod(const char *path, mode_t mode, dev_t rdev=0);
int open(const char *path, int flags, mode_t mode=0);
+ int open(const char *path, int flags, mode_t mode, int stripe_unit, int stripe_count, int object_size, const char *data_pool);
int lookup_hash(inodeno_t ino, inodeno_t dirino, const char *name);
int lookup_ino(inodeno_t ino);
int close(int fd);
diff --git a/src/include/cephfs/libcephfs.h b/src/include/cephfs/libcephfs.h
index 3ebbac13226..71bf25f6aed 100644
--- a/src/include/cephfs/libcephfs.h
+++ b/src/include/cephfs/libcephfs.h
@@ -602,6 +602,25 @@ int ceph_mknod(struct ceph_mount_info *cmount, const char *path, mode_t mode, de
int ceph_open(struct ceph_mount_info *cmount, const char *path, int flags, mode_t mode);
/**
+ * Create and/or open a file with a specific file layout.
+ *
+ * @param cmount the ceph mount handle to use for performing the open.
+ * @param path the path of the file to open. If the flags parameter includes O_CREAT,
+ * the file will first be created before opening.
+ * @param flags a set of option masks that control how the file is created/opened.
+ * @param mode the permissions to place on the file if the file does not exist and O_CREAT
+ * is specified in the flags.
+ * @param stripe_unit the stripe unit size (option, -1 for default)
+ * @param stripe_count the stripe count (optional, -1 for default)
+ * @param object_size the object size (optional, -1 for default)
+ * @param data_pool name of target data pool name (optional, NULL or empty string for default)
+ * @returns a non-negative file descriptor number on success or a negative error code on failure.
+ */
+int ceph_open_layout(struct ceph_mount_info *cmount, const char *path, int flags,
+ mode_t mode, int stripe_unit, int stripe_count, int object_size,
+ const char *data_pool);
+
+/**
* Close the open file.
*
* @param cmount the ceph mount handle to use for performing the close.
diff --git a/src/libcephfs.cc b/src/libcephfs.cc
index f23b959c9b1..02cf0864972 100644
--- a/src/libcephfs.cc
+++ b/src/libcephfs.cc
@@ -610,6 +610,15 @@ extern "C" int ceph_open(struct ceph_mount_info *cmount, const char *path,
return cmount->get_client()->open(path, flags, mode);
}
+extern "C" int ceph_open_layout(struct ceph_mount_info *cmount, const char *path, int flags,
+ mode_t mode, int stripe_unit, int stripe_count, int object_size, const char *data_pool)
+{
+ if (!cmount->is_mounted())
+ return -ENOTCONN;
+ return cmount->get_client()->open(path, flags, mode, stripe_unit,
+ stripe_count, object_size, data_pool);
+}
+
extern "C" int ceph_close(struct ceph_mount_info *cmount, int fd)
{
if (!cmount->is_mounted())
diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc
index f398f4d4d2d..42fb411362d 100644
--- a/src/test/libcephfs/test.cc
+++ b/src/test/libcephfs/test.cc
@@ -149,6 +149,28 @@ TEST(LibCephFS, Mount) {
ceph_shutdown(cmount);
}
+TEST(LibCephFS, Open_layout) {
+ struct ceph_mount_info *cmount;
+ ASSERT_EQ(ceph_create(&cmount, NULL), 0);
+ ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
+ ASSERT_EQ(ceph_mount(cmount, NULL), 0);
+
+ /* valid layout */
+ char test_layout_file[256];
+ sprintf(test_layout_file, "test_layout_%d_b", getpid());
+ int fd = ceph_open_layout(cmount, test_layout_file, O_CREAT, 0666, (1<<20), 7, (1<<20), NULL);
+ ASSERT_GT(fd, 0);
+ ceph_close(cmount, fd);
+
+ /* invalid layout */
+ sprintf(test_layout_file, "test_layout_%d_c", getpid());
+ fd = ceph_open_layout(cmount, test_layout_file, O_CREAT, 0666, (1<<20), 1, 19, NULL);
+ ASSERT_EQ(fd, -EINVAL);
+ ceph_close(cmount, fd);
+
+ ceph_shutdown(cmount);
+}
+
TEST(LibCephFS, Dir_ls) {
pid_t mypid = getpid();