[Devel] [PATCH RH9 6/6] ext4: Provide a balloon nipple for management
Kirill Tkhai
ktkhai at virtuozzo.com
Tue Oct 5 18:42:52 MSK 2021
From: Konstantin Khorenko <khorenko at virtuozzo.com>
When the fs is mounted with active balloon someone will have to
inflate/blow off one. To make it possible there will be a special
ioctl for obtaining the fd.
Not very elegant solution maybe, but it's OK for PVC containers.
+++
ext4: fix file allocation check in ext4_open_balloon
Function alloc_file() doesn't return NULL (unlike in 2.6.32-x).
It returns error pointer. File structure allocation may fail before
file->f_ep_links is initialized, which may lead to crash in
eventpoll_release_file().
https://jira.sw.ru/browse/PSBM-41222
mFixes: 9cea7449aa589f325fff378e7256a3c2fc8f048d
"ext4: Provide a balloon nipple for management"
Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>
(cherry picked from vz7 commit 100feb098ab22c6b8b25861c3b2dfaa9c5db0b03)
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
+++
ext4/balloon: Use proper O_ mode flags in balloon opening code
alloc_file() expects O_* mode flags, so provide them, not
internal FMODE_* ones.
mFixes: bee340a206d7 ("ext4: Provide a balloon nipple for management")
https://jira.sw.ru/browse/PSBM-129392
Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>
Reviewed-by: Kirill Tkhai <ktkhai at virtuozzo.com>
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
fs/ext4/ext4.h | 1 +
fs/ext4/ioctl.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/inode.c | 1 +
3 files changed, 61 insertions(+)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 9b655a94eb16..df46d5586ca1 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -720,6 +720,7 @@ enum {
#define EXT4_IOC_CLEAR_ES_CACHE _IO('f', 40)
#define EXT4_IOC_GETSTATE _IOW('f', 41, __u32)
#define EXT4_IOC_GET_ES_CACHE _IOWR('f', 42, struct fiemap)
+#define EXT4_IOC_OPEN_BALLOON _IO('f', 42)
#define EXT4_IOC_CHECKPOINT _IOW('f', 43, __u32)
#define EXT4_IOC_SHUTDOWN _IOR ('X', 125, __u32)
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index 6eed6170aded..6e2be4859571 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -850,6 +850,59 @@ static int ext4_ioctl_checkpoint(struct file *filp, unsigned long arg)
return err;
}
+static int ext4_open_balloon(struct super_block *sb, struct vfsmount *mnt)
+{
+ struct inode *balloon_ino;
+ int err, fd;
+ struct file *filp;
+ struct dentry *de;
+ struct path path;
+ fmode_t mode;
+
+ balloon_ino = EXT4_SB(sb)->s_balloon_ino;
+ err = -ENOENT;
+ if (balloon_ino == NULL)
+ goto err;
+
+ err = fd = get_unused_fd_flags(0);
+ if (err < 0)
+ goto err_fd;
+
+ __iget(balloon_ino);
+ de = d_obtain_alias(balloon_ino);
+ err = PTR_ERR(de);
+ if (IS_ERR(de))
+ goto err_de;
+
+ path.dentry = de;
+ path.mnt = mntget(mnt);
+ err = mnt_want_write(path.mnt);
+ if (err)
+ mode = O_RDONLY;
+ else
+ mode = O_RDWR;
+ filp = alloc_file(&path, mode, &ext4_file_operations);
+ if (filp->f_mode & FMODE_WRITE)
+ mnt_drop_write(path.mnt);
+ if (IS_ERR(filp)) {
+ err = PTR_ERR(filp);
+ goto err_filp;
+ }
+
+ filp->f_flags |= O_LARGEFILE;
+ fd_install(fd, filp);
+ return fd;
+
+err_filp:
+ path_put(&path);
+err_de:
+ put_unused_fd(fd);
+err_fd:
+ /* nothing */
+err:
+ return err;
+}
+
static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct inode *inode = file_inode(filp);
@@ -1264,6 +1317,12 @@ static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
case EXT4_IOC_CHECKPOINT:
return ext4_ioctl_checkpoint(filp, arg);
+ case EXT4_IOC_OPEN_BALLOON:
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+
+ return ext4_open_balloon(inode->i_sb, filp->f_path.mnt);
+
default:
return -ENOTTY;
}
diff --git a/fs/inode.c b/fs/inode.c
index c93500d84264..55498b31f088 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -414,6 +414,7 @@ void __iget(struct inode *inode)
{
atomic_inc(&inode->i_count);
}
+EXPORT_SYMBOL(__iget);
/*
* get additional reference to inode; caller must already hold one.
More information about the Devel
mailing list