Example #1
0
	void file::close()
	{
		if (!is_open()) return;

#ifdef TORRENT_WINDOWS

		// if this file is open for writing, has the sparse
		// flag set, but there are no sparse regions, unset
		// the flag
		open_mode_t const rw_mode = m_open_mode & open_mode::rw_mask;
		if ((rw_mode != open_mode::read_only)
			&& (m_open_mode & open_mode::sparse)
			&& !is_sparse(native_handle()))
		{
			overlapped_t ol;
			// according to MSDN, clearing the sparse flag of a file only
			// works on windows vista and later
#ifdef TORRENT_MINGW
			typedef struct _FILE_SET_SPARSE_BUFFER {
				BOOLEAN SetSparse;
			} FILE_SET_SPARSE_BUFFER;
#endif
			DWORD temp;
			FILE_SET_SPARSE_BUFFER b;
			b.SetSparse = FALSE;
			BOOL ret = ::DeviceIoControl(native_handle(), FSCTL_SET_SPARSE, &b, sizeof(b)
				, 0, 0, &temp, &ol.ol);
			error_code ec;
			if (ret == FALSE && GetLastError() == ERROR_IO_PENDING)
			{
				ol.wait(native_handle(), ec);
			}
		}

		CloseHandle(native_handle());
#else
		if (m_file_handle != INVALID_HANDLE_VALUE)
			::close(m_file_handle);
#endif

		m_file_handle = INVALID_HANDLE_VALUE;

		m_open_mode = open_mode_t{};
	}
Example #2
0
static int write_direct_mapping(struct defrag_ctx *c, struct data_extent *e)
{
	struct inode *inode = c->inodes[e->inode_nr];
	__u32 cur_block = e->start_block;
	__u32 cur_logical = e->start_logical;
	__u32 new_block;
	int sync_inode = 0;

	/* Direct blocks */
	for (cur_logical = e->start_logical;
	     cur_logical < EXT2_IND_LBLOCK(&c->sb) && cur_block <= e->end_block;
	     cur_logical++) {
		if (!is_sparse(inode, cur_logical))
			new_block = cur_block++;
		else
			new_block = 0;
		if (inode->on_disk->i_block[cur_logical] != new_block) {
			inode->on_disk->i_block[cur_logical] = new_block;
			sync_inode = 1;
		}
	}
	if (cur_block > e->end_block)
		goto out;

	/* Singly indirect blocks */
	if (cur_logical == EXT2_IND_LBLOCK(&c->sb)) {
		if (is_sparse(inode, cur_logical))
			new_block = 0;
		else
			new_block = cur_block++;
		cur_logical++;
	} else {
		new_block = inode->on_disk->i_block[EXT2_IND_BLOCK];
	}
	if (cur_logical > EXT2_IND_LBLOCK(&c->sb)
	    && cur_logical < EXT2_DIND_LBLOCK(&c->sb)) {
		write_ind_metadata(c, e, new_block, &cur_logical, &cur_block);
	}
	if (inode->on_disk->i_block[EXT2_IND_BLOCK] != new_block) {
		inode->on_disk->i_block[EXT2_IND_BLOCK] = new_block;
		sync_inode = 1;
	}
	if (cur_block > e->end_block)
		goto out;

	/* Doubly indirect blocks */
	if (cur_logical == EXT2_DIND_LBLOCK(&c->sb)) {
		if (is_sparse(inode, cur_logical) || cur_block > e->end_block)
			new_block = 0;
		else
			new_block = cur_block++;
		cur_logical++;
	} else {
		new_block = inode->on_disk->i_block[EXT2_DIND_BLOCK];
	}
	if (cur_logical > EXT2_DIND_LBLOCK(&c->sb)
	    && cur_logical < EXT2_TIND_LBLOCK(&c->sb)) {
		write_dind_metadata(c, e, new_block, &cur_logical, &cur_block);
	}
	if (inode->on_disk->i_block[EXT2_DIND_BLOCK] != new_block) {
		inode->on_disk->i_block[EXT2_DIND_BLOCK] = new_block;
		sync_inode = 1;
	}
	if (cur_block > e->end_block)
		goto out;

	/* Triply indirect blocks */
	if (cur_logical == EXT2_TIND_LBLOCK(&c->sb)) {
		if (is_sparse(inode, cur_logical) || cur_block > e->end_block)
			new_block = 0;
		else
			new_block = cur_block++;
		cur_logical++;
	} else {
		new_block = inode->on_disk->i_block[EXT2_TIND_BLOCK];
	}
	if (cur_logical > EXT2_TIND_LBLOCK(&c->sb)) {
		write_tind_metadata(c, e, new_block, &cur_logical, &cur_block);
	}
	if (inode->on_disk->i_block[EXT2_TIND_BLOCK] != new_block) {
		inode->on_disk->i_block[EXT2_TIND_BLOCK] = new_block;
		sync_inode = 1;
	}

out:
	if (sync_inode)
		/* Assumes the inode is completely within one page */
		return msync(PAGE_START(inode->on_disk),getpagesize(), MS_SYNC);
	return 0;
}
Example #3
0
static int write_tind_metadata(struct defrag_ctx *c, struct data_extent *e,
                              __u32 tind_block, __u32 *cur_logical,
                              __u32 *cur_block)
{
	struct inode *inode = c->inodes[e->inode_nr];
	__u32 offset = *cur_logical;
	__u32 ind_blocks = EXT2_ADDR_PER_BLOCK(&c->sb);
	__u32 blocks_per_ind = 1 + ind_blocks;
	__u32 blocks_per_dind = 1 + ind_blocks * blocks_per_ind;
	__u32 blocks_per_tind = 1 + ind_blocks * blocks_per_dind;
	__u32 buffer[EXT2_ADDR_PER_BLOCK(&c->sb)];
	int ret;
	char to_sync = 0;

	if (tind_block == 0) {
		*cur_logical += blocks_per_tind;
		return 0;
	}
	ret = read_block(c, buffer, tind_block);
	if (ret)
		return -1;
	offset -= EXT2_TIND_LBLOCK(&c->sb) + 1;
	offset = offset % blocks_per_tind;
	if (offset % blocks_per_dind) {
		offset = offset / blocks_per_dind;
		ret = write_dind_metadata(c, e, buffer[offset], cur_logical,
		                         cur_block);
		if (ret)
			return ret;
		offset++;
	} else {
		offset = offset / blocks_per_dind;
	}
	while (offset < EXT2_ADDR_PER_BLOCK(&c->sb)
	                                        && *cur_block <= e->end_block) {
		__u32 new_block;
		if (is_sparse(inode, *cur_logical))
			new_block = 0;
		else
			new_block = (*cur_block)++;
		(*cur_logical)++;
		if (new_block) {
			ret = write_dind_metadata(c, e, new_block,
			                          cur_logical, cur_block);
			if (ret)
				return ret;
		} else {
			*cur_logical += blocks_per_dind - 1;
		}
		if (buffer[offset] != new_block) {
			to_sync = 1;
			buffer[offset] = new_block;
		}
		offset++;
	}
	if (to_sync) {
		ret = write_block(c, buffer, tind_block);
		return ret;
	}
	return 0;
}
Example #4
0
/*-------------------------------------------------------------------------
 * Function:	main
 *
 * Purpose:	Tests indexed storage stuff.
 *
 * Return:	Success:	exit(0)
 *
 *		Failure:	exit(non-zero)
 *
 * Programmer:	Robb Matzke
 *		Wednesday, October 15, 1997
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
int
main(int argc, char *argv[])
{
    hid_t		fapl=-1, file=-1, fcpl=-1;
    herr_t		status;
    int			nerrors = 0;
    unsigned		size_of_test;
    unsigned            u;              /* Local index variable */
    char		filename[1024];
    int                 skip_test = 0;
    int                 has_sparse_support = 0;

    /* Parse arguments or assume these tests (`small', `medium' ) */
    if (1 == argc) {
        size_of_test = TEST_SMALL | TEST_MEDIUM | TEST_LARGE;
    } else {
        int			i;
        for (i = 1, size_of_test = 0; i < argc; i++) {
            if (!strcmp(argv[i], "small")) {
                size_of_test |= TEST_SMALL;
            } else if (!strcmp(argv[i], "medium")) {
                size_of_test |= TEST_MEDIUM;
            } else if (!strcmp(argv[i], "large")) {
                size_of_test |= TEST_LARGE;
            } else {
                printf("unrecognized argument: %s\n", argv[i]);
#if 0
                exit(1);
#endif
            }
        }
    }
    printf("Test sizes: ");
    if (size_of_test & TEST_SMALL)
        printf(" SMALL");
    if (size_of_test & TEST_MEDIUM)
        printf(" MEDIUM");
    if (size_of_test & TEST_LARGE)
        printf(" LARGE");
    printf("\n");

    /* Set the random # seed */
    HDsrandom((unsigned)HDtime(NULL));

    /* Check to see if the file system supports POSIX-style sparse files.
     * Windows NTFS does not, so we want to avoid tests which create
     * very large files.
     */
    has_sparse_support = is_sparse();

    /* Reset library */
    h5_reset();
    fapl = h5_fileaccess();

    /* Use larger file addresses... */
    fcpl = H5Pcreate(H5P_FILE_CREATE);
    H5Pset_sizes(fcpl, (size_t)8, (size_t)0);

    /* Create the test file */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
    if ((file=H5Fcreate(filename, H5F_ACC_TRUNC, fcpl, fapl)) < 0) {
        printf("Cannot create file %s; test aborted\n", filename);
        exit(1);
    }

    /* Initialize chunk dimensions */
    for(u = 0; u < H5O_LAYOUT_NDIMS; u++)
        chunk_dims[u] = TEST_CHUNK_SIZE;

    /*
        * Creation test: Creates empty objects with various raw data sizes
        * and alignments.
        */
    status = test_create(file, "create");
    nerrors += status < 0 ? 1 : 0;

    if (size_of_test & TEST_SMALL) {
        status = test_extend(file, "extend", (size_t)10, (size_t)0, (size_t)0);
        nerrors += status < 0 ? 1 : 0;
        status = test_extend(file, "extend", (size_t)10, (size_t)10, (size_t)0);
        nerrors += status < 0 ? 1 : 0;
        status = test_extend(file, "extend", (size_t)10, (size_t)10, (size_t)10);
        nerrors += status < 0 ? 1 : 0;
    }
    if (size_of_test & TEST_MEDIUM) {
        status = test_extend(file, "extend", (size_t)10000, (size_t)0, (size_t)0);
        nerrors += status < 0 ? 1 : 0;
        status = test_extend(file, "extend", (size_t)2500, (size_t)10, (size_t)0);
        nerrors += status < 0 ? 1 : 0;
        status = test_extend(file, "extend", (size_t)10, (size_t)400, (size_t)10);
        nerrors += status < 0 ? 1 : 0;
    }
    skip_test = 0;
    if (size_of_test & TEST_SMALL) {
        status = test_sparse(file, "sparse", (size_t)100, (size_t)5, (size_t)0, (size_t)0, skip_test);
        nerrors += status < 0 ? 1 : 0;
        status = test_sparse(file, "sparse", (size_t)100, (size_t)3, (size_t)4, (size_t)0, skip_test);
        nerrors += status < 0 ? 1 : 0;
        status = test_sparse(file, "sparse", (size_t)100, (size_t)2, (size_t)3, (size_t)4, skip_test);
        nerrors += status < 0 ? 1 : 0;
    }
    if (size_of_test & TEST_MEDIUM) {
        status = test_sparse(file, "sparse", (size_t)1000, (size_t)30, (size_t)0, (size_t)0, skip_test);
        nerrors += status < 0 ? 1 : 0;
        status = test_sparse(file, "sparse", (size_t)2000, (size_t)7, (size_t)3, (size_t)0, skip_test);
        nerrors += status < 0 ? 1 : 0;
        status = test_sparse(file, "sparse", (size_t)2000, (size_t)4, (size_t)2, (size_t)3, skip_test);
        nerrors += status < 0 ? 1 : 0;
    }
    skip_test = !has_sparse_support;
    if (size_of_test & TEST_LARGE) {
        /* This test is skipped if there is no POSIX-style sparse file support
         * e.g.: Windows NTFS filesystems
         */
        status = test_sparse(file, "sparse", (size_t)800, (size_t)50, (size_t)50, (size_t)50, skip_test);
        if(skip_test)
            printf("    The current VFD does not support sparse files on this platform.\n");
        nerrors += status < 0 ? 1 : 0;
    }

    /* Close the test file and exit */
    H5Pclose(fcpl);
    H5Fclose(file);

    /* Verify symbol table messages are cached */
    nerrors += (h5_verify_cached_stabs(FILENAME, fapl) < 0 ? 1 : 0);

    if (nerrors) {
        printf("***** %d I-STORE TEST%s FAILED! *****\n",
                nerrors, 1 == nerrors ? "" : "S");
        exit(1);
    }

    printf("All i-store tests passed.\n");

    h5_cleanup(FILENAME, fapl);

    return 0;
}
/*-------------------------------------------------------------------------
 * Function:	main
 *
 * Purpose:
 *
 * Return:	Success:
 *
 *		Failure:
 *
 * Programmer:	Robb Matzke
 *              Friday, April 10, 1998
 *
 * Modifications:
 *		Albert Cheng, 2002/03/28
 *		Added command option -fsize.
 *		Albert Cheng, 2002/04/19
 *		Added command option -c.
 *
 *              Raymond Lu, 2007/05/25
 *              Added similar tests for SEC2 and STDIO drivers.
 *
 *-------------------------------------------------------------------------
 */
int
main (int ac, char **av)
{
    unsigned long seed = 0;             /* Random # seed */
    hid_t fapl = -1;
    hid_t driver = -1;

    /* parameters setup */

    while (--ac > 0){
        av++;
        if (HDstrcmp("-fsize", *av)==0){
            /* specify a different family file size */
            ac--; av++;
            if (ac > 0) {
                family_size_def = (hsize_t)HDstrtoull(*av, NULL, 0);
            }
            else{
                printf("***Missing fsize value***\n");
                usage();
                return 1;
            }
        }
        else if (HDstrcmp("-c", *av)==0){
            /* turn off file system check before test */
            cflag=0;
        }
        else if (HDstrcmp("-h", *av)==0){
            usage();
            return 0;
        }else{
            usage();
            return 1;
        }
    }

    /* check VFD to see if this is one we test */
    if((fapl = h5_fileaccess()) < 0)
        goto error;
    if((driver = H5Pget_driver(fapl)) < 0)
        goto error;

    /* check sparse file support unless cflag is not set. */
    if(cflag)
        sparse_support = is_sparse();

    /* Choose random # seed */
    seed = (unsigned long)HDtime(NULL);
#ifdef QAK
    /* seed = (unsigned long)1155438845; */
    HDfprintf(stderr, "Random # seed was: %lu\n", seed);
#endif /* QAK */
    HDsrandom(seed);

    /* run VFD-specific test */
    if(H5FD_SEC2 == driver) {
        if(test_sec2(fapl) != 0)
            goto error;
    }
    else if(H5FD_STDIO == driver) {
        if(test_stdio(fapl) != 0)
            goto error;
    }
    else if(H5FD_FAMILY == driver) {
        if(test_family(fapl) != 0)
            goto error;
    }
    else
        HDputs("This VFD is not supported");

    /* End with normal exit code */
    /* fapls are cleaned up in the vfd test code */
    return 0;

error:
    HDputs("*** TEST FAILED ***");
    if(fapl > 0)
        H5Pclose(fapl);
    return 1;
}
Example #6
0
/*-------------------------------------------------------------------------
 * Function:	main
 *
 * Purpose:
 *
 * Return:	Success:
 *
 *		Failure:
 *
 * Programmer:	Robb Matzke
 *              Friday, April 10, 1998
 *
 * Modifications:
 *		Albert Cheng, 2002/03/28
 *		Added command option -fsize.
 *		Albert Cheng, 2002/04/19
 *		Added command option -c.
 *
 *-------------------------------------------------------------------------
 */
int
main (int ac, char **av)
{
    hid_t	fapl=-1;
    hsize_t	family_size;
    hsize_t	family_size_def;	/* default family file size */
    double	family_size_def_dbl;	/* default family file size */
    int		cflag=1;		/* check file system before test */
    char	filename[1024];

    /* parameters setup */
    family_size_def = FAMILY_SIZE;

    while (--ac > 0){
	av++;
	if (strcmp("-fsize", *av)==0){
	    /* specify a different family file size */
	    ac--; av++;
	    if (ac > 0){
		family_size_def_dbl = atof(*av);
                H5_ASSIGN_OVERFLOW(family_size_def,family_size_def_dbl,double,hsize_t);
		if (family_size_def <= 0)
		    family_size_def = (hsize_t)FAMILY_SIZE;
	    }
	    else{
		printf("***Missing fsize value***\n");
		usage();
		return 1;
	    }
	}
	else if (strcmp("-c", *av)==0){
	    /* turn off file system check before test */
	    cflag=0;
	}
	else if (strcmp("-h", *av)==0){
	    usage();
	    return 0;
	}else{
	    usage();
	    return 1;
	}
    }

    /* Reset library */
    h5_reset();
    fapl = h5_fileaccess();

    /* Test big file with the family driver */
    puts("Testing big file with the Family Driver ");
    if (H5FD_FAMILY!=H5Pget_driver(fapl)) {
	HDfprintf(stdout,
	   "Changing file drivers to the family driver, %Hu bytes each\n",
	   family_size_def);
	if (H5Pset_fapl_family(fapl, family_size_def, H5P_DEFAULT)<0) goto error;
    } else if (H5Pget_fapl_family(fapl, &family_size, NULL)<0) {
	goto error;
    } else if (family_size!=family_size_def) {
	HDfprintf(stdout, "Changing family member size from %Hu to %Hu\n",
	       family_size, family_size_def);
	if (H5Pset_fapl_family(fapl, family_size_def, H5P_DEFAULT)<0)
	    goto error;
    }

    if (cflag){
	/*
	 * We shouldn't run this test if the file system doesn't support holes
	 * because we would generate multi-gigabyte files.
	 */
	puts("Checking if file system is adequate for this test...");
	if (sizeof(long_long)<8 || 0==GB8LL) {
	    puts("Test skipped because sizeof(long_long) is too small. This");
	    puts("hardware apparently doesn't support 64-bit integer types.");
	    usage();
	    goto quit;
	}
	if (!is_sparse()) {
	    puts("Test skipped because file system does not support holes.");
	    usage();
	    goto quit;
	}
	if (!enough_room(fapl)) {
	    puts("Test skipped because of quota (file size or num open files).");
	    usage();
	    goto quit;
	}
	if (sizeof(hsize_t)<=4) {
	    puts("Test skipped because the hdf5 library was configured with the");
	    puts("--disable-hsizet flag in order to work around a compiler bug.");
	    usage();
	    goto quit;
	}
    }

    /* Do the test with the Family Driver */
    h5_fixname(FILENAME[0], fapl, filename, sizeof filename);

    if (writer(filename, fapl, WRT_N)) goto error;
    if (reader(filename, fapl)) goto error;

    puts("Test passed with the Family Driver.");

    /*
     * We shouldn't run this test if the file system doesn't support big files 
     * because we would generate multi-gigabyte files.
     */
    puts("\nChecking if file system supports big files...");
    if (!supports_big()) {
        puts("Tests for sec2 and stdio are skipped because file system does not support big files.");
        usage();
        goto quit;
    }

    /* Clean up the test file */
    if (h5_cleanup(FILENAME, fapl)) remove(DNAME);

    /* Test big file with the SEC2 driver */
    puts("Testing big file with the SEC2 Driver ");

    fapl = h5_fileaccess();
    if(H5Pset_fapl_sec2(fapl)<0)

    HDmemset(filename, 0, sizeof(filename));
    h5_fixname(FILENAME[2], fapl, filename, sizeof filename);

    if (writer(filename, fapl, WRT_N)) goto error;
    if (reader(filename, fapl)) goto error;

    puts("Test passed with the SEC2 Driver.");

#ifdef H5_HAVE_FSEEKO
    /* Clean up the test file */
    if (h5_cleanup(FILENAME, fapl)) remove(DNAME);

    /* Test big file with the STDIO driver only if fseeko is supported,
     * because the OFFSET parameter of fseek has the type LONG, not big
     * enough to support big files. */
    puts("\nTesting big file with the STDIO Driver ");

    fapl = h5_fileaccess();
    if(H5Pset_fapl_stdio(fapl)<0)

    HDmemset(filename, 0, sizeof(filename));
    h5_fixname(FILENAME[1], fapl, filename, sizeof filename);

    if (writer(filename, fapl, WRT_N)) goto error;
    if (reader(filename, fapl)) goto error;
    puts("Test passed with the STDIO Driver.");
#endif

quit:
    /* End with normal exit code */
    if (h5_cleanup(FILENAME, fapl)) remove(DNAME);
    return 0;

error:
    if (fapl>=0) H5Pclose(fapl);
    puts("*** TEST FAILED ***");
    return 1;
}