11
#include <sys/xattr.h>
13
#include "rgw_access.h"
27
#define DIR_NAME "/tmp/radosgw"
29
int RGWFS::list_buckets_init(string& id, RGWAccessHandle *handle)
31
DIR *dir = opendir(DIR_NAME);
32
struct rgwfs_state *state;
37
state = (struct rgwfs_state *)malloc(sizeof(struct rgwfs_state));
43
*handle = (RGWAccessHandle)state;
48
int RGWFS::list_buckets_next(string& id, RGWObjEnt& obj, RGWAccessHandle *handle)
50
struct rgwfs_state *state;
51
struct dirent *dirent;
56
state = *(struct rgwfs_state **)handle;
62
dirent = readdir(state->dir);
69
if (dirent->d_name[0] == '.')
72
obj.name = dirent->d_name;
76
snprintf(buf, BUF_SIZE, "%s/%s", DIR_NAME, obj.name.c_str());
77
if (stat(buf, &statbuf) < 0)
79
obj.mtime = statbuf.st_mtime;
80
obj.size = statbuf.st_size;
85
int RGWFS::list_objects(string& id, string& bucket, int max, string& prefix, string& delim,
86
string& marker, vector<RGWObjEnt>& result, map<string, bool>& common_prefixes)
88
map<string, bool> dir_map;
91
snprintf(path, BUF_SIZE, "%s/%s", DIR_NAME, bucket.c_str());
93
DIR *dir = opendir(path);
98
struct dirent *dirent;
99
dirent = readdir(dir);
102
if (dirent->d_name[0] == '.')
105
if (prefix.empty() ||
106
(prefix.compare(0, prefix.size(), prefix) == 0)) {
107
dir_map[dirent->d_name] = true;
114
map<string, bool>::iterator iter;
116
iter = dir_map.lower_bound(marker);
118
iter = dir_map.begin();
125
for (i=0; i<max && iter != dir_map.end(); i++, ++iter) {
129
obj.name = iter->first;
130
snprintf(buf, BUF_SIZE, "%s/%s", path, obj.name.c_str());
131
if (stat(buf, &statbuf) < 0)
133
obj.mtime = statbuf.st_mtime;
134
obj.size = statbuf.st_size;
136
if (get_attr(RGW_ATTR_ETAG, buf, &etag) >= 0) {
137
strncpy(obj.etag, etag, sizeof(obj.etag));
138
obj.etag[sizeof(obj.etag)-1] = '\0';
141
result.push_back(obj);
148
int RGWFS::create_bucket(std::string& id, std::string& bucket, map<std::string, bufferlist>& attrs, uint64_t auid)
150
int len = strlen(DIR_NAME) + 1 + bucket.size() + 1;
152
snprintf(buf, len, "%s/%s", DIR_NAME, bucket.c_str());
154
if (mkdir(buf, 0755) < 0)
157
map<std::string, bufferlist>::iterator iter;
158
for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
159
const string& name = iter->first;
160
bufferlist& bl = iter->second;
163
int r = setxattr(buf, name.c_str(), bl.c_str(), bl.length(), 0);
175
int RGWFS::put_obj(std::string& id, std::string& bucket, std::string& obj, const char *data, size_t size,
177
map<string, bufferlist>& attrs)
179
int len = strlen(DIR_NAME) + 1 + bucket.size() + 1 + obj.size() + 1;
181
snprintf(buf, len, "%s/%s/%s", DIR_NAME, bucket.c_str(), obj.c_str());
184
fd = open(buf, O_CREAT | O_WRONLY, 0755);
189
map<string, bufferlist>::iterator iter;
190
for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
191
const string& name = iter->first;
192
bufferlist& bl = iter->second;
195
r = fsetxattr(fd, name.c_str(), bl.c_str(), bl.length(), 0);
204
r = write(fd, data, size);
221
*mtime = st.st_mtime;
231
int RGWFS::copy_obj(std::string& id, std::string& dest_bucket, std::string& dest_obj,
232
std::string& src_bucket, std::string& src_obj,
234
const time_t *mod_ptr,
235
const time_t *unmod_ptr,
236
const char *if_match,
237
const char *if_nomatch,
238
map<string, bufferlist>& attrs,
244
map<string, bufferlist> attrset;
245
ret = get_obj(src_bucket, src_obj, &data, 0, -1, &attrset,
246
mod_ptr, unmod_ptr, if_match, if_nomatch, true, err);
250
map<string, bufferlist>::iterator iter;
251
for (iter = attrs.begin(); iter != attrs.end(); ++iter) {
252
attrset[iter->first] = iter->second;
256
ret = put_obj(id, dest_bucket, dest_obj, data, ret, mtime, attrs);
262
int RGWFS::delete_bucket(std::string& id, std::string& bucket)
264
int len = strlen(DIR_NAME) + 1 + bucket.size() + 1;
266
snprintf(buf, len, "%s/%s", DIR_NAME, bucket.c_str());
275
int RGWFS::delete_obj(std::string& id, std::string& bucket, std::string& obj)
277
int len = strlen(DIR_NAME) + 1 + bucket.size() + 1 + obj.size() + 1;
279
snprintf(buf, len, "%s/%s/%s", DIR_NAME, bucket.c_str(), obj.c_str());
287
int RGWFS::get_attr(const char *name, int fd, char **attr)
291
size_t len = ETAG_LEN;
295
attr_buf = (char *)malloc(len);
296
attr_len = fgetxattr(fd, name, attr_buf, len);
314
int RGWFS::get_attr(const char *name, const char *path, char **attr)
317
size_t len = ETAG_LEN;
321
attr_buf = (char *)malloc(len);
322
attr_len = getxattr(path, name, attr_buf, len);
331
cerr << "getxattr on " << path << " returned" << -errno << std::endl;
341
int RGWFS::get_attr(std::string& bucket, std::string& obj,
342
const char *name, bufferlist& dest)
344
int len = strlen(DIR_NAME) + 1 + bucket.size() + 1 + obj.size() + 1;
349
snprintf(buf, len, "%s/%s/%s", DIR_NAME, bucket.c_str(), obj.c_str());
351
r = get_attr(name, buf, &data);
354
dest.append(data, r);
361
int RGWFS::set_attr(std::string& bucket, std::string& obj,
362
const char *name, bufferlist& bl)
364
int len = strlen(DIR_NAME) + 1 + bucket.size() + 1 + obj.size() + 1;
368
snprintf(buf, len, "%s/%s/%s", DIR_NAME, bucket.c_str(), obj.c_str());
370
r = setxattr(buf, name, bl.c_str(), bl.length(), 0);
372
int ret = (r < 0 ? -errno : 0);
373
cerr << "setxattr: path=" << buf << " ret=" << ret << std::endl;
378
int RGWFS::get_obj(std::string& bucket, std::string& obj,
379
char **data, off_t ofs, off_t end,
380
map<string, bufferlist> *attrs,
381
const time_t *mod_ptr,
382
const time_t *unmod_ptr,
383
const char *if_match,
384
const char *if_nomatch,
388
int len = strlen(DIR_NAME) + 1 + bucket.size() + 1 + obj.size() + 1;
396
snprintf(buf, len, "%s/%s/%s", DIR_NAME, bucket.c_str(), obj.c_str());
398
fd = open(buf, O_RDONLY, 0755);
408
end = st.st_size - 1;
410
max_len = end - ofs + 1;
414
if (st.st_mtime < *mod_ptr) {
416
err->code = "PreconditionFailed";
422
if (st.st_mtime >= *mod_ptr) {
424
err->code = "PreconditionFailed";
428
if (if_match || if_nomatch) {
429
r = get_attr(RGW_ATTR_ETAG, fd, &etag);
435
cerr << "etag=" << etag << " " << " if_match=" << if_match << endl;
436
if (strcmp(if_match, etag)) {
438
err->code = "PreconditionFailed";
444
cerr << "etag=" << etag << " " << " if_nomatch=" << if_nomatch << endl;
445
if (strcmp(if_nomatch, etag) == 0) {
447
err->code = "PreconditionFailed";
457
*data = (char *)malloc(max_len);
464
while (pos < max_len) {
465
r = read(fd, (*data) + pos, max_len);
470
cerr << "pos=" << pos << " r=" << r << " max_len=" << max_len << endl;
471
r = -EIO; /* should not happen as we validated file size earlier */