static void open_log_file (void) { int fd; if (log_file_opened) return; mutex_lock (&open_log_file_lock); fd = open (LOG_FILE_PATH, O_WRONLY | O_CREAT | O_APPEND | O_FSYNC, S_IRUSR | S_IWUSR); if (fd < 0) goto error; log_file = fdopen (fd, "a"); if (log_file == NULL) goto error; log_file_opened = 1; mutex_unlock (&open_log_file_lock); return; error: minixfs_error ("cannot open log file %s: %s", LOG_FILE_PATH, strerror (errno)); if (fd <= 0) close (fd); mutex_unlock (&open_log_file_lock); use_log_file = !use_log_file; return; }
/* Free node NP; the on disk copy has already been synced with diskfs_node_update (where NP->dn_stat.st_mode was 0). Its mode used to be OLD_MODE. */ void diskfs_free_node (struct node *np, mode_t old_mode) { char *bh; ino_t inum = np->cache_id; block_t imap_block; assert (!diskfs_readonly); spin_lock (&global_lock); if (inum < MINIXFS_FIRST_INO || inum > sblock->s_ninodes) { minixfs_error ("trying to free a reserved or nonexistent inode: %Lu", inum); spin_unlock (&global_lock); return; } minixfs_debug ("freeing inode %Lu", inum); imap_block = inum >> LOG2_BITS_PER_BLOCK; if (imap_block >= sblock->s_imap_blocks) { minixfs_error ("nonexistent imap in superblock: %u", imap_block); spin_unlock (&global_lock); return; } bh = bptr (I_MAP_BOFFS + imap_block); if (! clear_bit (inum & (BITS_PER_BLOCK - 1), bh)) minixfs_warning ("bit already cleared for inode %Lu", inum); else { record_global_poke (bh); sblock_info->s_free_inodes_count++; } spin_unlock (&global_lock); alloc_sync (0); }
ino_t minixfs_new_inode (void) { char *bh = bptr (I_MAP_BOFFS); ino_t inum; unsigned long bits = sblock->s_ninodes; spin_lock (&global_lock); repeat: inum = find_first_zero_bit ((unsigned long *) bh, bits); if (inum < bits) { assert (sblock_info->s_free_inodes_count > 0); minixfs_debug ("eligible bit found at position %Lu", inum); if (set_bit (inum, bh)) { /* shouldn't happen */ minixfs_warning ("bit already set for inode %Lu", inum); goto repeat; } record_global_poke (bh); } else { assert (sblock_info->s_free_inodes_count == 0); minixfs_debug ("no more free inodes"); inum = 0; goto sync_out; } if (inum < MINIXFS_FIRST_INO) { minixfs_error ("reserved inode"); inum = 0; goto sync_out; } sblock_info->s_free_inodes_count--; sync_out: spin_unlock (&global_lock); alloc_sync (0); return inum; }