[Devel] [PATCH vz9 03/10] ext4: Don't show the active balloon to user

Konstantin Khorenko khorenko at virtuozzo.com
Thu Nov 28 19:51:47 MSK 2024


From: "Maxim V. Patlasov" <mpatlasov at parallels.com>

This is a port of
e123b6d ext4: Don't show the active balloon to user

Fix the readdir and lookup. The former one pretends the inode doesn't
exists, the latter one denies an access to on. Reporting negative dentry
in lookup is pointless, as in that case smth will have to be don the
ext4_create callback :\

[VvS RH79 rebase vz7.170.x]: minor context changes

(cherry picked from vz7 commit c231c40a93927f3080067e5d880ef11841de278c)
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
Feature: fs/ext4: fast online shrink support
---
 fs/ext4/dir.c   | 15 ++++++++++++++-
 fs/ext4/namei.c |  9 +++++++++
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 3985f8c33f95..36be6cad2ee3 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -123,6 +123,14 @@ int __ext4_check_dir_entry(const char *function, unsigned int line,
 	return 1;
 }
 
+static inline int ext4_balloon(struct super_block *sb, unsigned ino)
+{
+	struct ext4_sb_info *sbi;
+
+	sbi = EXT4_SB(sb);
+	return sbi->s_balloon_ino && (sbi->s_balloon_ino->i_ino == ino);
+}
+
 static int ext4_readdir(struct file *file, struct dir_context *ctx)
 {
 	unsigned int offset;
@@ -267,7 +275,8 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
 			}
 			offset += ext4_rec_len_from_disk(de->rec_len,
 					sb->s_blocksize);
-			if (le32_to_cpu(de->inode)) {
+			if (le32_to_cpu(de->inode) &&
+			    !ext4_balloon(sb, le32_to_cpu(de->inode))) {
 				if (!IS_ENCRYPTED(inode)) {
 					if (!dir_emit(ctx, de->name,
 					    de->name_len,
@@ -533,6 +542,9 @@ static int call_filldir(struct file *file, struct dir_context *ctx,
 	}
 	ctx->pos = hash2pos(file, fname->hash, fname->minor_hash);
 	while (fname) {
+		if (ext4_balloon(sb, fname->inode))
+			goto skip;
+
 		if (!dir_emit(ctx, fname->name,
 				fname->name_len,
 				fname->inode,
@@ -540,6 +552,7 @@ static int call_filldir(struct file *file, struct dir_context *ctx,
 			info->extra_fname = fname;
 			return 1;
 		}
+skip:
 		fname = fname->next;
 	}
 	return 0;
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index 005896d25aac..78d8c3e6e6aa 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -1869,6 +1869,11 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, unsi
 			iput(inode);
 			return ERR_PTR(-EPERM);
 		}
+		if (!IS_ERR(inode) &&
+		    inode == EXT4_SB(inode->i_sb)->s_balloon_ino) {
+			iput(inode);
+			return ERR_PTR(-EPERM);
+		}
 	}
 
 #ifdef CONFIG_UNICODE
@@ -3320,6 +3325,10 @@ static int ext4_unlink(struct inode *dir, struct dentry *dentry)
 	retval = dquot_initialize(d_inode(dentry));
 	if (retval)
 		goto out_trace;
+        if (d_inode(dentry) == EXT4_SB(dir->i_sb)->s_balloon_ino) {
+		retval = -EPERM;
+                goto out_trace;
+	}
 
 	retval = __ext4_unlink(dir, &dentry->d_name, d_inode(dentry), dentry);
 #ifdef CONFIG_UNICODE
-- 
2.43.5



More information about the Devel mailing list