/** Add a snapshot. */
  Snapshot addSnapshot(int id, String name) throws SnapshotException, QuotaExceededException {
    // check snapshot quota
    final int n = getNumSnapshots();
    if (n + 1 > snapshotQuota) {
      throw new SnapshotException(
          "Failed to add snapshot: there are already "
              + n
              + " snapshot(s) and the snapshot quota is "
              + snapshotQuota);
    }
    final Snapshot s = new Snapshot(id, name, this);
    final byte[] nameBytes = s.getRoot().getLocalNameBytes();
    final int i = searchSnapshot(nameBytes);
    if (i >= 0) {
      throw new SnapshotException(
          "Failed to add snapshot: there is already a "
              + "snapshot with the same name \""
              + Snapshot.getSnapshotName(s)
              + "\".");
    }

    final DirectoryDiff d = getDiffs().addDiff(s, this);
    d.snapshotINode = s.getRoot();
    snapshotsByNames.add(-i - 1, s);

    // set modification time
    updateModificationTime(Time.now(), null, null);
    s.getRoot().setModificationTime(getModificationTime(), null, null);
    return s;
  }