0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #include <linux/fs.h>
0021 #include <linux/vfs.h>
0022 #include <linux/kernel.h>
0023 #include <linux/string.h>
0024 #include <linux/pagemap.h>
0025 #include <linux/xattr.h>
0026
0027 #include "squashfs_fs.h"
0028 #include "squashfs_fs_sb.h"
0029 #include "squashfs_fs_i.h"
0030 #include "squashfs.h"
0031 #include "xattr.h"
0032
0033 static int squashfs_symlink_read_folio(struct file *file, struct folio *folio)
0034 {
0035 struct page *page = &folio->page;
0036 struct inode *inode = page->mapping->host;
0037 struct super_block *sb = inode->i_sb;
0038 struct squashfs_sb_info *msblk = sb->s_fs_info;
0039 int index = page->index << PAGE_SHIFT;
0040 u64 block = squashfs_i(inode)->start;
0041 int offset = squashfs_i(inode)->offset;
0042 int length = min_t(int, i_size_read(inode) - index, PAGE_SIZE);
0043 int bytes, copied;
0044 void *pageaddr;
0045 struct squashfs_cache_entry *entry;
0046
0047 TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
0048 "%llx, offset %x\n", page->index, block, offset);
0049
0050
0051
0052
0053 if (index) {
0054 bytes = squashfs_read_metadata(sb, NULL, &block, &offset,
0055 index);
0056 if (bytes < 0) {
0057 ERROR("Unable to read symlink [%llx:%x]\n",
0058 squashfs_i(inode)->start,
0059 squashfs_i(inode)->offset);
0060 goto error_out;
0061 }
0062 }
0063
0064
0065
0066
0067
0068
0069
0070
0071 for (bytes = 0; bytes < length; offset = 0, bytes += copied) {
0072 entry = squashfs_cache_get(sb, msblk->block_cache, block, 0);
0073 if (entry->error) {
0074 ERROR("Unable to read symlink [%llx:%x]\n",
0075 squashfs_i(inode)->start,
0076 squashfs_i(inode)->offset);
0077 squashfs_cache_put(entry);
0078 goto error_out;
0079 }
0080
0081 pageaddr = kmap_atomic(page);
0082 copied = squashfs_copy_data(pageaddr + bytes, entry, offset,
0083 length - bytes);
0084 if (copied == length - bytes)
0085 memset(pageaddr + length, 0, PAGE_SIZE - length);
0086 else
0087 block = entry->next_index;
0088 kunmap_atomic(pageaddr);
0089 squashfs_cache_put(entry);
0090 }
0091
0092 flush_dcache_page(page);
0093 SetPageUptodate(page);
0094 unlock_page(page);
0095 return 0;
0096
0097 error_out:
0098 SetPageError(page);
0099 unlock_page(page);
0100 return 0;
0101 }
0102
0103
0104 const struct address_space_operations squashfs_symlink_aops = {
0105 .read_folio = squashfs_symlink_read_folio
0106 };
0107
0108 const struct inode_operations squashfs_symlink_inode_ops = {
0109 .get_link = page_get_link,
0110 .listxattr = squashfs_listxattr
0111 };
0112