int gridfs_getattr(const char *path, struct stat *stbuf) { int res = 0; memset(stbuf, 0, sizeof(struct stat)); if(strcmp(path, "/") == 0) { stbuf->st_mode = S_IFDIR | 0777; stbuf->st_nlink = 2; return 0; } path = fuse_to_mongo_path(path); map<string,LocalGridFile*>::const_iterator file_iter; file_iter = open_files.find(path); if(file_iter != open_files.end()) { stbuf->st_mode = S_IFREG | 0555; stbuf->st_nlink = 1; stbuf->st_ctime = time(NULL); stbuf->st_mtime = time(NULL); stbuf->st_size = file_iter->second->getLength(); return 0; } // HACK: This is a protective measure to ensure we don't spin off into forever if a path without a period is requested. if(path_depth(path) > 10) { return -ENOENT; } // HACK: Assumes that if the last part of the path has a '.' in it, it's the leaf of the path, and if we haven't found a match by now, // give up and go home. This works just dandy as long as you avoid putting periods in your 'directory' names. /*if(!is_leaf(path)) { stbuf->st_mode = S_IFDIR | 0777; stbuf->st_nlink = 2; return 0; }*/ ScopedDbConnection sdc(*gridfs_options.conn_string); ScopedDbConnection_init(sdc); GridFS gf(sdc.conn(), gridfs_options.db, gridfs_options.prefix); GridFile file = gf.findFile(path); sdc.done(); if(!file.exists()) { return -ENOENT; } stbuf->st_mode = S_IFREG | 0555; stbuf->st_nlink = 1; stbuf->st_size = file.getContentLength(); time_t upload_time = mongo_time_to_unix_time(file.getUploadDate()); stbuf->st_ctime = upload_time; stbuf->st_mtime = upload_time; return 0; }
/* * date = gridfile:upload_date() */ static int gridfile_upload_date(lua_State *L) { GridFile *gridfile = userdata_to_gridfile(L, 1); Date_t upload_date = gridfile->getUploadDate(); push_bsontype_table(L, mongo::Date); lua_pushnumber(L, upload_date); lua_rawseti(L, -2, 1); return 1; }
int LocalMemoryGridFile::flush() { trace() << " -> LocalMemoryGridFile::flush {file: " << _filename << "}" << endl; if (!_dirty) { // Since, there are no dirty chunks, this does not need a flush info() << "buffers are not dirty.. need not flush {filename: " << _filename << "}" << endl; return 0; } size_t bufferLen = 0; boost::shared_array<char> buffer = createFlushBuffer(bufferLen); if (!buffer.get() && bufferLen > 0) { // Failed to create flush buffer return -ENOMEM; } // Get the existing gridfile from GridFS to get metadata and delete the // file from the system try { ScopedDbConnection dbc(globalFSOptions._connectString); GridFS gridFS(dbc.conn(), globalFSOptions._db, globalFSOptions._collPrefix); GridFile origGridFile = gridFS.findFile(BSON("filename" << _filename)); if (!origGridFile.exists()) { dbc.done(); warn() << "Requested file not found for flushing back data {file: " << _filename << "}" << endl; return -EBADF; } //TODO: Make checks for appropriate object correctness //i.e. do not update anything that is not a Regular File //Check what happens in case of a link gridFS.removeFile(_filename); trace() << "Removing the current file from GridFS {file: " << _filename << "}" << endl; //TODO: Check for remove status if that was successfull or not //TODO: Rather have an update along with active / passive flag for the //file try { GridFS gridFS(dbc.conn(), globalFSOptions._db, globalFSOptions._collPrefix); // Create an empty file to signify the file creation and open a local file for the same trace() << "Adding new file to GridFS {file: " << _filename << "}" << endl; BSONObj fileObj = gridFS.storeFile(buffer.get(), bufferLen, _filename); if (!fileObj.isValid()) { warn() << "Failed to save file object in data flush {file: " << _filename << "}" << std::endl; dbc.done(); return -EBADF; } // Update the last updated date for the document BSONObj metadata = origGridFile.getMetadata(); BSONElement fileObjId = fileObj.getField("_id"); dbc->update(globalFSOptions._filesNS, BSON("_id" << fileObjId.OID()), BSON("$set" << BSON( "uploadDate" << origGridFile.getUploadDate() << "metadata.type" << "file" << "metadata.filename" << mgridfs::getPathBasename(_filename) << "metadata.directory" << mgridfs::getPathDirname(_filename) << "metadata.lastUpdated" << jsTime() << "metadata.uid" << metadata["uid"] << "metadata.gid" << metadata["gid"] << "metadata.mode" << metadata["mode"] ) ) ); } catch (DBException& e) { error() << "Caught exception in saving remote file in flush {code: " << e.getCode() << ", what: " << e.what() << ", exception: " << e.toString() << "}" << endl; return -EIO; } dbc.done(); } catch (DBException& e) { // Something failed in getting the file from GridFS error() << "Caught exception in getting remote file for flush {code: " << e.getCode() << ", what: " << e.what() << ", exception: " << e.toString() << "}" << endl; return -EIO; } _dirty = false; debug() << "Completed flushing the file content to GridFS {file: " << _filename << "}" << endl; return 0; }