파일 시스템 내에서 동기화를 위해 lock을 사용하려 한다. 우선 filesys_init에서 lock을 초기화 해준다.

void
filesys_init (bool format) {
	filesys_disk = disk_get (0, 1);
	if (filesys_disk == NULL)
		PANIC ("hd0:1 (hdb) not present, file system initialization failed");

	inode_init ();

	lock_init(&filesys_lock);

#ifdef EFILESYS
	fat_init ();

	if (format)
		do_format ();

	fat_open ();
	init_fat_bitmap();
#else
	/* Original FS */
	free_map_init ();

	if (format)
		do_format ();

	free_map_open ();
#endif
}

그리고 파일 시스템의 세부 동작들 마다 lock을 걸어준다.

bool
filesys_create (const char *name, off_t initial_size) {
	bool success = false;

	lock_acquire(&filesys_lock);

	// Parse path and get directory
	struct path* path = parse_filepath(name);
	if(path->dircount==-1) { // create-empty, create-long
		goto done_lock;
	}
	struct dir* dir = find_subdir(path->dirnames, path->dircount);
	if(dir == NULL) {
		goto done;
	}

	struct inode *inode = NULL; 
	if(dir_lookup(dir, path->filename, &inode)){ // create-exists (trying to create file that already exists)
		goto done;
	}

	disk_sector_t inode_sector = 0;
	// struct dir *dir = dir_open_root ();

	#ifdef EFILESYS
	cluster_t clst = fat_create_chain(0);
	if(clst == 0){ // FAT is full (= disk is full)
		goto done;
	}
	inode_sector = cluster_to_sector(clst);

	success = (dir != NULL			
			&& inode_create (inode_sector, initial_size, false)
			&& dir_add (dir, path->filename, inode_sector));

	if (!success)
		fat_remove_chain (inode_sector, 0);

	// struct path path = parse_filepath(name);
	// struct dir *dir = dir_open(find_subdir(path.dirnames, path.dircount));

	// create?
	#else
	success = (dir != NULL
			&& free_map_allocate (1, &inode_sector)
			&& inode_create (inode_sector, initial_size, false)
			&& dir_add (dir, name, inode_sector));
	if (!success && inode_sector != 0)
		free_map_release (inode_sector, 1);
	#endif

done:
	dir_close (dir);
	free_path(path);
done_lock:
	lock_release(&filesys_lock);

	return success;
}
struct file *
filesys_open (const char *name) {
	
	lock_acquire(&filesys_lock);

	// Parse path and get directory
	struct path* path = parse_filepath(name);
	if(path->dircount==-1) { // open-empty
		lock_release(&filesys_lock);
		return NULL;
	}

	struct dir* dir = find_subdir(path->dirnames, path->dircount);
	if(dir == NULL) {
		dir_close (dir);
		free_path(path);
		lock_release(&filesys_lock);
		return NULL;
	}
	if (path->filename == "root"){ // open "/"
		lock_release(&filesys_lock);
		return file_open(inode_open (cluster_to_sector(1)));
	}
	// struct dir *dir = dir_open_root ();
	struct inode *inode = NULL;

	if (dir != NULL)
		dir_lookup (dir, path->filename, &inode);

	struct file *file = file_open (inode);

	dir_close (dir);
	free_path(path);

	lock_release(&filesys_lock);

	return file;
}
bool
filesys_remove (const char *name) {
	bool success = false;

	lock_acquire(&filesys_lock);

	// Parse path and get directory
	struct path* path = parse_filepath(name);
	if(path->dircount==-1) {
		goto done_lock;
	}
	struct dir* dir = find_subdir(path->dirnames, path->dircount);
	if(dir == NULL) {
		goto done;
	}

	// Check if the target is open (dir-rm-cwd)
	struct inode *inode = NULL; 
	dir_lookup(dir, path->filename, &inode);
	// if(inode == NULL || (inode_isdir(inode) && inode->open_cnt > 2)){ // only dir can't be closed when open (dir-rm-cwd vs syn-remove)
	if(inode == NULL){ // only dir can't be closed when open (dir-rm-cwd vs syn-remove)
		goto done;
	}

	//printf("isDir? %d / openCnt %d\\n", inode->data.isdir, inode->open_cnt);

	struct dir *cwd = current_directory();
	if(cwd->inode == inode)
		set_current_directory(NULL); 

	// struct dir *dir = dir_open_root ();
	success = dir != NULL && dir_remove (dir, path->filename);

done: 
	dir_close (dir);
	free_path(path);
done_lock:
	lock_release(&filesys_lock);

	return success;
}