#define F2FS_IOC_PRECACHE_EXTENTS      _IO(F2FS_IOCTL_MAGIC, 15)
 #define F2FS_IOC_RESIZE_FS             _IOW(F2FS_IOCTL_MAGIC, 16, __u64)
 
+#define F2FS_IOC_GET_VOLUME_NAME       FS_IOC_GETFSLABEL
+#define F2FS_IOC_SET_VOLUME_NAME       FS_IOC_SETFSLABEL
+
 #define F2FS_IOC_SET_ENCRYPTION_POLICY FS_IOC_SET_ENCRYPTION_POLICY
 #define F2FS_IOC_GET_ENCRYPTION_POLICY FS_IOC_GET_ENCRYPTION_POLICY
 #define F2FS_IOC_GET_ENCRYPTION_PWSALT FS_IOC_GET_ENCRYPTION_PWSALT
 
 #include <linux/uio.h>
 #include <linux/uuid.h>
 #include <linux/file.h>
+#include <linux/nls.h>
 
 #include "f2fs.h"
 #include "node.h"
        return ret;
 }
 
+static int f2fs_get_volume_name(struct file *filp, unsigned long arg)
+{
+       struct inode *inode = file_inode(filp);
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+       char *vbuf;
+       int count;
+       int err = 0;
+
+       vbuf = f2fs_kzalloc(sbi, MAX_VOLUME_NAME, GFP_KERNEL);
+       if (!vbuf)
+               return -ENOMEM;
+
+       down_read(&sbi->sb_lock);
+       count = utf16s_to_utf8s(sbi->raw_super->volume_name,
+                       ARRAY_SIZE(sbi->raw_super->volume_name),
+                       UTF16_LITTLE_ENDIAN, vbuf, MAX_VOLUME_NAME);
+       up_read(&sbi->sb_lock);
+
+       if (copy_to_user((char __user *)arg, vbuf,
+                               min(FSLABEL_MAX, count)))
+               err = -EFAULT;
+
+       kvfree(vbuf);
+       return err;
+}
+
+static int f2fs_set_volume_name(struct file *filp, unsigned long arg)
+{
+       struct inode *inode = file_inode(filp);
+       struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
+       char *vbuf;
+       int err = 0;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EPERM;
+
+       vbuf = strndup_user((const char __user *)arg, FSLABEL_MAX);
+       if (IS_ERR(vbuf))
+               return PTR_ERR(vbuf);
+
+       err = mnt_want_write_file(filp);
+       if (err)
+               goto out;
+
+       down_write(&sbi->sb_lock);
+
+       memset(sbi->raw_super->volume_name, 0,
+                       sizeof(sbi->raw_super->volume_name));
+       utf8s_to_utf16s(vbuf, strlen(vbuf), UTF16_LITTLE_ENDIAN,
+                       sbi->raw_super->volume_name,
+                       ARRAY_SIZE(sbi->raw_super->volume_name));
+
+       err = f2fs_commit_super(sbi, false);
+
+       up_write(&sbi->sb_lock);
+
+       mnt_drop_write_file(filp);
+out:
+       kfree(vbuf);
+       return err;
+}
+
 long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
 {
        int ret;
                return f2fs_ioc_precache_extents(filp, arg);
        case F2FS_IOC_RESIZE_FS:
                return f2fs_ioc_resize_fs(filp, arg);
+       case F2FS_IOC_GET_VOLUME_NAME:
+               return f2fs_get_volume_name(filp, arg);
+       case F2FS_IOC_SET_VOLUME_NAME:
+               return f2fs_set_volume_name(filp, arg);
        default:
                return -ENOTTY;
        }
        case F2FS_IOC_SET_PIN_FILE:
        case F2FS_IOC_PRECACHE_EXTENTS:
        case F2FS_IOC_RESIZE_FS:
+       case F2FS_IOC_GET_VOLUME_NAME:
+       case F2FS_IOC_SET_VOLUME_NAME:
                break;
        default:
                return -ENOIOCTLCMD;