@Override
  public FileMetadata createSymLink(
      long fileId,
      long parentId,
      String fileName,
      int atime,
      int ctime,
      int mtime,
      String userId,
      String groupId,
      String ref,
      AtomicDBUpdate update) {

    // create metadata
    BufferBackedFileMetadata fileMetadata =
        new BufferBackedFileMetadata(
            parentId,
            fileName,
            userId,
            groupId,
            fileId,
            atime,
            ctime,
            mtime,
            ref.length(),
            0777,
            0,
            (short) 1,
            0,
            0,
            false);

    // create link target (XAttr)
    BufferBackedXAttr lt =
        new BufferBackedXAttr(fileId, SYSTEM_UID, LINK_TARGET_ATTR_NAME, ref.getBytes(), (short) 0);
    update.addUpdate(XATTRS_INDEX, lt.getKeyBuf(), lt.getValBuf());

    // update main metadata in the file index
    update.addUpdate(
        FILE_INDEX, fileMetadata.getFCMetadataKey(), fileMetadata.getFCMetadataValue());
    update.addUpdate(
        FILE_INDEX, fileMetadata.getRCMetadata().getKey(), fileMetadata.getRCMetadata().getValue());

    // add an entry to the file ID index
    update.addUpdate(
        FILE_ID_INDEX,
        BabuDBStorageHelper.createFileIdIndexKey(fileId, (byte) 3),
        BabuDBStorageHelper.createFileIdIndexValue(parentId, fileName));

    return fileMetadata;
  }
  @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 FileMetadata createFile(
      long fileId,
      long parentId,
      String fileName,
      int atime,
      int ctime,
      int mtime,
      String userId,
      String groupId,
      int perms,
      long w32Attrs,
      long size,
      boolean readOnly,
      int epoch,
      int issEpoch,
      AtomicDBUpdate update)
      throws DatabaseException {

    // create metadata
    BufferBackedFileMetadata fileMetadata =
        new BufferBackedFileMetadata(
            parentId, fileName, userId, groupId, fileId, atime, ctime, mtime, size, perms, w32Attrs,
            (short) 1, epoch, issEpoch, readOnly);

    // update main metadata in the file index
    update.addUpdate(
        FILE_INDEX, fileMetadata.getFCMetadataKey(), fileMetadata.getFCMetadataValue());
    update.addUpdate(
        FILE_INDEX, fileMetadata.getRCMetadata().getKey(), fileMetadata.getRCMetadata().getValue());

    // add an entry to the file ID index
    update.addUpdate(
        FILE_ID_INDEX,
        BabuDBStorageHelper.createFileIdIndexKey(fileId, (byte) 3),
        BabuDBStorageHelper.createFileIdIndexValue(parentId, fileName));

    volume.updateVolumeSize(size, update);
    updateCount(NUM_FILES_KEY, true, update);

    return fileMetadata;
  }
  public FileMetadata createDir(
      long fileId,
      long parentId,
      String fileName,
      int atime,
      int ctime,
      int mtime,
      String userId,
      String groupId,
      int perms,
      long w32Attrs,
      boolean initCount,
      AtomicDBUpdate update)
      throws DatabaseException {

    // create metadata
    BufferBackedFileMetadata fileMetadata =
        new BufferBackedFileMetadata(
            parentId, fileName, userId, groupId, fileId, atime, ctime, mtime, perms, w32Attrs,
            (short) 1);

    // update main metadata in the file index
    update.addUpdate(
        FILE_INDEX, fileMetadata.getFCMetadataKey(), fileMetadata.getFCMetadataValue());
    update.addUpdate(
        FILE_INDEX, fileMetadata.getRCMetadata().getKey(), fileMetadata.getRCMetadata().getValue());

    // add an entry to the file ID index
    update.addUpdate(
        FILE_ID_INDEX,
        BabuDBStorageHelper.createFileIdIndexKey(fileId, (byte) 3),
        BabuDBStorageHelper.createFileIdIndexValue(parentId, fileName));

    if (initCount) initCount(NUM_DIRS_KEY, update);
    else updateCount(NUM_DIRS_KEY, true, update);

    return fileMetadata;
  }