11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * symlink.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (c) 1999 Al Smith 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Portions derived from work (c) 1995,1996 Christian Vogelgsang. 71da177e4SLinus Torvalds */ 81da177e4SLinus Torvalds 91da177e4SLinus Torvalds #include <linux/string.h> 101da177e4SLinus Torvalds #include <linux/pagemap.h> 111da177e4SLinus Torvalds #include <linux/buffer_head.h> 1245254b4fSChristoph Hellwig #include "efs.h" 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds static int efs_symlink_readpage(struct file *file, struct page *page) 151da177e4SLinus Torvalds { 161da177e4SLinus Torvalds char *link = kmap(page); 171da177e4SLinus Torvalds struct buffer_head * bh; 181da177e4SLinus Torvalds struct inode * inode = page->mapping->host; 191da177e4SLinus Torvalds efs_block_t size = inode->i_size; 201da177e4SLinus Torvalds int err; 211da177e4SLinus Torvalds 221da177e4SLinus Torvalds err = -ENAMETOOLONG; 231da177e4SLinus Torvalds if (size > 2 * EFS_BLOCKSIZE) 24*e7ec952fSAl Viro goto fail; 251da177e4SLinus Torvalds 261da177e4SLinus Torvalds /* read first 512 bytes of link target */ 271da177e4SLinus Torvalds err = -EIO; 281da177e4SLinus Torvalds bh = sb_bread(inode->i_sb, efs_bmap(inode, 0)); 291da177e4SLinus Torvalds if (!bh) 301da177e4SLinus Torvalds goto fail; 311da177e4SLinus Torvalds memcpy(link, bh->b_data, (size > EFS_BLOCKSIZE) ? EFS_BLOCKSIZE : size); 321da177e4SLinus Torvalds brelse(bh); 331da177e4SLinus Torvalds if (size > EFS_BLOCKSIZE) { 341da177e4SLinus Torvalds bh = sb_bread(inode->i_sb, efs_bmap(inode, 1)); 351da177e4SLinus Torvalds if (!bh) 361da177e4SLinus Torvalds goto fail; 371da177e4SLinus Torvalds memcpy(link + EFS_BLOCKSIZE, bh->b_data, size - EFS_BLOCKSIZE); 381da177e4SLinus Torvalds brelse(bh); 391da177e4SLinus Torvalds } 401da177e4SLinus Torvalds link[size] = '\0'; 411da177e4SLinus Torvalds SetPageUptodate(page); 421da177e4SLinus Torvalds kunmap(page); 431da177e4SLinus Torvalds unlock_page(page); 441da177e4SLinus Torvalds return 0; 451da177e4SLinus Torvalds fail: 461da177e4SLinus Torvalds SetPageError(page); 471da177e4SLinus Torvalds kunmap(page); 481da177e4SLinus Torvalds unlock_page(page); 491da177e4SLinus Torvalds return err; 501da177e4SLinus Torvalds } 511da177e4SLinus Torvalds 52f5e54d6eSChristoph Hellwig const struct address_space_operations efs_symlink_aops = { 531da177e4SLinus Torvalds .readpage = efs_symlink_readpage 541da177e4SLinus Torvalds }; 55