rtems 文件系统(5)_1

之前讲到 rtems_filesystem_initialize 函数中调用了mount函数,在该函数中实现了文件系统的挂载,那么到底怎么挂载的呢?

下面具体分析一下

int mount(

  const char                 *source,
  const char                 *target,
  const char                 *filesystemtype,
  rtems_filesystem_options_t  options,
  const void                 *data
)
{
  int rv = 0;


  if (
    options == RTEMS_FILESYSTEM_READ_ONLY
      || options == RTEMS_FILESYSTEM_READ_WRITE)

 {

    rtems_filesystem_fsmount_me_t fsmount_me_h =
      rtems_filesystem_get_mount_handler( filesystemtype );

    if ( fsmount_me_h != NULL ) {
      size_t target_length = 0;
      rtems_filesystem_mount_table_entry_t *mt_entry = alloc_mount_table_entry(
        source,
        target,
        filesystemtype,
        &target_length
      );


      if ( mt_entry != NULL ) {
        mt_entry->writeable = options == RTEMS_FILESYSTEM_READ_WRITE;


        rv = (*fsmount_me_h)( mt_entry, data );
        if ( rv == 0 ) {
          if ( target != NULL ) {
            rv = register_subordinate_file_system( mt_entry, target );
          } else {
            rv = register_root_file_system( mt_entry );
          }


          if ( rv != 0 ) {
            (*mt_entry->ops->fsunmount_me_h)( mt_entry );
          }
        }


        if ( rv != 0 ) {
          free( mt_entry );
        }
      } else {
        errno = ENOMEM;
        rv = -1;
      }
    } else {
      errno = EINVAL;
      rv = -1;
    }
  } else {
    errno = EINVAL;
    rv = -1;
  }

  return rv;
}


第一点:rtems_filesystem_fsmount_me_t 这个在cpukit/libcsupport/include/rtems/libio.h中定义。是一个函数指针的类型

如下定义:它有两个参数

typedef int (*rtems_filesystem_fsmount_me_t)(

rtems_filesystem_mount_table_entry_t *mt_entry,

const void *data);
第二点:rtems_filesystem_get_mount_handler( filesystemtype );

这个函数在cpukit/libcsupport/src/mount-mgr.c中定义,这个文件是manage mount table的

这个函数会迭代查找rtems_filesystem_table_t结构体类型的rtems_filesystem_table,后面详细说明

在这个函数内部使用了一个结构体

typedef struct {
  const char *type;
  rtems_filesystem_fsmount_me_t mount_h;
} find_arg;
该函数最终为了找到对应type 的 mount_h函数。注意返回值类型就是我们想要的rtems_filesystem_fsmount_me_t类型

rtems_filesystem_fsmount_me_t
rtems_filesystem_get_mount_handler(
  const char *type
)
{
  find_arg fa = {
    .type = type,
    .mount_h = NULL
  };

  if ( type != NULL ) {
    rtems_filesystem_iterate( find_handler, &fa );
  }

  return fa.mount_h;
}

第三点 rtems_filesystem_iterate 这个迭代函数,这个函数设计成有点类似c++模板,输入的routine类型为

rtems_per_filesystem_routine,本身就是一种操作函数,在这里作用是比较type的操作。

bool rtems_filesystem_iterate(
  rtems_per_filesystem_routine routine,
  void *routine_arg
)
{
  rtems_chain_control *chain = &filesystem_chain;
  const rtems_filesystem_table_t *table_entry = &rtems_filesystem_table [0];
  rtems_chain_node *node = NULL;
  bool stop = false;

  while ( table_entry->type && !stop ) {
    stop = (*routine)( table_entry, routine_arg ); //这里进行比较type
    ++table_entry;
  }

  if ( !stop ) {
    rtems_libio_lock();
    for (
      node = rtems_chain_first( chain );
      !rtems_chain_is_tail( chain, node ) && !stop;
      node = rtems_chain_next( node )
    ) {
      const filesystem_node *fsn = (filesystem_node *) node;

      stop = (*routine)( &fsn->entry, routine_arg );
    }
    rtems_libio_unlock();
  }

  return stop;
}

1)filesystem_chain代表文件系统的一个链表,链表后面单独学习研究。链表输入rtems内核的东西

2)rtems_filesystem_table是文件系统的一个表,这个表的元素类型如下,可见通过查找type,就可以找到对应的文件系统的处理函数mount_h

typedef struct rtems_filesystem_table_t {
  const char                    *type;
  rtems_filesystem_fsmount_me_t  mount_h;
} rtems_filesystem_table_t;

其中的比较type的函数如下所示

static bool find_handler(const rtems_filesystem_table_t *entry, void *arg)
{
  find_arg *fa = arg;

  if ( strcmp( entry->type, fa->type ) != 0 ) {
    return false;
  } else {
    fa->mount_h = entry->mount_h;

    return true;
  }
}

rtems_filesystem_table是一个默认的文件系统表,它在cpukit/sapi/include/confdefs.h 中有定义,如下

/**
   * The default file system table. Must be terminated with the NULL entry if
   * you provide your own.
   */
  #if !defined(CONFIGURE_HAS_OWN_FILESYSTEM_TABLE) && \
    !defined(CONFIGURE_APPLICATION_DISABLE_FILESYSTEM)
    const rtems_filesystem_table_t rtems_filesystem_table[] = {
      #if !defined(CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM)
        { "/", IMFS_initialize_support },  //如果没定义为dev的文件系统,那么就有这个
      #endif
      #if defined(CONFIGURE_FILESYSTEM_IMFS) && \
          defined(CONFIGURE_FILESYSTEM_ENTRY_IMFS)
        CONFIGURE_FILESYSTEM_ENTRY_IMFS,  /这个在其它地方也有定义,一般都会定义CONFIGURE_FILESYSTEM_IMFS,如下面
      #endif
      #if defined(CONFIGURE_FILESYSTEM_DEVFS) && \
          defined(CONFIGURE_FILESYSTEM_ENTRY_DEVFS)
        CONFIGURE_FILESYSTEM_ENTRY_DEVFS,
      #endif
      #if defined(CONFIGURE_FILESYSTEM_TFTPFS) && \
          defined(CONFIGURE_FILESYSTEM_ENTRY_TFTPFS)
        CONFIGURE_FILESYSTEM_ENTRY_TFTPFS,
      #endif
      #if defined(CONFIGURE_FILESYSTEM_FTPFS) && \
          defined(CONFIGURE_FILESYSTEM_ENTRY_FTPFS)
        CONFIGURE_FILESYSTEM_ENTRY_FTPFS,
      #endif
      #if defined(CONFIGURE_FILESYSTEM_NFS) && \
          defined(CONFIGURE_FILESYSTEM_ENTRY_NFS)
        CONFIGURE_FILESYSTEM_ENTRY_NFS,
      #endif
      #if defined(CONFIGURE_FILESYSTEM_DOSFS) && \
          defined(CONFIGURE_FILESYSTEM_ENTRY_DOSFS)
        CONFIGURE_FILESYSTEM_ENTRY_DOSFS,
      #endif
      #if defined(CONFIGURE_FILESYSTEM_RFS) && \
          defined(CONFIGURE_FILESYSTEM_ENTRY_RFS)
        CONFIGURE_FILESYSTEM_ENTRY_RFS,
      #endif
      #if defined(CONFIGURE_FILESYSTEM_JFFS2) && \
          defined(CONFIGURE_FILESYSTEM_ENTRY_JFFS2)
        CONFIGURE_FILESYSTEM_ENTRY_JFFS2,
      #endif
      CONFIGURE_FILESYSTEM_NULL
    };
  #endif

上面一些宏定义,我没有标注的,比如 CONFIGURE_FILESYSTEM_ENTRY_JFFS2 都在cpukit/sapi/include/confdefs.h 中有定义

这里不关注其它类型的文件系统,先关注IMFS

/**
 * This defines the IMFS file system table entry.
 */
#if !defined(CONFIGURE_FILESYSTEM_ENTRY_IMFS) && \
  defined(CONFIGURE_FILESYSTEM_IMFS)
  #define CONFIGURE_FILESYSTEM_ENTRY_IMFS \
    { RTEMS_FILESYSTEM_TYPE_IMFS, IMFS_initialize }
#endif
这部分也是上面 rtems_filesystem_table的一部分

  /**
   * Table termination record.
   */
  #define CONFIGURE_FILESYSTEM_NULL { NULL, NULL }
默认情况下,如果只有定义了IMFS,那么 rtems_filesystem_table有三个值(包括上面的NULL值)


第四点:如果没有在rtems_filesystem_table中找到,那么需要在chain中找,暂时理解为如果默认的rtems_filesystem_table中没有定义,那么后面挂载的文件系统会放到chain中。所以要到chain中继续查找。chain中通过rtems_filesystem_register和 rtems_filesystem_unregister 增加或者删除,这两个函数也在cpukit/libcsupport/src/mount-mgr.c中定义。暂时不考虑




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值