diff --git a/kernel/src/fs/exfat/inode.rs b/kernel/src/fs/exfat/inode.rs index 2d9d0d6d6..aed6f6f27 100644 --- a/kernel/src/fs/exfat/inode.rs +++ b/kernel/src/fs/exfat/inode.rs @@ -1108,6 +1108,9 @@ impl Inode for ExfatInode { if inner.inode_type.is_directory() { return_errno!(Errno::EISDIR) } + if !inner.inode_type.is_regular_file() { + return_errno!(Errno::EINVAL); + } let file_size = inner.size; let fs = inner.fs(); diff --git a/kernel/src/fs/ext2/inode.rs b/kernel/src/fs/ext2/inode.rs index fb05aeda4..8dff64c91 100644 --- a/kernel/src/fs/ext2/inode.rs +++ b/kernel/src/fs/ext2/inode.rs @@ -107,9 +107,12 @@ impl Inode { } pub fn resize(&self, new_size: usize) -> Result<()> { - if self.type_ != InodeType::File { + if self.type_ == InodeType::Dir { return_errno!(Errno::EISDIR); } + if self.type_ != InodeType::File { + return_errno!(Errno::EINVAL); + } let inner = self.inner.upread(); if new_size == inner.file_size() { @@ -782,10 +785,6 @@ impl Inode { } pub fn fallocate(&self, mode: FallocMode, offset: usize, len: usize) -> Result<()> { - if self.type_ != InodeType::File { - return_errno_with_message!(Errno::EISDIR, "not regular file"); - } - match mode { FallocMode::PunchHoleKeepSize => { // Make the whole operation atomic diff --git a/kernel/src/fs/inode_handle/mod.rs b/kernel/src/fs/inode_handle/mod.rs index 90510cf7d..7fb1b7316 100644 --- a/kernel/src/fs/inode_handle/mod.rs +++ b/kernel/src/fs/inode_handle/mod.rs @@ -406,6 +406,18 @@ pub fn do_fallocate_util( offset: usize, len: usize, ) -> Result<()> { + let inode_type = inode.type_(); + // TODO: `fallocate` on pipe files also fails with `ESPIPE`. + if inode_type == InodeType::NamedPipe { + return_errno_with_message!(Errno::ESPIPE, "the inode is a FIFO file"); + } + if !(inode_type == InodeType::File || inode_type == InodeType::Dir) { + return_errno_with_message!( + Errno::ENODEV, + "the inode is not a regular file or a directory" + ); + } + if status_flags.contains(StatusFlags::O_APPEND) && (mode == FallocMode::PunchHoleKeepSize || mode == FallocMode::CollapseRange diff --git a/kernel/src/fs/overlayfs/fs.rs b/kernel/src/fs/overlayfs/fs.rs index f5b9890de..d4d2f2a7c 100644 --- a/kernel/src/fs/overlayfs/fs.rs +++ b/kernel/src/fs/overlayfs/fs.rs @@ -414,8 +414,11 @@ impl OverlayInode { } pub fn resize(&self, new_size: usize) -> Result<()> { + if self.type_ == InodeType::Dir { + return_errno_with_message!(Errno::EISDIR, "the inode is a directory"); + } if self.type_ != InodeType::File { - return_errno_with_message!(Errno::EISDIR, "not regular file"); + return_errno_with_message!(Errno::EINVAL, "the inode is not a regular file"); } if self.get_top_valid_inode().size() == new_size { diff --git a/kernel/src/fs/ramfs/fs.rs b/kernel/src/fs/ramfs/fs.rs index 8cf603459..87ae7bcb9 100644 --- a/kernel/src/fs/ramfs/fs.rs +++ b/kernel/src/fs/ramfs/fs.rs @@ -613,8 +613,11 @@ impl Inode for RamInode { } fn resize(&self, new_size: usize) -> Result<()> { + if self.typ == InodeType::Dir { + return_errno_with_message!(Errno::EISDIR, "the inode is a directory"); + } if self.typ != InodeType::File { - return_errno_with_message!(Errno::EISDIR, "not regular file"); + return_errno_with_message!(Errno::EINVAL, "the inode is not a regular file"); } let file_size = self.size(); @@ -1156,10 +1159,6 @@ impl Inode for RamInode { } fn fallocate(&self, mode: FallocMode, offset: usize, len: usize) -> Result<()> { - if self.typ != InodeType::File { - return_errno_with_message!(Errno::EISDIR, "not regular file"); - } - // The support for flags is consistent with Linux match mode { FallocMode::Allocate => {