echo > /root/test.txt和truncate -s 0 /test.txt都可以截断文件。
如果文件句柄没有被关闭,仍然被别的进程占据写的话可以将文件的前半部分变成空洞。
前者在内核态行为是通过sys_open调用下来的
ret_from_syscall
=>asmlinkage long sys_open(const char __user *filename, int flags, int mode);
struct file *f = do_filp_open(dfd, tmp, flags, mode, 0);
=>struct file *do_filp_open(int dfd, const char *pathname, int open_flag, int mode, int acc_mode)
filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname);
=>static struct file *do_last(struct nameidata *nd, struct path *path, int open_flag, int acc_mode, int mode, const char *pathname)
filp = finish_open(nd, open_flag, acc_mode);
=>static struct file *finish_open(struct nameidata *nd, int open_flag, int acc_mode)
will_truncate = open_will_truncate(open_flag, nd->path.dentry->d_inode);
if (will_truncate)
error = handle_truncate(&nd->path);
=>static int handle_truncate(struct path *path)
do_truncate(path->dentry, 0, ATTR_MTIME|ATTR_CTIME|ATTR_OPEN, NULL);
后者是如下调用
ret_from_syscall
=>static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
=>int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, struct file *filp)
struct iattr newattrs;
newattrs.ia_size = length;
ret = notify_change(dentry, &newattrs);
=>int notify_change(struct dentry * dentry, struct iattr * attr)
error = inode_setattr(inode, attr);
=>int inode_setattr(struct inode * inode, struct iattr * attr)
int error = vmtruncate(inode, attr->ia_size);
=>int vmtruncate(struct inode *inode, loff_t offset)
error = inode_newsize_ok(inode, offset);
oldsize = inode->i_size;
i_size_write(inode, offset);
=>static inline void i_size_write(struct inode *inode, loff_t i_size)
inode->i_size = i_size;
truncate_pagecache(inode, oldsize, offset);
inode->i_op->truncate(inode);
mark_inode_dirty(inode);
linux系统编程:用truncate调整文件大小
https://www.cnblogs.com/ghostwu/archive/2018/01/11/8269220.html