140-jffs2-use-.rename2-and-add-RENAME_WHITEOUT-support.patch 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. From: Felix Fietkau <[email protected]>
  2. Subject: jffs2: use .rename2 and add RENAME_WHITEOUT support
  3. It is required for renames on overlayfs
  4. Signed-off-by: Felix Fietkau <[email protected]>
  5. ---
  6. --- a/fs/jffs2/dir.c
  7. +++ b/fs/jffs2/dir.c
  8. @@ -617,8 +617,8 @@ static int jffs2_rmdir (struct inode *di
  9. return ret;
  10. }
  11. -static int jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i,
  12. - struct dentry *dentry, umode_t mode, dev_t rdev)
  13. +static int __jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i,
  14. + struct dentry *dentry, umode_t mode, dev_t rdev, bool whiteout)
  15. {
  16. struct jffs2_inode_info *f, *dir_f;
  17. struct jffs2_sb_info *c;
  18. @@ -758,7 +758,11 @@ static int jffs2_mknod (struct mnt_idmap
  19. mutex_unlock(&dir_f->sem);
  20. jffs2_complete_reservation(c);
  21. - d_instantiate_new(dentry, inode);
  22. + if (!whiteout)
  23. + d_instantiate_new(dentry, inode);
  24. + else
  25. + unlock_new_inode(inode);
  26. +
  27. return 0;
  28. fail:
  29. @@ -766,6 +770,19 @@ static int jffs2_mknod (struct mnt_idmap
  30. return ret;
  31. }
  32. +static int jffs2_mknod (struct mnt_idmap *idmap, struct inode *dir_i,
  33. + struct dentry *dentry, umode_t mode, dev_t rdev)
  34. +{
  35. + return __jffs2_mknod(idmap, dir_i, dentry, mode, rdev, false);
  36. +}
  37. +
  38. +static int jffs2_whiteout (struct mnt_idmap *idmap, struct inode *old_dir,
  39. + struct dentry *old_dentry)
  40. +{
  41. + return __jffs2_mknod(idmap, old_dir, old_dentry, S_IFCHR | WHITEOUT_MODE,
  42. + WHITEOUT_DEV, true);
  43. +}
  44. +
  45. static int jffs2_rename (struct mnt_idmap *idmap,
  46. struct inode *old_dir_i, struct dentry *old_dentry,
  47. struct inode *new_dir_i, struct dentry *new_dentry,
  48. @@ -777,7 +794,7 @@ static int jffs2_rename (struct mnt_idma
  49. uint8_t type;
  50. uint32_t now;
  51. - if (flags & ~RENAME_NOREPLACE)
  52. + if (flags & ~(RENAME_NOREPLACE|RENAME_WHITEOUT))
  53. return -EINVAL;
  54. /* The VFS will check for us and prevent trying to rename a
  55. @@ -843,9 +860,14 @@ static int jffs2_rename (struct mnt_idma
  56. if (d_is_dir(old_dentry) && !victim_f)
  57. inc_nlink(new_dir_i);
  58. - /* Unlink the original */
  59. - ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
  60. - old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
  61. + if (flags & RENAME_WHITEOUT)
  62. + /* Replace with whiteout */
  63. + ret = jffs2_whiteout(idmap, old_dir_i, old_dentry);
  64. + else
  65. + /* Unlink the original */
  66. + ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
  67. + old_dentry->d_name.name,
  68. + old_dentry->d_name.len, NULL, now);
  69. /* We don't touch inode->i_nlink */