001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hdfs.server.datanode.fsdataset;
019
020import java.io.Closeable;
021import java.io.File;
022import java.io.IOException;
023import java.nio.channels.ClosedChannelException;
024
025import org.apache.hadoop.fs.StorageType;
026import org.apache.hadoop.hdfs.protocol.ExtendedBlock;
027
028/**
029 * This is an interface for the underlying volume.
030 */
031public interface FsVolumeSpi {
032  /**
033   * Obtain a reference object that had increased 1 reference count of the
034   * volume.
035   *
036   * It is caller's responsibility to close {@link FsVolumeReference} to decrease
037   * the reference count on the volume.
038   */
039  FsVolumeReference obtainReference() throws ClosedChannelException;
040
041  /** @return the StorageUuid of the volume */
042  String getStorageID();
043
044  /** @return a list of block pools. */
045  String[] getBlockPoolList();
046
047  /** @return the available storage space in bytes. */
048  long getAvailable() throws IOException;
049
050  /** @return the base path to the volume */
051  String getBasePath();
052
053  /** @return the path to the volume */
054  String getPath(String bpid) throws IOException;
055
056  /** @return the directory for the finalized blocks in the block pool. */
057  File getFinalizedDir(String bpid) throws IOException;
058  
059  StorageType getStorageType();
060
061  /** Returns true if the volume is NOT backed by persistent storage. */
062  boolean isTransientStorage();
063
064  /**
065   * Reserve disk space for a block (RBW or Re-replicating)
066   * so a writer does not run out of space before the block is full.
067   */
068  void reserveSpaceForReplica(long bytesToReserve);
069
070  /**
071   * Release disk space previously reserved for block opened for write.
072   */
073  void releaseReservedSpace(long bytesToRelease);
074
075  /**
076   * Release reserved memory for an RBW block written to transient storage
077   * i.e. RAM.
078   * bytesToRelease will be rounded down to the OS page size since locked
079   * memory reservation must always be a multiple of the page size.
080   */
081  void releaseLockedMemory(long bytesToRelease);
082
083  /**
084   * BlockIterator will return ExtendedBlock entries from a block pool in
085   * this volume.  The entries will be returned in sorted order.<p/>
086   *
087   * BlockIterator objects themselves do not always have internal
088   * synchronization, so they can only safely be used by a single thread at a
089   * time.<p/>
090   *
091   * Closing the iterator does not save it.  You must call save to save it.
092   */
093  interface BlockIterator extends Closeable {
094    /**
095     * Get the next block.<p/>
096     *
097     * Note that this block may be removed in between the time we list it,
098     * and the time the caller tries to use it, or it may represent a stale
099     * entry.  Callers should handle the case where the returned block no
100     * longer exists.
101     *
102     * @return               The next block, or null if there are no
103     *                         more blocks.  Null if there was an error
104     *                         determining the next block.
105     *
106     * @throws IOException   If there was an error getting the next block in
107     *                         this volume.  In this case, EOF will be set on
108     *                         the iterator.
109     */
110    ExtendedBlock nextBlock() throws IOException;
111
112    /**
113     * Returns true if we got to the end of the block pool.
114     */
115    boolean atEnd();
116
117    /**
118     * Repositions the iterator at the beginning of the block pool.
119     */
120    void rewind();
121
122    /**
123     * Save this block iterator to the underlying volume.
124     * Any existing saved block iterator with this name will be overwritten.
125     * maxStalenessMs will not be saved.
126     *
127     * @throws IOException   If there was an error when saving the block
128     *                         iterator.
129     */
130    void save() throws IOException;
131
132    /**
133     * Set the maximum staleness of entries that we will return.<p/>
134     *
135     * A maximum staleness of 0 means we will never return stale entries; a
136     * larger value will allow us to reduce resource consumption in exchange
137     * for returning more potentially stale entries.  Even with staleness set
138     * to 0, consumers of this API must handle race conditions where block
139     * disappear before they can be processed.
140     */
141    void setMaxStalenessMs(long maxStalenessMs);
142
143    /**
144     * Get the wall-clock time, measured in milliseconds since the Epoch,
145     * when this iterator was created.
146     */
147    long getIterStartMs();
148
149    /**
150     * Get the wall-clock time, measured in milliseconds since the Epoch,
151     * when this iterator was last saved.  Returns iterStartMs if the
152     * iterator was never saved.
153     */
154    long getLastSavedMs();
155
156    /**
157     * Get the id of the block pool which this iterator traverses.
158     */
159    String getBlockPoolId();
160  }
161
162  /**
163   * Create a new block iterator.  It will start at the beginning of the
164   * block set.
165   *
166   * @param bpid             The block pool id to iterate over.
167   * @param name             The name of the block iterator to create.
168   *
169   * @return                 The new block iterator.
170   */
171  BlockIterator newBlockIterator(String bpid, String name);
172
173  /**
174   * Load a saved block iterator.
175   *
176   * @param bpid             The block pool id to iterate over.
177   * @param name             The name of the block iterator to load.
178   *
179   * @return                 The saved block iterator.
180   * @throws IOException     If there was an IO error loading the saved
181   *                           block iterator.
182   */
183  BlockIterator loadBlockIterator(String bpid, String name) throws IOException;
184
185  /**
186   * Get the FSDatasetSpi which this volume is a part of.
187   */
188  FsDatasetSpi getDataset();
189
190  /**
191   * Load last partial chunk checksum from checksum file.
192   * Need to be called with FsDataset lock acquired.
193   * @param blockFile
194   * @param metaFile
195   * @return the last partial checksum
196   * @throws IOException
197   */
198  byte[] loadLastPartialChunkChecksum(File blockFile, File metaFile)
199      throws IOException;
200}