1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * Copyright (c) 2000-2001 Christoph Hellwig. 3*1da177e4SLinus Torvalds * All rights reserved. 4*1da177e4SLinus Torvalds * 5*1da177e4SLinus Torvalds * Redistribution and use in source and binary forms, with or without 6*1da177e4SLinus Torvalds * modification, are permitted provided that the following conditions 7*1da177e4SLinus Torvalds * are met: 8*1da177e4SLinus Torvalds * 1. Redistributions of source code must retain the above copyright 9*1da177e4SLinus Torvalds * notice, this list of conditions, and the following disclaimer, 10*1da177e4SLinus Torvalds * without modification. 11*1da177e4SLinus Torvalds * 2. The name of the author may not be used to endorse or promote products 12*1da177e4SLinus Torvalds * derived from this software without specific prior written permission. 13*1da177e4SLinus Torvalds * 14*1da177e4SLinus Torvalds * Alternatively, this software may be distributed under the terms of the 15*1da177e4SLinus Torvalds * GNU General Public License ("GPL"). 16*1da177e4SLinus Torvalds * 17*1da177e4SLinus Torvalds * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18*1da177e4SLinus Torvalds * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*1da177e4SLinus Torvalds * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*1da177e4SLinus Torvalds * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 21*1da177e4SLinus Torvalds * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*1da177e4SLinus Torvalds * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*1da177e4SLinus Torvalds * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*1da177e4SLinus Torvalds * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*1da177e4SLinus Torvalds * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*1da177e4SLinus Torvalds * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*1da177e4SLinus Torvalds * SUCH DAMAGE. 28*1da177e4SLinus Torvalds */ 29*1da177e4SLinus Torvalds 30*1da177e4SLinus Torvalds /* 31*1da177e4SLinus Torvalds * Veritas filesystem driver - support for 'immed' inodes. 32*1da177e4SLinus Torvalds */ 33*1da177e4SLinus Torvalds #include <linux/fs.h> 34*1da177e4SLinus Torvalds #include <linux/pagemap.h> 35*1da177e4SLinus Torvalds #include <linux/namei.h> 36*1da177e4SLinus Torvalds 37*1da177e4SLinus Torvalds #include "vxfs.h" 38*1da177e4SLinus Torvalds #include "vxfs_inode.h" 39*1da177e4SLinus Torvalds 40*1da177e4SLinus Torvalds 41*1da177e4SLinus Torvalds static int vxfs_immed_follow_link(struct dentry *, struct nameidata *); 42*1da177e4SLinus Torvalds 43*1da177e4SLinus Torvalds static int vxfs_immed_readpage(struct file *, struct page *); 44*1da177e4SLinus Torvalds 45*1da177e4SLinus Torvalds /* 46*1da177e4SLinus Torvalds * Inode operations for immed symlinks. 47*1da177e4SLinus Torvalds * 48*1da177e4SLinus Torvalds * Unliked all other operations we do not go through the pagecache, 49*1da177e4SLinus Torvalds * but do all work directly on the inode. 50*1da177e4SLinus Torvalds */ 51*1da177e4SLinus Torvalds struct inode_operations vxfs_immed_symlink_iops = { 52*1da177e4SLinus Torvalds .readlink = generic_readlink, 53*1da177e4SLinus Torvalds .follow_link = vxfs_immed_follow_link, 54*1da177e4SLinus Torvalds }; 55*1da177e4SLinus Torvalds 56*1da177e4SLinus Torvalds /* 57*1da177e4SLinus Torvalds * Adress space operations for immed files and directories. 58*1da177e4SLinus Torvalds */ 59*1da177e4SLinus Torvalds struct address_space_operations vxfs_immed_aops = { 60*1da177e4SLinus Torvalds .readpage = vxfs_immed_readpage, 61*1da177e4SLinus Torvalds }; 62*1da177e4SLinus Torvalds 63*1da177e4SLinus Torvalds /** 64*1da177e4SLinus Torvalds * vxfs_immed_follow_link - follow immed symlink 65*1da177e4SLinus Torvalds * @dp: dentry for the link 66*1da177e4SLinus Torvalds * @np: pathname lookup data for the current path walk 67*1da177e4SLinus Torvalds * 68*1da177e4SLinus Torvalds * Description: 69*1da177e4SLinus Torvalds * vxfs_immed_follow_link restarts the pathname lookup with 70*1da177e4SLinus Torvalds * the data obtained from @dp. 71*1da177e4SLinus Torvalds * 72*1da177e4SLinus Torvalds * Returns: 73*1da177e4SLinus Torvalds * Zero on success, else a negative error code. 74*1da177e4SLinus Torvalds */ 75*1da177e4SLinus Torvalds static int 76*1da177e4SLinus Torvalds vxfs_immed_follow_link(struct dentry *dp, struct nameidata *np) 77*1da177e4SLinus Torvalds { 78*1da177e4SLinus Torvalds struct vxfs_inode_info *vip = VXFS_INO(dp->d_inode); 79*1da177e4SLinus Torvalds nd_set_link(np, vip->vii_immed.vi_immed); 80*1da177e4SLinus Torvalds return 0; 81*1da177e4SLinus Torvalds } 82*1da177e4SLinus Torvalds 83*1da177e4SLinus Torvalds /** 84*1da177e4SLinus Torvalds * vxfs_immed_readpage - read part of an immed inode into pagecache 85*1da177e4SLinus Torvalds * @file: file context (unused) 86*1da177e4SLinus Torvalds * @page: page frame to fill in. 87*1da177e4SLinus Torvalds * 88*1da177e4SLinus Torvalds * Description: 89*1da177e4SLinus Torvalds * vxfs_immed_readpage reads a part of the immed area of the 90*1da177e4SLinus Torvalds * file that hosts @pp into the pagecache. 91*1da177e4SLinus Torvalds * 92*1da177e4SLinus Torvalds * Returns: 93*1da177e4SLinus Torvalds * Zero on success, else a negative error code. 94*1da177e4SLinus Torvalds * 95*1da177e4SLinus Torvalds * Locking status: 96*1da177e4SLinus Torvalds * @page is locked and will be unlocked. 97*1da177e4SLinus Torvalds */ 98*1da177e4SLinus Torvalds static int 99*1da177e4SLinus Torvalds vxfs_immed_readpage(struct file *fp, struct page *pp) 100*1da177e4SLinus Torvalds { 101*1da177e4SLinus Torvalds struct vxfs_inode_info *vip = VXFS_INO(pp->mapping->host); 102*1da177e4SLinus Torvalds u_int64_t offset = pp->index << PAGE_CACHE_SHIFT; 103*1da177e4SLinus Torvalds caddr_t kaddr; 104*1da177e4SLinus Torvalds 105*1da177e4SLinus Torvalds kaddr = kmap(pp); 106*1da177e4SLinus Torvalds memcpy(kaddr, vip->vii_immed.vi_immed + offset, PAGE_CACHE_SIZE); 107*1da177e4SLinus Torvalds kunmap(pp); 108*1da177e4SLinus Torvalds 109*1da177e4SLinus Torvalds flush_dcache_page(pp); 110*1da177e4SLinus Torvalds SetPageUptodate(pp); 111*1da177e4SLinus Torvalds unlock_page(pp); 112*1da177e4SLinus Torvalds 113*1da177e4SLinus Torvalds return 0; 114*1da177e4SLinus Torvalds } 115