@Override
    public void addChunk(String filename, byte[] buf, int chunkNum, String fromIP, int clientRMIPort)
            throws RemoteException 
    {
    	if (hasChunk(filename, chunkNum)) {
    		System.err.println("[Error**] " + filename + "_" + chunkNum + " already exists");
    		return;
    	}

        try {
            /* write file on to local storage */
            FileIO.writeFile(buf, this.dataNodePath + filename + "_" + chunkNum);        
            System.err.println("[Error**] " + filename + "_" + chunkNum + " written to " + this.dataNodePath);
        } 
        catch (IOException e) {
            e.printStackTrace();
            System.err.println("[Error**] IO exception occuring when writing file " + filename);
            throw new RemoteException("[Error] IO exception occuring when writing file " + filename);
        }
        
        // try {
        //     /* feedback acknowledge to client (really need this?) */
        //     // TODO: should put a time limit here when trying connecting to client?
        //     System.out.println("[LOG] Connecting to client " + fromIP + "...");
        //     Registry clientRegistry = LocateRegistry.getRegistry(fromIP, clientRMIPort);        
        //     DFSClientInterface client = (DFSClientInterface) clientRegistry.lookup(this.clientServiceName);
        //     client.sendChunkReceivedACK(InetAddress.getLocalHost().getHostAddress(), filename, chunkNum);
        //     System.out.println("[LOG] Client " + fromIP + " acknowledged.");
        // }
        // catch (NotBoundException | UnknownHostException e) {
        //     e.printStackTrace();
        //     System.err.println("[Error**)] Unable to connect to client");
        //     try {
        //         /* delete the chunk that has been writen to disk */
        //         FileIO.deleteFile(dataNodePath + filename + "_" + chunkNum);
        //         System.out.println("[LOG] Removed " + filename + "_" + chunkNum + "because cannot feedback to client");
        //     }
        //     catch (IOException e1) {
        //         System.out.println("[Error**] Exception occurs when removing" + filename + "_" + chunkNum);
        //     }
        //     throw new RemoteException();
        // }
        
        /* update local file list */
        if (this.fileList.containsKey(filename)) {
            HDFSFile file = this.fileList.get(filename);
            file.addChunk(new HDFSChunk(filename, chunkNum));
        }
        else {
            HDFSFile file = new HDFSFile(filename, 0);
            file.addChunk(new HDFSChunk(filename, chunkNum));
        }

        // TODO: add replicas in other dataNodes?
        return;
    }