Updated as of April 2, 2001.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2983 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper
2003-03-21 21:03:51 +00:00
parent 9168ef4ba7
commit ba5d0baeee
4 changed files with 157 additions and 44 deletions
+23 -14
View File
@@ -2,13 +2,13 @@
Copyright 1999-2001, Be Incorporated. All Rights Reserved. Copyright 1999-2001, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License. This file may be used under the terms of the Be Sample Code License.
*/ */
#include <KernelExport.h> #include <KernelExport.h>
#include <fsproto.h> #include <fsproto.h>
#include <lock.h> #include <lock.h>
#include <cache.h> #include <cache.h>
#include <stdlib.h>
#include <dirent.h> #include <dirent.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@@ -347,9 +347,11 @@ static status_t findfile(nspace *vol, vnode *dir, const char *file,
any other case-insensitive matches. If there are, the any other case-insensitive matches. If there are, the
dups_exist flag is set to true. */ dups_exist flag is set to true. */
int result = 0; int result = 0;
vnode_id _vnid; vnode_id found_vnid = 0;
bool found_file = false; bool found_file = false;
// dprintf("findfile: %s in %Lx, case %d dups %d\n", file, dir->vnid, check_case, check_dups);
if (check_nspace_magic(vol, "findfile")) return EINVAL; if (check_nspace_magic(vol, "findfile")) return EINVAL;
if (check_vnode_magic(dir, "findfile")) return EINVAL; if (check_vnode_magic(dir, "findfile")) return EINVAL;
@@ -360,12 +362,11 @@ static status_t findfile(nspace *vol, vnode *dir, const char *file,
if ((strcmp(file,".") == 0) && (dir->vnid == vol->root_vnode.vnid)) { if ((strcmp(file,".") == 0) && (dir->vnid == vol->root_vnode.vnid)) {
found_file = true; found_file = true;
_vnid = dir->vnid; found_vnid = dir->vnid;
} else if ((strcmp(file, "..") == 0) && (dir->vnid == vol->root_vnode.vnid)) { } else if ((strcmp(file, "..") == 0) && (dir->vnid == vol->root_vnode.vnid)) {
found_file = true; found_file = true;
_vnid = dir->dir_vnid; found_vnid = dir->dir_vnid;
} else { } else {
char filename[512];
struct diri diri; struct diri diri;
// XXX: do it in a smarter way // XXX: do it in a smarter way
@@ -373,6 +374,9 @@ static status_t findfile(nspace *vol, vnode *dir, const char *file,
while (1) while (1)
{ {
char filename[512];
vnode_id _vnid;
result = get_next_dirent(vol, dir, &diri, &_vnid, filename, 512); result = get_next_dirent(vol, dir, &diri, &_vnid, filename, 512);
if (result != B_NO_ERROR) if (result != B_NO_ERROR)
@@ -380,37 +384,41 @@ static status_t findfile(nspace *vol, vnode *dir, const char *file,
if(check_case) { if(check_case) {
if (!found_file && !strcmp(filename, file)) { if (!found_file && !strcmp(filename, file)) {
result = B_OK;
found_file = true; found_file = true;
found_vnid = _vnid;
} else if(check_dups && !strcasecmp(filename, file)) { } else if(check_dups && !strcasecmp(filename, file)) {
*dups_exist = true; *dups_exist = true;
} }
} else { } else {
if (!strcasecmp(filename, file)) { if (!strcasecmp(filename, file)) {
result = B_OK;
if(check_dups && found_file) { if(check_dups && found_file) {
*dups_exist = true; *dups_exist = true;
} }
found_file = true; found_file = true;
found_vnid = _vnid;
} }
} }
if(found_file) { if(found_file && (!check_dups || (check_dups && *dups_exist))) {
if(!check_dups) {
break; break;
} else if(*dups_exist) {
break;
}
} }
} }
diri_free(&diri); diri_free(&diri);
} }
if (found_file) { if (found_file) {
if (vnid) *vnid = _vnid; if (vnid) *vnid = found_vnid;
if (node) result = get_vnode(vol->id, _vnid, (void **)node); if (node) result = get_vnode(vol->id, found_vnid, (void **)node);
result = B_OK;
} else { } else {
result = ENOENT; result = ENOENT;
} }
#if 0
dprintf("findfile: returning %d", result);
if(dups_exist)
dprintf(" dups_exist %d\n", *dups_exist);
else
dprintf("\n");
#endif
return result; return result;
} }
@@ -916,6 +924,7 @@ int dosfs_read_vnode(void *_vol, vnode_id vnid, char reenter, void **_node)
entry->cluster = info.cluster; entry->cluster = info.cluster;
entry->mode = info.mode; entry->mode = info.mode;
entry->st_size = info.size; entry->st_size = info.size;
entry->dirty = false;
if (info.mode & FAT_SUBDIR) { if (info.mode & FAT_SUBDIR) {
entry->st_size = count_clusters(vol,entry->cluster) * vol->sectors_per_cluster * vol->bytes_per_sector; entry->st_size = count_clusters(vol,entry->cluster) * vol->sectors_per_cluster * vol->bytes_per_sector;
} }
+56 -17
View File
@@ -2,7 +2,6 @@
Copyright 1999-2001, Be Incorporated. All Rights Reserved. Copyright 1999-2001, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License. This file may be used under the terms of the Be Sample Code License.
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -143,7 +142,7 @@ static int lock_removable_device(int fd, bool state)
} }
static status_t mount_fat_disk(const char *path, nspace_id nsid, static status_t mount_fat_disk(const char *path, nspace_id nsid,
const int flags, nspace** newVol) const int flags, nspace** newVol, int fs_flags, int op_sync_mode)
{ {
nspace *vol = NULL; nspace *vol = NULL;
uint8 buf[512]; uint8 buf[512];
@@ -159,6 +158,7 @@ static status_t mount_fat_disk(const char *path, nspace_id nsid,
vol->magic = NSPACE_MAGIC; vol->magic = NSPACE_MAGIC;
vol->flags = B_FS_IS_PERSISTENT | B_FS_HAS_MIME; vol->flags = B_FS_IS_PERSISTENT | B_FS_HAS_MIME;
vol->fs_flags = fs_flags;
// open read-only for now // open read-only for now
if ((err = (vol->fd = open(path, O_RDONLY))) < 0) { if ((err = (vol->fd = open(path, O_RDONLY))) < 0) {
@@ -201,10 +201,27 @@ static status_t mount_fat_disk(const char *path, nspace_id nsid,
dprintf("dosfs: unable to open %s (%s)\n", path, strerror(err)); dprintf("dosfs: unable to open %s (%s)\n", path, strerror(err));
goto error0; goto error0;
} }
if (vol->flags & B_FS_IS_REMOVABLE) if ((vol->flags & B_FS_IS_REMOVABLE) && (vol->fs_flags & FS_FLAGS_LOCK_DOOR))
lock_removable_device(vol->fd, true); lock_removable_device(vol->fd, true);
} }
// see if we need to go into op sync mode
vol->fs_flags &= ~FS_FLAGS_OP_SYNC;
switch(op_sync_mode) {
case 1:
if((vol->flags & B_FS_IS_REMOVABLE) == 0) {
// we're not removable, so skip op_sync
break;
}
case 2:
dprintf("dosfs: mounted with op_sync enabled\n");
vol->fs_flags |= FS_FLAGS_OP_SYNC;
break;
case 0:
default:
;
}
// read in the boot sector // read in the boot sector
if ((err = read_pos(vol->fd, 0, (void*)buf, 512)) != 512) { if ((err = read_pos(vol->fd, 0, (void*)buf, 512)) != 512) {
dprintf("dosfs: error reading boot sector\n"); dprintf("dosfs: error reading boot sector\n");
@@ -467,6 +484,7 @@ static status_t mount_fat_disk(const char *path, nspace_id nsid,
vol->root_vnode.mode = FAT_SUBDIR; vol->root_vnode.mode = FAT_SUBDIR;
time(&(vol->root_vnode.st_time)); time(&(vol->root_vnode.st_time));
vol->root_vnode.mime = NULL; vol->root_vnode.mime = NULL;
vol->root_vnode.dirty = false;
dlist_add(vol, vol->root_vnode.vnid); dlist_add(vol, vol->root_vnode.vnid);
// find volume label (supercedes any label in the bpb) // find volume label (supercedes any label in the bpb)
@@ -502,7 +520,7 @@ error2:
error1: error1:
remove_cached_device_blocks(vol->fd, NO_WRITES); remove_cached_device_blocks(vol->fd, NO_WRITES);
error: error:
if (!(vol->flags & B_FS_IS_READONLY) && (vol->flags & B_FS_IS_REMOVABLE)) if (!(vol->flags & B_FS_IS_READONLY) && (vol->flags & B_FS_IS_REMOVABLE) && (vol->fs_flags & FS_FLAGS_LOCK_DOOR))
lock_removable_device(vol->fd, false); lock_removable_device(vol->fd, false);
error0: error0:
close(vol->fd); close(vol->fd);
@@ -516,6 +534,8 @@ static int dosfs_mount(nspace_id nsid, const char *device, ulong flags, void *pa
int result; int result;
nspace *vol; nspace *vol;
void *handle; void *handle;
int op_sync_mode;
int fs_flags = 0;
handle = load_driver_settings("dos"); handle = load_driver_settings("dos");
debug_attr = strtoul(get_driver_parameter(handle, "debug_attr", "0", "0"), NULL, 0); debug_attr = strtoul(get_driver_parameter(handle, "debug_attr", "0", "0"), NULL, 0);
@@ -527,6 +547,18 @@ static int dosfs_mount(nspace_id nsid, const char *device, ulong flags, void *pa
debug_file = strtoul(get_driver_parameter(handle, "debug_file", "0", "0"), NULL, 0); debug_file = strtoul(get_driver_parameter(handle, "debug_file", "0", "0"), NULL, 0);
debug_iter = strtoul(get_driver_parameter(handle, "debug_iter", "0", "0"), NULL, 0); debug_iter = strtoul(get_driver_parameter(handle, "debug_iter", "0", "0"), NULL, 0);
debug_vcache = strtoul(get_driver_parameter(handle, "debug_vcache", "0", "0"), NULL, 0); debug_vcache = strtoul(get_driver_parameter(handle, "debug_vcache", "0", "0"), NULL, 0);
op_sync_mode = strtoul(get_driver_parameter(handle, "op_sync_mode", "0", "0"), NULL, 0);
if (op_sync_mode < 0 || op_sync_mode > 2) {
op_sync_mode = 0;
}
if (strcasecmp(get_driver_parameter(handle, "lock_device", "true", "true"), "false") == 0) {
dprintf("dosfs: mounted with lock_device = false\n");
} else {
dprintf("dosfs: mounted with lock_device = true\n");
fs_flags |= FS_FLAGS_LOCK_DOOR;
}
unload_driver_settings(handle); unload_driver_settings(handle);
/* parms and len are command line options; dosfs doesn't use any so /* parms and len are command line options; dosfs doesn't use any so
@@ -544,7 +576,7 @@ static int dosfs_mount(nspace_id nsid, const char *device, ulong flags, void *pa
} }
// Try and mount volume as a FAT volume // Try and mount volume as a FAT volume
if ((result = mount_fat_disk(device, nsid, flags, &vol)) == B_NO_ERROR) { if ((result = mount_fat_disk(device, nsid, flags, &vol, fs_flags, op_sync_mode)) == B_NO_ERROR) {
char name[32]; char name[32];
if (check_nspace_magic(vol, "dosfs_mount")) return EINVAL; if (check_nspace_magic(vol, "dosfs_mount")) return EINVAL;
@@ -643,7 +675,7 @@ static int dosfs_unmount(void *_vol)
dlist_uninit(vol); dlist_uninit(vol);
uninit_vcache(vol); uninit_vcache(vol);
if (!(vol->flags & B_FS_IS_READONLY) && (vol->flags & B_FS_IS_REMOVABLE)) if (!(vol->flags & B_FS_IS_READONLY) && (vol->flags & B_FS_IS_REMOVABLE) && (vol->fs_flags & FS_FLAGS_LOCK_DOOR))
lock_removable_device(vol->fd, false); lock_removable_device(vol->fd, false);
result = close(vol->fd); result = close(vol->fd);
free_lock(&(vol->vlock)); free_lock(&(vol->vlock));
@@ -798,6 +830,9 @@ static int dosfs_wfsstat(void *_vol, struct fs_info * fss, long mask)
memcpy(vol->vol_label, name, 11); memcpy(vol->vol_label, name, 11);
} }
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
bi: UNLOCK_VOL(vol); bi: UNLOCK_VOL(vol);
return result; return result;
@@ -896,25 +931,29 @@ static int dosfs_ioctl(void *_vol, void *_node, void *cookie, int code,
return result; return result;
} }
static int dosfs_sync(void *_vol) int _dosfs_sync(nspace *vol)
{ {
nspace *vol = (nspace *)_vol; if (check_nspace_magic(vol, "dosfs_sync"))
LOCK_VOL(vol);
if (check_nspace_magic((nspace*)_vol, "dosfs_sync")) {
UNLOCK_VOL(vol);
return EINVAL; return EINVAL;
}
DPRINTF(0, ("dosfs_sync called on volume %lx\n", vol->id));
update_fsinfo(vol); update_fsinfo(vol);
flush_device(vol->fd, 0); flush_device(vol->fd, 0);
return 0;
}
static int dosfs_sync(void *_vol)
{
nspace *vol = (nspace *)_vol;
int err;
DPRINTF(0, ("dosfs_sync called on volume %lx\n", vol->id));
LOCK_VOL(vol);
err = _dosfs_sync(vol);
UNLOCK_VOL(vol); UNLOCK_VOL(vol);
return 0; return err;
} }
static int dosfs_fsync(void *vol, void *node) static int dosfs_fsync(void *vol, void *node)
+9 -1
View File
@@ -2,7 +2,6 @@
Copyright 1999-2001, Be Incorporated. All Rights Reserved. Copyright 1999-2001, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License. This file may be used under the terms of the Be Sample Code License.
*/ */
#ifndef _DOSFS_H_ #ifndef _DOSFS_H_
#define _DOSFS_H_ #define _DOSFS_H_
@@ -101,6 +100,8 @@ typedef struct vnode
const char *mime; // mime type (null if none) const char *mime; // mime type (null if none)
bool dirty; // track if vnode had been written to
#if TRACK_FILENAME #if TRACK_FILENAME
char *filename; char *filename;
#endif #endif
@@ -155,6 +156,8 @@ typedef struct _nspace
vnode_id beos_vnid; // vnid of \BEOS directory vnode_id beos_vnid; // vnid of \BEOS directory
bool respect_disk_image; bool respect_disk_image;
int fs_flags; // flags for this mount
lock vlock; lock vlock;
// vcache state // vcache state
@@ -172,6 +175,9 @@ typedef struct _nspace
} dlist; } dlist;
} nspace; } nspace;
#define FS_FLAGS_OP_SYNC 0x1
#define FS_FLAGS_LOCK_DOOR 0x2
#define LOCK_VOL(vol) \ #define LOCK_VOL(vol) \
if (vol == NULL) { dprintf("null vol\n"); return EINVAL; } else LOCK((vol)->vlock) if (vol == NULL) { dprintf("null vol\n"); return EINVAL; } else LOCK((vol)->vlock)
@@ -200,4 +206,6 @@ int check_nspace_magic(struct _nspace *t, char *funcname);
extern int debug_attr, debug_dir, debug_dlist, debug_dosfs, debug_encodings, extern int debug_attr, debug_dir, debug_dlist, debug_dosfs, debug_encodings,
debug_fat, debug_file, debug_iter, debug_vcache; debug_fat, debug_file, debug_iter, debug_vcache;
int _dosfs_sync(nspace *vol);
#endif #endif
+73 -16
View File
@@ -2,7 +2,6 @@
Copyright 1999-2001, Be Incorporated. All Rights Reserved. Copyright 1999-2001, Be Incorporated. All Rights Reserved.
This file may be used under the terms of the Be Sample Code License. This file may be used under the terms of the Be Sample Code License.
*/ */
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
@@ -113,6 +112,12 @@ int dosfs_write_vnode(void *_vol, void *_node, char reenter)
DPRINTF(0, ("dosfs_write_vnode (vnode_id %Lx)\n", ((vnode *)_node)->vnid)); DPRINTF(0, ("dosfs_write_vnode (vnode_id %Lx)\n", ((vnode *)_node)->vnid));
if ((vol->fs_flags & FS_FLAGS_OP_SYNC) && node->dirty) {
LOCK_VOL(vol);
_dosfs_sync(vol);
UNLOCK_VOL(vol);
}
if (node != NULL) { if (node != NULL) {
#if TRACK_FILENAME #if TRACK_FILENAME
if (node->filename) free(node->filename); if (node->filename) free(node->filename);
@@ -229,6 +234,12 @@ int dosfs_wstat(void *_vol, void *_node, struct stat *st, long mask)
if (dirty) { if (dirty) {
write_vnode_entry(vol, node); write_vnode_entry(vol, node);
notify_listener(B_STAT_CHANGED, vol->id, 0, 0, node->vnid, NULL); notify_listener(B_STAT_CHANGED, vol->id, 0, 0, node->vnid, NULL);
if (vol->fs_flags & FS_FLAGS_OP_SYNC) {
// sync the filesystem
_dosfs_sync(vol);
node->dirty = false;
}
} }
if (err != B_OK) DPRINTF(0, ("dosfs_wstat (%s)\n", strerror(err))); if (err != B_OK) DPRINTF(0, ("dosfs_wstat (%s)\n", strerror(err)));
@@ -537,6 +548,7 @@ int dosfs_write(void *_vol, void *_node, void *_cookie, off_t pos,
write_vnode_entry(vol, node); write_vnode_entry(vol, node);
DPRINTF(0, ("setting file size to %Lx (%lx clusters)\n", node->st_size, clusters)); DPRINTF(0, ("setting file size to %Lx (%lx clusters)\n", node->st_size, clusters));
node->dirty = true;
} }
if (cluster1 == 0xffffffff) { if (cluster1 == 0xffffffff) {
@@ -558,6 +570,9 @@ int dosfs_write(void *_vol, void *_node, void *_cookie, off_t pos,
ASSERT(iter.cluster == get_nth_fat_entry(vol, node->cluster, pos / vol->bytes_per_sector / vol->sectors_per_cluster)); ASSERT(iter.cluster == get_nth_fat_entry(vol, node->cluster, pos / vol->bytes_per_sector / vol->sectors_per_cluster));
if(*len > 0)
node->dirty = true;
// write partial first sector if necessary // write partial first sector if necessary
if ((pos % vol->bytes_per_sector) != 0) { if ((pos % vol->bytes_per_sector) != 0) {
size_t amt; size_t amt;
@@ -655,6 +670,11 @@ int dosfs_close(void *_vol, void *_node, void *_cookie)
DPRINTF(0, ("dosfs_close (vnode id %Lx)\n", ((vnode *)_node)->vnid)); DPRINTF(0, ("dosfs_close (vnode id %Lx)\n", ((vnode *)_node)->vnid));
if ((vol->fs_flags & FS_FLAGS_OP_SYNC) && node->dirty) {
_dosfs_sync(vol);
node->dirty = false;
}
UNLOCK_VOL(vol); UNLOCK_VOL(vol);
return 0; return 0;
@@ -788,17 +808,22 @@ int dosfs_create(void *_vol, void *_dir, const char *name, int omode,
// XXX: dangerous construct // XXX: dangerous construct
if (find_vnid_in_vcache(vol, dummy.vnid) == B_OK) { if (find_vnid_in_vcache(vol, dummy.vnid) == B_OK) {
dummy.vnid = generate_unique_vnid(vol); dummy.vnid = generate_unique_vnid(vol);
if ((result = add_to_vcache(vol, dummy.vnid, GENERATE_DIR_INDEX_VNID(dummy.dir_vnid, dummy.sindex))) < 0) if ((result = add_to_vcache(vol, dummy.vnid, GENERATE_DIR_INDEX_VNID(dummy.dir_vnid, dummy.sindex))) < 0) {
// XXX: should remove entry on failure // XXX: should remove entry on failure
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
goto bi; goto bi;
} }
}
*vnid = dummy.vnid; *vnid = dummy.vnid;
dummy.magic = ~VNODE_MAGIC; dummy.magic = ~VNODE_MAGIC;
result = get_vnode(vol->id, *vnid, (void **)&file); result = get_vnode(vol->id, *vnid, (void **)&file);
if (result < B_OK) if (result < B_OK) {
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
goto bi; goto bi;
}
} else { } else {
goto bi; goto bi;
} }
@@ -814,6 +839,9 @@ int dosfs_create(void *_vol, void *_dir, const char *name, int omode,
result = 0; result = 0;
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
bi: if (result != B_OK) free(cookie); bi: if (result != B_OK) free(cookie);
UNLOCK_VOL(vol); UNLOCK_VOL(vol);
@@ -953,6 +981,9 @@ int dosfs_mkdir(void *_vol, void *_dir, const char *name, int perms)
result = B_OK; result = B_OK;
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
UNLOCK_VOL(vol); UNLOCK_VOL(vol);
return result; return result;
@@ -960,6 +991,8 @@ bi5:free(buffer);
bi4:dlist_remove(vol, dummy.vnid); bi4:dlist_remove(vol, dummy.vnid);
bi3:if (IS_ARTIFICIAL_VNID(dummy.vnid)) remove_from_vcache(vol, dummy.vnid); bi3:if (IS_ARTIFICIAL_VNID(dummy.vnid)) remove_from_vcache(vol, dummy.vnid);
bi2:clear_fat_chain(vol, dummy.cluster); bi2:clear_fat_chain(vol, dummy.cluster);
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
bi: dummy.magic = ~VNODE_MAGIC; bi: dummy.magic = ~VNODE_MAGIC;
UNLOCK_VOL(vol); UNLOCK_VOL(vol);
@@ -975,6 +1008,7 @@ int dosfs_rename(void *_vol, void *_odir, const char *oldname,
vnode *odir = (vnode *)_odir, *ndir = (vnode *)_ndir, *file, *file2; vnode *odir = (vnode *)_odir, *ndir = (vnode *)_ndir, *file, *file2;
uint32 ns, ne; uint32 ns, ne;
bool dups_exist; bool dups_exist;
bool dirty = false;
LOCK_VOL(vol); LOCK_VOL(vol);
@@ -1080,20 +1114,25 @@ int dosfs_rename(void *_vol, void *_odir, const char *oldname,
remove_vnode(vol->id, file2->vnid); // must be done in this order remove_vnode(vol->id, file2->vnid); // must be done in this order
put_vnode(vol->id, file2->vnid); put_vnode(vol->id, file2->vnid);
// erase old directory entry dirty = true;
if ((result = erase_dir_entry(vol, file)) != B_OK) {
dprintf("dosfs_rename: error erasing old directory entry for %s (%s)\n", newname, strerror(result));
goto bi1;
}
} else if (result == ENOENT && (!dups_exist || odir->vnid == ndir->vnid)) {
// there isn't an entry and there is no duplicates in the target dir or
// there isn't an entry and the target dir is the same as the source dir
// erase old directory entry // erase old directory entry
if ((result = erase_dir_entry(vol, file)) != B_OK) { if ((result = erase_dir_entry(vol, file)) != B_OK) {
dprintf("dosfs_rename: error erasing old directory entry for %s (%s)\n", newname, strerror(result)); dprintf("dosfs_rename: error erasing old directory entry for %s (%s)\n", newname, strerror(result));
goto bi1; goto bi1;
} }
} else if (result == ENOENT && (!dups_exist || (odir->vnid == ndir->vnid && !strcasecmp(oldname, newname)))) {
// there isn't an entry and there are no duplicates in the target dir or
// there isn't an entry and the target dir is the same as the source dir and
// the source and target name are the same, case-insensitively
// erase old directory entry
if ((result = erase_dir_entry(vol, file)) != B_OK) {
dprintf("dosfs_rename: error erasing old directory entry for %s (%s)\n", newname, strerror(result));
goto bi1;
}
dirty = true;
// create the new directory entry // create the new directory entry
if ((result = create_dir_entry(vol, ndir, file, newname, &ns, &ne)) != B_OK) { if ((result = create_dir_entry(vol, ndir, file, newname, &ns, &ne)) != B_OK) {
@@ -1111,6 +1150,8 @@ int dosfs_rename(void *_vol, void *_odir, const char *oldname,
// shrink the directory (an error here is not disastrous) // shrink the directory (an error here is not disastrous)
compact_directory(vol, odir); compact_directory(vol, odir);
dirty = true;
// update vnode information // update vnode information
file->dir_vnid = ndir->vnid; file->dir_vnid = ndir->vnid;
file->sindex = ns; file->sindex = ns;
@@ -1173,9 +1214,14 @@ int dosfs_rename(void *_vol, void *_odir, const char *oldname,
result = 0; result = 0;
bi2:if (result != B_OK) put_vnode(vol->id, file2->vnid); bi2:
bi1:put_vnode(vol->id, file->vnid); if (result != B_OK) put_vnode(vol->id, file2->vnid);
bi: UNLOCK_VOL(vol); bi1:
put_vnode(vol->id, file->vnid);
bi:
if ((vol->fs_flags & FS_FLAGS_OP_SYNC) && dirty)
_dosfs_sync(vol);
UNLOCK_VOL(vol);
if (result != B_OK) DPRINTF(0, ("dosfs_rename (%s)\n", strerror(result))); if (result != B_OK) DPRINTF(0, ("dosfs_rename (%s)\n", strerror(result)));
return result; return result;
} }
@@ -1219,7 +1265,15 @@ int dosfs_remove_vnode(void *_vol, void *_node, char reenter)
node->magic = ~VNODE_MAGIC; // munge magic number to be safe node->magic = ~VNODE_MAGIC; // munge magic number to be safe
free(node); free(node);
if (!reenter) UNLOCK_VOL(vol); if (!reenter) {
if (vol->fs_flags & FS_FLAGS_OP_SYNC) {
// sync the entire filesystem,
// but only if we're not reentrant. Presumably the
// function that called this will sync.
_dosfs_sync(vol);
}
UNLOCK_VOL(vol);
}
return 0; return 0;
} }
@@ -1322,6 +1376,9 @@ static int do_unlink(void *_vol, void *_dir, const char *name, bool is_file)
result = 0; result = 0;
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
bi1:put_vnode(vol->id, vnid); // get 1 free bi1:put_vnode(vol->id, vnid); // get 1 free
bi: UNLOCK_VOL(vol); bi: UNLOCK_VOL(vol);