- struct dir dir;
- struct bitmap free_map;
- disk_sector_no hdr_sector;
- struct filehdr *filehdr;
- bool success = false;
-
- /* Read the root directory. */
- dir_init (&dir, NUM_DIR_ENTRIES);
- dir_read (&dir, &root_dir_file);
- if (dir_lookup (&dir, name, NULL))
- goto exit1;
-
- /* Allocate a block for the file header. */
- if (!bitmap_init (&free_map, disk_size (filesys_disk)))
- goto exit1;
- bitmap_read (&free_map, &free_map_file);
- hdr_sector = bitmap_find_and_set (&free_map);
- if (hdr_sector == BITMAP_ERROR)
- goto exit2;
-
- /* Add the file to the directory. */
- if (!dir_add (&dir, name, hdr_sector))
- goto exit2;
-
- /* Allocate space for the file. */
- filehdr = filehdr_allocate (&free_map, initial_size);
- if (filehdr == NULL)
- goto exit2;
-
- /* Write everything back. */
- filehdr_write (filehdr, hdr_sector);
- dir_write (&dir, &root_dir_file);
- bitmap_write (&free_map, &free_map_file);
-
- success = true;
-
- /* Clean up. */
- filehdr_destroy (filehdr);
- exit2:
- bitmap_destroy (&free_map);
- exit1:
- dir_destroy (&dir);
+ block_sector_t inode_sector = 0;
+ struct dir *dir = dir_open_root ();
+ bool success = (dir != NULL
+ && free_map_allocate (1, &inode_sector)
+ && inode_create (inode_sector, initial_size)
+ && dir_add (dir, name, inode_sector));
+ if (!success && inode_sector != 0)
+ free_map_release (inode_sector, 1);
+ dir_close (dir);