- 论坛徽章:
- 0
|
/********************************************
*Created By: Prometheus
*Date : 2009-5-19
********************************************/
#include
#include
#include
#include
#include
#include
static void cp_old_stat(struct inode * inode, struct old_stat * statbuf)
{
struct old_stat tmp;
printk("VFS: Warning: %s using old stat() call. Recompile your binary.\n",
current->comm);
/*复制节点中指定的信息*/
tmp.st_dev = inode->i_dev;
tmp.st_ino = inode->i_ino;
tmp.st_mode = inode->i_mode;
tmp.st_nlink = inode->i_nlink;
tmp.st_uid = inode->i_uid;
tmp.st_gid = inode->i_gid;
tmp.st_rdev = inode->i_rdev;
tmp.st_size = inode->i_size;
tmp.st_atime = inode->i_atime;
tmp.st_mtime = inode->i_mtime;
tmp.st_ctime = inode->i_ctime;
/*statbuf i_dev;
tmp.st_ino = inode->i_ino;
tmp.st_mode = inode->i_mode;
tmp.st_nlink = inode->i_nlink;
tmp.st_uid = inode->i_uid;
tmp.st_gid = inode->i_gid;
tmp.st_rdev = inode->i_rdev;
tmp.st_size = inode->i_size;
tmp.st_atime = inode->i_atime;
tmp.st_mtime = inode->i_mtime;
tmp.st_ctime = inode->i_ctime;
/*old_stat new_stat现在的区别是后者具有字段st_blocks和st_blksize
*对于有的文件系统在节点的位置就提供了文件的块的大小,这样就直接
*复制节点中的相应的块大小就可以了,而有的文件系统(比如Minix和dos
*文件系统就没有跟踪文件块数,这时候就需要自己进行计算了哦)
are approximated with a simple algorithm if
* they aren't supported directly by the filesystem. The minix and msdos
* filesystems don't keep track of blocks, so they would either have to
* be counted explicitly (by delving into the file itself), or by using
* this simple algorithm to get a reasonable (although not 100% accurate)
* value.
*/
/*
* Use minix fs values for the number of direct and indirect blocks. The
* count is now exact for the minix fs except that it counts zero blocks.
* Everything is in BLOCK_SIZE'd units until the assignment to
* tmp.st_blksize.
*/
#define D_B 7 /*直接块,7块*/
#define I_B (BLOCK_SIZE / sizeof(unsigned short)) /*间接块512(1024/2)*/
if (!inode->i_blksize) { /*节点中没有信息就要自己计算了:-(*/
/*st_size字段保存了文件的总的大小(字节位单位)
*这里进行进位计算,查看文件占用的多少逻辑块
*由于这里没有跟踪文件块信息,可能是比较老的
*文件系统了(比如Minix)而没有可变的块大小了,
*所以下面直接使用了默认的块大小进行计算了:-)*/
//对于下面的计算,上面的注释也写的很清楚了,所有的计算都是使用
//BLOCK_SIZE 进行计算的,而最终要转换成使用 512 进行单位计算的块数了
blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE; /*文件占用的总块数*/
if (blocks > D_B) { //使用了间接块,由于间接块本身也用了直接块了,这里进行校正
indirect = (blocks - D_B + I_B - 1) / I_B;
blocks += indirect;
if (indirect > 1) { //二级间接块
indirect = (indirect - 1 + I_B - 1) / I_B;
blocks += indirect;
if (indirect > 1)
blocks++;
}
}
tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
tmp.st_blksize = BLOCK_SIZE;
} else { /*如果文件系统提供就很方便*/
tmp.st_blocks = inode->i_blocks;
tmp.st_blksize = inode->i_blksize;
}
memcpy_tofs(statbuf,&tmp,sizeof(tmp));
}
asmlinkage int sys_stat(char * filename, struct old_stat * statbuf)
{
struct inode * inode;
int error;
error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
if (error)
return error;
error = namei(filename,&inode);
if (error)
return error;
cp_old_stat(inode,statbuf);
iput(inode);
return 0;
}
asmlinkage int sys_newstat(char * filename, struct new_stat * statbuf)
{
struct inode * inode;
int error;
error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
if (error)
return error;
error = namei(filename,&inode);
if (error)
return error;
cp_new_stat(inode,statbuf);
iput(inode);
return 0;
}
/*功能相似于stat,只是对于符号连接,返回的信息是符号连接本身而不是
*符号连接指向的文件,这里的差别主要是读取节点的时候使用的函数是
*lnamei而不是namei*/
asmlinkage int sys_lstat(char * filename, struct old_stat * statbuf)
{
struct inode * inode;
int error;
error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
if (error)
return error;
error = lnamei(filename,&inode);
if (error)
return error;
cp_old_stat(inode,statbuf);
iput(inode);
return 0;
}
asmlinkage int sys_newlstat(char * filename, struct new_stat * statbuf)
{
struct inode * inode;
int error;
error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
if (error)
return error;
error = lnamei(filename,&inode);
if (error)
return error;
cp_new_stat(inode,statbuf);
iput(inode);
return 0;
}
/*功能同上面,只是参数是文件描述符*/
asmlinkage int sys_fstat(unsigned int fd, struct old_stat * statbuf)
{
struct file * f;
struct inode * inode;
int error;
error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
if (error)
return error;
if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode))
return -EBADF;
cp_old_stat(inode,statbuf);
return 0;
}
asmlinkage int sys_newfstat(unsigned int fd, struct new_stat * statbuf)
{
struct file * f;
struct inode * inode;
int error;
error = verify_area(VERIFY_WRITE,statbuf,sizeof (*statbuf));
if (error)
return error;
if (fd >= NR_OPEN || !(f=current->filp[fd]) || !(inode=f->f_inode))
return -EBADF;
cp_new_stat(inode,statbuf);
return 0;
}
/*将作为符号链接的path的内容读取并存放到buf中,
*这会将内容截断到bufsiz长度,而且字符串不会自动
*添加空字符到字符串的结尾,或许这是对于符号
*连接转换为实际的路径所要调用的函数哦*/
asmlinkage int sys_readlink(const char * path, char * buf, int bufsiz)
{
struct inode * inode;
int error;
if (bufsiz i_op || !inode->i_op->readlink) {
iput(inode);
return -EINVAL;
}
return inode->i_op->readlink(inode,buf,bufsiz);
}
文档地址:http://blogimg.chinaunix.net/blog/upfile2/090519193335.pdf
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/90306/showart_1933060.html |
|