Data structure for chunkserver lease management

- Master server maps chunkhandle to replicas, primary replica, and lease
  time.
- Will replace MasterServer.chunkhandle2locations.
Replace chunkhandle2loctions

- MasterServer.chunkhandle2locations is replaced with
  MasterServer.chhandle2locAndLease.
- MasterServer.chunkhandle2locationsAndLease is shortend to
  MasterServer.ckhandle2locAndLease.
- FindLocations RPC now also reports PrimaryLocation.
Master grant lease to chunkservers

- Master server grants lease to chunkservers on FindLocations RPC, it
  only grants a new lease if no one currently holds a lease on that
  chunk.
- Nits: Style fix, add comment, and move unexported functions after
  exported functions in master.go.
Lease extension requests with heartbeat

- Chunkservers request lease extensions whenever it services a write
  request from client. Extension requests are buffered up and
  piggybacked on heartbeat RPCs.
- Add find grained lock on chunkserver side for pending extension
  requests to avoid over-locking chunkserver, since pending extension
  locks are used for every heartbeat RPC.
- Style fix: Move all unexported functions after exported functions in
  chunkserver.go
Merge branch 'master' into chunkserver-lease
Seperate FindLocation and FindLeaseHolder RPCs

- Add FindLeaseHolder RPC handler in master.
- Remove lease holder related information in FindLocation RPC.
- Rename Client.cache to Client.locationCache.
- Add Client.leaseHolderCache for caching leaseholder information.
Add Client.findLeaseHolder function.
Implement  ChunkServer.PushData()

ChunkServer.PushData handles RPC calls from client to temporarily store
client's data in memory, will be committed to disk via subsequent write
requests.
Add client PushData RPC call

Client push data to all replicas before sending any write requests to
chunkservers. The write logic has not yet changed.
Integrate chunk server lease into write APIs

- Add return value check for Client.write since our testing
  scripts rely the return value of Client.Write to determine
  whether a write request is successful.
- Change in write logic. In addition to acquire all replica's
  location, the client RPCs master for primary replica's
  location. Then use ChunkServer.PushData RPC to transmit data to
  chunk servers' memory. Once data is pushed to all replicas, we send
  a write request to the primary replica only. The primary replica
  should take care of write requests on the chunk server side.
- Add a DataId structure. This structure is used to identify the data
  pushed to chunk server's memory using PushData RPC.
- Add test for chunk server lease.
Remove debugging code
Change chunkindex to chunIndex in client.go
Remove ClientLease related code/test
Remove ClientLease code in master.go
Function name change

ChunkServer.updateChunkServerMeta to ChunkServer.reportChunkInfo.