@Override public void setMetadata(FileMetadata metadata, byte type, AtomicDBUpdate update) throws DatabaseException { assert (metadata instanceof BufferBackedFileMetadata); BufferBackedFileMetadata md = (BufferBackedFileMetadata) metadata; int index = md.getIndexId(); if (type == -1) for (byte i = 0; i < BufferBackedFileMetadata.NUM_BUFFERS; i++) { byte[] valBuf = md.getValueBuffer(i); assert (valBuf != null); update.addUpdate( index, index == FILE_ID_INDEX ? BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), i) : md.getKeyBuffer(i), valBuf); } else { byte[] valBuf = md.getValueBuffer(type); assert (valBuf != null); update.addUpdate( index, index == FILE_ID_INDEX ? BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), type) : md.getKeyBuffer(type), valBuf); } }
@Override public void startRequest(MRCRequest rq) throws Throwable { final removexattrRequest rqArgs = (removexattrRequest) rq.getRequestArgs(); final VolumeManager vMan = master.getVolumeManager(); final FileAccessManager faMan = master.getFileAccessManager(); Path p = new Path(rqArgs.getVolumeName(), rqArgs.getPath()); validateContext(rq); StorageManager sMan = vMan.getStorageManagerByName(p.getComp(0)); PathResolver res = new PathResolver(sMan, p); // check whether the path prefix is searchable faMan.checkSearchPermission( sMan, res, rq.getDetails().userId, rq.getDetails().superUser, rq.getDetails().groupIds); // check whether file exists res.checkIfFileDoesNotExist(); // retrieve and prepare the metadata to return FileMetadata file = res.getFile(); AtomicDBUpdate update = sMan.createAtomicDBUpdate(master, rq); // if the attribute is a system attribute, set it final String attrKey = rqArgs.getName(); // set a system attribute if (attrKey.startsWith("xtreemfs.")) { // check whether the user has privileged permissions to set // system attributes faMan.checkPrivilegedPermissions( sMan, file, rq.getDetails().userId, rq.getDetails().superUser, rq.getDetails().groupIds); MRCHelper.setSysAttrValue( sMan, vMan, faMan, res.getParentDirId(), file, attrKey.substring(9), "", update); } // set a user attribute else { sMan.setXAttr(file.getId(), rq.getDetails().userId, attrKey, null, update); } // update POSIX timestamps int time = (int) (TimeSync.getGlobalTime() / 1000); MRCHelper.updateFileTimes(res.getParentDirId(), file, false, true, false, sMan, time, update); // set the response rq.setResponse(timestampResponse.newBuilder().setTimestampS(time).build()); update.execute(); }
protected static StatVFS getVolumeInfo(MRCRequestDispatcher master, StorageManager sMan) throws DatabaseException { final VolumeInfo volume = sMan.getVolumeInfo(); final FileMetadata volumeRoot = sMan.getMetadata(1); int blockSize = sMan.getDefaultStripingPolicy(1).getStripeSize() * 1024; long bavail = master.getOSDStatusManager().getUsableSpace(volume.getId()) / blockSize; long bfree = master.getOSDStatusManager().getFreeSpace(volume.getId()) / blockSize; long blocks = master.getOSDStatusManager().getTotalSpace(volume.getId()) / blockSize; String volumeId = volume.getId(); AccessControlPolicyType acPolId = AccessControlPolicyType.valueOf(volume.getAcPolicyId()); StripingPolicy.Builder defaultStripingPolicy = Converter.stripingPolicyToStripingPolicy(sMan.getDefaultStripingPolicy(1)); String volumeName = volume.getName(); String owningGroupId = volumeRoot.getOwningGroupId(); String ownerId = volumeRoot.getOwnerId(); int perms = volumeRoot.getPerms(); long newEtag = blockSize + bavail + blocks; return StatVFS.newBuilder() .setBsize(blockSize) .setBfree(bfree) .setBavail(bavail) .setBlocks(blocks) .setFsid(volumeId) .setNamemax(1024) .setOwnerUserId(ownerId) .setOwnerGroupId(owningGroupId) .setName(volumeName) .setEtag(newEtag) .setMode(perms) .setAccessControlPolicy(acPolId) .setDefaultStripingPolicy(defaultStripingPolicy) .build(); }
@Override public void link( final FileMetadata metadata, final long newParentId, final String newFileName, final AtomicDBUpdate update) { // get the link source BufferBackedFileMetadata md = (BufferBackedFileMetadata) metadata; // increment the link count short links = metadata.getLinkCount(); md.setLinkCount((short) (links + 1)); // insert the whole metadata of the original file in the file ID // index update.addUpdate( FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), FileMetadata.FC_METADATA), md.getFCMetadataValue()); update.addUpdate( FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), FileMetadata.RC_METADATA), md.getRCMetadata().getValue()); // remove the back link update.addUpdate( FILE_ID_INDEX, BabuDBStorageHelper.createFileIdIndexKey(metadata.getId(), (byte) 3), null); // if the metadata was retrieved from the FILE_INDEX and hasn't // been deleted before (i.e. links == 0), ensure that the original // file in the file index now points to the file ID index, and // remove the FC and XLoc metadata entries if (links != 0 && md.getIndexId() == FILE_INDEX) { update.addUpdate( FILE_INDEX, md.getRCMetadata().getKey(), BabuDBStorageHelper.createLinkTarget(metadata.getId())); update.addUpdate(FILE_INDEX, md.getFCMetadataKey(), null); } // create an entry for the new link to the metadata in the file // index update.addUpdate( FILE_INDEX, BabuDBStorageHelper.createFileKey(newParentId, newFileName, FileMetadata.RC_METADATA), BabuDBStorageHelper.createLinkTarget(metadata.getId())); }
@Override public void createSnapshot(String snapName, long parentId, String dirName, boolean recursive) throws DatabaseException { try { // determine the prefixes for the snapshot byte[][][] prefixes = null; FileMetadata snapDir = getMetadata(parentId, dirName); // for a full volume snapshot, simply use a 'null' prefix (full: // dirID == 1 && recursive) if (snapDir.getId() != 1 || !recursive) { // get the IDs of all files and directories contained in the // given directory; if recursive == true, include subdirectories List<FileMetadata> nestedFiles = new LinkedList<FileMetadata>(); BabuDBStorageHelper.getNestedFiles(nestedFiles, database, snapDir.getId(), recursive); List<byte[]> dirEntryPrefixes = new ArrayList<byte[]>(nestedFiles.size()); List<byte[]> filePrefixes = new ArrayList<byte[]>(nestedFiles.size()); // include the extended attributes of the volume's root // directory if it's not the snapshot directory - they are // needed to access volume-wide parameters in the snapshot, such // as the access control policy if (snapDir.getId() != 1) filePrefixes.add(ByteBuffer.wrap(new byte[8]).putLong(1).array()); // include all metadata of the snapshot (i.e. top level) dir byte[] idxKey = BabuDBStorageHelper.createFileKey(parentId, dirName, (byte) -1); byte[] fileKey = BabuDBStorageHelper.createFilePrefixKey(snapDir.getId()); dirEntryPrefixes.add(idxKey); filePrefixes.add(fileKey); // include the snapshot directory content idxKey = BabuDBStorageHelper.createFilePrefixKey(snapDir.getId()); dirEntryPrefixes.add(idxKey); // determine the key prefixes of all nested files to include and // exclude for (FileMetadata file : nestedFiles) { // create a prefix key for the nested file byte[] key = BabuDBStorageHelper.createFilePrefixKey(file.getId()); // if the nested file is a directory, ... if (file.isDirectory()) { // include the directory in the file prefixes // and the directory prefix in the dir entry prefixes filePrefixes.add(key); dirEntryPrefixes.add(key); } // if the nested file is a file, ... else filePrefixes.add(key); } byte[][] dirEntryPrefixesA = dirEntryPrefixes.toArray(new byte[dirEntryPrefixes.size()][]); byte[][] filePrefixesA = filePrefixes.toArray(new byte[filePrefixes.size()][]); Arrays.sort(dirEntryPrefixesA, DefaultByteRangeComparator.getInstance()); Arrays.sort(filePrefixesA, DefaultByteRangeComparator.getInstance()); // FILE_INDEX, XATTRS_INDEX, ACL_INDEX, FILE_ID_INDEX, // VOLUME_INDEX prefixes = new byte[][][] {dirEntryPrefixesA, filePrefixesA, filePrefixesA, filePrefixesA, null}; } // create the snapshot SnapshotConfig snap = new DefaultSnapshotConfig(snapName, ALL_INDICES, prefixes, null); snapMan.createPersistentSnapshot(database.getName(), snap); } catch (BabuDBException exc) { throw new DatabaseException(exc); } }