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:
committed by
waddlesplash
parent
9dcb1b7ff7
commit
8896f5d72f
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user