本文共 2105 字,大约阅读时间需要 7 分钟。
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