[Bug 8177] Problems with big sparsed files

samba-bugs at samba.org samba-bugs at samba.org
Fri Oct 19 06:49:15 MDT 2012


https://bugzilla.samba.org/show_bug.cgi?id=8177

--- Comment #17 from molniev <molniev at hotmail.com> 2012-10-19 12:49:07 UTC ---
Hi.
I'am using rsync 3.0.9 on ESXi 5.0 and detect this bug (thanks Remco Hosman).
I made ​​a patch that solves the problem. This code reads the files, aligned
with the 4096 border. The size of the blocks in (4096 * 4096 * 2) bytes (I
think it will be faster, but you sacrifice memory).

Replace the file "fileio.c" function "map_ptr" (line 180-264) with the
following code:

char *map_ptr(struct map_struct *map, OFF_T offset, int32 len)
{
    OFF_T ret = 0;
    int32 read_size = 0;
    int32 n = 0;

    if (0 == len) return NULL;
    if (len < 0) { rprintf(FERROR, "invalid len passed to map_ptr: %ld\n",
(long)len); exit_cleanup(RERR_FILEIO); }

    if ( (offset >= map->p_offset) && (offset + len <= map->p_offset +
map->p_len) )
        return map->p + (offset - map->p_offset);

    map->p_offset = (offset >> 12);
    map->p_offset = (map->p_offset << 12);    
    while (map->p_len < (len + 4096) )
        map->p_len += (4096 * 4096 * 2);

    if (map->p_len > map->p_size) {
        map->p_size = map->p_len;    
        map->p = realloc_array(map->p, char, map->p_size);
        if (!map->p) out_of_memory("map_ptr");
    }

    if (map->p_fd_offset != map->p_offset) {
        ret = do_lseek(map->fd, map->p_offset, SEEK_SET);
        if (ret != map->p_offset) {
            rsyserr(FERROR, errno, "lseek returned %.0f, not %.0f",
(double)ret, (double)map->p_offset);
            exit_cleanup(RERR_FILEIO);
        }
        map->p_fd_offset = map->p_offset;
    }

    if (map->p_offset + map->p_len > map->file_size) {
        if (map->p_offset > map->file_size) {
            map->status = ENODATA;
            printf("DBG path function map_ptr error: %i\n", (int)__LINE__);
            memset(map->p + (offset - map->p_offset), 0, len);
            return (map->p + (offset - map->p_offset) );
        }
        map->p_len = map->file_size - map->p_offset;
        if (len > (map->p_len - (offset - map->p_offset) ) ) {
            map->status = ENODATA;
            printf("DBG path function map_ptr error: %i\n", (int)__LINE__);
            memset(map->p + map->p_len, 0, map->p_len - len);
        }
    }

    read_size = map->p_len;
    while (read_size > 0) {
        n = read(map->fd, map->p, read_size);
        if (n <= 0) {
            if (!map->status) map->status = n ? errno : ENODATA;
            printf("DBG path function map_ptr error: %i\n", (int)__LINE__);
            memset(map->p, 0, map->p_len);
            break;
        }
        map->p_fd_offset += n;
        read_size -= n;
    }

    return map->p + (map->p_offset - offset);
}

If you find a bug in my code - please let - I'll try to fix it.

-- 
Configure bugmail: https://bugzilla.samba.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the QA contact for the bug.


More information about the rsync mailing list