Merge tag 'f2fs-for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 21 Sep 2019 21:26:33 +0000 (14:26 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 21 Sep 2019 21:26:33 +0000 (14:26 -0700)
Pull f2fs updates from Jaegeuk Kim:
 "In this round, we introduced casefolding support in f2fs, and fixed
  various bugs in individual features such as IO alignment,
  checkpoint=disable, quota, and swapfile.

  Enhancement:
   - support casefolding w/ enhancement in ext4
   - support fiemap for directory
   - support FS_IO_GET|SET_FSLABEL

  Bug fix:
   - fix IO stuck during checkpoint=disable
   - avoid infinite GC loop
   - fix panic/overflow related to IO alignment feature
   - fix livelock in swap file
   - fix discard command leak
   - disallow dio for atomic_write"

* tag 'f2fs-for-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/jaegeuk/f2fs: (51 commits)
  f2fs: add a condition to detect overflow in f2fs_ioc_gc_range()
  f2fs: fix to add missing F2FS_IO_ALIGNED() condition
  f2fs: fix to fallback to buffered IO in IO aligned mode
  f2fs: fix to handle error path correctly in f2fs_map_blocks
  f2fs: fix extent corrupotion during directIO in LFS mode
  f2fs: check all the data segments against all node ones
  f2fs: Add a small clarification to CONFIG_FS_F2FS_FS_SECURITY
  f2fs: fix inode rwsem regression
  f2fs: fix to avoid accessing uninitialized field of inode page in is_alive()
  f2fs: avoid infinite GC loop due to stale atomic files
  f2fs: Fix indefinite loop in f2fs_gc()
  f2fs: convert inline_data in prior to i_size_write
  f2fs: fix error path of f2fs_convert_inline_page()
  f2fs: add missing documents of reserve_root/resuid/resgid
  f2fs: fix flushing node pages when checkpoint is disabled
  f2fs: enhance f2fs_is_checkpoint_ready()'s readability
  f2fs: clean up __bio_alloc()'s parameter
  f2fs: fix wrong error injection path in inc_valid_block_count()
  f2fs: fix to writeout dirty inode during node flush
  f2fs: optimize case-insensitive lookups
  ...

1  2 
fs/f2fs/data.c
fs/f2fs/f2fs.h
fs/f2fs/file.c
fs/f2fs/inode.c
fs/f2fs/super.c
fs/f2fs/sysfs.c
include/uapi/linux/fs.h

diff --cc fs/f2fs/data.c
Simple merge
diff --cc fs/f2fs/f2fs.h
index 7c5f121edac531428c16b5a31afda9c9ded89eba,11c5a6d9f849529f85389e3471030067c654deea..4024790028aab1ecdc1d984b9bb724da31de7125
@@@ -152,8 -151,9 +152,9 @@@ struct f2fs_mount_info 
  #define F2FS_FEATURE_QUOTA_INO                0x0080
  #define F2FS_FEATURE_INODE_CRTIME     0x0100
  #define F2FS_FEATURE_LOST_FOUND               0x0200
 -#define F2FS_FEATURE_VERITY           0x0400  /* reserved */
 +#define F2FS_FEATURE_VERITY           0x0400
  #define F2FS_FEATURE_SB_CHKSUM                0x0800
+ #define F2FS_FEATURE_CASEFOLD         0x1000
  
  #define __F2FS_HAS_FEATURE(raw_super, mask)                           \
        ((raw_super->feature & cpu_to_le32(mask)) != 0)
@@@ -3574,8 -3584,8 +3597,9 @@@ F2FS_FEATURE_FUNCS(flexible_inline_xatt
  F2FS_FEATURE_FUNCS(quota_ino, QUOTA_INO);
  F2FS_FEATURE_FUNCS(inode_crtime, INODE_CRTIME);
  F2FS_FEATURE_FUNCS(lost_found, LOST_FOUND);
 +F2FS_FEATURE_FUNCS(verity, VERITY);
  F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM);
+ F2FS_FEATURE_FUNCS(casefold, CASEFOLD);
  
  #ifdef CONFIG_BLK_DEV_ZONED
  static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
diff --cc fs/f2fs/file.c
index 56efde9d36596bd3c9e5bdb328abe6a47df61180,e4b78fb3fc79be7de9b72b960203ac24a6228bad..29bc0a542759a279f994862fe6eb3c8f97eac39d
@@@ -1717,7 -1722,7 +1733,8 @@@ static const struct 
                FS_ENCRYPT_FL |         \
                FS_INLINE_DATA_FL |     \
                FS_NOCOW_FL |           \
-               FS_VERITY_FL)
++              FS_VERITY_FL |          \
+               FS_CASEFOLD_FL)
  
  #define F2FS_SETTABLE_FS_FL (         \
                FS_SYNC_FL |            \
@@@ -3117,30 -3088,68 +3145,92 @@@ static int f2fs_ioc_resize_fs(struct fi
        return ret;
  }
  
 +static int f2fs_ioc_enable_verity(struct file *filp, unsigned long arg)
 +{
 +      struct inode *inode = file_inode(filp);
 +
 +      f2fs_update_time(F2FS_I_SB(inode), REQ_TIME);
 +
 +      if (!f2fs_sb_has_verity(F2FS_I_SB(inode))) {
 +              f2fs_warn(F2FS_I_SB(inode),
 +                        "Can't enable fs-verity on inode %lu: the verity feature is not enabled on this filesystem.\n",
 +                        inode->i_ino);
 +              return -EOPNOTSUPP;
 +      }
 +
 +      return fsverity_ioctl_enable(filp, (const void __user *)arg);
 +}
 +
 +static int f2fs_ioc_measure_verity(struct file *filp, unsigned long arg)
 +{
 +      if (!f2fs_sb_has_verity(F2FS_I_SB(file_inode(filp))))
 +              return -EOPNOTSUPP;
 +
 +      return fsverity_ioctl_measure(filp, (void __user *)arg);
 +}
 +
+ 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)
  {
        if (unlikely(f2fs_cp_error(F2FS_I_SB(file_inode(filp)))))
                return f2fs_ioc_precache_extents(filp, arg);
        case F2FS_IOC_RESIZE_FS:
                return f2fs_ioc_resize_fs(filp, arg);
 +      case FS_IOC_ENABLE_VERITY:
 +              return f2fs_ioc_enable_verity(filp, arg);
 +      case FS_IOC_MEASURE_VERITY:
 +              return f2fs_ioc_measure_verity(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;
        }
@@@ -3332,8 -3324,8 +3424,10 @@@ long f2fs_compat_ioctl(struct file *fil
        case F2FS_IOC_SET_PIN_FILE:
        case F2FS_IOC_PRECACHE_EXTENTS:
        case F2FS_IOC_RESIZE_FS:
 +      case FS_IOC_ENABLE_VERITY:
 +      case FS_IOC_MEASURE_VERITY:
+       case F2FS_IOC_GET_VOLUME_NAME:
+       case F2FS_IOC_SET_VOLUME_NAME:
                break;
        default:
                return -ENOIOCTLCMD;
diff --cc fs/f2fs/inode.c
index 06da75d418e0e34aaf058a81e56f6fa40f01d023,87214414936b4c5305d92299ab0e2b24dcc7df28..db4fec30c30dfc4a2163246f3baa2007f49a2c2f
@@@ -46,11 -46,11 +46,13 @@@ void f2fs_set_inode_flags(struct inode 
                new_fl |= S_DIRSYNC;
        if (file_is_encrypt(inode))
                new_fl |= S_ENCRYPTED;
 +      if (file_is_verity(inode))
 +              new_fl |= S_VERITY;
+       if (flags & F2FS_CASEFOLD_FL)
+               new_fl |= S_CASEFOLD;
        inode_set_flags(inode, new_fl,
                        S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|
-                       S_ENCRYPTED|S_VERITY);
 -                      S_ENCRYPTED|S_CASEFOLD);
++                      S_ENCRYPTED|S_VERITY|S_CASEFOLD);
  }
  
  static void __get_inode_rdev(struct inode *inode, struct f2fs_inode *ri)
diff --cc fs/f2fs/super.c
Simple merge
diff --cc fs/f2fs/sysfs.c
index 0cd64f99406859e49fc6bd81c56433ca37f2c182,f9fcca695db9f1cbc445a0467891684e3d4bf2da..b558b64a4c9ca33eee88896bc53ab4f07036a22f
@@@ -367,8 -381,8 +384,9 @@@ enum feat_id 
        FEAT_QUOTA_INO,
        FEAT_INODE_CRTIME,
        FEAT_LOST_FOUND,
 +      FEAT_VERITY,
        FEAT_SB_CHECKSUM,
+       FEAT_CASEFOLD,
  };
  
  static ssize_t f2fs_feature_show(struct f2fs_attr *a,
        case FEAT_QUOTA_INO:
        case FEAT_INODE_CRTIME:
        case FEAT_LOST_FOUND:
 +      case FEAT_VERITY:
        case FEAT_SB_CHECKSUM:
+       case FEAT_CASEFOLD:
                return snprintf(buf, PAGE_SIZE, "supported\n");
        }
        return 0;
@@@ -475,10 -490,8 +495,11 @@@ F2FS_FEATURE_RO_ATTR(flexible_inline_xa
  F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO);
  F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME);
  F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND);
 +#ifdef CONFIG_FS_VERITY
 +F2FS_FEATURE_RO_ATTR(verity, FEAT_VERITY);
 +#endif
  F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM);
+ F2FS_FEATURE_RO_ATTR(casefold, FEAT_CASEFOLD);
  
  #define ATTR_LIST(name) (&f2fs_attr_##name.attr)
  static struct attribute *f2fs_attrs[] = {
@@@ -542,10 -556,8 +564,11 @@@ static struct attribute *f2fs_feat_attr
        ATTR_LIST(quota_ino),
        ATTR_LIST(inode_crtime),
        ATTR_LIST(lost_found),
 +#ifdef CONFIG_FS_VERITY
 +      ATTR_LIST(verity),
 +#endif
        ATTR_LIST(sb_checksum),
+       ATTR_LIST(casefold),
        NULL,
  };
  ATTRIBUTE_GROUPS(f2fs_feat);
Simple merge