diff --git a/src/add-ons/kernel/file_systems/fat/attr.cpp b/src/add-ons/kernel/file_systems/fat/attr.cpp index c5ea45e3ea..696874d40d 100644 --- a/src/add-ons/kernel/file_systems/fat/attr.cpp +++ b/src/add-ons/kernel/file_systems/fat/attr.cpp @@ -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; } diff --git a/src/add-ons/kernel/file_systems/fat/dir.cpp b/src/add-ons/kernel/file_systems/fat/dir.cpp index 530050e569..ace2e09eb8 100644 --- a/src/add-ons/kernel/file_systems/fat/dir.cpp +++ b/src/add-ons/kernel/file_systems/fat/dir.cpp @@ -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; } - diff --git a/src/add-ons/kernel/file_systems/fat/dosfs.cpp b/src/add-ons/kernel/file_systems/fat/dosfs.cpp index 8a9b8267b9..8577149344 100644 --- a/src/add-ons/kernel/file_systems/fat/dosfs.cpp +++ b/src/add-ons/kernel/file_systems/fat/dosfs.cpp @@ -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; } diff --git a/src/add-ons/kernel/file_systems/fat/dosfs.h b/src/add-ons/kernel/file_systems/fat/dosfs.h index 22649102e4..a338df7835 100644 --- a/src/add-ons/kernel/file_systems/fat/dosfs.h +++ b/src/add-ons/kernel/file_systems/fat/dosfs.h @@ -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; diff --git a/src/add-ons/kernel/file_systems/fat/file.cpp b/src/add-ons/kernel/file_systems/fat/file.cpp index 850c69584e..ec8285e7fb 100644 --- a/src/add-ons/kernel/file_systems/fat/file.cpp +++ b/src/add-ons/kernel/file_systems/fat/file.cpp @@ -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; } diff --git a/src/add-ons/kernel/file_systems/fat/iter.cpp b/src/add-ons/kernel/file_systems/fat/iter.cpp index 2168619ce5..f59e6ab531 100644 --- a/src/add-ons/kernel/file_systems/fat/iter.cpp +++ b/src/add-ons/kernel/file_systems/fat/iter.cpp @@ -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); } diff --git a/src/add-ons/kernel/file_systems/fat/iter.h b/src/add-ons/kernel/file_systems/fat/iter.h index 4aa7bdfa36..ea996b6a48 100644 --- a/src/add-ons/kernel/file_systems/fat/iter.h +++ b/src/add-ons/kernel/file_systems/fat/iter.h @@ -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);