⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fs.c

📁 Simple Operating Systems (简称SOS)是一个可以运行在X86平台上(包括QEMU
💻 C
📖 第 1 页 / 共 4 页
字号:
  retval = sos_fs_write(tmp_of, symlink_target, & len);  mark_dirty_fsnode(fsnode, FALSE);  fsnode->close_opened_file(fsnode, tmp_of);    if ((SOS_OK != retval) || (len != symlink_target_len))    {      fs_remove_node(creator, symlink);      if (SOS_OK == retval)	retval = -SOS_ENAMETOOLONG;    }  sos_fs_nscache_unref_node(symlink);  return retval;}sos_ret_t sos_fs_mkdir(const struct sos_process * creator,		       const char * _path,		       sos_size_t _pathlen,		       sos_ui32_t access_rights){  struct sos_fs_pathname path;  path.contents = _path;  path.length   = _pathlen;  return fs_create_node(& path, creator, access_rights,			SOS_FS_NODE_DIRECTORY, NULL);}sos_ret_t sos_fs_rmdir(const struct sos_process * actor,		       const char * _path,		       sos_size_t _pathlen){  sos_ret_t retval;  struct sos_fs_pathname path;  struct sos_fs_nscache_node * nsnode;  path.contents = _path;  path.length   = _pathlen;  if (path.length <= 0)    return -SOS_ENOENT;  if (path.contents[0] == '/')    nsnode = sos_process_get_root(actor)->direntry;  else    nsnode = sos_process_get_cwd(actor)->direntry;  retval = fs_lookup_node(& path, FALSE,			  sos_process_get_root(actor)->direntry,			  nsnode,			  & nsnode, & path, 0);  if (SOS_OK != retval)    return retval;  /* Make sure the whole path has been resolved */  if (path.length > 0)    {      sos_fs_nscache_unref_node(nsnode);      return -SOS_ENOENT;    }  /* Cannot rmdir non-dir nodes */  if (sos_fs_nscache_get_fs_node(nsnode)->type != SOS_FS_NODE_DIRECTORY)    retval = -SOS_ENOTDIR;  /* Cannot remove directory if it is still used by somebody else */  else if (sos_fs_nscache_get_ref_cnt(nsnode) > 1)    retval = -SOS_EBUSY;  /* Cannot remove directory if it is still has children stored on     disk */  else if (sos_fs_nscache_get_fs_node(nsnode)->ondisk_lnk_cnt > 1)    retval = -SOS_ENOTEMPTY;  /* Otherwise, yes : suppress the node on disk */  else    retval = fs_remove_node(actor, nsnode);  sos_fs_nscache_unref_node(nsnode);  return retval;}sos_ret_t sos_fs_stat(const struct sos_process * actor,		      const char * _path,		      sos_size_t _pathlen,		      int nofollow,		      struct sos_fs_stat * result){  sos_ret_t retval;  struct sos_fs_pathname path;  struct sos_fs_nscache_node * nsnode;  struct sos_fs_node * fsnode;  path.contents = _path;  path.length   = _pathlen;  if (path.length <= 0)    return -SOS_ENOENT;  if (path.contents[0] == '/')    nsnode = sos_process_get_root(actor)->direntry;  else    nsnode = sos_process_get_cwd(actor)->direntry;  retval = fs_lookup_node(& path, (nofollow != 0),			  sos_process_get_root(actor)->direntry,			  nsnode,			  & nsnode, & path, 0);  if (SOS_OK != retval)    return retval;  /* Make sure the whole path has been resolved */  if (path.length > 0)    {      sos_fs_nscache_unref_node(nsnode);      return -SOS_ENOENT;    }  fsnode = sos_fs_nscache_get_fs_node(nsnode);  retval = fsnode->ops_file->stat(fsnode, result);    sos_fs_nscache_unref_node(nsnode);  return retval;}sos_ret_t sos_fs_fsync(struct sos_fs_opened_file * of){  struct sos_fs_node * fsnode = sos_fs_nscache_get_fs_node(of->direntry);  return fsnode->ops_file->sync(fsnode);}sos_ret_t sos_fs_chmod(const struct sos_process * actor,		       const char * _path,		       sos_size_t _pathlen,		       sos_ui32_t access_rights){  sos_ret_t retval;  struct sos_fs_pathname path;  struct sos_fs_nscache_node * nsnode;  struct sos_fs_node * fsnode;  path.contents = _path;  path.length   = _pathlen;  if (path.length <= 0)    return -SOS_ENOENT;  if (path.contents[0] == '/')    nsnode = sos_process_get_root(actor)->direntry;  else    nsnode = sos_process_get_cwd(actor)->direntry;  retval = fs_lookup_node(& path, TRUE,			  sos_process_get_root(actor)->direntry,			  nsnode,			  & nsnode, & path, 0);  if (SOS_OK != retval)    return retval;  /* Make sure the whole path has been resolved */  if (path.length > 0)    {      sos_fs_nscache_unref_node(nsnode);      return -SOS_ENOENT;    }  fsnode = sos_fs_nscache_get_fs_node(nsnode);  retval = fsnode->ops_file->chmod(fsnode, access_rights);  if (SOS_OK == retval)    mark_dirty_fsnode(fsnode, FALSE);    sos_fs_nscache_unref_node(nsnode);  return retval;}sos_ret_t sos_fs_vfstat(const struct sos_process * actor,			const char * _path,			sos_size_t _pathlen,			struct sos_fs_statfs * result){  sos_ret_t retval;  struct sos_fs_pathname path;  struct sos_fs_nscache_node * nsnode;  struct sos_fs_node * fsnode;  path.contents = _path;  path.length   = _pathlen;  if (path.length <= 0)    return -SOS_ENOENT;  if (path.contents[0] == '/')    nsnode = sos_process_get_root(actor)->direntry;  else    nsnode = sos_process_get_cwd(actor)->direntry;  retval = fs_lookup_node(& path, FALSE,			  sos_process_get_root(actor)->direntry,			  nsnode,			  & nsnode, & path, 0);  if (SOS_OK != retval)    return retval;  /* Make sure the whole path has been resolved */  if (path.length > 0)    {      sos_fs_nscache_unref_node(nsnode);      return -SOS_ENOENT;    }  fsnode = sos_fs_nscache_get_fs_node(nsnode);  if (fsnode->fs->statfs)    retval = fsnode->fs->statfs(fsnode->fs, result);  else    retval = -SOS_ENOSUP;    sos_fs_nscache_unref_node(nsnode);  return retval;  }/** This function is resilient against mounting/unmounting of other FS */sos_ret_t sos_fs_sync_all_fs(){  int dummy = 0;  sos_ui64_t uid = 0;  while (1)    {      /* Iterate over the FS types */      struct sos_fs_manager_type * fstype;      int ntype;      list_foreach(fs_list, fstype, ntype)	{	  /* Iterate over the FS instances */	  struct sos_fs_manager_instance * fs;	  int ninst;	  list_foreach(fstype->instances, fs, ninst)	    {	      if (fs->uid <= uid)		continue;	      uid = fs->uid;	      sos_fs_sync_fs(fs);	      /* We must NOT continue the loops because the		 prev/next/current fs types/instances might have been		 removed or added (sync blocks, by definition) ! */	      goto lookup_next_fs;	    }	}    lookup_next_fs:      /* Loop over */      dummy ++;    }  return SOS_OK;}/* ************************************************************* * mount/umount stuff */sos_ret_t sos_fs_register_fs_instance(struct sos_fs_manager_instance * fs,				      struct sos_fs_node * root_fsnode){  sos_ret_t retval;  struct sos_fs_nscache_node * nsnode_root;  retval = sos_fs_nscache_create_mounted_root(root_fsnode, & nsnode_root);  if (SOS_OK != retval)    return retval;  fs->uid  = ++last_fs_instance_uid;  fs->root = nsnode_root;  sos_hash_insert(fs->nodecache, root_fsnode);  list_add_tail(fs->fs_type->instances, fs);  return SOS_OK;}sos_ret_t sos_fs_unregister_fs_instance(struct sos_fs_manager_instance * fs){  fs->uid = 0;  list_delete(fs->fs_type->instances, fs);  return SOS_OK;}sos_ret_t sos_fs_register_fs_type(struct sos_fs_manager_type * fstype){  struct sos_fs_manager_type * iterator;  int nbtypes;  list_foreach_forward(fs_list, iterator, nbtypes)    {      if (! strncmp(fstype->name, iterator->name, SOS_FS_MANAGER_NAME_MAXLEN))	return -SOS_EEXIST;    }  list_add_tail(fs_list, fstype);  return SOS_OK;}sos_ret_t sos_fs_unregister_fs_type(struct sos_fs_manager_type * fstype){  struct sos_fs_manager_type * iterator;  int nbtypes;  if (! list_is_empty(fstype->instances))    return -SOS_EBUSY;  list_foreach_forward(fs_list, iterator, nbtypes)    {      if (! strncmp(fstype->name, iterator->name, SOS_FS_MANAGER_NAME_MAXLEN))	{	  list_delete(fs_list, fstype);	  return SOS_OK;	}    }  return -SOS_EINVAL;}/** * _src_path may be empty */sos_ret_t sos_fs_mount(struct sos_process * actor,		       const char * _src_path,		       sos_size_t _src_pathlen,		       const char * _dst_path,		       sos_size_t _dst_pathlen,		       const char * fsname,		       sos_ui32_t mountflags,		       const char * args,		       struct sos_fs_manager_instance ** result_fs){  sos_ret_t retval;  struct sos_fs_pathname src_path, dst_path;  struct sos_fs_nscache_node * src_nsnode, * dst_nsnode;  struct sos_fs_manager_type * fs_type;  struct sos_fs_manager_instance * new_fs;  int nb_fstypes;  if (_dst_pathlen <= 0)    return -SOS_ENOENT;  /* Look for the FS manager type */  list_foreach(fs_list, fs_type, nb_fstypes)    {      if (! strcmp(fsname, fs_type->name))	break;    }  if (! list_foreach_early_break(fs_list, fs_type, nb_fstypes))    return -SOS_ENODEV;  src_path.contents = _src_path;  src_path.length   = _src_pathlen;  /* Compute the start_nsnode for the source */  if (src_path.length <= 0)    src_nsnode = NULL;  else if (src_path.contents[0] == '/')    src_nsnode = sos_process_get_root(actor)->direntry;  else    src_nsnode = sos_process_get_cwd(actor)->direntry;  /* Lookup the source node */  if (src_nsnode)    {      retval = fs_lookup_node(& src_path, TRUE,			      sos_process_get_root(actor)->direntry,			      src_nsnode,			      & src_nsnode, & src_path, 0);      if (SOS_OK != retval)	return retval;      /* Make sure the whole path has been resolved */      if (src_path.length > 0)	{	  sos_fs_nscache_unref_node(src_nsnode);	  return -SOS_ENOENT;	}    }  dst_path.contents = _dst_path;  dst_path.length   = _dst_pathlen;  /* Compute the start_nsnode for the destination */  if (dst_path.contents[0] == '/')    dst_nsnode = sos_process_get_root(actor)->direntry;  else    dst_nsnode = sos_process_get_cwd(actor)->direntry;  /* Lookup the destination node */  retval = fs_lookup_node(& dst_path, TRUE,			  sos_process_get_root(actor)->direntry,			  dst_nsnode,			  & dst_nsnode, & dst_path, 0);  if ((SOS_OK != retval) || (dst_path.length > 0))    {      if (src_nsnode)	sos_fs_nscache_unref_node(src_nsnode);      if (dst_path.length > 0)	retval = -SOS_ENOENT;      return retval;    }  /* Actually call the mount callback of the FS */  retval    = fs_type->mount(fs_type,		     (src_nsnode)?sos_fs_nscache_get_fs_node(src_nsnode):NULL,		     args, & new_fs);  if (SOS_OK != retval)    {      if (src_nsnode)	sos_fs_nscache_unref_node(src_nsnode);      sos_fs_nscache_unref_node(dst_nsnode);      return retval;    }  /* Make sure the nodecache was created */  SOS_ASSERT_FATAL(NULL != new_fs->nodecache);  SOS_ASSERT_FATAL(NULL != new_fs->root);  /* Update some reserved fields */  sos_fs_nscache_get_fs_node(new_fs->root)->fs = new_fs;  /* Register the mountpoint in the nscache */  retval = sos_fs_nscache_mount(dst_nsnode, new_fs->root);  SOS_ASSERT_FATAL(SOS_OK == retval);  /* Un-reference the temporary nsnodes */  if (src_nsnode)    sos_fs_nscache_unref_node(src_nsnode);  sos_fs_nscache_unref_node(dst_nsnode);  if (result_fs)    *result_fs = new_fs;  return SOS_OK;}sos_ret_t sos_fs_umount(struct sos_process * actor,			const char * _mounted_root_path,			sos_size_t _mounted_root_pathlen){  sos_ret_t retval;  struct sos_fs_pathname mounted_root_path;  struct sos_fs_nscache_node * mounted_root_nsnode;  struct sos_fs_manager_instance * fs;  if (_mounted_root_pathlen <= 0)    return -SOS_ENOENT;  mounted_root_path.contents = _mounted_root_path;  mounted_root_path.length   = _mounted_root_pathlen;  /* Compute the start_nsnode for the mounted_root */  if (mounted_root_path.contents[0] == '/')    mounted_root_nsnode = sos_process_get_root(actor)->direntry;  else    mounted_root_nsnode = sos_process_get_cwd(actor)->direntry;  /* Lookup the mounted_root node */  retval = fs_lookup_node(& mounted_root_path, TRUE,			  sos_process_get_root(actor)->direntry,			  mounted_root_nsnode,			  & mounted_root_nsnode, & mounted_root_path, 0);  if (SOS_OK != retval)    return retval;  /* Make sure the whole path has been resolved */  if (mounted_root_path.length > 0)    {      sos_fs_nscache_unref_node(mounted_root_nsnode);      return -SOS_ENOENT;    }  /* Make sure this node is the real root of the FS */  fs = sos_fs_nscache_get_fs_node(mounted_root_nsnode)->fs;  if (fs->root != mounted_root_nsnode)    {      sos_fs_nscache_unref_node(mounted_root_nsnode);      return -SOS_ENOENT;    }  /* Disconnect this FS mounted_root from namespace cache */  retval = sos_fs_nscache_umount(mounted_root_nsnode);  /* Mounted_Root not needed anymore */  sos_fs_nscache_unref_node(mounted_root_nsnode);  if (SOS_OK != retval)    return retval;  fs->root = NULL;  /* Flush any changes to disk */  retval = sos_fs_sync_fs(fs);  if (SOS_OK != retval)    {      return retval;    }  retval = fs->fs_type->umount(fs->fs_type, fs);  return retval;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -