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

歡迎訪問 生活随笔!

生活随笔

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

linux

linux 如何赋值目录,Linux文件系统之目录的建立

發(fā)布時間:2023/12/4 linux 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux 如何赋值目录,Linux文件系统之目录的建立 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一:前言

在用戶空間中,建立目錄所用的API為mkdir().它在內(nèi)核中的系統(tǒng)調(diào)用入口是sys_mkdir().今天跟蹤一下

函數(shù)來分析linux文件系統(tǒng)中目錄的建立過程.

二:sys_mkdir()

Sys_mkdir()對應(yīng)的代碼如下:

asmlinkage long sys_mkdir(const char __user * pathname, int mode)

{

int error = 0;

char * tmp;

//把用戶空間的值copy到內(nèi)核空間

tmp = getname(pathname);

error = PTR_ERR(tmp);

if (!IS_ERR(tmp)) {

struct dentry *dentry;

struct nameidata nd;

//先查到它的父目錄,看父目錄是否存在

error = path_lookup(tmp, LOOKUP_PARENT, &nd);

if (error)

goto out;

//尋找子結(jié)點(diǎn)的dentry. 如果沒有,則新建之

dentry = lookup_create(&nd, 1);

error = PTR_ERR(dentry);

if (!IS_ERR(dentry)) {

if (!IS_POSIXACL(nd.dentry->d_inode))

mode &= ~current->fs->umask;

//與具體的文件系統(tǒng)相關(guān)的部份

error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);

//減少dentry的引用計(jì)數(shù)

dput(dentry);

}

up(&nd.dentry->d_inode->i_sem);

//釋放臨時內(nèi)存

path_release(&nd);

out:

putname(tmp);

}

return error;

}

這個函數(shù)里面有幾個重要的子函數(shù). path_lookup()在前一篇文章中已經(jīng)分析過了.如果不太了解,請參閱相關(guān)的部份.

lookup_create()的代碼如下:

{

struct dentry *dentry;

//防止并發(fā)操作,獲得信號量

down(&nd->dentry->d_inode->i_sem);

dentry = ERR_PTR(-EEXIST);

//如果之前的查找過程失敗

if (nd->last_type != LAST_NORM)

goto fail;

//去掉LOOKUP_PARENT標(biāo)志

nd->flags &= ~LOOKUP_PARENT;

//在緩存中尋找相應(yīng)的dentry.如果沒有。則新建之

dentry = lookup_hash(&nd->last, nd->dentry);

//創(chuàng)建或者查找失敗

if (IS_ERR(dentry))

goto fail;

//如果不是建立一個目錄而且文件名字不是以0結(jié)尾

//出錯退出

if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)

goto enoent;

return dentry;

enoent:

dput(dentry);

dentry = ERR_PTR(-ENOENT);

fail:

return dentry;

}

lookup_hash()à __lookup_hash():

static struct dentry * __lookup_hash(struct qstr *name, struct dentry * base, struct nameidata *nd)

{

struct dentry * dentry;

struct inode *inode;

int err;

inode = base->d_inode;

//檢查是否有相關(guān)的權(quán)限

err = permission(inode, MAY_EXEC, nd);

dentry = ERR_PTR(err);

if (err)

goto out;

/*

* See if the low-level filesystem might want

* to use its own hash..

*/

//如果自定義了hash計(jì)算

if (base->d_op && base->d_op->d_hash) {

err = base->d_op->d_hash(base, name);

dentry = ERR_PTR(err);

if (err < 0)

goto out;

}

//從緩存中尋找

dentry = cached_lookup(base, name, nd);

if (!dentry) {

//如果緩存中沒有相關(guān)項(xiàng)。則新建之

struct dentry *new = d_alloc(base, name);

dentry = ERR_PTR(-ENOMEM);

if (!new)

goto out;

//到具體的文件系統(tǒng)中查找

dentry = inode->i_op->lookup(inode, new, nd);

if (!dentry)

dentry = new;

else

dput(new);

}

out:

return dentry;

}

值得注意的是:經(jīng)過上述的操作,返回的dentry有可能是原本就存在的.對這種情況是怎么排除的呢?繼續(xù)看sys_mkdir()的另一個子函數(shù):

int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)

{

//對異常情況的排除和權(quán)限的檢查

int error = may_create(dir, dentry, NULL);

if (error)

return error;

//如果父結(jié)點(diǎn)不允許mkdir操作

if (!dir->i_op || !dir->i_op->mkdir)

return -EPERM;

mode &= (S_IRWXUGO|S_ISVTX);

error = security_inode_mkdir(dir, dentry, mode);

if (error)

return error;

DQUOT_INIT(dir);

//調(diào)用父結(jié)點(diǎn)的mkdir操作

error = dir->i_op->mkdir(dir, dentry, mode);

if (!error) {

//如果成功,通告與之關(guān)聯(lián)的進(jìn)程

inode_dir_notify(dir, DN_CREATE);

security_inode_post_mkdir(dir,dentry, mode);

}

return error;

}

在這里看到,最終會調(diào)用父進(jìn)程的i_op.mkdir操作.另外,對于上面說的相應(yīng)結(jié)點(diǎn)已經(jīng)存在的情況是在may_create()中檢測的:

static inline int may_create(struct inode *dir, struct dentry *child,

struct nameidata *nd)

{

//如果欲建結(jié)點(diǎn)的inode已經(jīng)存在

//對于一個新建的dentry.其d_inode指向?yàn)榭?

if (child->d_inode)

return -EEXIST;

//判斷父目錄是否已經(jīng)失效

if (IS_DEADDIR(dir))

return -ENOENT;

//權(quán)限檢查

return permission(dir,MAY_WRITE | MAY_EXEC, nd);

}

Mkdir的大體架構(gòu)就如此了.下面討論一下rootfs和ext2中的目錄創(chuàng)建.

三:rootfs的目錄創(chuàng)建

在前一篇文章分析到.掛載rootfs時,對文件系統(tǒng)根目錄的inode.i_op賦值如下:

static struct inode_operations ramfs_dir_inode_operations = {

.create?????? = ramfs_create,

.lookup?????? = simple_lookup,

.link???????? = simple_link,

.unlink?????? = simple_unlink,

.symlink = ramfs_symlink,

.mkdir??????? = ramfs_mkdir,

.rmdir??????? = simple_rmdir,

.mknod??????? = ramfs_mknod,

.rename?????? = simple_rename,

};

對應(yīng)的mkdir操作入口是ramfs_mkdir():

static int ramfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)

{

//創(chuàng)建結(jié)點(diǎn)

int retval = ramfs_mknod(dir, dentry, mode | S_IFDIR, 0);

//如果創(chuàng)建成功,更新i_nlink計(jì)數(shù)

if (!retval)

dir->i_nlink++;

return retval;

}

Ramsf_mknod()的代碼如下:

static int

ramfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)

{

//在文件系統(tǒng)中分其為配一個inode

struct inode * inode = ramfs_get_inode(dir->i_sb, mode, dev);

int error = -ENOSPC;

if (inode) {

//如果分配成功

if (dir->i_mode & S_ISGID) {

inode->i_gid = dir->i_gid;

if (S_ISDIR(mode))

inode->i_mode |= S_ISGID;

}

//將dentry與分配的inode關(guān)聯(lián)起來

d_instantiate(dentry, inode);

//增加dentry的引用計(jì)數(shù)

dget(dentry); /* Extra count - pin the dentry in core */

error = 0;

}

return error;

}

這個函數(shù)中的子函數(shù)我們都在前面已經(jīng)分析過.請自行查閱本站的其它文檔.其操作非常簡單。就是分配一個inode。然后將inode 與dentry建立關(guān)聯(lián).因?yàn)閞ootfs是一個基于RAM的文件系統(tǒng)。其inode的分配就是在內(nèi)存中創(chuàng)建一個inode空間,然后為其各項(xiàng)操作賦值而已.

四:ext2中的目錄創(chuàng)建

經(jīng)過上一章的分析可以看到.ext2文件系統(tǒng)根目錄的inode.i_op被賦值為ext2_dir_inode_operations.其結(jié)構(gòu)如下所示:

struct inode_operations ext2_dir_inode_operations = {

.create?????? = ext2_create,

.lookup?????? = ext2_lookup,

.link???????? = ext2_link,

.unlink?????? = ext2_unlink,

.symlink = ext2_symlink,

.mkdir??????? = ext2_mkdir,

.rmdir??????? = ext2_rmdir,

.mknod??????? = ext2_mknod,

.rename?????? = ext2_rename,

#ifdef CONFIG_EXT2_FS_XATTR

.setxattr = generic_setxattr,

.getxattr = generic_getxattr,

.listxattr??? = ext2_listxattr,

.removexattr? = generic_removexattr,

#endif

.setattr = ext2_setattr,

.permission?? = ext2_permission,

}

Mkdir對應(yīng)的入口為ext2_mkdir().代碼如下:

static int ext2_mkdir(struct inode * dir, struct dentry * dentry, int mode)

{

struct inode * inode;

int err = -EMLINK;

if (dir->i_nlink >= EXT2_LINK_MAX)

goto out;

//增加dir的引用計(jì)數(shù),并將其置為"臟"

ext2_inc_count(dir);

//在文件系統(tǒng)中分配一個inode

inode = ext2_new_inode (dir, S_IFDIR | mode);

err = PTR_ERR(inode);

if (IS_ERR(inode))

goto out_dir;

//為inode的各項(xiàng)操作賦值

inode->i_op = &ext2_dir_inode_operations;

inode->i_fop = &ext2_dir_operations;

//為inode對應(yīng)的i_mapping賦值

if (test_opt(inode->i_sb, NOBH))

inode->i_mapping->a_ops = &ext2_nobh_aops;

else

inode->i_mapping->a_ops = &ext2_aops;

//增加inode的引用計(jì)數(shù),并將其置為"臟"

ext2_inc_count(inode);

//對目錄結(jié)點(diǎn)的初始化

err = ext2_make_empty(inode, dir);

if (err)

goto out_fail;

//更新父目錄,使inode加入父目錄

err = ext2_add_link(dentry, inode);

if (err)

goto out_fail;

//使dentry和inode建立關(guān)聯(lián)

d_instantiate(dentry, inode);

out:

return err;

out_fail:

ext2_dec_count(inode);

ext2_dec_count(inode);

iput(inode);

out_dir:

ext2_dec_count(dir);

goto out;

}

逐個分析上面所涉及到的子函數(shù).

在ext2中分配一個inode是由ext2_new_inode()完成的.它的代碼如下:

struct inode *ext2_new_inode(struct inode *dir, int mode)

{

struct super_block *sb;

struct buffer_head *bitmap_bh = NULL;

struct buffer_head *bh2;

int group, i;

ino_t ino = 0;

struct inode * inode;

struct ext2_group_desc *gdp;

struct ext2_super_block *es;

struct ext2_inode_info *ei;

struct ext2_sb_info *sbi;

int err;

sb = dir->i_sb;

//分配一個inode

inode = new_inode(sb);

if (!inode)

return ERR_PTR(-ENOMEM);

//inode的私有結(jié)構(gòu)

ei = EXT2_I(inode);

//super_block中的ext2私有結(jié)構(gòu)

sbi = EXT2_SB(sb);

//ext2的super_block

es = sbi->s_es;

//尋找一個合適的組來分配inode

if (S_ISDIR(mode)) {

if (test_opt(sb, OLDALLOC))

group = find_group_dir(sb, dir);

else

group = find_group_orlov(sb, dir);

} else

group = find_group_other(sb, dir);

if (group == -1) {

err = -ENOSPC;

goto fail;

}

//遍歷組描述符

for (i = 0; i < sbi->s_groups_count; i++) {

//group對應(yīng)的組開始遍歷

//取得組描述符

gdp = ext2_get_group_desc(sb, group, &bh2);

//釋放bitmap_bh.已經(jīng)后面會使用這個臨時變量

brelse(bitmap_bh);

//取得組描述符里的inode位圖

bitmap_bh = read_inode_bitmap(sb, group);

if (!bitmap_bh) {

err = -EIO;

goto fail;

}

ino = 0;

repeat_in_this_group:

//尋找位圖中第一個沒有使用的位

ino = ext2_find_next_zero_bit((unsigned long *)bitmap_bh->b_data,

EXT2_INODES_PER_GROUP(sb), ino);

//如果找到的位大于塊組中的inode數(shù).那從group之后的塊組中分配

if (ino >= EXT2_INODES_PER_GROUP(sb)) {

/*

* Rare race: find_group_xx() decided that there were

* free inodes in this group, but by the time we tried

* to allocate one, they're all gone.? This can also

* occur because the counters which find_group_orlov()

* uses are approximate.? So just go and search the

* next block group.

*/

//已經(jīng)到達(dá)塊組數(shù)目最大值。則將其置為零.然后重新循環(huán)

if (++group == sbi->s_groups_count)

group = 0;

continue;

}

//將inode 位圖中的分配位置位

if (ext2_set_bit_atomic(sb_bgl_lock(sbi, group),

ino, bitmap_bh->b_data)) {

/* we lost this inode */

//如果該位已經(jīng)被置位了.說明其它的內(nèi)核控制路徑將其分配了.

//那就找它的下一個沒有被使用的inode

//如果下一個超過了這個組中的最大inode數(shù)目。那從下一個塊組中分配

if (++ino >= EXT2_INODES_PER_GROUP(sb)) {

/* this group is exhausted, try next group */

if (++group == sbi->s_groups_count)

group = 0;

continue;

}

/* try to find free inode in the same group */

//重新從塊組中尋找沒有被使用的inode

goto repeat_in_this_group;

}

//如果運(yùn)行到這里的話,說明分配成功了

goto got;

}

/*

* Scanned all blockgroups.

*/

err = -ENOSPC;

goto fail;

got:

mark_buffer_dirty(bitmap_bh);

if (sb->s_flags & MS_SYNCHRONOUS)

sync_dirty_buffer(bitmap_bh);

brelse(bitmap_bh);

//將塊組中的inode序號轉(zhuǎn)換為全局inode計(jì)數(shù)

ino += group * EXT2_INODES_PER_GROUP(sb) + 1;

//如果inode序號小于super_block的超始inode序號或者大于inode總數(shù)

//出錯退出

if (ino < EXT2_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {

ext2_error (sb, "ext2_new_inode",

"reserved inode or inode > inodes count - "

"block_group = %d,inode=%lu", group,

(unsigned long) ino);

err = -EIO;

goto fail;

}

//更新統(tǒng)計(jì)計(jì)數(shù)

percpu_counter_mod(&sbi->s_freeinodes_counter, -1);

if (S_ISDIR(mode))

percpu_counter_inc(&sbi->s_dirs_counter);

spin_lock(sb_bgl_lock(sbi, group));

gdp->bg_free_inodes_count =

cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1);

//更新s_debts

if (S_ISDIR(mode)) {

if (sbi->s_debts[group] < 255)

sbi->s_debts[group]++;

gdp->bg_used_dirs_count =

cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1);

} else {

if (sbi->s_debts[group])

sbi->s_debts[group]--;

}

spin_unlock(sb_bgl_lock(sbi, group));

sb->s_dirt = 1;

mark_buffer_dirty(bh2);

inode->i_uid = current->fsuid;

if (test_opt (sb, GRPID))

inode->i_gid = dir->i_gid;

else if (dir->i_mode & S_ISGID) {

inode->i_gid = dir->i_gid;

if (S_ISDIR(mode))

mode |= S_ISGID;

} else

inode->i_gid = current->fsgid;

inode->i_mode = mode;

//更新inode表示的索引結(jié)點(diǎn)號

inode->i_ino = ino;

inode->i_blksize = PAGE_SIZE;??? /* This is the optimal IO size (for stat), not the fs block size */

inode->i_blocks = 0;

//使i_mtine,i_atime,i_ctime置為當(dāng)前時間

inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;

memset(ei->i_data, 0, sizeof(ei->i_data));

ei->i_flags = EXT2_I(dir)->i_flags & ~EXT2_BTREE_FL;

if (S_ISLNK(mode))

ei->i_flags &= ~(EXT2_IMMUTABLE_FL|EXT2_APPEND_FL);

/* dirsync is only applied to directories */

if (!S_ISDIR(mode))

ei->i_flags &= ~EXT2_DIRSYNC_FL;

ei->i_faddr = 0;

ei->i_frag_no = 0;

ei->i_frag_size = 0;

ei->i_file_acl = 0;

ei->i_dir_acl = 0;

ei->i_dtime = 0;

ei->i_block_group = group;

ei->i_next_alloc_block = 0;

ei->i_next_alloc_goal = 0;

ei->i_prealloc_block = 0;

ei->i_prealloc_count = 0;

ei->i_dir_start_lookup = 0;

ei->i_state = EXT2_STATE_NEW;

ext2_set_inode_flags(inode);

spin_lock(&sbi->s_next_gen_lock);

inode->i_generation = sbi->s_next_generation++;

spin_unlock(&sbi->s_next_gen_lock);

insert_inode_hash(inode);

if (DQUOT_ALLOC_INODE(inode)) {

DQUOT_DROP(inode);

err = -ENOSPC;

goto fail2;

}

err = ext2_init_acl(inode, dir);

if (err) {

DQUOT_FREE_INODE(inode);

goto fail2;

}

//置inode為“臟”

mark_inode_dirty(inode);

ext2_debug("allocating inode %lu\n", inode->i_ino);

ext2_preread_inode(inode);

return inode;

fail2:

inode->i_flags |= S_NOQUOTA;

inode->i_nlink = 0;

iput(inode);

return ERR_PTR(err);

fail:

make_bad_inode(inode);

iput(inode);

return ERR_PTR(err);

}

查找一個末使用的索引結(jié)點(diǎn)有一個規(guī)則,就是盡量使每個塊組達(dá)到平衡.所以linux在ext2_sb_info結(jié)構(gòu)中加了一個s_debts字段.用來表示每個塊組中的文件與目錄的分配情況.計(jì)算的方法是在此find_group_orlov(目錄)和find_group_other(其它類型的文件)中完成的.

每個頁面都包含兩個特殊目錄結(jié)構(gòu) “.”和 “..”.單點(diǎn)代表其本身,雙點(diǎn)代表父目錄.這個過程是在ext2_make_empty()中完成的.對應(yīng)代碼如下:

int ext2_make_empty(struct inode *inode, struct inode *parent)

{

struct address_space *mapping = inode->i_mapping;

//找到頁面映射所代表的首個頁面

struct page *page = grab_cache_page(mapping, 0);

unsigned chunk_size = ext2_chunk_size(inode);

struct ext2_dir_entry_2 * de;

int err;

void *kaddr;

if (!page)

return -ENOMEM;

//先調(diào)用prepare_write().因?yàn)橹髸age寫到文件系統(tǒng)中去

err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size);

if (err) {

unlock_page(page);

goto fail;

}

//將page臨時映射到內(nèi)核

kaddr = kmap_atomic(page, KM_USER0);

//目錄中的第一個文件對象

de = (struct ext2_dir_entry_2 *)kaddr;

//每個目錄中都有兩個默認(rèn)存在的對象.和..

//將'.'加至目錄中,其inode結(jié)點(diǎn)號指向其本身

de->name_len = 1;

de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1));

memcpy (de->name, ".\0\0", 4);

de->inode = cpu_to_le32(inode->i_ino);

ext2_set_de_type (de, inode);

//設(shè)置'..'.使其指向父目錄

de = (struct ext2_dir_entry_2 *)(kaddr + EXT2_DIR_REC_LEN(1));

de->name_len = 2;

de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1));

de->inode = cpu_to_le32(parent->i_ino);

memcpy (de->name, "..\0", 4);

ext2_set_de_type (de, inode);

//釋放掉映射區(qū)間

kunmap_atomic(kaddr, KM_USER0);

//將更改的頁面提交到文件系統(tǒng)

err = ext2_commit_chunk(page, 0, chunk_size);

fail:

//頁面使用完了,減少其使用計(jì)數(shù)

page_cache_release(page);

return err;

}

初始完成之后,要將子目錄插入父目錄所表的空間的。它是由ext2_add_link()完成的。代碼如下:

int ext2_add_link (struct dentry *dentry, struct inode *inode)

{

//得到父目錄的inode

struct inode *dir = dentry->d_parent->d_inode;

const char *name = dentry->d_name.name;

int namelen = dentry->d_name.len;

unsigned chunk_size = ext2_chunk_size(dir);

unsigned reclen = EXT2_DIR_REC_LEN(namelen);

unsigned short rec_len, name_len;

struct page *page = NULL;

ext2_dirent * de;

//父目錄結(jié)點(diǎn)大小所占的頁面數(shù)

unsigned long npages = dir_pages(dir);

unsigned long n;

char *kaddr;

unsigned from, to;

int err;

/*

* We take care of directory expansion in the same loop.

* This code plays outside i_size, so it locks the page

* to protect that region.

*/

//遍歷結(jié)點(diǎn)所在的空間

for (n = 0; n <= npages; n++) {

char *dir_end;

page = ext2_get_page(dir, n);

err = PTR_ERR(page);

if (IS_ERR(page))

goto out;

lock_page(page);

kaddr = page_address(page);

//本頁面的最后的位置.

//ext2_last_byte: 如果剩余的長度大于一個頁面,則返回一個頁面大小.否則返回剩余空間大小

dir_end = kaddr + ext2_last_byte(dir, n);

de = (ext2_dirent *)kaddr;

kaddr += PAGE_CACHE_SIZE - reclen;

while ((char *)de <= kaddr) {

//到了結(jié)點(diǎn)空間的末尾

if ((char *)de == dir_end) {

/* We hit i_size */

name_len = 0;

rec_len = chunk_size;

de->rec_len = cpu_to_le16(chunk_size);

de->inode = 0;

goto got_it;

}

//目錄中文件所占空間長度為0.非法

if (de->rec_len == 0) {

ext2_error(dir->i_sb, __FUNCTION__,

"zero-length directory entry");

err = -EIO;

goto out_unlock;

}

err = -EEXIST;

//在目錄所包含的文件中,含有同名的結(jié)點(diǎn)

if (ext2_match (namelen, name, de))

goto out_unlock;

name_len = EXT2_DIR_REC_LEN(de->name_len);

rec_len = le16_to_cpu(de->rec_len);

//de->inode==0.表示目錄中的此結(jié)點(diǎn)被刪除

//rec_len >= reclen:表示舊結(jié)點(diǎn)中有足夠的空間存儲新的結(jié)點(diǎn)

if (!de->inode && rec_len >= reclen)

goto got_it;

//這個結(jié)點(diǎn)中有空間剩余.(可能是它后面有節(jié)點(diǎn)被刪除造成的)

if (rec_len >= name_len + reclen)

goto got_it;

de = (ext2_dirent *) ((char *) de + rec_len);

}

unlock_page(page);

ext2_put_page(page);

}

BUG();

return -EINVAL;

got_it:

from = (char*)de - (char*)page_address(page);

to = from + rec_len;

err = page->mapping->a_ops->prepare_write(NULL, page, from, to);

if (err)

goto out_unlock;

if (de->inode) {

//這是屬于結(jié)點(diǎn)空間有剩余的情況

//即在空間中插入一個新的結(jié)點(diǎn)

ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);

de1->rec_len = cpu_to_le16(rec_len - name_len);

de->rec_len = cpu_to_le16(name_len);

de = de1;

}

//對目錄的相關(guān)項(xiàng)進(jìn)行賦值

de->name_len = namelen;

memcpy (de->name, name, namelen);

de->inode = cpu_to_le32(inode->i_ino);

ext2_set_de_type (de, inode);

//提交所做的修改,將其寫入文件系統(tǒng)

err = ext2_commit_chunk(page, from, to);

//更改時間戳

dir->i_mtime = dir->i_ctime = CURRENT_TIME;

EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;

mark_inode_dirty(dir);

/* OFFSET_CACHE */

out_put:

ext2_put_page(page);

out:

return err;

out_unlock:

unlock_page(page);

goto out_put;

}

在這里,忽略了頁面映射與文件系統(tǒng)驅(qū)動的交互過程。關(guān)于頁面緩存后續(xù)再給出章節(jié)進(jìn)行分析.

五:小結(jié)

在這一節(jié)里,以rootfs和ext2文件系統(tǒng)為例分析了目錄的建立過程.只要對ext2文件系統(tǒng)的相關(guān)部分有所了解.理解這部份代碼并不難.其中關(guān)于頁面緩存部份以后再給出專題分析.詳情請關(guān)注本站更新.

總結(jié)

以上是生活随笔為你收集整理的linux 如何赋值目录,Linux文件系统之目录的建立的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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