日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux+内核中开启nfs,NFS Client in Linux Kernel - Open

發(fā)布時(shí)間:2024/9/30 linux 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux+内核中开启nfs,NFS Client in Linux Kernel - Open 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. Callstack for Opening for a file

open() => nfs4_file_open() => nfs4_atomic_open() => nfs4_do_open() => _nfs4_do_open()

_nfs4_do_open分析:

nfs4_get_state_owner()獲得open owner對(duì)象

設(shè)置claim,他有幾種可能CLAIM_NULL(文件用文件名描述),CLAIM_FH(文件用current filehandle描述), CLAIM_PREVIOUS(用于reclaim open)

nfs4_opendata_alloc()分配nfs4_opendata

_nfs4_open_and_get_state()發(fā)送OPEN NFS命令

4.1 _nfs4_proc_open, 發(fā)送OPEN NFS命令

4.2 nfs4_opendata_to_nfs4_state() =>_nfs4_opendata_to_nfs4_state(), 創(chuàng)建open state,并將OPEN NFS命令得到的open state id,跟新這里。

open state存在ctx->state,其中ctx是nfs_open_context,它存儲(chǔ)在filp->private_data。對(duì)文件open以后,就可以通過filp->private_data得到ctx,并得到ctx->state->open_stateid,通過這個(gè)stateid向NFS Server發(fā)送READ/WRITE/LOCK操作。

2. NFS協(xié)議中的Open owner

NFS協(xié)議規(guī)定發(fā)送OPEN時(shí)候要發(fā)送一個(gè)open owner,標(biāo)識(shí)這個(gè)open的owner。在Server看來,clientid可以區(qū)分是來自哪個(gè)client的,open owner可以區(qū)分不同進(jìn)程的open請(qǐng)求。

摘自[nfs4.1協(xié)議]https://tools.ietf.org/html/rfc5661

NFS協(xié)議中Open owner和Lock owner都用下面這個(gè)結(jié)構(gòu)體表達(dá)。

struct state_owner4 {

clientid4 clientid;

opaque owner;

};

clientid,Server分配的,唯一標(biāo)識(shí)一個(gè)和server建立session的client

字符串+字符串的長度,唯一標(biāo)識(shí)client中的一個(gè)進(jìn)程

client標(biāo)識(shí)+進(jìn)程標(biāo)識(shí),唯一確定一個(gè)lock的owner。

### 2.1 Linux Kernel中對(duì)Open owner的設(shè)置

static inline void encode_openhdr(struct xdr_stream *xdr, const struct nfs_openargs *arg)

{

...

*p++ = cpu_to_be32(24);

p = xdr_encode_opaque_fixed(p, "open id:", 8);

*p++ = cpu_to_be32(arg->server->s_dev);

*p++ = cpu_to_be32(arg->id.uniquifier);

xdr_encode_hyper(p, arg->id.create_time);

}

Lock owner大小24字節(jié):

8字節(jié)的固定字符,"lock id:"

4字節(jié)的s_dev,表示是本地哪個(gè)文件系統(tǒng)。

4字節(jié)的id。由ida_get_new函數(shù)創(chuàng)建,在本地文件系統(tǒng)中唯一。

8字節(jié)的create_time

以上三點(diǎn),保證了在一個(gè)client內(nèi)Lock owner是唯一的。

再加上clientid,可以保證所有和Server建立session連接的client來自的lock owner是唯一確定。

3. Linux Kernel對(duì)一個(gè)打開實(shí)體Owner的描述

struct nfs4_state_owner {

struct nfs_server *so_server;

struct list_head so_lru;

unsigned long so_expires;

struct rb_node so_server_node;

struct rpc_cred *so_cred; //以這個(gè)為key,插入到紅黑樹里

spinlock_t so_lock;

atomic_t so_count;

unsigned long so_flags;

struct list_head so_states;

struct nfs_seqid_counter so_seqid;

seqcount_t so_reclaim_seqcount;

struct mutex so_delegreturn_mutex;

};

3.1 創(chuàng)建nfs4_state_owner

nfs4_get_state_owner()

首先通過so_cred為key,在紅黑樹里搜索

如果沒有搜到,創(chuàng)建一個(gè)

4. Linux Kernel對(duì)一個(gè)打開實(shí)體的描述

這個(gè)數(shù)據(jù)結(jié)構(gòu)專門描述open state,一個(gè)實(shí)體會(huì)被多個(gè)Owner打開,所以struct nfs4_state和struct nfs4_state_owner是一對(duì)多的關(guān)系

struct nfs4_state {

struct list_head open_states; //對(duì)于同一個(gè)inode,所有open state存在inode->open_states

struct list_head inode_states; //對(duì)于同一個(gè)owner,所有的open state存在owner->so_states

struct list_head lock_states; //這個(gè)open state下所有的lock state

struct nfs4_state_owner *owner; /* Pointer to the open owner */

struct inode *inode; /* Pointer to the inode */

unsigned long flags; /* Do we hold any locks? */

spinlock_t state_lock; /* Protects the lock_states list */

seqlock_t seqlock; /* Protects the stateid/open_stateid */

nfs4_stateid stateid; /* Current stateid: may be delegation */

nfs4_stateid open_stateid; /* OPEN stateid */

/* The following 3 fields are protected by owner->so_lock */

unsigned int n_rdonly; /* Number of read-only references */

unsigned int n_wronly; /* Number of write-only references */

unsigned int n_rdwr; /* Number of read/write references */

fmode_t state; /* State on the server (R,W, or RW) */

atomic_t count;

};

4.1 創(chuàng)建nfs4_state

nfs4_get_open_state

通過owner和inode的組合,試圖尋找一下

如果找不到創(chuàng)建一個(gè)和inode關(guān)聯(lián)

4. open stateid for Read/Write/Lock/Setattr/Close

這些操作都是依靠open stateid來向Server交互的。

參見下列函數(shù)的實(shí)現(xiàn)

encode_read()

encode_write()

encode_setattr()

encode_close()

encode_lock()

encode_locku()

static void encode_read(struct xdr_stream *xdr, const struct nfs_pgio_args *args,

struct compound_hdr *hdr)

{

__be32 *p;

encode_op_hdr(xdr, OP_READ, decode_read_maxsz, hdr);

encode_nfs4_stateid(xdr, &args->stateid); //NFS Server需要通過stateid找到file owner

p = reserve_space(xdr, 12);

p = xdr_encode_hyper(p, args->offset);

*p = cpu_to_be32(args->count);

}

調(diào)用棧

//open for file

nfs4_file_open <= sys_open

open_context // nfs4_atomic_open

nfs4_do_open

_nfs4_do_open

nfs4_recover_expired_lease

//如果當(dāng)前Dentry訪問過,則claim = NFS4_OPEN_CLAIM_FH

nfs4_opendata_alloc

_nfs4_open_and_get_state

_nfs4_proc_open

nfs4_run_open_task //send OPEN request to server

nfs4_open_prepare

//如果claim == NFS4_OPEN_CLAIM_FH,將OPEN修改成OPEN_NOATTR

//open for dir

nfs_opendir <= sys_open

if (filp->f_path.dentry == filp->f_path.mnt->mnt_root)

__nfs_revalidate_inode

getattr

//read dir

nfs_readdir <= sys_getdents

readdir_search_pagecache

find_cache_page

get_cache_page

=> nfs_readdir_filler

nfs_readdir_xdr_to_array

nfs_readdir_xdr_filler

readdir //nfs4_proc_readdir

_nfs4_proc_readdir //send READDIR

nfs_readdir_search_array

總結(jié)

以上是生活随笔為你收集整理的linux+内核中开启nfs,NFS Client in Linux Kernel - Open的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。