Linux内核 - 线程创建, memcpy的应用

应用场景

第一次ll操作返回正常的显示信息,第二次做ll操作报no such file的错误信息模拟,实验可以成功模拟出来下效果。

记录一下,此次试验的小知识点。模拟中,是在lookup函数中修改dentry内容,主要内存块拷贝+延迟的操作。需要利用到内核线程的启动。

#include <linux/sched.h>
#include <linux/errno.h>
#include <linux/kthread.h>

struct d_replace{                                                           // 参数传递
	struct dentry *old_dentry;
	struct dentry *new_dentry;
};

static void func_d_replace(void *data){                                     // 替换函数
	msleep(2000);
	dfprintk(VFS, "into func dentry replace");
	struct d_replace *d = (struct d_replace *)data;
	dfprintk(VFS, "d replace new name is %s \n", d->new_dentry->d_name.name);
	dfprintk(VFS, "d replace old name is %s \n", d->old_dentry->d_name.name);
	//d->old_dentry = d->new_dentry;
	memcpy(d->old_dentry, d->new_dentry, sizeof(*(d->old_dentry)));
	dfprintk(VFS, "cover dentry new name is %s \n", d->new_dentry->d_name.name);
	dfprintk(VFS, "cover dentry old name is %s \n", d->old_dentry->d_name.name);
}

struct dentry *nfs_lookup(struct inode *dir, struct dentry * jhash_size, unsigned int flags)
{
	struct dentry *res;
	struct dentry *parent;
	struct inode *inode = NULL;
	struct nfs_fh *fhandle = NULL;
	struct nfs_fattr *fattr = NULL;
	int error;

	struct task_struct *task;                            // 声明补充变量
	const unsigned char *name;
	struct d_replace *d_rep;
	struct dentry *d_new;
	
	d_new = d_alloc(dentry->d_parent, &dentry->d_name);  // 创建一个dentry
	d_rep = kmalloc(sizeof(*d_rep), GFP_KERNEL);           // 申请结构体空间

	dfprintk(VFS, "NFS: lookup(%s/%s)\n",
		dentry->d_parent->d_name.name, dentry->d_name.name);
	nfs_inc_stats(dir, NFSIOS_VFSLOOKUP);

	res = ERR_PTR(-ENAMETOOLONG);
	if (dentry->d_name.len > NFS_SERVER(dir)->namelen)
		goto out;

	/*
	 * If we're doing an exclusive create, optimize away the lookup
	 * but don't hash the dentry.
	 */
	if (nfs_is_exclusive_create(dir, flags)) {
		d_instantiate(dentry, NULL);
		res = NULL;
		goto out;
	}

	res = ERR_PTR(-ENOMEM);
	fhandle = nfs_alloc_fhandle();
	fattr = nfs_alloc_fattr();
	if (fhandle == NULL || fattr == NULL)
		goto out;

	parent = dentry->d_parent;
	/* Protect against concurrent sillydeletes */
	nfs_block_sillyrename(parent);
	error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr);
	if (error == -ENOENT)
		goto no_entry;
	if (error < 0) {
		res = ERR_PTR(error);
		goto out_unblock_sillyrename;
	}
	inode = nfs_fhget(dentry->d_sb, fhandle, fattr);
	res = ERR_CAST(inode);
	if (IS_ERR(res))
		goto out_unblock_sillyrename;

	/* Success: notify readdir to use READDIRPLUS */
	nfs_advise_use_readdirplus(dir);

no_entry:
	res = d_materialise_unique(dentry, inode);
	if (res != NULL) {
		if (IS_ERR(res))
			goto out_unblock_sillyrename;
		dentry = res;
	}
	nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
out_unblock_sillyrename:
	nfs_unblock_sillyrename(parent);
out:
	nfs_free_fattr(fattr);
	nfs_free_fhandle(fhandle);

	name = "debug";					//特殊目录名,修改它的dentry
	if(strcasecmp(dentry->d_name.name, name) == 0){				// 创建线程
		dfprintk(VFS, "name is debug, ready...");
		d_rep->old_dentry = dentry;
		d_rep->new_dentry = d_new;
		dfprintk(VFS, "new name is %s", d_rep->new_dentry->d_name.name);
		dfprintk(VFS, "old name is %s", d_rep->old_dentry->d_name.name);
		task = kthread_create(func_d_replace, d_rep, "replace dentry");
		if(IS_ERR(task)){
			dfprintk(VFS, "unable to start kernel thread");
		}
		wake_up_process(task);
	}
	return res;
}
EXPORT_SYMBOL_GPL(nfs_lookup);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值