truncate.c
是Linux内核中处理文件截断操作的核心实现文件,位于fs/
目录下。它实现了系统调用truncate()
和ftruncate()
,以及相关的辅助函数。
truncate.c
主要提供以下功能:
1. 实现truncate()
和ftruncate()
系统调用
2. 处理文件大小调整操作
3. 管理文件截断时的磁盘空间分配与释放
4. 维护文件系统一致性
int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
struct file *filp)
{
struct inode *inode = dentry->d_inode;
struct iattr newattrs;
/* 准备属性变更结构 */
newattrs.ia_size = length;
newattrs.ia_valid = ATTR_SIZE | time_attrs;
if (filp) {
newattrs.ia_file = filp;
newattrs.ia_valid |= ATTR_FILE;
}
/* 调用inode变更通知 */
return notify_change(dentry, &newattrs, NULL);
}
这是截断操作的核心函数,它: - 接收目标dentry、新长度和可选的文件指针 - 准备一个iattr结构描述要变更的属性 - 通过notify_change()通知文件系统执行实际变更
SYSCALL_DEFINE2(truncate, const char __user *, path, long, length)
{
struct path file;
int error;
error = user_path(path, &file);
if (error)
goto out;
error = do_truncate(file.dentry, length, 0, NULL);
path_put(&file);
out:
return error;
}
truncate()
系统调用实现:
1. 通过用户路径查找文件
2. 调用do_truncate()执行截断
3. 释放路径引用
SYSCALL_DEFINE2(ftruncate, unsigned int, fd, unsigned long, length)
{
struct fd f = fdget(fd);
int error = -EBADF;
if (f.file) {
error = do_truncate(f.file->f_path.dentry, length, 0, f.file);
fdput(f);
}
return error;
}
ftruncate()
系统调用实现:
1. 通过文件描述符获取文件结构
2. 调用do_truncate()执行截断
3. 释放文件引用
struct iattr {
unsigned int ia_valid;
umode_t ia_mode;
kuid_t ia_uid;
kgid_t ia_gid;
loff_t ia_size;
struct timespec ia_atime;
struct timespec ia_mtime;
struct timespec ia_ctime;
struct file *ia_file;
};
用于传递文件属性变更请求,ia_valid
字段标识哪些属性需要修改。
实际的空间分配和释放操作由具体文件系统通过inode_operations
中的truncate
方法实现。例如:
const struct inode_operations ext4_file_inode_operations = {
.truncate = ext4_truncate,
/* 其他操作 */
};
truncate.c
中处理多种错误情况:
- EACCES:权限不足
- EINVAL:无效参数
- EISDIR:目标是目录
- ENOENT:文件不存在
- EPERM:只读文件系统
- EFBIG:文件过大
// 用户空间调用示例
int ret = truncate("/path/to/file", 1024); // 截断文件到1024字节
if (ret < 0) {
perror("truncate failed");
}
Linux的truncate.c
实现提供了一个高效、安全的文件截断机制,通过VFS层抽象支持多种文件系统,同时处理了各种边界条件和错误情况。其设计体现了Linux文件系统模块的灵活性和可扩展性。