/*
       * Read the aligned data in file into aligned buffer first, then copy the data
       * into the final buffer.  If the data size is bigger than maximal copy buffer
       * size, do the reading by segment (the outer while loop).  If not, do one step
       * reading.
       */
      do {
         /* Read the aligned data in file first.  Not able to handle interrupted
     * system calls and partial results like sec2 driver does because the
     * data may no longer be aligned. It's expecially true when the data in
     * data may no longer be aligned. It's especially true when the data in
     * file is smaller than ALLOC_SIZE. */
        HDmemset(copy_buf, 0, alloc_size);
                /* Calculate how much data we have to read in this iteration
                 * (including unused parts of blocks) */
                if((copy_size + copy_offset) < alloc_size)
                    read_size = ((copy_size + copy_offset - 1) / _fbsize + 1)
                            * _fbsize;
                else
                    read_size = alloc_size;
                /* Calculate how much data we have to write in this iteration
                 * (including unused parts of blocks) */
                if((copy_size + copy_offset) < alloc_size)
                    write_size = ((copy_size + copy_offset - 1) / _fbsize + 1)
                            * _fbsize;
                else
                    write_size = alloc_size;
        /*
          * Read the aligned data first if the aligned region doesn't fall
         * entirely in the range to be writen.  Not able to handle interrupted
         * entirely in the range to be written.  Not able to handle interrupted
     * system calls and partial results like sec2 driver does because the
     * data may no longer be aligned. It's expecially true when the data in
     * data may no longer be aligned. It's especially true when the data in
     * file is smaller than ALLOC_SIZE.  Only read the entire section if
                 * both ends are misaligned, otherwise only read the block on the
                 * misaligned end.
         */
        HDmemset(copy_buf, 0, _fbsize);
                if(copy_offset > 0) {
                    if((write_addr + write_size) > (addr + size)) {
                        HDassert((write_addr + write_size) - (addr + size) < _fbsize);
                        read_size = write_size;