Skip to content

Commit

Permalink
Split up operations.cpp into several files for groups of (mostly) rel…
Browse files Browse the repository at this point in the history
…ated operations.
  • Loading branch information
Imroy committed Nov 26, 2013
1 parent b53000a commit 2642a70
Show file tree
Hide file tree
Showing 8 changed files with 612 additions and 523 deletions.
519 changes: 6 additions & 513 deletions operations.cpp

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions operations.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@
#define ENOATTR 93
#endif

#include <map>
#include <fuse.h>
#include <mongo/client/connpool.h>

#include "local_gridfile.h"
#include "options.h"

extern std::map<std::string, LocalGridFile::ptr> open_files;

int gridfs_getattr(const char *path, struct stat *stbuf);

Expand Down Expand Up @@ -66,4 +73,10 @@ int gridfs_flush(const char* path, struct fuse_file_info* ffi);

int gridfs_rename(const char* old_path, const char* new_path);

std::shared_ptr<mongo::ScopedDbConnection> make_ScopedDbConnection(void);

inline mongo::GridFS get_gridfs(std::shared_ptr<mongo::ScopedDbConnection> sdc) {
return mongo::GridFS(sdc->conn(), gridfs_options.db, gridfs_options.prefix);
}

#endif
57 changes: 57 additions & 0 deletions ops_dir.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2009 Michael Stephens
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <mongo/bson/bson.h>
#include <mongo/client/gridfs.h>

#include "operations.h"
#include "options.h"

int gridfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) {
if (strcmp(path, "/") != 0)
return -ENOENT;

/* Create string to hold last filename seen */
std::string lastFN;

filler(buf, ".", NULL, 0);
filler(buf, "..", NULL, 0);

auto sdc = make_ScopedDbConnection();
mongo::GridFS gf = get_gridfs(sdc);

std::unique_ptr<mongo::DBClientCursor> cursor = gf.list();
while (cursor->more()) {
mongo::BSONObj f = cursor->next();

/* If this filename matches the last filename we've seen, *do not* add it to the buffer because it's a duplicate filename */
if (lastFN != f.getStringField("filename")) {
filler(buf, f.getStringField("filename") , NULL , 0);
}

/* Update lastFN with our cursor's current filename */
lastFN = f.getStringField("filename");
fprintf(stderr, "DEBUG: %s\n", lastFN.c_str());
}

for (auto i : open_files) {
filler(buf, i.first.c_str(), NULL, 0);
}

return 0;
}

181 changes: 181 additions & 0 deletions ops_file.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/*
* Copyright 2009 Michael Stephens
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <algorithm>
#include <pwd.h>
#include <grp.h>

#include <mongo/bson/bson.h>
#include <mongo/client/gridfs.h>

#include "operations.h"
#include "utils.h"
#include "options.h"

unsigned int FH = 1;

int gridfs_open(const char *path, struct fuse_file_info *fi) {
if ((fi->flags & O_ACCMODE) != O_RDONLY)
return -EACCES;

path = fuse_to_mongo_path(path);
if (open_files.find(path) != open_files.end())
return 0;

auto sdc = make_ScopedDbConnection();
mongo::GridFS gf = get_gridfs(sdc);

mongo::GridFile file = gf.findFile(path);

if (!file.exists())
return -ENOENT;

return 0;
}

int gridfs_release(const char* path, struct fuse_file_info* ffi) {
// fh is not set if file is opened read only
// Would check ffi->flags for O_RDONLY instead but MacFuse doesn't
// seem to properly pass flags into release
if (!ffi->fh)
return 0;

path = fuse_to_mongo_path(path);
open_files.erase(path);

return 0;
}

int gridfs_create(const char* path, mode_t mode, struct fuse_file_info* ffi) {
fuse_context *context = fuse_get_context();
path = fuse_to_mongo_path(path);
open_files[path] = std::make_shared<LocalGridFile>(context->uid, context->gid, mode);

ffi->fh = FH++;

return 0;
}

int gridfs_unlink(const char* path) {
auto sdc = make_ScopedDbConnection();
mongo::GridFS gf = get_gridfs(sdc);

path = fuse_to_mongo_path(path);
gf.removeFile(path);

return 0;
}

int gridfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
path = fuse_to_mongo_path(path);
auto file_iter = open_files.find(path);
if (file_iter != open_files.end()) {
LocalGridFile::ptr lgf = file_iter->second;
return lgf->read(buf, size, offset);
}

auto sdc = make_ScopedDbConnection();
mongo::GridFS gf = get_gridfs(sdc);
mongo::GridFile file = gf.findFile(path);

if (!file.exists())
return -EBADF;

int chunk_size = file.getChunkSize();
int chunk_num = offset / chunk_size;

size_t len = 0;
while (len < size && chunk_num < file.getNumChunks()) {
mongo::GridFSChunk chunk = file.getChunk(chunk_num);
int to_read;
int cl = chunk.len();

const char *d = chunk.data(cl);

if (len) {
to_read = std::min((long unsigned)cl, (long unsigned)(size - len));
memcpy(buf + len, d, to_read);
} else {
to_read = std::min((long unsigned)(cl - (offset % chunk_size)), (long unsigned)(size - len));
memcpy(buf + len, d + (offset % chunk_size), to_read);
}

len += to_read;
chunk_num++;
}

return len;
}

int gridfs_write(const char* path, const char* buf, size_t nbyte, off_t offset, struct fuse_file_info* ffi) {
path = fuse_to_mongo_path(path);
if (open_files.find(path) == open_files.end())
return -ENOENT;

LocalGridFile::ptr lgf = open_files[path];

return lgf->write(buf, nbyte, offset);
}

int gridfs_flush(const char* path, struct fuse_file_info *ffi) {
if (!ffi->fh)
return 0;

path = fuse_to_mongo_path(path);
auto file_iter = open_files.find(path);
if (file_iter == open_files.end())
return -ENOENT;

LocalGridFile::ptr lgf = file_iter->second;

if (lgf->is_clean())
return 0;

auto sdc = make_ScopedDbConnection();
mongo::GridFS gf = get_gridfs(sdc);

if (gf.findFile(path).exists())
gf.removeFile(path);

size_t len = lgf->Length();
char *buf = new char[len];
lgf->read(buf, len, 0);

mongo::BSONObj file_obj = gf.storeFile(buf, len, path);

mongo::BSONObjBuilder b;
{
passwd *pw = getpwuid(lgf->Uid());
if (pw)
b.append("owner", pw->pw_name);
}
{
group *gr = getgrgid(lgf->Gid());
if (gr)
b.append("group", gr->gr_name);
}
b.append("mode", lgf->Mode());

sdc->conn().update(db_name() + ".files",
BSON("filename" << path),
BSON("$set" << b.obj()));

lgf->set_flushed();

return 0;
}

Loading

0 comments on commit 2642a70

Please sign in to comment.