vvfat.c (4d1467a5683c8c91ab89d56a13c82c0a87bbbca5) vvfat.c (fb2575f95411644abe7f0606594035b63a5132ad)
1/* vim:set shiftwidth=4 ts=4: */
2/*
3 * QEMU Block driver for virtual VFAT (shadows a local directory)
4 *
5 * Copyright (c) 2004,2005 Johannes E. Schindelin
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal

--- 763 unchanged lines hidden (view full) ---

772 (void)create_short_and_long_name(s, i, ".", 1);
773 (void)create_short_and_long_name(s, i, "..", 1);
774 }
775
776 /* actually read the directory, and allocate the mappings */
777 while((entry=readdir(dir))) {
778 unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
779 char* buffer;
1/* vim:set shiftwidth=4 ts=4: */
2/*
3 * QEMU Block driver for virtual VFAT (shadows a local directory)
4 *
5 * Copyright (c) 2004,2005 Johannes E. Schindelin
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal

--- 763 unchanged lines hidden (view full) ---

772 (void)create_short_and_long_name(s, i, ".", 1);
773 (void)create_short_and_long_name(s, i, "..", 1);
774 }
775
776 /* actually read the directory, and allocate the mappings */
777 while((entry=readdir(dir))) {
778 unsigned int length=strlen(dirname)+2+strlen(entry->d_name);
779 char* buffer;
780 direntry_t* direntry;
781 struct stat st;
782 int is_dot=!strcmp(entry->d_name,".");
783 int is_dotdot=!strcmp(entry->d_name,"..");
784
785 if (first_cluster == 0 && s->directory.next >= s->root_entries - 1) {
786 fprintf(stderr, "Too many entries in root directory\n");
787 closedir(dir);
788 return -2;

--- 63 unchanged lines hidden (view full) ---

852 } else {
853 g_free(buffer);
854 }
855 }
856 closedir(dir);
857
858 /* fill with zeroes up to the end of the cluster */
859 while(s->directory.next%(0x10*s->sectors_per_cluster)) {
780 struct stat st;
781 int is_dot=!strcmp(entry->d_name,".");
782 int is_dotdot=!strcmp(entry->d_name,"..");
783
784 if (first_cluster == 0 && s->directory.next >= s->root_entries - 1) {
785 fprintf(stderr, "Too many entries in root directory\n");
786 closedir(dir);
787 return -2;

--- 63 unchanged lines hidden (view full) ---

851 } else {
852 g_free(buffer);
853 }
854 }
855 closedir(dir);
856
857 /* fill with zeroes up to the end of the cluster */
858 while(s->directory.next%(0x10*s->sectors_per_cluster)) {
860 direntry_t* direntry=array_get_next(&(s->directory));
859 direntry = array_get_next(&(s->directory));
861 memset(direntry,0,sizeof(direntry_t));
862 }
863
864 if (s->fat_type != 32 &&
865 mapping_index == 0 &&
866 s->directory.next < s->root_entries) {
867 /* root directory */
868 int cur = s->directory.next;

--- 1088 unchanged lines hidden (view full) ---

1957 }
1958
1959 if (copy_it) {
1960 int i;
1961 /*
1962 * This is horribly inefficient, but that is okay, since
1963 * it is rarely executed, if at all.
1964 */
860 memset(direntry,0,sizeof(direntry_t));
861 }
862
863 if (s->fat_type != 32 &&
864 mapping_index == 0 &&
865 s->directory.next < s->root_entries) {
866 /* root directory */
867 int cur = s->directory.next;

--- 1088 unchanged lines hidden (view full) ---

1956 }
1957
1958 if (copy_it) {
1959 int i;
1960 /*
1961 * This is horribly inefficient, but that is okay, since
1962 * it is rarely executed, if at all.
1963 */
1965 int64_t offset = cluster2sector(s, cluster_num);
1964 int64_t offs = cluster2sector(s, cluster_num);
1966
1967 vvfat_close_current_file(s);
1968 for (i = 0; i < s->sectors_per_cluster; i++) {
1969 int res;
1970
1971 res = bdrv_is_allocated(s->qcow->bs,
1965
1966 vvfat_close_current_file(s);
1967 for (i = 0; i < s->sectors_per_cluster; i++) {
1968 int res;
1969
1970 res = bdrv_is_allocated(s->qcow->bs,
1972 (offset + i) * BDRV_SECTOR_SIZE,
1971 (offs + i) * BDRV_SECTOR_SIZE,
1973 BDRV_SECTOR_SIZE, NULL);
1974 if (res < 0) {
1975 return -1;
1976 }
1977 if (!res) {
1972 BDRV_SECTOR_SIZE, NULL);
1973 if (res < 0) {
1974 return -1;
1975 }
1976 if (!res) {
1978 res = vvfat_read(s->bs, offset, s->cluster_buffer, 1);
1977 res = vvfat_read(s->bs, offs, s->cluster_buffer, 1);
1979 if (res) {
1980 return -1;
1981 }
1978 if (res) {
1979 return -1;
1980 }
1982 res = bdrv_co_pwrite(s->qcow, offset * BDRV_SECTOR_SIZE,
1981 res = bdrv_co_pwrite(s->qcow, offs * BDRV_SECTOR_SIZE,
1983 BDRV_SECTOR_SIZE, s->cluster_buffer,
1984 0);
1985 if (res < 0) {
1986 return -2;
1987 }
1988 }
1989 }
1990 }

--- 471 unchanged lines hidden (view full) ---

2462 return -1;
2463 } else if (new_cluster_count < old_cluster_count)
2464 remove_direntries(s,
2465 current_dir_index + factor * new_cluster_count,
2466 factor * (old_cluster_count - new_cluster_count));
2467
2468 for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
2469 direntry_t *first_direntry;
1982 BDRV_SECTOR_SIZE, s->cluster_buffer,
1983 0);
1984 if (res < 0) {
1985 return -2;
1986 }
1987 }
1988 }
1989 }

--- 471 unchanged lines hidden (view full) ---

2461 return -1;
2462 } else if (new_cluster_count < old_cluster_count)
2463 remove_direntries(s,
2464 current_dir_index + factor * new_cluster_count,
2465 factor * (old_cluster_count - new_cluster_count));
2466
2467 for (c = first_cluster; !fat_eof(s, c); c = modified_fat_get(s, c)) {
2468 direntry_t *first_direntry;
2470 void* direntry = array_get(&(s->directory), current_dir_index);
2471 int ret = vvfat_read(s->bs, cluster2sector(s, c), direntry,
2469
2470 direntry = array_get(&(s->directory), current_dir_index);
2471 ret = vvfat_read(s->bs, cluster2sector(s, c), (uint8_t *)direntry,
2472 s->sectors_per_cluster);
2473 if (ret)
2474 return ret;
2475
2476 /* The first directory entry on the filesystem is the volume name */
2477 first_direntry = (direntry_t*) s->directory.pointer;
2478 assert(!memcmp(first_direntry->name, s->volume_label, 11));
2479

--- 205 unchanged lines hidden (view full) ---

2685
2686 if (mapping->mode & MODE_DIRECTORY) {
2687 int l1 = strlen(mapping->path);
2688 int l2 = strlen(old_path);
2689 int diff = l1 - l2;
2690 direntry_t* direntry = array_get(&(s->directory),
2691 mapping->info.dir.first_dir_index);
2692 uint32_t c = mapping->begin;
2472 s->sectors_per_cluster);
2473 if (ret)
2474 return ret;
2475
2476 /* The first directory entry on the filesystem is the volume name */
2477 first_direntry = (direntry_t*) s->directory.pointer;
2478 assert(!memcmp(first_direntry->name, s->volume_label, 11));
2479

--- 205 unchanged lines hidden (view full) ---

2685
2686 if (mapping->mode & MODE_DIRECTORY) {
2687 int l1 = strlen(mapping->path);
2688 int l2 = strlen(old_path);
2689 int diff = l1 - l2;
2690 direntry_t* direntry = array_get(&(s->directory),
2691 mapping->info.dir.first_dir_index);
2692 uint32_t c = mapping->begin;
2693 int i = 0;
2693 int j = 0;
2694
2695 /* recurse */
2696 while (!fat_eof(s, c)) {
2697 do {
2694
2695 /* recurse */
2696 while (!fat_eof(s, c)) {
2697 do {
2698 direntry_t* d = direntry + i;
2698 direntry_t *d = direntry + j;
2699
2700 if (is_file(d) || (is_directory(d) && !is_dot(d))) {
2701 int l;
2702 char *new_path;
2703 mapping_t* m = find_mapping_for_cluster(s,
2704 begin_of_direntry(d));
2705 if (m == NULL) {
2706 return -1;

--- 4 unchanged lines hidden (view full) ---

2711 assert(!strncmp(m->path, mapping->path, l2));
2712
2713 pstrcpy(new_path, l + diff + 1, mapping->path);
2714 pstrcpy(new_path + l1, l + diff + 1 - l1,
2715 m->path + l2);
2716
2717 schedule_rename(s, m->begin, new_path);
2718 }
2699
2700 if (is_file(d) || (is_directory(d) && !is_dot(d))) {
2701 int l;
2702 char *new_path;
2703 mapping_t* m = find_mapping_for_cluster(s,
2704 begin_of_direntry(d));
2705 if (m == NULL) {
2706 return -1;

--- 4 unchanged lines hidden (view full) ---

2711 assert(!strncmp(m->path, mapping->path, l2));
2712
2713 pstrcpy(new_path, l + diff + 1, mapping->path);
2714 pstrcpy(new_path + l1, l + diff + 1 - l1,
2715 m->path + l2);
2716
2717 schedule_rename(s, m->begin, new_path);
2718 }
2719 i++;
2720 } while((i % (0x10 * s->sectors_per_cluster)) != 0);
2719 j++;
2720 } while (j % (0x10 * s->sectors_per_cluster) != 0);
2721 c = fat_get(s, c);
2722 }
2723 }
2724
2725 g_free(old_path);
2726 array_remove(&(s->commits), i);
2727 continue;
2728 } else if (commit->action == ACTION_MKDIR) {

--- 70 unchanged lines hidden (view full) ---

2799 fail = -3;
2800
2801 break;
2802 }
2803 case ACTION_NEW_FILE: {
2804 int begin = commit->param.new_file.first_cluster;
2805 mapping_t* mapping = find_mapping_for_cluster(s, begin);
2806 direntry_t* entry;
2721 c = fat_get(s, c);
2722 }
2723 }
2724
2725 g_free(old_path);
2726 array_remove(&(s->commits), i);
2727 continue;
2728 } else if (commit->action == ACTION_MKDIR) {

--- 70 unchanged lines hidden (view full) ---

2799 fail = -3;
2800
2801 break;
2802 }
2803 case ACTION_NEW_FILE: {
2804 int begin = commit->param.new_file.first_cluster;
2805 mapping_t* mapping = find_mapping_for_cluster(s, begin);
2806 direntry_t* entry;
2807 int i;
2807 int j;
2808
2809 /* find direntry */
2808
2809 /* find direntry */
2810 for (i = 0; i < s->directory.next; i++) {
2811 entry = array_get(&(s->directory), i);
2810 for (j = 0; j < s->directory.next; j++) {
2811 entry = array_get(&(s->directory), j);
2812 if (is_file(entry) && begin_of_direntry(entry) == begin)
2813 break;
2814 }
2815
2812 if (is_file(entry) && begin_of_direntry(entry) == begin)
2813 break;
2814 }
2815
2816 if (i >= s->directory.next) {
2816 if (j >= s->directory.next) {
2817 fail = -6;
2818 continue;
2819 }
2820
2821 /* make sure there exists an initial mapping */
2822 if (mapping && mapping->begin != begin) {
2823 mapping->end = begin;
2824 mapping = NULL;
2825 }
2826 if (mapping == NULL) {
2827 mapping = insert_mapping(s, begin, begin+1);
2828 }
2829 /* most members will be fixed in commit_mappings() */
2830 assert(commit->path);
2831 mapping->path = commit->path;
2832 mapping->read_only = 0;
2833 mapping->mode = MODE_NORMAL;
2834 mapping->info.file.offset = 0;
2835
2817 fail = -6;
2818 continue;
2819 }
2820
2821 /* make sure there exists an initial mapping */
2822 if (mapping && mapping->begin != begin) {
2823 mapping->end = begin;
2824 mapping = NULL;
2825 }
2826 if (mapping == NULL) {
2827 mapping = insert_mapping(s, begin, begin+1);
2828 }
2829 /* most members will be fixed in commit_mappings() */
2830 assert(commit->path);
2831 mapping->path = commit->path;
2832 mapping->read_only = 0;
2833 mapping->mode = MODE_NORMAL;
2834 mapping->info.file.offset = 0;
2835
2836 if (commit_one_file(s, i, 0))
2836 if (commit_one_file(s, j, 0)) {
2837 fail = -7;
2837 fail = -7;
2838 }
2838
2839 break;
2840 }
2841 default:
2842 abort();
2843 }
2844 }
2845 if (i > 0 && array_remove_slice(&(s->commits), 0, i))

--- 444 unchanged lines hidden ---
2839
2840 break;
2841 }
2842 default:
2843 abort();
2844 }
2845 }
2846 if (i > 0 && array_remove_slice(&(s->commits), 0, i))

--- 444 unchanged lines hidden ---