1 // SPDX-License-Identifier: GPL-2.0
3 * linux/fs/ext4/symlink.c
5 * Only fast symlinks left here - the rest is done by generic code. AV, 1999
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)
14 * linux/fs/minix/symlink.c
16 * Copyright (C) 1991, 1992 Linus Torvalds
18 * ext4 symlink handling code
22 #include <linux/namei.h>
26 static const char *ext4_encrypted_get_link(struct dentry
*dentry
,
28 struct delayed_call
*done
)
30 struct buffer_head
*bh
= NULL
;
32 unsigned int max_size
;
36 return ERR_PTR(-ECHILD
);
38 if (ext4_inode_is_fast_symlink(inode
)) {
39 caddr
= EXT4_I(inode
)->i_data
;
40 max_size
= sizeof(EXT4_I(inode
)->i_data
);
42 bh
= ext4_bread(NULL
, inode
, 0, 0);
46 EXT4_ERROR_INODE(inode
, "bad symlink.");
47 return ERR_PTR(-EFSCORRUPTED
);
50 max_size
= inode
->i_sb
->s_blocksize
;
53 paddr
= fscrypt_get_symlink(inode
, caddr
, max_size
, done
);
58 static int ext4_encrypted_symlink_getattr(struct mnt_idmap
*idmap
,
59 const struct path
*path
,
60 struct kstat
*stat
, u32 request_mask
,
61 unsigned int query_flags
)
63 ext4_getattr(idmap
, path
, stat
, request_mask
, query_flags
);
65 return fscrypt_symlink_getattr(path
, stat
);
68 static void ext4_free_link(void *bh
)
73 static const char *ext4_get_link(struct dentry
*dentry
, struct inode
*inode
,
74 struct delayed_call
*callback
)
76 struct buffer_head
*bh
;
80 * Create a new inlined symlink is not supported, just provide a
81 * method to read the leftovers.
83 if (ext4_has_inline_data(inode
)) {
85 return ERR_PTR(-ECHILD
);
87 inline_link
= ext4_read_inline_link(inode
);
88 if (!IS_ERR(inline_link
))
89 set_delayed_call(callback
, kfree_link
, inline_link
);
94 bh
= ext4_getblk(NULL
, inode
, 0, EXT4_GET_BLOCKS_CACHED_NOWAIT
);
95 if (IS_ERR(bh
) || !bh
)
96 return ERR_PTR(-ECHILD
);
97 if (!ext4_buffer_uptodate(bh
)) {
99 return ERR_PTR(-ECHILD
);
102 bh
= ext4_bread(NULL
, inode
, 0, 0);
106 EXT4_ERROR_INODE(inode
, "bad symlink.");
107 return ERR_PTR(-EFSCORRUPTED
);
111 set_delayed_call(callback
, ext4_free_link
, bh
);
112 nd_terminate_link(bh
->b_data
, inode
->i_size
,
113 inode
->i_sb
->s_blocksize
- 1);
117 const struct inode_operations ext4_encrypted_symlink_inode_operations
= {
118 .get_link
= ext4_encrypted_get_link
,
119 .setattr
= ext4_setattr
,
120 .getattr
= ext4_encrypted_symlink_getattr
,
121 .listxattr
= ext4_listxattr
,
124 const struct inode_operations ext4_symlink_inode_operations
= {
125 .get_link
= ext4_get_link
,
126 .setattr
= ext4_setattr
,
127 .getattr
= ext4_getattr
,
128 .listxattr
= ext4_listxattr
,
131 const struct inode_operations ext4_fast_symlink_inode_operations
= {
132 .get_link
= simple_get_link
,
133 .setattr
= ext4_setattr
,
134 .getattr
= ext4_getattr
,
135 .listxattr
= ext4_listxattr
,