From 152d6bdcca40a929571db03a74ceb13b0c946ead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 28 Jul 2009 00:58:26 +0000 Subject: [PATCH] * Replaced diri_mark_dirty() with a diri_make_writable(), and fixed its usage throughout the code. * Got rid of the transactions - they weren't really used, and thus only created unnecessary overhead. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31836 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/kernel/file_systems/fat/dir.c | 8 +-- src/add-ons/kernel/file_systems/fat/dosfs.c | 28 +++++----- src/add-ons/kernel/file_systems/fat/fat.c | 39 ++++++-------- src/add-ons/kernel/file_systems/fat/file.c | 6 ++- src/add-ons/kernel/file_systems/fat/iter.c | 59 +++++++-------------- src/add-ons/kernel/file_systems/fat/iter.h | 13 ++--- 6 files changed, 61 insertions(+), 92 deletions(-) diff --git a/src/add-ons/kernel/file_systems/fat/dir.c b/src/add-ons/kernel/file_systems/fat/dir.c index e0ce4d2c40..74b8bc96e6 100644 --- a/src/add-ons/kernel/file_systems/fat/dir.c +++ b/src/add-ons/kernel/file_systems/fat/dir.c @@ -485,8 +485,8 @@ erase_dir_entry(nspace *vol, vnode *node) buffer = diri_init(vol, VNODE_PARENT_DIR_CLUSTER(node), node->sindex, &diri); for (i = node->sindex; i <= node->eindex && buffer; buffer = diri_next_entry(&diri), i++) { + diri_make_writable(&diri); buffer[0] = 0xe5; // mark entry erased - diri_mark_dirty(&diri); } diri_free(&diri); @@ -718,6 +718,7 @@ _create_dir_entry_(nspace *vol, vnode *dir, struct _entry_info_ *info, for (i = 1; i < required_entries && buffer; i++) { const char *p = nlong + (required_entries - i - 1) * 26; // go to unicode offset + diri_make_writable(&diri); memset(buffer, 0, 0x20); buffer[0] = required_entries - i + ((i == 1) ? 0x40 : 0); buffer[0x0b] = 0x0f; @@ -725,7 +726,6 @@ _create_dir_entry_(nspace *vol, vnode *dir, struct _entry_info_ *info, memcpy(buffer+1,p,10); memcpy(buffer+0x0e,p+10,12); memcpy(buffer+0x1c,p+22,4); - diri_mark_dirty(&diri); buffer = diri_next_entry(&diri); } @@ -737,6 +737,7 @@ _create_dir_entry_(nspace *vol, vnode *dir, struct _entry_info_ *info, } // write directory entry + diri_make_writable(&diri); memcpy(buffer, nshort, 11); buffer[0x0b] = info->mode; memset(buffer+0xc, 0, 0x16-0xc); @@ -758,15 +759,14 @@ _create_dir_entry_(nspace *vol, vnode *dir, struct _entry_info_ *info, buffer[0x1d] = (i >> 8) & 0xff; buffer[0x1e] = (i >> 16) & 0xff; buffer[0x1f] = (i >> 24) & 0xff; - diri_mark_dirty(&diri); if (last_entry) { // add end of directory markers to the rest of the // cluster; need to clear all the other entries or else // scandisk will complain. while ((buffer = diri_next_entry(&diri)) != NULL) { + diri_make_writable(&diri); memset(buffer, 0, 0x20); - diri_mark_dirty(&diri); } } diff --git a/src/add-ons/kernel/file_systems/fat/dosfs.c b/src/add-ons/kernel/file_systems/fat/dosfs.c index c8f5a04d42..685a58a835 100644 --- a/src/add-ons/kernel/file_systems/fat/dosfs.c +++ b/src/add-ons/kernel/file_systems/fat/dosfs.c @@ -203,7 +203,7 @@ mount_fat_disk(const char *path, fs_volume *_vol, const int flags, vol->fs_flags = fs_flags; // open read-only for now - if ((err = (vol->fd = open(path, O_RDONLY))) < 0) { + if ((err = (vol->fd = open(path, O_RDONLY | O_NOCACHE))) < 0) { dprintf("dosfs error: unable to open %s (%s)\n", path, strerror(err)); goto error0; } @@ -243,7 +243,7 @@ mount_fat_disk(const char *path, fs_volume *_vol, const int flags, } else { // reopen it with read/write permissions close(vol->fd); - if ((err = (vol->fd = open(path, O_RDWR))) < 0) { + if ((err = (vol->fd = open(path, O_RDWR | O_NOCACHE))) < 0) { dprintf("dosfs error: unable to open %s (%s)\n", path, strerror(err)); goto error0; @@ -825,10 +825,9 @@ update_fsinfo(nspace *vol) { if (vol->fat_bits == 32 && vol->fsinfo_sector != 0xffff && (vol->flags & B_FS_IS_READONLY) == 0) { - uchar *buffer; - int32 tid = cache_start_transaction(vol->fBlockCache); - if ((buffer = (uchar *)block_cache_get_writable_etc(vol->fBlockCache, - vol->fsinfo_sector, 0, vol->bytes_per_sector, tid)) != NULL) { + uchar *buffer = (uchar *)block_cache_get_writable_etc(vol->fBlockCache, + vol->fsinfo_sector, 0, vol->bytes_per_sector, -1); + if (buffer != NULL) { if ((read32(buffer,0) == 0x41615252) && (read32(buffer,0x1e4) == 0x61417272) && (read16(buffer,0x1fe) == 0xaa55)) { //number of free clusters buffer[0x1e8] = (vol->free_clusters & 0xff); @@ -843,12 +842,10 @@ update_fsinfo(nspace *vol) } else { dprintf("update_fsinfo: fsinfo block has invalid magic number\n"); block_cache_set_dirty(vol->fBlockCache, vol->fsinfo_sector, - false, tid); + false, -1); } block_cache_put(vol->fBlockCache, vol->fsinfo_sector); - cache_end_transaction(vol->fBlockCache, tid, NULL, NULL); } else { - cache_end_transaction(vol->fBlockCache, tid, NULL, NULL); dprintf("update_fsinfo: error getting fsinfo sector %x\n", vol->fsinfo_sector); } @@ -1038,10 +1035,9 @@ dosfs_write_fs_stat(fs_volume *_vol, const struct fs_info * fss, uint32 mask) if (vol->vol_entry == -1) { // stored in the bpb - uchar *buffer; - int32 tid = cache_start_transaction(vol->fBlockCache); - if ((buffer = block_cache_get_writable_etc(vol->fBlockCache, 0, 0, vol->bytes_per_sector, tid)) == NULL) { - cache_end_transaction(vol->fBlockCache, tid, NULL, NULL); + uchar *buffer = block_cache_get_writable_etc(vol->fBlockCache, 0, 0, + vol->bytes_per_sector, -1); + if (buffer == NULL) { result = EIO; goto bi; } @@ -1050,14 +1046,13 @@ dosfs_write_fs_stat(fs_volume *_vol, const struct fs_info * fss, uint32 mask) || (vol->sectors_per_fat != 0 && (buffer[0x26] != 0x29 || strncmp(buffer + 0x2b, vol->vol_label, 11) == 0))) { dprintf("dosfs_wfsstat: label mismatch\n"); - block_cache_set_dirty(vol->fBlockCache, 0, false, tid); + block_cache_set_dirty(vol->fBlockCache, 0, false, -1); result = B_ERROR; } else { memcpy(buffer + 0x2b, name, 11); result = B_OK; } block_cache_put(vol->fBlockCache, 0); - cache_end_transaction(vol->fBlockCache, tid, NULL, NULL); } else if (vol->vol_entry >= 0) { struct diri diri; uint8 *buffer; @@ -1070,8 +1065,9 @@ dosfs_write_fs_stat(fs_volume *_vol, const struct fs_info * fss, uint32 mask) result = B_ERROR; goto bi; } + + diri_make_writable(&diri); memcpy(buffer, name, 11); - diri_mark_dirty(&diri); diri_free(&diri); result = B_OK; } else { diff --git a/src/add-ons/kernel/file_systems/fat/fat.c b/src/add-ons/kernel/file_systems/fat/fat.c index 7ccb9e681f..98de2de304 100644 --- a/src/add-ons/kernel/file_systems/fat/fat.c +++ b/src/add-ons/kernel/file_systems/fat/fat.c @@ -22,7 +22,7 @@ #define DPRINTF(a,b) if (debug_fat > (a)) dprintf b static status_t -mirror_fats(nspace *vol, uint32 sector, uint8 *buffer, int32 transactionID) +mirror_fats(nspace *vol, uint32 sector, uint8 *buffer) { uint32 i; char *buf = buffer; @@ -38,7 +38,7 @@ mirror_fats(nspace *vol, uint32 sector, uint8 *buffer, int32 transactionID) continue; blockData = block_cache_get_writable_etc(vol->fBlockCache, sector - + i * vol->sectors_per_fat, 0, 1, transactionID); + + i * vol->sectors_per_fat, 0, 1, -1); memcpy(blockData, buf, vol->bytes_per_sector); buf += vol->bytes_per_sector; block_cache_put(vol->fBlockCache, sector + i * vol->sectors_per_fat); @@ -90,7 +90,7 @@ enum { }; static int32 -_fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N, int32 _tid) +_fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N) { int32 result = 0; uint32 n = 0, first = 0, last = 0; @@ -98,7 +98,6 @@ _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N, int32 _tid) uint32 sector; uint32 offset, value = 0; /* quiet warning */ uint8 *block1, *block2 = NULL; /* quiet warning */ - int32 transactionID = _tid; bool readOnly = action != _IOCTL_SET_ENTRY_ && action != _IOCTL_ALLOCATE_N_ENTRIES_; @@ -141,11 +140,8 @@ _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N, int32 _tid) if (readOnly) { block1 = (uint8 *)block_cache_get(vol->fBlockCache, sector); } else { - if (transactionID == -1) - transactionID = cache_start_transaction(vol->fBlockCache); - block1 = (uint8 *)block_cache_get_writable(vol->fBlockCache, sector, - transactionID); + -1); } if (block1 == NULL) { @@ -165,7 +161,7 @@ _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N, int32 _tid) ++sector); } else { block2 = (uint8 *)block_cache_get_writable(vol->fBlockCache, - ++sector, transactionID); + ++sector, -1); } if (block2 == NULL) { @@ -206,7 +202,7 @@ _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N, int32 _tid) block1[offset] &= (andmask & 0xff); block1[offset] |= (ormask & 0xff); if (offset == vol->bytes_per_sector - 1) { - mirror_fats(vol, sector - 1, block1, transactionID); + mirror_fats(vol, sector - 1, block1); block2[0] &= (andmask >> 8); block2[0] |= (ormask >> 8); } else { @@ -258,11 +254,11 @@ _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N, int32 _tid) result = value; goto bi; } else if (action == _IOCTL_SET_ENTRY_) { - mirror_fats(vol, sector, block1, transactionID); + mirror_fats(vol, sector, block1); goto bi; } else if (action == _IOCTL_ALLOCATE_N_ENTRIES_ && value == 0) { vol->free_clusters--; - mirror_fats(vol, sector, block1, transactionID); + mirror_fats(vol, sector, block1); if (n == 0) { ASSERT(first == 0); @@ -272,8 +268,8 @@ _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N, int32 _tid) ASSERT(IS_DATA_CLUSTER(last)); // set last cluster to point to us - if ((result = _fat_ioctl_(vol, _IOCTL_SET_ENTRY_, last, cluster, - transactionID)) < 0) { + result = _fat_ioctl_(vol, _IOCTL_SET_ENTRY_, last, cluster); + if (result < 0) { ASSERT(0); goto bi; } @@ -298,7 +294,7 @@ _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N, int32 _tid) block1 = (uint8 *)block_cache_get(vol->fBlockCache, sector); else { block1 = (uint8 *)block_cache_get_writable(vol->fBlockCache, - sector, transactionID); + sector, -1); } } @@ -314,7 +310,7 @@ _fat_ioctl_(nspace *vol, uint32 action, uint32 cluster, int32 N, int32 _tid) block1 = (uint8 *)block_cache_get(vol->fBlockCache, sector); else { block1 = (uint8 *)block_cache_get_writable(vol->fBlockCache, - sector, transactionID); + sector, -1); } } @@ -329,9 +325,6 @@ bi: if (block1 != NULL) block_cache_put(vol->fBlockCache, sector); - if (_tid == -1 && transactionID > 0) - cache_end_transaction(vol->fBlockCache, transactionID, NULL, NULL); - if (action == _IOCTL_ALLOCATE_N_ENTRIES_) { if (result < 0) { DPRINTF(0, ("pooh. there is a problem. clearing chain (%ld)\n", @@ -362,14 +355,14 @@ bi: int32 count_free_clusters(nspace *vol) { - return _fat_ioctl_(vol, _IOCTL_COUNT_FREE_, 0, 0, -1); + return _fat_ioctl_(vol, _IOCTL_COUNT_FREE_, 0, 0); } static int32 get_fat_entry(nspace *vol, uint32 cluster) { - int32 value = _fat_ioctl_(vol, _IOCTL_GET_ENTRY_, cluster, 0, -1); + int32 value = _fat_ioctl_(vol, _IOCTL_GET_ENTRY_, cluster, 0); if (value < 0) return value; @@ -391,7 +384,7 @@ get_fat_entry(nspace *vol, uint32 cluster) static status_t set_fat_entry(nspace *vol, uint32 cluster, int32 value) { - return _fat_ioctl_(vol, _IOCTL_SET_ENTRY_, cluster, value, -1); + return _fat_ioctl_(vol, _IOCTL_SET_ENTRY_, cluster, value); } @@ -507,7 +500,7 @@ allocate_n_fat_entries(nspace *vol, int32 n, int32 *start) DPRINTF(2, ("allocating %ld fat entries\n", n)); - c = _fat_ioctl_(vol, _IOCTL_ALLOCATE_N_ENTRIES_, 0, n, -1); + c = _fat_ioctl_(vol, _IOCTL_ALLOCATE_N_ENTRIES_, 0, n); if (c < 0) return c; diff --git a/src/add-ons/kernel/file_systems/fat/file.c b/src/add-ons/kernel/file_systems/fat/file.c index 8bd9ec8ebf..de1d091100 100644 --- a/src/add-ons/kernel/file_systems/fat/file.c +++ b/src/add-ons/kernel/file_systems/fat/file.c @@ -95,6 +95,7 @@ status_t write_vnode_entry(nspace *vol, vnode *node) if (buffer == NULL) return ENOENT; + diri_make_writable(&diri); buffer[0x0b] = node->mode; // file attributes memset(buffer+0xc, 0, 0x16-0xc); @@ -118,7 +119,6 @@ status_t write_vnode_entry(nspace *vol, vnode *node) buffer[0x1f] = (node->st_size >> 24) & 0xff; } - diri_mark_dirty(&diri); diri_free(&diri); // TODO: figure out which stats have actually changed @@ -1258,6 +1258,9 @@ dosfs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname, result = EIO; goto bi2; } + + diri_make_writable(&diri); + if (memcmp(buffer, ".. ", 11)) { dprintf("invalid directory :(\n"); result = EIO; @@ -1274,7 +1277,6 @@ dosfs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname, buffer[0x15] = (ndir->cluster >> 24) & 0xff; } } - diri_mark_dirty(&diri); diri_free(&diri); } diff --git a/src/add-ons/kernel/file_systems/fat/iter.c b/src/add-ons/kernel/file_systems/fat/iter.c index de8cabaf52..2841026c72 100644 --- a/src/add-ons/kernel/file_systems/fat/iter.c +++ b/src/add-ons/kernel/file_systems/fat/iter.c @@ -109,21 +109,13 @@ iter_csi(struct csi *csi, int sectors) uint8 * -csi_get_block(struct csi *csi, int32 tid) +csi_get_block(struct csi *csi) { if (_validate_cs_(csi->vol, csi->cluster, csi->sector) != 0) return NULL; - // TODO: the file system should be a bit smarter than this - // (ie. it should know when it needs a writable block) - - if (csi->vol->flags & B_FS_IS_READONLY) { - return (uint8 *)block_cache_get_etc(csi->vol->fBlockCache, csi_to_block(csi), - 1, csi->vol->bytes_per_sector); - } else { - return block_cache_get_writable_etc(csi->vol->fBlockCache, csi_to_block(csi), - 1, csi->vol->bytes_per_sector, tid); - } + return (uint8 *)block_cache_get_etc(csi->vol->fBlockCache, + csi_to_block(csi), 1, csi->vol->bytes_per_sector); } @@ -139,16 +131,13 @@ csi_release_block(struct csi *csi) status_t -csi_mark_block_dirty(struct csi *csi, int32 tid) +csi_make_writable(struct csi *csi) { - ASSERT(_validate_cs_(csi->vol, csi->cluster, csi->sector) == 0); if (_validate_cs_(csi->vol, csi->cluster, csi->sector) != 0) return EINVAL; - // TODO : block_cache doesn't implement this - //block_cache_set_dirty(csi->vol->fBlockCache, csi_to_block(csi), true, tid); - - return B_OK; + return block_cache_make_writable(csi->vol->fBlockCache, csi_to_block(csi), + -1); } @@ -202,7 +191,7 @@ csi_write_blocks(struct csi *csi, uint8 *buffer, ssize_t len) off_t block; status_t err; char *buf = buffer; - int32 i, tid; + int32 i; ASSERT(len >= csi->vol->bytes_per_sector); @@ -223,14 +212,13 @@ csi_write_blocks(struct csi *csi, uint8 *buffer, ssize_t len) sectors++; } - tid = cache_start_transaction(csi->vol->fBlockCache); for (i = block; i < block + sectors; i++) { - char *blockData = block_cache_get_writable_etc(csi->vol->fBlockCache, i, 0, 1, tid); + char *blockData = block_cache_get_writable_etc(csi->vol->fBlockCache, i, + 0, 1, -1); memcpy(blockData, buf, csi->vol->bytes_per_sector); buf += csi->vol->bytes_per_sector; block_cache_put(csi->vol->fBlockCache, i); } - cache_end_transaction(csi->vol->fBlockCache, tid, NULL, NULL); /* return the last state of the iterator because that's what dosfs_write * expects. this lets it meaningfully cache the state even when it's @@ -245,7 +233,6 @@ status_t csi_write_block(struct csi *csi, uint8 *buffer) { off_t block; - int32 tid; char *blockData; block = csi_to_block(csi); @@ -254,16 +241,18 @@ csi_write_block(struct csi *csi, uint8 *buffer) if (_validate_cs_(csi->vol, csi->cluster, csi->sector) != 0) return EINVAL; - tid = cache_start_transaction(csi->vol->fBlockCache); - blockData = block_cache_get_writable_etc(csi->vol->fBlockCache, block, 0, 1, tid); + blockData = block_cache_get_writable_etc(csi->vol->fBlockCache, block, 0, 1, + -1); memcpy(blockData, buffer, csi->vol->bytes_per_sector); block_cache_put(csi->vol->fBlockCache, block); - cache_end_transaction(csi->vol->fBlockCache, tid, NULL, NULL); return B_OK; } +// #pragma mark - + + static void _diri_release_current_block_(struct diri *diri) { @@ -294,17 +283,11 @@ diri_init(nspace *vol, uint32 cluster, uint32 index, struct diri *diri) / (vol->bytes_per_sector / 0x20)) != 0) return NULL; - diri->tid = cache_start_transaction(diri->csi.vol->fBlockCache); - if (diri->tid < B_OK) - return NULL; - // get current sector - diri->current_block = csi_get_block(&(diri->csi), diri->tid); + diri->current_block = csi_get_block(&diri->csi); - if (diri->current_block == NULL) { - cache_end_transaction(diri->csi.vol->fBlockCache, diri->tid, NULL, NULL); + if (diri->current_block == NULL) return NULL; - } // now the diri is valid diri->magic = DIRI_MAGIC; @@ -323,8 +306,6 @@ diri_free(struct diri *diri) if (diri->current_block) _diri_release_current_block_(diri); - cache_end_transaction(diri->csi.vol->fBlockCache, diri->tid, NULL, NULL); - return 0; } @@ -354,7 +335,7 @@ diri_next_entry(struct diri *diri) _diri_release_current_block_(diri); if (iter_csi(&(diri->csi), 1) != 0) return NULL; - diri->current_block = csi_get_block(&(diri->csi), diri->tid); + diri->current_block = csi_get_block(&(diri->csi)); if (diri->current_block == NULL) return NULL; } @@ -375,7 +356,7 @@ diri_rewind(struct diri *diri) _diri_release_current_block_(diri); if (init_csi(diri->csi.vol, diri->starting_cluster, 0, &(diri->csi)) != 0) return NULL; - diri->current_block = csi_get_block(&(diri->csi), diri->tid); + diri->current_block = csi_get_block(&diri->csi); } diri->current_index = 0; return diri->current_block; @@ -383,7 +364,7 @@ diri_rewind(struct diri *diri) void -diri_mark_dirty(struct diri *diri) +diri_make_writable(struct diri *diri) { - csi_mark_block_dirty(&(diri->csi), diri->tid); + csi_make_writable(&diri->csi); } diff --git a/src/add-ons/kernel/file_systems/fat/iter.h b/src/add-ons/kernel/file_systems/fat/iter.h index a277ee6bc7..4e66aa5791 100644 --- a/src/add-ons/kernel/file_systems/fat/iter.h +++ b/src/add-ons/kernel/file_systems/fat/iter.h @@ -8,8 +8,7 @@ struct _nspace; /* csi keeps track of current cluster and sector info */ -struct csi -{ +struct csi { struct _nspace *vol; uint32 cluster; uint32 sector; @@ -18,23 +17,21 @@ struct csi off_t csi_to_block(struct csi *csi); int init_csi(struct _nspace *vol, uint32 cluster, uint32 sector, struct csi *csi); int iter_csi(struct csi *csi, int sectors); -uint8 *csi_get_block(struct csi *csi, int32 tid); +uint8 *csi_get_block(struct csi *csi); status_t csi_release_block(struct csi *csi); -status_t csi_mark_block_dirty(struct csi *csi, int32 tid); +status_t csi_make_writable(struct csi *csi); status_t csi_read_blocks(struct csi *csi, uint8 *buffer, ssize_t len); status_t csi_write_blocks(struct csi *csi, uint8 *buffer, ssize_t len); status_t csi_write_block(struct csi *csi, uint8 *buffer); /* directory entry iterator */ #define DIRI_MAGIC '!duM' -struct diri -{ +struct diri { uint32 magic; struct csi csi; uint32 starting_cluster; uint32 current_index; uint8 *current_block; - int32 tid; }; uint8 *diri_init(struct _nspace *vol, uint32 cluster, uint32 index, struct diri *diri); @@ -42,7 +39,7 @@ int diri_free(struct diri *diri); uint8 *diri_current_entry(struct diri *diri); uint8 *diri_next_entry(struct diri *diri); uint8 *diri_rewind(struct diri *diri); -void diri_mark_dirty(struct diri *diri); +void diri_make_writable(struct diri *diri); int check_diri_magic(struct diri *t, char *funcname);