18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * symlink.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (c) 1999 Al Smith 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Portions derived from work (c) 1995,1996 Christian Vogelgsang. 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/string.h> 118c2ecf20Sopenharmony_ci#include <linux/pagemap.h> 128c2ecf20Sopenharmony_ci#include <linux/buffer_head.h> 138c2ecf20Sopenharmony_ci#include "efs.h" 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_cistatic int efs_symlink_readpage(struct file *file, struct page *page) 168c2ecf20Sopenharmony_ci{ 178c2ecf20Sopenharmony_ci char *link = page_address(page); 188c2ecf20Sopenharmony_ci struct buffer_head * bh; 198c2ecf20Sopenharmony_ci struct inode * inode = page->mapping->host; 208c2ecf20Sopenharmony_ci efs_block_t size = inode->i_size; 218c2ecf20Sopenharmony_ci int err; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci err = -ENAMETOOLONG; 248c2ecf20Sopenharmony_ci if (size > 2 * EFS_BLOCKSIZE) 258c2ecf20Sopenharmony_ci goto fail; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci /* read first 512 bytes of link target */ 288c2ecf20Sopenharmony_ci err = -EIO; 298c2ecf20Sopenharmony_ci bh = sb_bread(inode->i_sb, efs_bmap(inode, 0)); 308c2ecf20Sopenharmony_ci if (!bh) 318c2ecf20Sopenharmony_ci goto fail; 328c2ecf20Sopenharmony_ci memcpy(link, bh->b_data, (size > EFS_BLOCKSIZE) ? EFS_BLOCKSIZE : size); 338c2ecf20Sopenharmony_ci brelse(bh); 348c2ecf20Sopenharmony_ci if (size > EFS_BLOCKSIZE) { 358c2ecf20Sopenharmony_ci bh = sb_bread(inode->i_sb, efs_bmap(inode, 1)); 368c2ecf20Sopenharmony_ci if (!bh) 378c2ecf20Sopenharmony_ci goto fail; 388c2ecf20Sopenharmony_ci memcpy(link + EFS_BLOCKSIZE, bh->b_data, size - EFS_BLOCKSIZE); 398c2ecf20Sopenharmony_ci brelse(bh); 408c2ecf20Sopenharmony_ci } 418c2ecf20Sopenharmony_ci link[size] = '\0'; 428c2ecf20Sopenharmony_ci SetPageUptodate(page); 438c2ecf20Sopenharmony_ci unlock_page(page); 448c2ecf20Sopenharmony_ci return 0; 458c2ecf20Sopenharmony_cifail: 468c2ecf20Sopenharmony_ci SetPageError(page); 478c2ecf20Sopenharmony_ci unlock_page(page); 488c2ecf20Sopenharmony_ci return err; 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ciconst struct address_space_operations efs_symlink_aops = { 528c2ecf20Sopenharmony_ci .readpage = efs_symlink_readpage 538c2ecf20Sopenharmony_ci}; 54