NFS是一种跨操作系统的协议,Linux客户端可以挂载Windows服务器中的文件系统,Mic客户端也可以挂载Solaris服务器中的文件系统。Linux中,NFS客户端和NFS服务器端是分别开发的,客户端的程序位于fs/nfs/中,目前由NetApp的Trond Myklebust维护;服务器端的程序位于fs/nfsd中,由RedHat的J. Bruce Fields维护。前面几篇文章讲解了服务器端的处理过程,接下来讲讲客户端的数据结构和处理流程。
1.文件系统超级块 nfs_server
这是文件系统超级块结构中与NFS文件系统本身相关的字段,也就是struct super_block结构中的字段s_fs_info。NFS文件系统与其他文件系统一样,使用前也需要先挂载,挂载NFS文件系统时也会在内存中创建一个超级块结构struct super_block。由于NFS中的文件位于服务器端,所以NFS文件系统的挂载过程比其他文件系统挂载过程复杂一些,后面的文章可能会讲解这个挂载过程,这篇文件中先讲讲文件系统超级块中的这个数据结构struct nfs_server。
struct nfs_server {
// 这个结果所属的NFS客户端
struct nfs_client * nfs_client; /* shared client and NFS4 state */
// 一个nfs_client结构包含多个nfs_server结构,这些nfs_server结构组成一个链表。
// client_link指向链表中相邻的元素
struct list_head client_link; /* List of other nfs_server structs
* that share the same client
*/
// 系统中所有的nfs_server结构构成了一个链表,链表头是网络命名空间net_fs中的字段nfs_volume_list
// master_link指向链表中相邻的元素
struct list_head master_link; /* link in master servers list */
// RPC客户端,当发起RPC请求时需要使用这个客户端。
struct rpc_clnt * client; /* RPC client handle */
// RPC客户端,当发起与ACL相关的RPC请求时使用这个客户端。
struct rpc_clnt * client_acl; /* ACL RPC client handle */
// NFS中文件锁相关的数据结构,NFSv2和NFSv3依靠NLM实现文件锁,NFSv4本身实现了文件锁功能.
struct nlm_host *nlm_host; /* NLM client handle */
// IO统计信息
struct nfs_iostats __percpu *io_stats; /* I/O statistics */
// 文件系统的backing_dev_info结构
struct backing_dev_info backing_dev_info;
// 这是写操作中正在向服务器写入的数据,以数据页为单位
atomic_long_t writeback; /* number of writeback pages */
// 这是挂载NFS文件系统时指定的各种挂载选项
int flags; /* various flags */
// 这个字段保存了服务器的功能,如是否支持链接文件、是否支持ACL等,
// 这是通过GETATTR请求获取的。
unsigned int caps; /* server capabilities */
// READ请求中RPC报文传输数据的最大值,如果需要读取的数据量超过rsize,
// 就需要发起多个READ请求
unsigned int rsize; /* read size */
unsigned int rpages; /* read size (in pages) */
// WRITE请求中RPC报文传输数据的最大值,如果需要写入的数据量超过wsize,
// 就需要发起多个WRITE请求
unsigned int wsize; /* write size */
unsigned int wpages; /* write size (in pages) */
// 如果WRITE请求中的数据量超出了wsize,必须分割成多个WRITE请求,
// 同时一定要保证分割后每个WRITE请求中的数据量是wtmult的倍数.
unsigned int wtmult; /* server disk block size */
// READDIR请求中最多可以包含的数据量.READDIR请求的目的是读取目录中文件和子目录的信息,
// 由于目录中可能包含很多文件,当这些信息超出dtsize的限制时,需要发起多个READDIR请求。
unsigned int dtsize; /* readdir size */
// NFS服务器使用的端口号
unsigned short port; /* "port=" setting */
// NFS服务器中数据块的大小
unsigned int bsize; /* server block size */
// 普通文件缓存最小超时时间
unsigned int acregmin; /* attr cache timeouts */
// 普通文件缓存最大超时时间
unsigned int acregmax;
// 目录缓存最小超时时间
unsigned int acdirmin;
// 目录缓存最大超时时间
unsigned int acdirmax;
// 文件系统中文件名称的最大长度
unsigned int namelen;
// 执行mount命令时添加的附加参数
unsigned int options; /* extra options enabled by mount */
// 支持FS-Cache缓存 这也是一个挂载选项.
#define NFS_OPTION_FSCACHE 0x00000001 /* - local caching enabled */
struct nfs_fsid fsid;