Revision 4a1d5e1f

b/block.c
1147 1147
}
1148 1148

  
1149 1149
/**
1150
 * Length of a allocated file in bytes. Sparse files are counted by actual
1151
 * allocated space. Return < 0 if error or unknown.
1152
 */
1153
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs)
1154
{
1155
    BlockDriver *drv = bs->drv;
1156
    if (!drv) {
1157
        return -ENOMEDIUM;
1158
    }
1159
    if (drv->bdrv_get_allocated_file_size) {
1160
        return drv->bdrv_get_allocated_file_size(bs);
1161
    }
1162
    if (bs->file) {
1163
        return bdrv_get_allocated_file_size(bs->file);
1164
    }
1165
    return -ENOTSUP;
1166
}
1167

  
1168
/**
1150 1169
 * Length of a file in bytes. Return < 0 if error or unknown.
1151 1170
 */
1152 1171
int64_t bdrv_getlength(BlockDriverState *bs)
b/block.h
89 89
    const uint8_t *buf, int nb_sectors);
90 90
int bdrv_truncate(BlockDriverState *bs, int64_t offset);
91 91
int64_t bdrv_getlength(BlockDriverState *bs);
92
int64_t bdrv_get_allocated_file_size(BlockDriverState *bs);
92 93
void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr);
93 94
void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs);
94 95
int bdrv_commit(BlockDriverState *bs);
b/block/raw-posix.c
793 793
}
794 794
#endif
795 795

  
796
static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
797
{
798
    struct stat st;
799
    BDRVRawState *s = bs->opaque;
800

  
801
    if (fstat(s->fd, &st) < 0) {
802
        return -errno;
803
    }
804
    return (int64_t)st.st_blocks * 512;
805
}
806

  
796 807
static int raw_create(const char *filename, QEMUOptionParameter *options)
797 808
{
798 809
    int fd;
......
888 899

  
889 900
    .bdrv_truncate = raw_truncate,
890 901
    .bdrv_getlength = raw_getlength,
902
    .bdrv_get_allocated_file_size
903
                        = raw_get_allocated_file_size,
891 904

  
892 905
    .create_options = raw_create_options,
893 906
};
......
1156 1169
    .bdrv_read          = raw_read,
1157 1170
    .bdrv_write         = raw_write,
1158 1171
    .bdrv_getlength	= raw_getlength,
1172
    .bdrv_get_allocated_file_size
1173
                        = raw_get_allocated_file_size,
1159 1174

  
1160 1175
    /* generic scsi device */
1161 1176
#ifdef __linux__
......
1277 1292
    .bdrv_read          = raw_read,
1278 1293
    .bdrv_write         = raw_write,
1279 1294
    .bdrv_getlength	= raw_getlength,
1295
    .bdrv_get_allocated_file_size
1296
                        = raw_get_allocated_file_size,
1280 1297

  
1281 1298
    /* removable device support */
1282 1299
    .bdrv_is_inserted   = floppy_is_inserted,
......
1380 1397
    .bdrv_read          = raw_read,
1381 1398
    .bdrv_write         = raw_write,
1382 1399
    .bdrv_getlength     = raw_getlength,
1400
    .bdrv_get_allocated_file_size
1401
                        = raw_get_allocated_file_size,
1383 1402

  
1384 1403
    /* removable device support */
1385 1404
    .bdrv_is_inserted   = cdrom_is_inserted,
......
1503 1522
    .bdrv_read          = raw_read,
1504 1523
    .bdrv_write         = raw_write,
1505 1524
    .bdrv_getlength     = raw_getlength,
1525
    .bdrv_get_allocated_file_size
1526
                        = raw_get_allocated_file_size,
1506 1527

  
1507 1528
    /* removable device support */
1508 1529
    .bdrv_is_inserted   = cdrom_is_inserted,
b/block/raw-win32.c
213 213
    return l.QuadPart;
214 214
}
215 215

  
216
static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
217
{
218
    typedef DWORD (WINAPI * get_compressed_t)(const char *filename,
219
                                              DWORD * high);
220
    get_compressed_t get_compressed;
221
    struct _stati64 st;
222
    const char *filename = bs->filename;
223
    /* WinNT support GetCompressedFileSize to determine allocate size */
224
    get_compressed =
225
        (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"),
226
                                            "GetCompressedFileSizeA");
227
    if (get_compressed) {
228
        DWORD high, low;
229
        low = get_compressed(filename, &high);
230
        if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR) {
231
            return (((int64_t) high) << 32) + low;
232
        }
233
    }
234

  
235
    if (_stati64(filename, &st) < 0) {
236
        return -1;
237
    }
238
    return st.st_size;
239
}
240

  
216 241
static int raw_create(const char *filename, QEMUOptionParameter *options)
217 242
{
218 243
    int fd;
......
257 282
    .bdrv_write		= raw_write,
258 283
    .bdrv_truncate	= raw_truncate,
259 284
    .bdrv_getlength	= raw_getlength,
285
    .bdrv_get_allocated_file_size
286
                        = raw_get_allocated_file_size,
260 287

  
261 288
    .create_options = raw_create_options,
262 289
};
......
419 446
    .bdrv_read		= raw_read,
420 447
    .bdrv_write	        = raw_write,
421 448
    .bdrv_getlength	= raw_getlength,
449
    .bdrv_get_allocated_file_size
450
                        = raw_get_allocated_file_size,
422 451
};
423 452

  
424 453
static void bdrv_file_init(void)
b/block/vmdk.c
1289 1289
    return ret;
1290 1290
}
1291 1291

  
1292
static int64_t vmdk_get_allocated_file_size(BlockDriverState *bs)
1293
{
1294
    int i;
1295
    int64_t ret = 0;
1296
    int64_t r;
1297
    BDRVVmdkState *s = bs->opaque;
1298

  
1299
    ret = bdrv_get_allocated_file_size(bs->file);
1300
    if (ret < 0) {
1301
        return ret;
1302
    }
1303
    for (i = 0; i < s->num_extents; i++) {
1304
        if (s->extents[i].file == bs->file) {
1305
            continue;
1306
        }
1307
        r = bdrv_get_allocated_file_size(s->extents[i].file);
1308
        if (r < 0) {
1309
            return r;
1310
        }
1311
        ret += r;
1312
    }
1313
    return ret;
1314
}
1292 1315

  
1293 1316
static QEMUOptionParameter vmdk_create_options[] = {
1294 1317
    {
......
1327 1350
    .bdrv_create    = vmdk_create,
1328 1351
    .bdrv_flush     = vmdk_flush,
1329 1352
    .bdrv_is_allocated  = vmdk_is_allocated,
1353
    .bdrv_get_allocated_file_size  = vmdk_get_allocated_file_size,
1330 1354

  
1331 1355
    .create_options = vmdk_create_options,
1332 1356
};
b/block_int.h
86 86
    const char *protocol_name;
87 87
    int (*bdrv_truncate)(BlockDriverState *bs, int64_t offset);
88 88
    int64_t (*bdrv_getlength)(BlockDriverState *bs);
89
    int64_t (*bdrv_get_allocated_file_size)(BlockDriverState *bs);
89 90
    int (*bdrv_write_compressed)(BlockDriverState *bs, int64_t sector_num,
90 91
                                 const uint8_t *buf, int nb_sectors);
91 92

  
b/qemu-img.c
1024 1024
    return 0;
1025 1025
}
1026 1026

  
1027
#ifdef _WIN32
1028
static int64_t get_allocated_file_size(const char *filename)
1029
{
1030
    typedef DWORD (WINAPI * get_compressed_t)(const char *filename, DWORD *high);
1031
    get_compressed_t get_compressed;
1032
    struct _stati64 st;
1033

  
1034
    /* WinNT support GetCompressedFileSize to determine allocate size */
1035
    get_compressed = (get_compressed_t) GetProcAddress(GetModuleHandle("kernel32"), "GetCompressedFileSizeA");
1036
    if (get_compressed) {
1037
    	DWORD high, low;
1038
    	low = get_compressed(filename, &high);
1039
    	if (low != 0xFFFFFFFFlu || GetLastError() == NO_ERROR)
1040
	    return (((int64_t) high) << 32) + low;
1041
    }
1042

  
1043
    if (_stati64(filename, &st) < 0)
1044
        return -1;
1045
    return st.st_size;
1046
}
1047
#else
1048
static int64_t get_allocated_file_size(const char *filename)
1049
{
1050
    struct stat st;
1051
    if (stat(filename, &st) < 0)
1052
        return -1;
1053
    return (int64_t)st.st_blocks * 512;
1054
}
1055
#endif
1056 1027

  
1057 1028
static void dump_snapshots(BlockDriverState *bs)
1058 1029
{
......
1112 1083
    bdrv_get_format(bs, fmt_name, sizeof(fmt_name));
1113 1084
    bdrv_get_geometry(bs, &total_sectors);
1114 1085
    get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512);
1115
    allocated_size = get_allocated_file_size(filename);
1086
    allocated_size = bdrv_get_allocated_file_size(bs);
1116 1087
    if (allocated_size < 0) {
1117 1088
        snprintf(dsize_buf, sizeof(dsize_buf), "unavailable");
1118 1089
    } else {

Also available in: Unified diff