symlink.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * linux/fs/ext4/symlink.c
  4. *
  5. * Only fast symlinks left here - the rest is done by generic code. AV, 1999
  6. *
  7. * Copyright (C) 1992, 1993, 1994, 1995
  8. * Remy Card (card@masi.ibp.fr)
  9. * Laboratoire MASI - Institut Blaise Pascal
  10. * Universite Pierre et Marie Curie (Paris VI)
  11. *
  12. * from
  13. *
  14. * linux/fs/minix/symlink.c
  15. *
  16. * Copyright (C) 1991, 1992 Linus Torvalds
  17. *
  18. * ext4 symlink handling code
  19. */
  20. #include <linux/fs.h>
  21. #include <linux/namei.h>
  22. #include "ext4.h"
  23. #include "xattr.h"
  24. static const char *ext4_encrypted_get_link(struct dentry *dentry,
  25. struct inode *inode,
  26. struct delayed_call *done)
  27. {
  28. struct buffer_head *bh = NULL;
  29. const void *caddr;
  30. unsigned int max_size;
  31. const char *paddr;
  32. if (!dentry)
  33. return ERR_PTR(-ECHILD);
  34. if (ext4_inode_is_fast_symlink(inode)) {
  35. caddr = EXT4_I(inode)->i_data;
  36. max_size = sizeof(EXT4_I(inode)->i_data);
  37. } else {
  38. bh = ext4_bread(NULL, inode, 0, 0);
  39. if (IS_ERR(bh))
  40. return ERR_CAST(bh);
  41. if (!bh) {
  42. EXT4_ERROR_INODE(inode, "bad symlink.");
  43. return ERR_PTR(-EFSCORRUPTED);
  44. }
  45. caddr = bh->b_data;
  46. max_size = inode->i_sb->s_blocksize;
  47. }
  48. paddr = fscrypt_get_symlink(inode, caddr, max_size, done);
  49. brelse(bh);
  50. return paddr;
  51. }
  52. static int ext4_encrypted_symlink_getattr(struct mnt_idmap *idmap,
  53. const struct path *path,
  54. struct kstat *stat, u32 request_mask,
  55. unsigned int query_flags)
  56. {
  57. ext4_getattr(idmap, path, stat, request_mask, query_flags);
  58. return fscrypt_symlink_getattr(path, stat);
  59. }
  60. static void ext4_free_link(void *bh)
  61. {
  62. brelse(bh);
  63. }
  64. static const char *ext4_get_link(struct dentry *dentry, struct inode *inode,
  65. struct delayed_call *callback)
  66. {
  67. struct buffer_head *bh;
  68. char *inline_link;
  69. /*
  70. * Create a new inlined symlink is not supported, just provide a
  71. * method to read the leftovers.
  72. */
  73. if (ext4_has_inline_data(inode)) {
  74. if (!dentry)
  75. return ERR_PTR(-ECHILD);
  76. inline_link = ext4_read_inline_link(inode);
  77. if (!IS_ERR(inline_link))
  78. set_delayed_call(callback, kfree_link, inline_link);
  79. return inline_link;
  80. }
  81. if (!dentry) {
  82. bh = ext4_getblk(NULL, inode, 0, EXT4_GET_BLOCKS_CACHED_NOWAIT);
  83. if (IS_ERR(bh) || !bh)
  84. return ERR_PTR(-ECHILD);
  85. if (!ext4_buffer_uptodate(bh)) {
  86. brelse(bh);
  87. return ERR_PTR(-ECHILD);
  88. }
  89. } else {
  90. bh = ext4_bread(NULL, inode, 0, 0);
  91. if (IS_ERR(bh))
  92. return ERR_CAST(bh);
  93. if (!bh) {
  94. EXT4_ERROR_INODE(inode, "bad symlink.");
  95. return ERR_PTR(-EFSCORRUPTED);
  96. }
  97. }
  98. set_delayed_call(callback, ext4_free_link, bh);
  99. nd_terminate_link(bh->b_data, inode->i_size,
  100. inode->i_sb->s_blocksize - 1);
  101. return bh->b_data;
  102. }
  103. const struct inode_operations ext4_encrypted_symlink_inode_operations = {
  104. .get_link = ext4_encrypted_get_link,
  105. .setattr = ext4_setattr,
  106. .getattr = ext4_encrypted_symlink_getattr,
  107. .listxattr = ext4_listxattr,
  108. };
  109. const struct inode_operations ext4_symlink_inode_operations = {
  110. .get_link = ext4_get_link,
  111. .setattr = ext4_setattr,
  112. .getattr = ext4_getattr,
  113. .listxattr = ext4_listxattr,
  114. };
  115. const struct inode_operations ext4_fast_symlink_inode_operations = {
  116. .get_link = simple_get_link,
  117. .setattr = ext4_setattr,
  118. .getattr = ext4_getattr,
  119. .listxattr = ext4_listxattr,
  120. };