FAT: Make more use of C++ features and utility classes.

This driver was fully C until relatively recently, when it was
switched to C++ so that it could be used with fs_shell. However,
it still is mostly using C paradigms; so this commit begins the
refactor away from that.

If I did this correctly, there should not be any functional change.

Change-Id: Id87d17b2e019ccdd1c7f07156cfe2a2124496675
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4725
Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
Augustin Cavalier
2021-12-01 21:16:26 +00:00
committed by waddlesplash
parent 9dcb1b7ff7
commit 8896f5d72f
7 changed files with 137 additions and 321 deletions
+13 -31
View File
@@ -27,11 +27,11 @@ int32 kBeOSTypeCookie = 0x1234;
status_t set_mime_type(vnode *node, const char *filename)
{
#ifdef FS_SHELL
#ifdef FS_SHELL
return B_ERROR;
#else
#else
return set_mime(&node->mime, filename);
#endif
#endif
}
@@ -44,16 +44,13 @@ dosfs_open_attrdir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
DPRINTF(0, ("dosfs_open_attrdir called\n"));
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
if ((*_cookie = malloc(sizeof(uint32))) == NULL) {
UNLOCK_VOL(vol);
return ENOMEM;
}
*(int32 *)(*_cookie) = 0;
UNLOCK_VOL(vol);
return 0;
}
@@ -67,12 +64,10 @@ dosfs_close_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
DPRINTF(0, ("dosfs_close_attrdir called\n"));
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
*(int32 *)_cookie = 1;
UNLOCK_VOL(vol);
return 0;
}
@@ -127,7 +122,7 @@ dosfs_read_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie,
*num = 0;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
if ((*cookie == 0) && (node->mime)) {
*num = 1;
@@ -140,8 +135,6 @@ dosfs_read_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie,
*cookie = 1;
UNLOCK_VOL(vol);
return 0;
}
@@ -156,15 +149,12 @@ dosfs_open_attr(fs_volume *_vol, fs_vnode *_node, const char *name,
if (strcmp(name, "BEOS:TYPE"))
return ENOENT;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
if (node->mime == NULL) {
UNLOCK_VOL(vol);
return ENOENT;
}
UNLOCK_VOL(vol);
*_cookie = &kBeOSTypeCookie;
return B_OK;
}
@@ -196,17 +186,15 @@ dosfs_read_attr_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie,
if (_cookie != &kBeOSTypeCookie)
return ENOENT;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
if (node->mime == NULL) {
UNLOCK_VOL(vol);
return ENOENT;
}
stat->st_type = MIME_STRING_TYPE;
stat->st_size = strlen(node->mime) + 1;
UNLOCK_VOL(vol);
return 0;
}
@@ -224,27 +212,21 @@ dosfs_read_attr(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
if (_cookie != &kBeOSTypeCookie)
return ENOENT;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
if (node->mime == NULL) {
UNLOCK_VOL(vol);
if (node->mime == NULL)
return ENOENT;
}
if ((pos < 0) || (pos > strlen(node->mime))) {
UNLOCK_VOL(vol);
if ((pos < 0) || (pos > strlen(node->mime)))
return EINVAL;
}
length = user_strlcpy((char*)buffer, node->mime + pos, *_length);
if (length < B_OK) {
UNLOCK_VOL(vol);
if (length < B_OK)
return B_BAD_ADDRESS;
}
if (length < *_length)
*_length = length + 1;
UNLOCK_VOL(vol);
return 0;
}
+24 -80
View File
@@ -157,7 +157,6 @@ _next_dirent_(struct diri *iter, struct _dirent_info_ *oinfo, char *filename,
// rewind to beginning of call
dprintf("error: long file name too long\n");
diri_free(iter);
diri_init(iter->csi.vol, iter->starting_cluster, start_index,
iter);
return ENAMETOOLONG;
@@ -297,8 +296,6 @@ check_dir_empty(nspace *vol, vnode *dir)
result = ENOTEMPTY;
}
diri_free(&iter);
return result;
}
@@ -405,7 +402,6 @@ findfile(nspace *vol, vnode *dir, const char *file, ino_t *vnid,
if (found_file && (!check_dups || (check_dups && *dups_exist)))
break;
}
diri_free(&diri);
}
if (found_file) {
if (vnid)
@@ -448,7 +444,6 @@ erase_dir_entry(nspace *vol, vnode *node)
}
result = _next_dirent_(&diri, &info, filename, 512);
diri_free(&diri);
if (result < 0)
return result;
@@ -466,7 +461,6 @@ erase_dir_entry(nspace *vol, vnode *node)
diri_make_writable(&diri);
buffer[0] = 0xe5; // mark entry erased
}
diri_free(&diri);
return 0;
}
@@ -533,7 +527,6 @@ compact_directory(nspace *vol, vnode *dir)
break;
}
}
diri_free(&diri);
return error;
}
@@ -562,8 +555,6 @@ find_short_name(nspace *vol, vnode *dir, const uchar *name)
buffer = diri_next_entry(&diri);
}
diri_free(&diri);
return result;
}
@@ -653,8 +644,6 @@ _create_dir_entry_(nspace *vol, vnode *dir, struct _entry_info_ *info,
// if at end of directory, last_entry flag will be true as it should be
diri_free(&diri);
if (error != B_OK && error != ENOENT)
return error;
@@ -723,7 +712,6 @@ _create_dir_entry_(nspace *vol, vnode *dir, struct _entry_info_ *info,
ASSERT(buffer != NULL);
if (buffer == NULL) { // this should never happen...
DPRINTF(0, ("_create_dir_entry_: the unthinkable has occured\n"));
diri_free(&diri);
return B_ERROR;
}
@@ -766,8 +754,6 @@ _create_dir_entry_(nspace *vol, vnode *dir, struct _entry_info_ *info,
}
}
diri_free(&diri);
return 0;
}
@@ -934,7 +920,7 @@ dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
struct diri iter;
char filename[512]; /* need this for setting mime type */
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
_node->private_node = NULL;
_node->ops = &gFATVnodeOps;
@@ -946,7 +932,7 @@ dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
dprintf("??? dosfs_read_vnode called on root node ???\n");
_node->private_node = (void *)&(vol->root_vnode);
*_type = make_mode(vol, &vol->root_vnode);
goto bi;
return result;
}
if (vcache_vnid_to_loc(vol, vnid, &loc) != B_OK)
@@ -955,15 +941,13 @@ dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
if (IS_ARTIFICIAL_VNID(loc) || IS_INVALID_VNID(loc)) {
DPRINTF(0, ("dosfs_read_vnode: unknown vnid %" B_PRIdINO " (loc %"
B_PRIdINO ")\n", vnid, loc));
result = ENOENT;
goto bi;
return ENOENT;
}
if ((dir_vnid = dlist_find(vol, DIR_OF_VNID(loc))) == -1LL) {
DPRINTF(0, ("dosfs_read_vnode: unknown directory at cluster %" B_PRIu32
"\n", DIR_OF_VNID(loc)));
result = ENOENT;
goto bi;
return ENOENT;
}
if (diri_init(vol, DIR_OF_VNID(loc),
@@ -971,8 +955,7 @@ dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
&iter) == NULL) {
dprintf("dosfs_read_vnode: error initializing directory for vnid %"
B_PRIdINO " (loc %" B_PRIdINO ")\n", vnid, loc);
result = ENOENT;
goto bi;
return ENOENT;
}
while (1) {
@@ -980,7 +963,7 @@ dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
if (result < 0) {
dprintf("dosfs_read_vnode: error finding vnid %" B_PRIdINO
" (loc %" B_PRIdINO ") (%s)\n", vnid, loc, strerror(result));
goto bi2;
return result;
}
if (IS_DIR_CLUSTER_VNID(loc)) {
@@ -991,15 +974,13 @@ dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
break;
dprintf("dosfs_read_vnode: error finding vnid %" B_PRIdINO
" (loc %" B_PRIdINO ") (%s)\n", vnid, loc, strerror(result));
result = ENOENT;
goto bi2;
return ENOENT;
}
}
if ((entry = (vnode *)calloc(sizeof(struct vnode), 1)) == NULL) {
DPRINTF(0, ("dosfs_read_vnode: out of memory\n"));
result = ENOMEM;
goto bi2;
return ENOMEM;
}
entry->vnid = vnid;
@@ -1045,15 +1026,7 @@ dosfs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type,
_node->private_node = entry;
*_type = make_mode(vol, entry);
bi2:
diri_free(&iter);
bi:
UNLOCK_VOL(vol);
if (result != B_OK)
DPRINTF(0, ("dosfs_read_vnode (%s)\n", strerror(result)));
return result;
return B_OK;
}
@@ -1067,7 +1040,7 @@ dosfs_walk(fs_volume *_vol, fs_vnode *_dir, const char *file, ino_t *_vnid)
vnode *vnode = NULL;
status_t result = ENOENT;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_walk: find %" B_PRIdINO "/%s\n", dir->vnid, file));
@@ -1078,8 +1051,6 @@ dosfs_walk(fs_volume *_vol, fs_vnode *_dir, const char *file, ino_t *_vnid)
DPRINTF(0, ("dosfs_walk: found vnid %" B_PRIdINO "\n", *_vnid));
}
UNLOCK_VOL(vol);
return result;
}
@@ -1091,7 +1062,7 @@ dosfs_access(fs_volume *_vol, fs_vnode *_node, int mode)
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_access (vnode id %" B_PRIdINO ", mode %o)\n", node->vnid,
mode));
@@ -1109,8 +1080,6 @@ dosfs_access(fs_volume *_vol, fs_vnode *_node, int mode)
}
}
UNLOCK_VOL(vol);
return result;
}
@@ -1132,10 +1101,8 @@ dosfs_opendir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
{
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
dircookie *cookie = NULL;
int result;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_opendir (vnode id %" B_PRIdINO ")\n", node->vnid));
@@ -1147,29 +1114,18 @@ dosfs_opendir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
* with the application than with the file system, anyway
*/
DPRINTF(0, ("dosfs_opendir error: vnode not a directory\n"));
result = ENOTDIR;
goto bi;
return ENOTDIR;
}
if ((cookie = (dircookie *)malloc(sizeof(dircookie))) == NULL) {
dircookie *cookie = (dircookie *)malloc(sizeof(dircookie));
if (cookie == NULL) {
DPRINTF(0, ("dosfs_opendir: out of memory error\n"));
result = ENOMEM;
goto bi;
return ENOMEM;
}
cookie->current_index = 0;
result = B_NO_ERROR;
bi:
*_cookie = (void *)cookie;
if (result != B_OK)
DPRINTF(0, ("dosfs_opendir (%s)\n", strerror(result)));
UNLOCK_VOL(vol);
return result;
return B_OK;
}
@@ -1183,7 +1139,7 @@ dosfs_readdir(fs_volume *_vol, fs_vnode *_dir, void *_cookie,
dircookie* cookie = (dircookie *)_cookie;
struct diri diri;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_readdir: vnode id %" B_PRIdINO ", index %" B_PRIu32 "\n",
dir->vnid, cookie->current_index));
@@ -1203,8 +1159,7 @@ dosfs_readdir(fs_volume *_vol, fs_vnode *_dir, void *_cookie,
*num = 1;
entry->d_ino = vol->root_vnode.vnid;
entry->d_dev = vol->id;
result = B_NO_ERROR;
goto bi;
return B_NO_ERROR;
}
}
@@ -1213,15 +1168,13 @@ dosfs_readdir(fs_volume *_vol, fs_vnode *_dir, void *_cookie,
// When you get to the end, don't return an error, just return 0
// in *num.
*num = 0;
result = B_NO_ERROR;
goto bi;
return B_NO_ERROR;
}
result = get_next_dirent(vol, dir, &diri, &entry->d_ino, entry->d_name,
bufsize - sizeof(struct dirent) - 1);
cookie->current_index = diri.current_index;
diri_free(&diri);
if (dir->vnid == vol->root_vnode.vnid)
cookie->current_index += 2;
@@ -1235,17 +1188,13 @@ dosfs_readdir(fs_volume *_vol, fs_vnode *_dir, void *_cookie,
// When you get to the end, don't return an error, just return 0
// in *num.
*num = 0;
result = B_NO_ERROR;
return B_OK;
} else {
dprintf("dosfs_readdir: error returned by get_next_dirent (%s)\n",
strerror(result));
}
bi:
if (result != B_OK) DPRINTF(0, ("dosfs_readdir (%s)\n", strerror(result)));
UNLOCK_VOL(vol);
return result;
return B_OK;
}
@@ -1256,14 +1205,12 @@ dosfs_rewinddir(fs_volume *_vol, fs_vnode *_node, void* _cookie)
vnode *node = (vnode *)_node->private_node;
dircookie *cookie = (dircookie *)_cookie;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_rewinddir (vnode id %" B_PRIdINO ")\n", node->vnid));
cookie->current_index = 0;
UNLOCK_VOL(vol);
return B_OK;
}
@@ -1286,15 +1233,12 @@ dosfs_free_dircookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
vnode *node = (vnode *)_node->private_node;
dircookie *cookie = (dircookie *)_cookie;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_free_dircookie (vnode id %" B_PRIdINO ")\n",
node->vnid));
free(cookie);
UNLOCK_VOL(vol);
return 0;
}
+20 -37
View File
@@ -174,12 +174,12 @@ volume_init(int fd, uint8* buf,
const int flags, int fs_flags,
device_geometry *geo)
{
nspace *vol = NULL;
uint8 media_buf[512];
int i;
status_t err;
if ((vol = (nspace *)calloc(sizeof(nspace), 1)) == NULL) {
nspace* vol = (nspace *)calloc(sizeof(nspace), 1);
if (vol == NULL) {
dprintf("dosfs error: out of memory\n");
return NULL;
}
@@ -419,8 +419,6 @@ volume_init(int fd, uint8* buf,
break;
}
}
diri_free(&diri);
}
DPRINTF(0, ("root vnode id = %" B_PRIdINO "\n", vol->root_vnode.vnid));
@@ -944,7 +942,7 @@ dosfs_unmount(fs_volume *_vol)
nspace* vol = (nspace*)_vol->private_volume;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_unmount volume %" B_PRIdDEV "\n", vol->id));
@@ -968,6 +966,7 @@ dosfs_unmount(fs_volume *_vol)
uninit_vcache(vol);
result = close(vol->fd);
lock.Unlock();
recursive_lock_destroy(&(vol->vlock));
free(vol);
@@ -985,7 +984,7 @@ dosfs_read_fs_stat(fs_volume *_vol, struct fs_info * fss)
{
nspace* vol = (nspace*)_vol->private_volume;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(1, ("dosfs_read_fs_stat called\n"));
@@ -1019,8 +1018,6 @@ dosfs_read_fs_stat(fs_volume *_vol, struct fs_info * fss)
// File system name
strcpy(fss->fsh_name, "fat");
UNLOCK_VOL(vol);
return B_OK;
}
@@ -1031,16 +1028,14 @@ dosfs_write_fs_stat(fs_volume *_vol, const struct fs_info * fss, uint32 mask)
status_t result = B_ERROR;
nspace* vol = (nspace*)_vol->private_volume;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_write_fs_stat called\n"));
/* if it's a r/o file system and not the special hack, then don't allow
* volume renaming */
if ((vol->flags & B_FS_IS_READONLY) && memcmp(vol->vol_label, "__RO__ ", 11)) {
UNLOCK_VOL(vol);
if ((vol->flags & B_FS_IS_READONLY) && memcmp(vol->vol_label, "__RO__ ", 11))
return EROFS;
}
if (mask & FS_WRITE_FSINFO_NAME) {
// sanitize name
@@ -1055,10 +1050,8 @@ dosfs_write_fs_stat(fs_volume *_vol, const struct fs_info * fss, uint32 mask)
if (strchr(sAcceptable, c) || (c == ' '))
name[i++] = c;
}
if (i == 0) { // bad name, kiddo
result = EINVAL;
goto bi;
}
if (i == 0) // bad name, kiddo
return EINVAL;
DPRINTF(1, ("wfsstat: sanitized to [%11.11s]\n", name));
if (vol->vol_entry == -1) {
@@ -1067,7 +1060,7 @@ dosfs_write_fs_stat(fs_volume *_vol, const struct fs_info * fss, uint32 mask)
result = block_cache_get_writable_etc(vol->fBlockCache, 0,
0, vol->bytes_per_sector, -1, (void**)&buffer);
if (result != B_OK)
goto bi;
return result;
if ((vol->sectors_per_fat == 0 && (buffer[0x42] != 0x29
|| strncmp((const char *)buffer + 0x47, vol->vol_label, 11)
@@ -1089,22 +1082,19 @@ dosfs_write_fs_stat(fs_volume *_vol, const struct fs_info * fss, uint32 mask)
buffer = diri_init(vol, vol->root_vnode.cluster, vol->vol_entry, &diri);
// check if it is the same as the old volume label
if (buffer == NULL || strncmp((const char *)buffer, vol->vol_label,
11) == 0) {
if (buffer == NULL || strncmp((const char *)buffer, vol->vol_label, 11) == 0) {
dprintf("dosfs_wfsstat: label mismatch\n");
diri_free(&diri);
result = B_ERROR;
goto bi;
return B_ERROR;
}
diri_make_writable(&diri);
memcpy(buffer, name, 11);
diri_free(&diri);
result = B_OK;
} else {
uint32 index;
result = create_volume_label(vol, name, &index);
if (result == B_OK) vol->vol_entry = index;
if (result == B_OK)
vol->vol_entry = index;
}
if (result == B_OK) {
@@ -1116,8 +1106,6 @@ dosfs_write_fs_stat(fs_volume *_vol, const struct fs_info * fss, uint32 mask)
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
bi: UNLOCK_VOL(vol);
return result;
}
@@ -1158,8 +1146,8 @@ dosfs_ioctl(fs_volume *_vol, fs_vnode *_node, void *cookie, uint32 code,
dump_fat_chain(vol, node->cluster);
break;
case 100002 :
{struct diri diri;
case 100002 : {
struct diri diri;
uint8 *buffer;
uint32 i;
for (i=0,buffer=diri_init(vol,node->cluster, 0, &diri);buffer;buffer=diri_next_entry(&diri),i++) {
@@ -1167,8 +1155,8 @@ dosfs_ioctl(fs_volume *_vol, fs_vnode *_node, void *cookie, uint32 code,
dprintf("entry %lx:\n", i);
dump_directory(buffer);
}
diri_free(&diri);}
break;
}
case 100003 :
dprintf("vcache validation not yet implemented\n");
@@ -1215,15 +1203,11 @@ static status_t
dosfs_sync(fs_volume *_vol)
{
nspace *vol = (nspace *)_vol->private_volume;
status_t err;
DPRINTF(0, ("dosfs_sync called on volume %" B_PRIdDEV "\n", vol->id));
LOCK_VOL(vol);
err = _dosfs_sync(vol);
UNLOCK_VOL(vol);
return err;
RecursiveLocker lock(vol->vlock);
return _dosfs_sync(vol);
}
@@ -1234,12 +1218,11 @@ dosfs_fsync(fs_volume *_vol, fs_vnode *_node)
vnode *node = (vnode *)_node->private_node;
status_t err = B_OK;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
if (node->cache)
err = file_cache_sync(node->cache);
UNLOCK_VOL(vol);
return err;
}
@@ -165,12 +165,6 @@ typedef struct _nspace {
#define FS_FLAGS_OP_SYNC 0x1
#define FS_FLAGS_LOCK_DOOR 0x2
#define LOCK_VOL(vol) \
if (vol == NULL) { dprintf("null vol\n"); return EINVAL; } else LOCK((vol)->vlock)
#define UNLOCK_VOL(vol) \
UNLOCK((vol)->vlock)
#define TOUCH(x) ((void)(x))
extern fs_vnode_ops gFATVnodeOps;
+71 -157
View File
@@ -56,7 +56,6 @@ status_t write_vnode_entry(nspace *vol, vnode *node)
struct diri diri;
uint8 *buffer;
// TODO : is it needed ? vfs job ?
// don't update entries of deleted files
//if (is_vnode_removed(vol->id, node->vnid) > 0) return 0;
@@ -103,8 +102,6 @@ status_t write_vnode_entry(nspace *vol, vnode *node)
buffer[0x1f] = (node->st_size >> 24) & 0xff;
}
diri_free(&diri);
// TODO: figure out which stats have actually changed
notify_stat_changed(vol->id, -1, node->vnid, B_STAT_MODE | B_STAT_UID
| B_STAT_GID | B_STAT_SIZE | B_STAT_ACCESS_TIME
@@ -129,9 +126,8 @@ dosfs_release_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter)
DPRINTF(0, ("dosfs_release_vnode (ino_t %" B_PRIdINO ")\n", node->vnid));
if ((vol->fs_flags & FS_FLAGS_OP_SYNC) && node->dirty) {
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
_dosfs_sync(vol);
UNLOCK_VOL(vol);
}
if (node->filename) free(node->filename);
@@ -153,7 +149,7 @@ dosfs_rstat(fs_volume *_vol, fs_vnode *_node, struct stat *st)
nspace *vol = (nspace*)_vol->private_volume;
vnode *node = (vnode*)_node->private_node;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(1, ("dosfs_rstat (vnode id %" B_PRIdINO ")\n", node->vnid));
@@ -173,8 +169,6 @@ dosfs_rstat(fs_volume *_vol, fs_vnode *_node, struct stat *st)
st->st_atim.tv_nsec = st->st_mtim.tv_nsec = st->st_ctim.tv_nsec
= st->st_crtim.tv_nsec = 0;
UNLOCK_VOL(vol);
return B_NO_ERROR;
}
@@ -188,19 +182,17 @@ dosfs_wstat(fs_volume *_vol, fs_vnode *_node, const struct stat *st,
vnode *node = (vnode*)_node->private_node;
bool dirty = false;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_wstat (vnode id %" B_PRIdINO ")\n", node->vnid));
if (vol->flags & B_FS_IS_READONLY) {
dprintf("can't wstat on read-only volume\n");
UNLOCK_VOL(vol);
return EROFS;
}
if (node->disk_image == 2) {
dprintf("can't wstat disk image\n");
UNLOCK_VOL(vol);
return EPERM;
}
@@ -264,9 +256,8 @@ dosfs_wstat(fs_volume *_vol, fs_vnode *_node, const struct stat *st,
}
}
if (err != B_OK) DPRINTF(0, ("dosfs_wstat (%s)\n", strerror(err)));
UNLOCK_VOL(vol);
if (err != B_OK)
DPRINTF(0, ("dosfs_wstat (%s)\n", strerror(err)));
return err;
}
@@ -278,60 +269,52 @@ dosfs_open(fs_volume *_vol, fs_vnode *_node, int omode, void **_cookie)
status_t result = EINVAL;
nspace *vol = (nspace *)_vol->private_volume;
vnode* node = (vnode*)_node->private_node;
filecookie *cookie;
*_cookie = NULL;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_open: vnode id %" B_PRIdINO ", omode %o\n", node->vnid,
omode));
if (omode & O_CREAT) {
dprintf("dosfs_open called with O_CREAT. call dosfs_create instead!\n");
result = EINVAL;
goto error;
return EINVAL;
}
if ((vol->flags & B_FS_IS_READONLY) ||
(node->mode & FAT_READ_ONLY) ||
(node->disk_image != 0) ||
if ((vol->flags & B_FS_IS_READONLY)
|| (node->mode & FAT_READ_ONLY)
|| (node->disk_image != 0)
// allow opening directories for ioctl() calls
// and to let BVolume to work
(node->mode & FAT_SUBDIR)) {
|| (node->mode & FAT_SUBDIR)) {
omode = (omode & ~O_RWMASK) | O_RDONLY;
}
if ((omode & O_TRUNC) && ((omode & O_RWMASK) == O_RDONLY)) {
DPRINTF(0, ("can't open file for reading with O_TRUNC\n"));
result = EPERM;
goto error;
return EPERM;
}
if (omode & O_TRUNC) {
DPRINTF(0, ("dosfs_open called with O_TRUNC set\n"));
if ((result = set_fat_chain_length(vol, node, 0, false)) != B_OK) {
dprintf("dosfs_open: error truncating file\n");
goto error;
return result;
}
node->mode = 0;
node->st_size = 0;
node->iteration++;
}
if ((cookie = (filecookie*)calloc(sizeof(filecookie), 1)) == NULL) {
result = ENOMEM;
goto error;
}
filecookie *cookie = (filecookie*)calloc(sizeof(filecookie), 1);
if (cookie == NULL)
return ENOMEM;
cookie->mode = omode;
*_cookie = cookie;
result = B_OK;
error:
if (result != B_OK) DPRINTF(0, ("dosfs_open (%s)\n", strerror(result)));
UNLOCK_VOL(vol);
return result;
}
@@ -345,13 +328,12 @@ dosfs_read(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
filecookie *cookie = (filecookie *)_cookie;
int result = B_OK;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
if (node->mode & FAT_SUBDIR) {
DPRINTF(0, ("dosfs_read called on subdirectory %" B_PRIdINO "\n",
node->vnid));
*len = 0;
UNLOCK_VOL(vol);
return EISDIR;
}
@@ -365,7 +347,6 @@ dosfs_read(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
} else {
DPRINTF(0, ("dosfs_read: read %" B_PRIuSIZE " bytes\n", *len));
}
UNLOCK_VOL(vol);
return result;
}
@@ -380,20 +361,16 @@ dosfs_write(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
filecookie *cookie = (filecookie *)_cookie;
int result = B_OK;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
if ((vol->flags & B_FS_IS_READONLY) != 0) {
UNLOCK_VOL(vol);
if ((vol->flags & B_FS_IS_READONLY) != 0)
return EROFS;
}
if (node->mode & FAT_SUBDIR) {
DPRINTF(0, ("dosfs_write called on subdirectory %" B_PRIdINO "\n",
node->vnid));
*len = 0;
UNLOCK_VOL(vol);
return EISDIR;
}
DPRINTF(0, ("dosfs_write called %" B_PRIuSIZE " bytes at %" B_PRIdOFF
@@ -403,8 +380,7 @@ dosfs_write(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
if ((cookie->mode & O_RWMASK) == O_RDONLY) {
dprintf("dosfs_write: called on file opened as read-only\n");
*len = 0;
result = EPERM;
goto bi;
return EPERM;
}
if (pos < 0) pos = 0;
@@ -416,8 +392,7 @@ dosfs_write(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
if (pos >= MAX_FILE_SIZE) {
dprintf("dosfs_write: write position exceeds fat limits\n");
*len = 0;
result = E2BIG;
goto bi;
return E2BIG;
}
if (pos + *len >= MAX_FILE_SIZE) {
@@ -430,7 +405,7 @@ dosfs_write(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
if (node->st_size <= (clusters - 1) * vol->sectors_per_cluster * vol->bytes_per_sector) {
if ((result = set_fat_chain_length(vol, node, clusters, false))
!= B_OK) {
goto bi;
return result;
}
node->iteration++;
}
@@ -449,14 +424,6 @@ dosfs_write(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
result = file_cache_write(node->cache, cookie, pos, buf, len);
bi:
if (result != B_OK) {
DPRINTF(0, ("dosfs_write (%s)\n", strerror(result)));
} else {
DPRINTF(0, ("dosfs_write: wrote %" B_PRIuSIZE " bytes\n", *len));
}
UNLOCK_VOL(vol);
return result;
}
@@ -467,7 +434,7 @@ dosfs_close(fs_volume *_vol, fs_vnode *_node, void *_cookie)
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_close (vnode id %" B_PRIdINO ")\n", node->vnid));
@@ -476,8 +443,6 @@ dosfs_close(fs_volume *_vol, fs_vnode *_node, void *_cookie)
node->dirty = false;
}
UNLOCK_VOL(vol);
return 0;
}
@@ -488,15 +453,14 @@ dosfs_free_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
filecookie *cookie = (filecookie *)_cookie;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_free_cookie (vnode id %" B_PRIdINO ")\n", node->vnid));
free(cookie);
UNLOCK_VOL(vol);
return 0;
return B_OK;
}
@@ -510,12 +474,11 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
status_t result = EINVAL;
bool dups_exist;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
ASSERT(name != NULL);
if (name == NULL) {
dprintf("dosfs_create called with null name\n");
UNLOCK_VOL(vol);
return EINVAL;
}
@@ -524,50 +487,44 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
if (vol->flags & B_FS_IS_READONLY) {
dprintf("dosfs_create called on read-only volume\n");
UNLOCK_VOL(vol);
return EROFS;
}
// TODO : is it needed ? vfs job ?
/*if (is_vnode_removed(vol->id, dir->vnid) > 0) {
dprintf("dosfs_create() called in removed directory. disallowed.\n");
UNLOCK_VOL(vol);
return EPERM;
}*/
if ((omode & O_RWMASK) == O_RDONLY) {
dprintf("invalid permissions used in creating file\n");
UNLOCK_VOL(vol);
return EPERM;
}
// create file cookie; do it here to make cleaning up easier
if ((cookie = (filecookie *)calloc(sizeof(filecookie), 1)) == NULL) {
result = ENOMEM;
goto bi;
}
cookie = (filecookie *)calloc(sizeof(filecookie), 1);
MemoryDeleter cookieDeleter(cookie);
if (cookie == NULL)
return ENOMEM;
result = findfile_case_duplicates(vol, dir, name, vnid, &file, &dups_exist);
if (result == B_OK) {
if (omode & O_EXCL) {
dprintf("exclusive dosfs_create called on existing file %s\n", name);
put_vnode(_vol, file->vnid);
result = EEXIST;
goto bi;
return EEXIST;
}
if (file->mode & FAT_SUBDIR) {
dprintf("can't dosfs_create over an existing subdirectory\n");
put_vnode(_vol, file->vnid);
result = EPERM;
goto bi;
return EPERM;
}
if (file->disk_image) {
dprintf("can't dosfs_create over a disk image\n");
put_vnode(_vol, file->vnid);
result = EPERM;
goto bi;
return EPERM;
}
if (omode & O_TRUNC) {
@@ -578,8 +535,7 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
} else if (result == ENOENT && dups_exist) {
// the file doesn't exist in the exact case, but another does in the
// non-exact case. We wont create the new file.
result = EEXIST;
goto bi;
return EEXIST;
} else if (result == ENOENT && !dups_exist) {
// the file doesn't already exist in any case
vnode dummy; /* used only to create directory entry */
@@ -594,7 +550,7 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
if ((result = create_dir_entry(vol, dir, &dummy, name, &(dummy.sindex), &(dummy.eindex))) != B_OK) {
dprintf("dosfs_create: error creating directory entry for %s (%s)\n", name, strerror(result));
goto bi;
return result;
}
dummy.vnid = GENERATE_DIR_INDEX_VNID(dummy.dir_vnid, dummy.sindex);
// XXX: dangerous construct
@@ -604,7 +560,7 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
// XXX: should remove entry on failure
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
goto bi;
return result;
}
}
*vnid = dummy.vnid;
@@ -613,29 +569,22 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
if (result < B_OK) {
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
goto bi;
return result;
}
} else {
goto bi;
return result;
}
cookie->mode = omode;
*_cookie = cookie;
cookieDeleter.Detach();
notify_entry_created(vol->id, dir->vnid, name, *vnid);
result = 0;
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
bi: if (result != B_OK) free(cookie);
UNLOCK_VOL(vol);
if (result != B_OK) DPRINTF(0, ("dosfs_create (%s)\n", strerror(result)));
return result;
return B_OK;
}
@@ -649,12 +598,12 @@ dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms)
uchar *buffer;
uint32 i;
LOCK_VOL(vol);
recursive_lock_lock(&vol->vlock);
// TODO : is it needed ? vfs job ?
/*if (is_vnode_removed(vol->id, dir->vnid) > 0) {
dprintf("dosfs_mkdir() called in removed directory. disallowed.\n");
UNLOCK_VOL(vol);
recursive_lock_unlock(&vol->vlock);
return EPERM;
}*/
@@ -664,7 +613,7 @@ dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms)
if ((dir->mode & FAT_SUBDIR) == 0) {
dprintf("dosfs_mkdir: vnode id %" B_PRIdINO " is not a directory\n",
dir->vnid);
UNLOCK_VOL(vol);
recursive_lock_unlock(&vol->vlock);
return EINVAL;
}
@@ -673,7 +622,7 @@ dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms)
if (vol->flags & B_FS_IS_READONLY) {
dprintf("mkdir called on read-only volume\n");
UNLOCK_VOL(vol);
recursive_lock_unlock(&vol->vlock);
return EROFS;
}
@@ -779,7 +728,7 @@ dosfs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms)
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
UNLOCK_VOL(vol);
recursive_lock_unlock(&vol->vlock);
return result;
bi5:
@@ -794,7 +743,7 @@ bi2:
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
_dosfs_sync(vol);
bi:
UNLOCK_VOL(vol);
recursive_lock_unlock(&vol->vlock);
if (result != B_OK) DPRINTF(0, ("dosfs_mkdir (%s)\n", strerror(result)));
return result;
}
@@ -813,44 +762,38 @@ dosfs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname,
bool dups_exist;
bool dirty = false;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_rename called: %" B_PRIdINO "/%s->%" B_PRIdINO "/%s\n",
odir->vnid, oldname, ndir->vnid, newname));
if (!oldname || !(*oldname) || !newname || !(*newname)) {
result = EINVAL;
goto bi;
}
if (!oldname || !(*oldname) || !newname || !(*newname))
return EINVAL;
if(!is_filename_legal(newname)) {
dprintf("dosfs_rename called with invalid name '%s'\n", newname);
result = EINVAL;
goto bi;
return EINVAL;
}
if (vol->flags & B_FS_IS_READONLY) {
dprintf("rename called on read-only volume\n");
result = EROFS;
goto bi;
return EROFS;
}
if ((odir->vnid == ndir->vnid) && !strcmp(oldname, newname)) {
result = EPERM;
goto bi;
return EPERM;
}
// locate the file
if ((result = findfile_case(vol,odir,oldname,NULL,&file)) != B_OK) {
DPRINTF(0, ("dosfs_rename: can't find file %s in directory %" B_PRIdINO
"\n", oldname, odir->vnid));
goto bi;
return result;
}
if (file->disk_image) {
dprintf("rename called on disk image or disk image directory\n");
result = EPERM;
goto bi1;
return EPERM;
}
// don't move a directory into one of its children
@@ -991,7 +934,6 @@ dosfs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname,
buffer[0x15] = (ndir->cluster >> 24) & 0xff;
}
}
diri_free(&diri);
}
if (file->filename) free(file->filename);
@@ -1015,10 +957,8 @@ bi2:
put_vnode(_vol, file2->vnid);
bi1:
put_vnode(_vol, 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)));
return result;
}
@@ -1030,13 +970,12 @@ dosfs_remove_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter)
nspace *vol = (nspace *)_vol->private_volume;
vnode *node = (vnode *)_node->private_node;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("dosfs_remove_vnode (%" B_PRIdINO ")\n", node->vnid));
if (vol->flags & B_FS_IS_READONLY) {
dprintf("dosfs_remove_vnode: read-only volume\n");
UNLOCK_VOL(vol);
return EROFS;
}
@@ -1065,8 +1004,6 @@ dosfs_remove_vnode(fs_volume *_vol, fs_vnode *_node, bool reenter)
_dosfs_sync(vol);
}
UNLOCK_VOL(vol);
return B_OK;
}
@@ -1086,22 +1023,20 @@ do_unlink(fs_volume *_vol, fs_vnode *_dir, const char *name, bool is_file)
if (!strcmp(name, ".."))
return EPERM;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
DPRINTF(0, ("do_unlink %" B_PRIdINO "/%s\n", dir->vnid, name));
if (vol->flags & B_FS_IS_READONLY) {
dprintf("do_unlink: read-only volume\n");
result = EROFS;
goto bi;
return EROFS;
}
// locate the file
if ((result = findfile_case(vol,dir,name,&vnid,&file)) != B_OK) {
DPRINTF(0, ("do_unlink: can't find file %s in directory %" B_PRIdINO
"\n", name, dir->vnid));
result = ENOENT;
goto bi;
return ENOENT;
}
if (file->disk_image) {
@@ -1168,9 +1103,6 @@ do_unlink(fs_volume *_vol, fs_vnode *_dir, const char *name, bool is_file)
bi1:
put_vnode(_vol, vnid); // get 1 free
bi:
UNLOCK_VOL(vol);
if (result != B_OK) DPRINTF(0, ("do_unlink (%s)\n", strerror(result)));
return result;
@@ -1215,9 +1147,9 @@ dosfs_read_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
status_t status;
if (node->cache == NULL)
return(B_BAD_VALUE);
return B_BAD_VALUE;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
while (true) {
struct file_io_vec fileVecs[8];
@@ -1241,8 +1173,6 @@ dosfs_read_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
bytesLeft -= bytes;
}
UNLOCK_VOL(vol);
return status;
}
@@ -1261,12 +1191,10 @@ dosfs_write_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
if (node->cache == NULL)
return B_BAD_VALUE;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
if ((vol->flags & B_FS_IS_READONLY) != 0) {
UNLOCK_VOL(vol);
if ((vol->flags & B_FS_IS_READONLY) != 0)
return EROFS;
}
while (true) {
struct file_io_vec fileVecs[8];
@@ -1290,8 +1218,6 @@ dosfs_write_pages(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
bytesLeft -= bytes;
}
UNLOCK_VOL(vol);
return status;
}
@@ -1309,13 +1235,12 @@ dosfs_get_file_map(fs_volume *_vol, fs_vnode *_node, off_t position,
size_t index = 0;
size_t max = *_count;
LOCK_VOL(vol);
RecursiveLocker lock(vol->vlock);
*_count = 0;
if ((node->mode & FAT_SUBDIR) != 0) {
DPRINTF(0, ("dosfs_get_file_map called on subdirectory %" B_PRIdINO
"\n", node->vnid));
UNLOCK_VOL(vol);
return EISDIR;
}
@@ -1326,8 +1251,7 @@ dosfs_get_file_map(fs_volume *_vol, fs_vnode *_node, off_t position,
position = 0;
if (node->st_size == 0 || length == 0 || position >= node->st_size) {
result = B_OK;
goto bi;
return B_OK;
}
// Truncate to file size, taking overflow into account.
@@ -1338,8 +1262,7 @@ dosfs_get_file_map(fs_volume *_vol, fs_vnode *_node, off_t position,
if (result != B_OK) {
dprintf("dosfs_get_file_map: invalid starting cluster (%" B_PRIu32
")\n", node->cluster);
result = EIO;
goto bi;
return EIO;
}
skipSectors = position / vol->bytes_per_sector;
@@ -1347,8 +1270,7 @@ dosfs_get_file_map(fs_volume *_vol, fs_vnode *_node, off_t position,
result = iter_csi(&iter, skipSectors);
if (result != B_OK) {
dprintf("dosfs_get_file_map: end of file reached (init)\n");
result = EIO;
goto bi;
return EIO;
}
}
@@ -1366,8 +1288,7 @@ dosfs_get_file_map(fs_volume *_vol, fs_vnode *_node, off_t position,
result = iter_csi(&iter, 1);
if (result != B_OK) {
dprintf("dosfs_get_file_map: end of file reached\n");
result = EIO;
goto bi;
return EIO;
}
if (block + sectors != csi_to_block(&iter)) {
@@ -1388,21 +1309,14 @@ dosfs_get_file_map(fs_volume *_vol, fs_vnode *_node, off_t position,
if (index >= max) {
// we're out of file_io_vecs; let's bail out
result = B_BUFFER_OVERFLOW;
goto bi;
*_count = index;
return B_BUFFER_OVERFLOW;
}
offset = 0;
}
result = B_OK;
bi:
*_count = index;
if (result != B_OK) {
DPRINTF(0, ("dosfs_get_file_map (%s)\n", strerror(result)));
}
UNLOCK_VOL(vol);
return result;
return B_OK;
}
+5 -7
View File
@@ -278,7 +278,8 @@ _diri_release_current_block_(struct diri *diri)
uint8 *
diri_init(nspace *vol, uint32 cluster, uint32 index, struct diri *diri)
{
diri->current_block = NULL;
if (diri->current_block != NULL)
_diri_release_current_block_(diri);
if (cluster >= vol->total_clusters + 2)
return NULL;
@@ -305,13 +306,10 @@ diri_init(nspace *vol, uint32 cluster, uint32 index, struct diri *diri)
}
int
diri_free(struct diri *diri)
diri::~diri()
{
if (diri->current_block)
_diri_release_current_block_(diri);
return 0;
if (current_block != NULL)
_diri_release_current_block_(this);
}
+4 -3
View File
@@ -34,14 +34,15 @@ status_t csi_write_block(struct csi *csi, uint8 *buffer);
/* directory entry iterator */
struct diri {
struct csi csi;
struct csi csi = {};
uint32 starting_cluster;
uint32 current_index;
uint8 *current_block;
uint8 *current_block = NULL;
~diri();
};
uint8 *diri_init(struct _nspace *vol, uint32 cluster, uint32 index, struct diri *diri);
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);