0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021 #include <linux/fs.h>
0022 #include <linux/namei.h>
0023 #include "ext4.h"
0024 #include "xattr.h"
0025
0026 static const char *ext4_encrypted_get_link(struct dentry *dentry,
0027 struct inode *inode,
0028 struct delayed_call *done)
0029 {
0030 struct buffer_head *bh = NULL;
0031 const void *caddr;
0032 unsigned int max_size;
0033 const char *paddr;
0034
0035 if (!dentry)
0036 return ERR_PTR(-ECHILD);
0037
0038 if (ext4_inode_is_fast_symlink(inode)) {
0039 caddr = EXT4_I(inode)->i_data;
0040 max_size = sizeof(EXT4_I(inode)->i_data);
0041 } else {
0042 bh = ext4_bread(NULL, inode, 0, 0);
0043 if (IS_ERR(bh))
0044 return ERR_CAST(bh);
0045 if (!bh) {
0046 EXT4_ERROR_INODE(inode, "bad symlink.");
0047 return ERR_PTR(-EFSCORRUPTED);
0048 }
0049 caddr = bh->b_data;
0050 max_size = inode->i_sb->s_blocksize;
0051 }
0052
0053 paddr = fscrypt_get_symlink(inode, caddr, max_size, done);
0054 brelse(bh);
0055 return paddr;
0056 }
0057
0058 static int ext4_encrypted_symlink_getattr(struct user_namespace *mnt_userns,
0059 const struct path *path,
0060 struct kstat *stat, u32 request_mask,
0061 unsigned int query_flags)
0062 {
0063 ext4_getattr(mnt_userns, path, stat, request_mask, query_flags);
0064
0065 return fscrypt_symlink_getattr(path, stat);
0066 }
0067
0068 static void ext4_free_link(void *bh)
0069 {
0070 brelse(bh);
0071 }
0072
0073 static const char *ext4_get_link(struct dentry *dentry, struct inode *inode,
0074 struct delayed_call *callback)
0075 {
0076 struct buffer_head *bh;
0077 char *inline_link;
0078
0079
0080
0081
0082
0083 if (ext4_has_inline_data(inode)) {
0084 if (!dentry)
0085 return ERR_PTR(-ECHILD);
0086
0087 inline_link = ext4_read_inline_link(inode);
0088 if (!IS_ERR(inline_link))
0089 set_delayed_call(callback, kfree_link, inline_link);
0090 return inline_link;
0091 }
0092
0093 if (!dentry) {
0094 bh = ext4_getblk(NULL, inode, 0, EXT4_GET_BLOCKS_CACHED_NOWAIT);
0095 if (IS_ERR(bh))
0096 return ERR_CAST(bh);
0097 if (!bh || !ext4_buffer_uptodate(bh))
0098 return ERR_PTR(-ECHILD);
0099 } else {
0100 bh = ext4_bread(NULL, inode, 0, 0);
0101 if (IS_ERR(bh))
0102 return ERR_CAST(bh);
0103 if (!bh) {
0104 EXT4_ERROR_INODE(inode, "bad symlink.");
0105 return ERR_PTR(-EFSCORRUPTED);
0106 }
0107 }
0108
0109 set_delayed_call(callback, ext4_free_link, bh);
0110 nd_terminate_link(bh->b_data, inode->i_size,
0111 inode->i_sb->s_blocksize - 1);
0112 return bh->b_data;
0113 }
0114
0115 const struct inode_operations ext4_encrypted_symlink_inode_operations = {
0116 .get_link = ext4_encrypted_get_link,
0117 .setattr = ext4_setattr,
0118 .getattr = ext4_encrypted_symlink_getattr,
0119 .listxattr = ext4_listxattr,
0120 };
0121
0122 const struct inode_operations ext4_symlink_inode_operations = {
0123 .get_link = ext4_get_link,
0124 .setattr = ext4_setattr,
0125 .getattr = ext4_getattr,
0126 .listxattr = ext4_listxattr,
0127 };
0128
0129 const struct inode_operations ext4_fast_symlink_inode_operations = {
0130 .get_link = simple_get_link,
0131 .setattr = ext4_setattr,
0132 .getattr = ext4_getattr,
0133 .listxattr = ext4_listxattr,
0134 };