* 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
This commit is contained in:
Axel Dörfler
2009-07-28 00:58:26 +00:00
parent 6e4ad06302
commit 152d6bdcca
6 changed files with 61 additions and 92 deletions
+4 -4
View File
@@ -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);
}
}
+12 -16
View File
@@ -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 {
+16 -23
View File
@@ -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;
+4 -2
View File
@@ -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);
}
+20 -39
View File
@@ -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);
}
+5 -8
View File
@@ -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);