免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

linux-sysfs

一、inode、dentry、sys_dirent、kobject

創(chuàng)新互聯(lián)主打移動(dòng)網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、網(wǎng)站改版、網(wǎng)絡(luò)推廣、網(wǎng)站維護(hù)、國際域名空間、等互聯(lián)網(wǎng)信息服務(wù),為各行業(yè)提供服務(wù)。在技術(shù)實(shí)力的保障下,我們?yōu)榭蛻舫兄Z穩(wěn)定,放心的服務(wù),根據(jù)網(wǎng)站的內(nèi)容與功能再?zèng)Q定采用什么樣的設(shè)計(jì)。最后,要實(shí)現(xiàn)符合網(wǎng)站需求的內(nèi)容、功能與設(shè)計(jì),我們還會(huì)規(guī)劃穩(wěn)定安全的技術(shù)方案做保障。

他們分別都有自己的一棵樹,inode和dentry就是vfs用的inode和dentry,sysfs之所以創(chuàng)建這兩個(gè)結(jié)構(gòu)就是為了與vfs交互。至于sys_dirent和kobject是sysfs維護(hù)信息用的,

sys_dirent可以對(duì)應(yīng)到文件,而kobject只能對(duì)應(yīng)到對(duì)象(目錄),其實(shí)sys_dirent比較簡單,也就是個(gè)輔助結(jié)構(gòu)

struct sysfs_dirent {
atomic_ts_count;/*引用計(jì)數(shù)*/
struct list_heads_sibling;
struct list_heads_children;
void * s_element;/*對(duì)應(yīng)于某一類型的數(shù)據(jù)結(jié)構(gòu),比如如果該結(jié)構(gòu)類型是目錄,則它對(duì)應(yīng)一個(gè)kobject,如果是屬性文件,它對(duì)應(yīng)一個(gè)attribute結(jié)構(gòu)*/
ints_type;/*類型: 包括目錄、根、屬性文件、二進(jìn)制文件
鏈接*/
umode_ts_mode;
ino_ts_ino;
struct dentry* s_dentry;
struct iattr* s_iattr;
atomic_ts_event;
};

靠s_element來與kobject建立關(guān)系,而還是通過s_element可以攜帶具體文件的信息,彌補(bǔ)了kobject無法對(duì)應(yīng)的文件的缺陷。

而dentry->d_fsdata = sysfs_dirent ,這樣sysfs_dirent 和dentry就建立了關(guān)系,從而dentry和kobject也建立了關(guān)系,而且從dentry也可得到具體文件的信息了。

二、sysfs文件的操作:

統(tǒng)一接口sysfs_file_operations:

const struct file_operations sysfs_file_operations = {
.read= sysfs_read_file,
.write= sysfs_write_file,
.llseek= generic_file_llseek,
.open= sysfs_open_file,
.release= sysfs_release,
.poll= sysfs_poll,
};

以sysfs_read_file為例,調(diào)用關(guān)系

sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
struct sysfs_buffer * buffer= file->private_data;
ssize_t retval = 0;


down(&buffer->sem);
if (buffer->needs_read_fill) {
if (buffer->orphaned)
retval = -ENODEV;
else
retval = fill_read_buffer(file->f_path.dentry,buffer);
if (retval)
goto out;
}
pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n",
__FUNCTION__, count, *ppos, buffer->page);
retval = simple_read_from_buffer(buf, count, ppos, buffer->page,
buffer->count);
out:
up(&buffer->sem);
return retval;
}

static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer)
{
struct sysfs_dirent * sd = dentry->d_fsdata;
struct attribute * attr = to_attr(dentry);

(static inline struct attribute * to_attr(struct dentry * dentry)

{
struct sysfs_dirent * sd = dentry->d_fsdata;
return ((struct attribute *) sd->s_element);
}

attr是show函數(shù)的參數(shù),通過他找到具體文件的屬性,從而找到具體的show函數(shù)。


struct kobject * kobj = to_kobj(dentry->d_parent);
struct sysfs_ops * ops = buffer->ops;

(

static int sysfs_open_file(struct inode *inode, struct file *file)
{

...

...

       buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
if (buffer) {
INIT_LIST_HEAD(&buffer->associates);
init_MUTEX(&buffer->sem);
buffer->needs_read_fill = 1;
buffer->ops = ops;(后面會(huì)講到)
add_to_collection(buffer, inode);
file->private_data = buffer;
} else
error = -ENOMEM;
goto Done;


}

sysfs_buffer是file的private_data結(jié)構(gòu),維護(hù)著具體文件的操作以及操作所用到的內(nèi)存信息

struct sysfs_buffer {
struct list_headassociates;
size_tcount;
loff_tpos;
char* page;
struct sysfs_ops* ops;
struct semaphoresem;
intorphaned;
intneeds_read_fill;
intevent;
};

)
int ret = 0;
ssize_t count;


if (!buffer->page)
buffer->page = (char *) get_zeroed_page(GFP_KERNEL);
if (!buffer->page)
return -ENOMEM;


buffer->event = atomic_read(&sd->s_event);
count = ops->show(kobj,attr,buffer->page);
BUG_ON(count > (ssize_t)PAGE_SIZE);
if (count >= 0) {
buffer->needs_read_fill = 0;
buffer->count = count;
} else {
ret = count;
}
return ret;
}

sysfs_read_file --- >  ops->show(該show函數(shù)是kobject里ktype的sysfs_ops,在sysfs_open_file中可以查到 ,)

static int sysfs_open_file(struct inode *inode, struct file *file)
{
struct kobject *kobj = sysfs_get_kobject(file->f_path.dentry->d_parent);
struct attribute * attr = to_attr(file->f_path.dentry);
struct sysfs_buffer_collection *set;
struct sysfs_buffer * buffer;
struct sysfs_ops * ops = NULL;
int error = 0;


if (!kobj || !attr)
goto Einval;


/* Grab the module reference for this attribute if we have one */
if (!try_module_get(attr->owner)) {
error = -ENODEV;
goto Done;
}


/* if the kobject has no ktype, then we assume that it is a subsystem
* itself, and use ops for it.
*/
if (kobj->kset && kobj->kset->ktype)
ops = kobj->kset->ktype->sysfs_ops;
else if (kobj->ktype)
ops = kobj->ktype->sysfs_ops;
else
ops = &subsys_sysfs_ops;

...

...

而sysfs_ops從何而來呢,他是在創(chuàng)建具體的kobject時(shí)被賦值的,以cpufreq為例:

cpufreq_add_dev函數(shù)中有

policy->kobj.ktype= &ktype_cpufreq;
strlcpy(policy->kobj.name, "cpufreq", KOBJ_NAME_LEN);
ret = kobject_register(&policy->kobj);

static struct kobj_type ktype_cpufreq = {
.sysfs_ops= &sysfs_ops,
.default_attrs= default_attrs,
.release= cpufreq_sysfs_release,
};

static struct sysfs_ops sysfs_ops = {
.show=show,
.store= store,
};

static ssize_t show(struct kobject * kobj, struct attribute * attr ,char * buf)
{
struct cpufreq_policy * policy = to_policy(kobj);
struct freq_attr * fattr = to_attr(attr);
ssize_t ret;
policy = cpufreq_cpu_get(policy->cpu);
if (!policy)
return -EINVAL;


if (lock_policy_rwsem_read(policy->cpu) < 0)
return -EINVAL;


if (fattr->show)
ret = fattr->show(policy, buf);
else
ret = -EIO;


unlock_policy_rwsem_read(policy->cpu);


cpufreq_cpu_put(policy);
return ret;
}

 to_attr 是通過一般屬性找到特定于某個(gè)對(duì)象文件的屬性,看懂__ATTR這個(gè)宏就明白了。

之所以層層調(diào)用組要是linux喜歡把公用的部分提取出來組成個(gè)函數(shù),私有部分再另組成個(gè)函數(shù)。

三、sysfs_create_file

該函數(shù)創(chuàng)建sysfs文件,就是創(chuàng)建一個(gè)sys_dirent的結(jié)構(gòu)。注意這里木有創(chuàng)建inode和dentry,文件的inode和dentry是被訪問前創(chuàng)建的,既lookup時(shí)創(chuàng)建的

static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry,
struct nameidata *nd)
{
struct sysfs_dirent * parent_sd = dentry->d_parent->d_fsdata;
struct sysfs_dirent * sd;
int err = 0;
/**
#define list_for_each_entry(pos, head, member)\
for (pos = list_entry((head)->next, typeof(*pos), member);\
    prefetch(pos->member.next), &pos->member != (head);\
    pos = list_entry(pos->member.next, typeof(*pos), member))
**/
list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
if (sd->s_type & SYSFS_NOT_PINNED) {/*hgq 這里判斷是不是文件,如果是才往下進(jìn)行,因?yàn)閷?duì)于目錄kobject,他在創(chuàng)建時(shí)就順帶創(chuàng)建了
dentry和inode,在sysfs_create_dir函數(shù)里,所以在內(nèi)存中已經(jīng)有了,也就不會(huì)調(diào)到這個(gè)函數(shù),這個(gè)函數(shù)是內(nèi)存里沒有相應(yīng)的
dentry和inode時(shí)才調(diào)用,在這里就是創(chuàng)建sysfs的文件的dentry和inode,因?yàn)閯?chuàng)建文件時(shí)沒有創(chuàng)建
dentry和inode,只是創(chuàng)建了sysfs_dirent*/
const unsigned char * name = sysfs_get_name(sd);


if (strcmp(name, dentry->d_name.name))
continue;


if (sd->s_type & SYSFS_KOBJ_LINK)
err = sysfs_attach_link(sd, dentry);
else
err = sysfs_attach_attr(sd, dentry);
break;
}
}

}

linux就是用時(shí)才去做一些事,以此可以節(jié)省空間。


分享題目:linux-sysfs
文章URL:http://m.newbst.com/article36/poospg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站網(wǎng)站制作軟件開發(fā)自適應(yīng)網(wǎng)站品牌網(wǎng)站制作動(dòng)態(tài)網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營