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