From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=188.121.53.26 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794440708; b=eawOoFCyTbe0baqT5obfYtOHVawD4Zbuk+mDLY8zFqjpj5AhN8dQp6QkMFqRwRTJY3+R +5dksHH8A6CwZ+C51YvHr1kzzDhdPZHYcHjXBG6uA/liNuXqNZFSkzrg+7bnciv83krDW RNAVbvRUCXBMpLmGROonI9Ll9cvfwF4uIxqVy5wcCemsrAm5QoKPvCyD6x9TGUNWiLfZ/ pjXilhHnh7HJHxqgUrWz47hSNlcUoaGBut4ddCIKQHisjOlCTArTFfr93EzicdnPZ7+xh L3VrZPejb6hIvA8/EOKDS9y4g9DMuLIBOJeJwYdTkQMuW3v19V43l8Zg2q1VucZofNg== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794440708; h=DMARC-Filter:Received:DKIM-Signature:DKIM-Signature:X-CMAE-Analysis: Feedback-ID:X-SECURESERVER-ACCT:From:To:Cc:Subject:Date:Message-ID: X-Mailer:In-Reply-To:References:MIME-Version: Content-Transfer-Encoding:X-CMAE-Envelope; bh=z9drwXo/uzTm2HmgebtAeKGkgBoc1JWW3NHlDvBVLGY=; b=eRdKe0vvdqOCr41xvej5igZqDEh6h2xnj7B/BOsuZE4rN+RaWnPCgobOF04cQqD0p+pk lNZQe5CQcZQpP++s3+eTrMqiv8V5Qly0BqP69UpfeZANaYtqFEDpkaelaUuWD0tHEfigW Qpn84qRr5JPWeVMWIKHsefEgSotn/EJ3dnatqMaP5n1jhiMaSuHyxapdNHYiPZDPPTQBr ILIIvr+GSk+u2my/d2SCnB35cop1U4hWymR/7bn9fKIIHdPxIEYQQIYQZfGYlDeqC9Pxj f9tG+LXfEV6tJgT09B+MDPpi2D9lvE/Q8RKv5MqUmhSEibAu2zApnhlDmS2Gbz5VArQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=squashfs.org.uk; spf=pass smtp.mailfrom=squashfs.org.uk; dkim=pass header.d=secureserver.net header.i=@secureserver.net header.a=rsa-sha256 header.s=secureserver2 header.b=WT+Kon16; dkim=pass header.d=squashfs.org.uk header.i=@squashfs.org.uk header.a=rsa-sha256 header.s=secureserver1 header.b=nB4g8+4t; arc=none smtp.remote-ip=188.121.53.26 Received: from sxplsmtpa04-03.prod.sxb1.secureserver.net (sxplsmtpa04-03.prod.sxb1.secureserver.net [188.121.53.26]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E7B9D606C0BC for ; Wed, 11 Nov 2026 23:45:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org E7B9D606C0BC Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=squashfs.org.uk Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=squashfs.org.uk Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key, unprotected) header.d=secureserver.net header.i=@secureserver.net header.a=rsa-sha256 header.s=secureserver2 header.b=WT+Kon16; dkim=pass (2048-bit key, unprotected) header.d=squashfs.org.uk header.i=@squashfs.org.uk header.a=rsa-sha256 header.s=secureserver1 header.b=nB4g8+4t Received: from avalon.fritz.box ([82.69.79.175]) by :SMTPAUTH: with ESMTPA id RHz6xtxIpLwCURHzvxAFZm; Wed, 11 Nov 2026 23:45:00 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=secureserver.net; s=secureserver2; t=1794440701; bh=z9drwXo/uzTm2HmgebtAeKGkgBoc1JWW3NHlDvBVLGY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=WT+Kon16BS3vtaGYLyaxK0Ab3G3fKStAq4O3qbwQqvfJrgxs76TYjrG2kvoB/Aq0P 0Rq6O+OIrBFAo7x0hUZviB7O1qxOJHjnr127a+/h4QaIZM552ZpvcPyAHokRT7pZHN v2oN+TLlMWuhx2/BTUIHFsEGeH9j3ZWNih5jwTYMzYwdvIwIJ2DPr6ZAYDHaJ6KXCH D9VRRo2JVfJgqWh9R1fxy518d9nJSdyZFJod0DTxVRvR7wwcNyar+xNW75lTUBOdEK 2bgVDJh3x0P+rmkKet2d5lV97b49jA5FchmuGrKRvn3yjrSm/SqrDbXRo+eYPB38G/ Tf4xPevra3bcQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=squashfs.org.uk; s=secureserver1; t=1794440701; bh=z9drwXo/uzTm2HmgebtAeKGkgBoc1JWW3NHlDvBVLGY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=nB4g8+4tWQ/UCLJxc7vZLNFLHFBqQlZvaSVZKAFw9ygPV96ucfZb7c7Ffd+fh/7TQ 4I9h4JlV5JK74nx48cK1PNglGnxrUk3H79cY1dRMkD1+XfAB2+xpovhK327DIAu8KI DNrzYwsQkVlD46joYVCipwg+NSupLJQhkGksRGBSnHXBN9r/ZhL56n6fQkeffn1E+2 7Gr1vavkOwl7IpmsBHRupUZo25TgodWQMfXbfJv2lYjAB7/05GDAoxSv1mO9ybJ7oE CEVfe0ni75xtz2VGLIjiwTepHIuVnWvDZpqwhkGjtjg4fHswAgWtwmEcT55isliIro CEOeIvakUHdLQ== X-CMAE-Analysis: v=2.4 cv=XZYcX455 c=1 sm=1 tr=0 ts=6af4fdfc a=84ok6UeoqCVsigPHarzEiQ==:117 a=84ok6UeoqCVsigPHarzEiQ==:17 a=FXvPX3liAAAA:8 a=T2VrowB_akgkcgLsTUAA:9 a=UObqyxdv-6Yh2QiB9mM_:22 Feedback-ID: 4eae38ca82fd1d3643e0118b9b0b2b6c:squashfs.org.uk:ssnet X-SECURESERVER-ACCT: phillip@squashfs.org.uk From: Phillip Lougher To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, akpm@linux-foundation.org Cc: Phillip Lougher Subject: [PATCH v2 20/22] Squashfs: fix variables in directory code and add more sanity checks Date: Wed, 11 Nov 2026 23:44:00 +0000 Message-ID: <20261111234402.252354-21-phillip@squashfs.org.uk> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20261111234402.252354-1-phillip@squashfs.org.uk> References: <20261111234402.252354-1-phillip@squashfs.org.uk> X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CMAE-Envelope: MS4xfCtMj1/3QvnhOg2l+NHEMD5yV9Qo6wybUhxsy74LBp4oY4iwrz832RqlszB2/86aSwsgSWtnNK4iBIZc8C3wQLfrhFGo6c6G2NgHBjdbp3I6S93AIEk+ P8RLJT1IArELUjISqEVdKJGTuQ4m3vhpcap5j2RkxNSbbBxwCYXSmqkYxx/OYhMj+/MgDnHdwJ5Gi4CBPupM7ME2joIySqhk70nOWKSsazDrtVtm6w8HzWLw ItOp92GzpCfTcbnikti16NhoJ2iT3HrkyiN4L384U7lzH15Q9nrbdtr8Hgvrqz+SMytkgNMXQgYGCvhOdeAh5zcjNUYarxVYnftpMyE2OQc= A directory larger than a metadata block (8192 bytes) will have a directory index to allow faster reading and lookup of names. This index allows the code to jump to the desired compressed metadata block, without requiring the directory to be scanned from the beginning. But the index handling code has a defect in that multiple variables including those used to read and track directory indexes from disk are signed ints. This means any index which is 2^31 or larger will be treated as a negative value. The knock on efect of this is that the offset into the desired metadata block is incorrectly computed, with the result the directory fails to be read, and an I/O error is returned. This commit corrects the variables (and function return value) to be unsigned int, and it also adds more sanity checking of the values read off disk (including directory size to avoid underflow in subtraction). Now if a directory index is found to be incorrect, the index is discarded and the previous index read from disk is used. This allows the directory to be read correctly without throwing an I/O error. Reproducer ========== The following reproducer creates a Squashfs filesystem with a root directory which has a directory index. The reproducer then corrupts root directory index 0 with an index value of -1. The filesystem is then mounted, and stat run on file /mnt/filename-490. If the exploit succeeds stat will report an I/O error and dmesg will contain Squashfs error reports. ===================================================================== #!/bin/bash finish() { popd 2>&1 > /dev/null rm -rf $DIR exit 1 } DIR=$(mktemp -d) pushd $DIR 2>&1 > /dev/null for i in $(seq 1 1000); do echo "filename-$i f 0700 0 0 echo hello" >> pseudo done echo "Create a Squashfs filesystem" if ! mksquashfs - img.sqsh -pf pseudo -pd "d 0777 0 0" -noI -no-progress -quiet; then echo Creating the Squashfs filesystem failed finish fi # Write -1 in little-endian format to file /usr/bin/echo -en "\xff\xff\xff\xff" > file echo "Over-write the root directory index 0, with an index value of -1." echo "This because the metadata is uncompressed can be over-written directly," echo "but, normally the metadata will be compressed." echo "The location of the 4 byte index is 32150" dd bs=1 seek=32150 if=file of=img.sqsh count=4 conv=notrunc status=none echo echo "Mount the filesystem on /mnt" if ! mount -t squashfs img.sqsh /mnt; then echo Mount of Squashfs filesystem failed finish fi echo echo "Run stat /mnt/filename-490 on the mounted filesystem" echo echo "If the exploit works stat will report I/O error, and dmesg will" echo "contain Squashfs error reports" echo stat /mnt/filename-490 umount /mnt popd 2>&1 > /dev/null rm -rf $DIR exit 0 ===================================================================== Fixes: 07972dde75c32 ("Squashfs: directory readdir operations") Fixes: c88da2c979369 ("Squashfs: directory lookup operations") Signed-off-by: Phillip Lougher --- fs/squashfs/dir.c | 73 ++++++++++++++++++++------ fs/squashfs/inode.c | 12 ++++- fs/squashfs/namei.c | 95 ++++++++++++++++++++++++++-------- fs/squashfs/squashfs_helpers.h | 7 +++ 4 files changed, 147 insertions(+), 40 deletions(-) diff --git a/fs/squashfs/dir.c b/fs/squashfs/dir.c index f6454f0d5b5c..33b8225fcdaa 100644 --- a/fs/squashfs/dir.c +++ b/fs/squashfs/dir.c @@ -37,17 +37,17 @@ static const unsigned char squashfs_filetype_table[] = { * (if any) we have managed to read - the index isn't essential, just * quicker. */ -static int get_dir_index_using_offset(struct super_block *sb, +static unsigned int get_dir_index_using_offset(struct super_block *sb, u64 *next_block, int *next_offset, u64 index_start, int index_offset, - int i_count, u64 f_pos) + unsigned int i_count, loff_t max_index, u64 f_pos) { struct squashfs_sb_info *msblk = sb->s_fs_info; s64 res; - int err, i, index, length = 0; - unsigned int size; + int err; + unsigned int i, index, length = 0, size, start_block, block; struct squashfs_dir_index dir_index; - TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %lld\n", + TRACE("Entered get_dir_index_using_offset, i_count %u, f_pos %lld\n", i_count, f_pos); /* @@ -58,6 +58,18 @@ static int get_dir_index_using_offset(struct super_block *sb, if (f_pos <= 3) return f_pos; f_pos -= 3; + max_index -= 3; + + /* + * A valid index starts at a directory header, and there must be enough + * room for a directory header and one directory entry. + */ + if (max_index < sizeof(struct squashfs_dir_header) + + sizeof(struct squashfs_dir_entry) + 1) + return 3; + + max_index -= sizeof(struct squashfs_dir_header) + + sizeof(struct squashfs_dir_entry) + 1; for (i = 0; i < i_count; i++) { err = squashfs_read_metadata(sb, &dir_index, &index_start, @@ -65,33 +77,51 @@ static int get_dir_index_using_offset(struct super_block *sb, if (err < 0) break; + /* Sanity check the directory index contents */ + + /* size should never be larger than SQUASHFS_NAME_LEN */ + size = le32_to_cpu(dir_index.size) + 1; + if (size > SQUASHFS_NAME_LEN) + break; + + /* The stored index should not be larger than max_index */ index = le32_to_cpu(dir_index.index); + if (index > max_index) + break; + + block = le32_to_cpu(dir_index.start_block); + + if (i > 0) { + /* The stored index should be larger than the previous index */ + if (index <= length) + break; + + /* The start_block should not be less than the previous start_block */ + if (block < start_block) + break; + } + if (index > f_pos) /* * Found the index we're looking for. */ break; - size = le32_to_cpu(dir_index.size) + 1; - - /* size should never be larger than SQUASHFS_NAME_LEN */ - if (size > SQUASHFS_NAME_LEN) - break; - err = squashfs_read_metadata(sb, NULL, &index_start, &index_offset, size); if (err < 0) break; - res = squashfs_dir_start(le32_to_cpu(dir_index.start_block), msblk); + res = squashfs_dir_start(block, msblk); if (res < 0) break; + start_block = block; length = index; *next_block = res; } - *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; + *next_offset = ((u64)length + *next_offset) % SQUASHFS_METADATA_SIZE; /* * Translate back from internal f_pos to external f_pos. @@ -105,7 +135,8 @@ static int squashfs_readdir(struct file *file, struct dir_context *ctx) struct inode *inode = file_inode(file); struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info; s64 block = squashfs_dir_start(squashfs_i(inode)->start, msblk); - int offset = squashfs_i(inode)->offset, length, err; + int offset = squashfs_i(inode)->offset, err; + loff_t length; unsigned int inode_number, dir_count, size, type; struct squashfs_dir_header dirh; struct squashfs_dir_entry *dire = NULL; @@ -154,12 +185,15 @@ static int squashfs_readdir(struct file *file, struct dir_context *ctx) squashfs_i(inode)->dir_idx_start, squashfs_i(inode)->dir_idx_offset, squashfs_i(inode)->dir_idx_cnt, - ctx->pos); + i_size_read(inode), ctx->pos); while (length < i_size_read(inode)) { /* * Read directory header */ + if (!squashfs_dir_space(inode, length, sizeof(dirh))) + goto failed_read; + err = squashfs_read_metadata(inode->i_sb, &dirh, &block, &offset, sizeof(dirh)); if (err < 0) @@ -176,23 +210,30 @@ static int squashfs_readdir(struct file *file, struct dir_context *ctx) /* * Read directory entry. */ + if (!squashfs_dir_space(inode, length, sizeof(*dire))) + goto failed_read; + err = squashfs_read_metadata(inode->i_sb, dire, &block, &offset, sizeof(*dire)); if (err < 0) goto failed_read; + length += sizeof(*dire); size = le16_to_cpu(dire->size) + 1; /* size should never be larger than SQUASHFS_NAME_LEN */ if (size > SQUASHFS_NAME_LEN) goto failed_read; + if (!squashfs_dir_space(inode, length, size)) + goto failed_read; + err = squashfs_read_metadata(inode->i_sb, dire->name, &block, &offset, size); if (err < 0) goto failed_read; - length += sizeof(*dire) + size; + length += size; if (ctx->pos >= length) continue; diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c index a512e8d00c41..5404d7ba6fc0 100644 --- a/fs/squashfs/inode.c +++ b/fs/squashfs/inode.c @@ -253,8 +253,12 @@ int squashfs_read_inode(struct inode *inode, long long ino) if (err < 0) goto failed_read; - set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); + /* The directory size must be 3 or larger, as it includes "." and ".." entries */ inode->i_size = le16_to_cpu(sqsh_ino->file_size); + if (inode->i_size < 3) + goto failed_read; + + set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); inode->i_op = &squashfs_dir_inode_ops; inode->i_fop = &squashfs_dir_ops; inode->i_mode |= S_IFDIR; @@ -278,9 +282,13 @@ int squashfs_read_inode(struct inode *inode, long long ino) if (err < 0) goto failed_read; + /* The directory size must be 3 or larger, as it includes "." and ".." entries */ + inode->i_size = le32_to_cpu(sqsh_ino->file_size); + if (inode->i_size < 3) + goto failed_read; + xattr_id = le32_to_cpu(sqsh_ino->xattr); set_nlink(inode, le32_to_cpu(sqsh_ino->nlink)); - inode->i_size = le32_to_cpu(sqsh_ino->file_size); inode->i_op = &squashfs_dir_inode_ops; inode->i_fop = &squashfs_dir_ops; inode->i_mode |= S_IFDIR; diff --git a/fs/squashfs/namei.c b/fs/squashfs/namei.c index 9f6f6792b549..89d5a09544dc 100644 --- a/fs/squashfs/namei.c +++ b/fs/squashfs/namei.c @@ -61,57 +61,96 @@ * (if any) we have managed to read - the index isn't essential, just * quicker. */ -static int get_dir_index_using_name(struct super_block *sb, +static unsigned int get_dir_index_using_name(struct super_block *sb, u64 *next_block, int *next_offset, u64 index_start, - int index_offset, int i_count, const char *name) + int index_offset, unsigned int i_count, + loff_t max_index, const char *name) { struct squashfs_sb_info *msblk = sb->s_fs_info; s64 res; - int i, length = 0, err; - unsigned int size; - struct squashfs_dir_index *index; + int err; + unsigned int i, index, length = 0, size, start_block, block; + struct squashfs_dir_index *dir_index; - TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count); + TRACE("Entered get_dir_index_using_name, i_count %u\n", i_count); - index = kmalloc(sizeof(*index) + SQUASHFS_NAME_LEN + 1, GFP_KERNEL); - if (index == NULL) { + dir_index = kmalloc(sizeof(*dir_index) + SQUASHFS_NAME_LEN + 1, GFP_KERNEL); + if (dir_index == NULL) { ERROR("Failed to allocate squashfs_dir_index\n"); goto out; } + /* + * Translate from external index to internal index. This is offset by + * 3 because we invent "." and ".." entries. + */ + max_index -= 3; + + /* + * A valid index starts at a directory header, and there must be enough + * room for a directory header and one directory entry. + */ + if (max_index < sizeof(struct squashfs_dir_header) + + sizeof(struct squashfs_dir_entry) + 1) + goto out; + + max_index -= sizeof(struct squashfs_dir_header) + + sizeof(struct squashfs_dir_entry) + 1; + for (i = 0; i < i_count; i++) { - err = squashfs_read_metadata(sb, index, &index_start, - &index_offset, sizeof(*index)); + err = squashfs_read_metadata(sb, dir_index, &index_start, + &index_offset, sizeof(*dir_index)); if (err < 0) break; + /* Sanity check the directory index contents */ - size = le32_to_cpu(index->size) + 1; + /* size should never be larger than SQUASHFS_NAME_LEN */ + size = le32_to_cpu(dir_index->size) + 1; if (size > SQUASHFS_NAME_LEN) break; - err = squashfs_read_metadata(sb, index->name, &index_start, + /* The stored index should not be larger than max_index */ + index = le32_to_cpu(dir_index->index); + if (index > max_index) + break; + + block = le32_to_cpu(dir_index->start_block); + + if (i > 0) { + /* The stored index should be larger than the previous index */ + if (index <= length) + break; + + /* The start_block should not be less than the previous start_block */ + if (block < start_block) + break; + } + + err = squashfs_read_metadata(sb, dir_index->name, &index_start, &index_offset, size); if (err < 0) break; - index->name[size] = '\0'; + dir_index->name[size] = '\0'; - if (strcmp(index->name, name) > 0) + if (strcmp(dir_index->name, name) > 0) + /* Found the index we're looking for. */ break; - res = squashfs_dir_start(le32_to_cpu(index->start_block), msblk); + res = squashfs_dir_start(block, msblk); if (res < 0) break; - length = le32_to_cpu(index->index); + start_block = block; + length = index; *next_block = res; } - *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE; - kfree(index); - out: + *next_offset = ((u64)length + *next_offset) % SQUASHFS_METADATA_SIZE; + kfree(dir_index); + /* * Return index (f_pos) of the looked up metadata block. Translate * from internal f_pos to external f_pos which is offset by 3 because @@ -133,7 +172,8 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, struct squashfs_dir_entry *dire = NULL; u64 block = squashfs_dir_start(squashfs_i(dir)->start, msblk); int offset = squashfs_i(dir)->offset; - int err, length; + int err; + loff_t length; unsigned int dir_count, size; TRACE("Entered squashfs_lookup [%llx:%x]\n", squashfs_i(dir)->start, offset); @@ -155,12 +195,16 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, length = get_dir_index_using_name(dir->i_sb, &block, &offset, squashfs_i(dir)->dir_idx_start, squashfs_i(dir)->dir_idx_offset, - squashfs_i(dir)->dir_idx_cnt, name); + squashfs_i(dir)->dir_idx_cnt, + i_size_read(dir), name); while (length < i_size_read(dir)) { /* * Read directory header. */ + if (!squashfs_dir_space(dir, length, sizeof(dirh))) + goto read_failure; + err = squashfs_read_metadata(dir->i_sb, &dirh, &block, &offset, sizeof(dirh)); if (err < 0) @@ -177,23 +221,30 @@ static struct dentry *squashfs_lookup(struct inode *dir, struct dentry *dentry, /* * Read directory entry. */ + if (!squashfs_dir_space(dir, length, sizeof(*dire))) + goto read_failure; + err = squashfs_read_metadata(dir->i_sb, dire, &block, &offset, sizeof(*dire)); if (err < 0) goto read_failure; + length += sizeof(*dire); size = le16_to_cpu(dire->size) + 1; /* size should never be larger than SQUASHFS_NAME_LEN */ if (size > SQUASHFS_NAME_LEN) goto data_error; + if (!squashfs_dir_space(dir, length, size)) + goto read_failure; + err = squashfs_read_metadata(dir->i_sb, dire->name, &block, &offset, size); if (err < 0) goto read_failure; - length += sizeof(*dire) + size; + length += size; if (name[0] < dire->name[0]) goto exit_lookup; diff --git a/fs/squashfs/squashfs_helpers.h b/fs/squashfs/squashfs_helpers.h index c25f5918b8fa..07a9e1cdd4e4 100644 --- a/fs/squashfs/squashfs_helpers.h +++ b/fs/squashfs/squashfs_helpers.h @@ -353,4 +353,11 @@ static inline s64 squashfs_add_indexes(u64 block, s64 blks, struct squashfs_sb_i return block + blks; } + +static inline bool squashfs_dir_space(struct inode *inode, loff_t length, int size) +{ + loff_t space = i_size_read(inode) - length; + + return space >= size; +} #endif -- 2.47.3