18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2000-2001 Christoph Hellwig. 38c2ecf20Sopenharmony_ci * Copyright (c) 2016 Krzysztof Blaszkowski 48c2ecf20Sopenharmony_ci * All rights reserved. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or without 78c2ecf20Sopenharmony_ci * modification, are permitted provided that the following conditions 88c2ecf20Sopenharmony_ci * are met: 98c2ecf20Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright 108c2ecf20Sopenharmony_ci * notice, this list of conditions, and the following disclaimer, 118c2ecf20Sopenharmony_ci * without modification. 128c2ecf20Sopenharmony_ci * 2. The name of the author may not be used to endorse or promote products 138c2ecf20Sopenharmony_ci * derived from this software without specific prior written permission. 148c2ecf20Sopenharmony_ci * 158c2ecf20Sopenharmony_ci * Alternatively, this software may be distributed under the terms of the 168c2ecf20Sopenharmony_ci * GNU General Public License ("GPL"). 178c2ecf20Sopenharmony_ci * 188c2ecf20Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 198c2ecf20Sopenharmony_ci * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 208c2ecf20Sopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 218c2ecf20Sopenharmony_ci * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 228c2ecf20Sopenharmony_ci * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 238c2ecf20Sopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 248c2ecf20Sopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 258c2ecf20Sopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 268c2ecf20Sopenharmony_ci * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 278c2ecf20Sopenharmony_ci * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 288c2ecf20Sopenharmony_ci * SUCH DAMAGE. 298c2ecf20Sopenharmony_ci */ 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* 328c2ecf20Sopenharmony_ci * Veritas filesystem driver - inode routines. 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci#include <linux/fs.h> 358c2ecf20Sopenharmony_ci#include <linux/buffer_head.h> 368c2ecf20Sopenharmony_ci#include <linux/pagemap.h> 378c2ecf20Sopenharmony_ci#include <linux/kernel.h> 388c2ecf20Sopenharmony_ci#include <linux/slab.h> 398c2ecf20Sopenharmony_ci#include <linux/namei.h> 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci#include "vxfs.h" 428c2ecf20Sopenharmony_ci#include "vxfs_inode.h" 438c2ecf20Sopenharmony_ci#include "vxfs_extern.h" 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci#ifdef DIAGNOSTIC 478c2ecf20Sopenharmony_ci/* 488c2ecf20Sopenharmony_ci * Dump inode contents (partially). 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_civoid 518c2ecf20Sopenharmony_civxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci printk(KERN_DEBUG "\n\n"); 548c2ecf20Sopenharmony_ci if (ino) 558c2ecf20Sopenharmony_ci printk(KERN_DEBUG "dumping vxfs inode %ld\n", ino); 568c2ecf20Sopenharmony_ci else 578c2ecf20Sopenharmony_ci printk(KERN_DEBUG "dumping unknown vxfs inode\n"); 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci printk(KERN_DEBUG "---------------------------\n"); 608c2ecf20Sopenharmony_ci printk(KERN_DEBUG "mode is %x\n", vip->vii_mode); 618c2ecf20Sopenharmony_ci printk(KERN_DEBUG "nlink:%u, uid:%u, gid:%u\n", 628c2ecf20Sopenharmony_ci vip->vii_nlink, vip->vii_uid, vip->vii_gid); 638c2ecf20Sopenharmony_ci printk(KERN_DEBUG "size:%Lx, blocks:%u\n", 648c2ecf20Sopenharmony_ci vip->vii_size, vip->vii_blocks); 658c2ecf20Sopenharmony_ci printk(KERN_DEBUG "orgtype:%u\n", vip->vii_orgtype); 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci#endif 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci/** 708c2ecf20Sopenharmony_ci * vxfs_transmod - mode for a VxFS inode 718c2ecf20Sopenharmony_ci * @vip: VxFS inode 728c2ecf20Sopenharmony_ci * 738c2ecf20Sopenharmony_ci * Description: 748c2ecf20Sopenharmony_ci * vxfs_transmod returns a Linux mode_t for a given 758c2ecf20Sopenharmony_ci * VxFS inode structure. 768c2ecf20Sopenharmony_ci */ 778c2ecf20Sopenharmony_cistatic __inline__ umode_t 788c2ecf20Sopenharmony_civxfs_transmod(struct vxfs_inode_info *vip) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci umode_t ret = vip->vii_mode & ~VXFS_TYPE_MASK; 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci if (VXFS_ISFIFO(vip)) 838c2ecf20Sopenharmony_ci ret |= S_IFIFO; 848c2ecf20Sopenharmony_ci if (VXFS_ISCHR(vip)) 858c2ecf20Sopenharmony_ci ret |= S_IFCHR; 868c2ecf20Sopenharmony_ci if (VXFS_ISDIR(vip)) 878c2ecf20Sopenharmony_ci ret |= S_IFDIR; 888c2ecf20Sopenharmony_ci if (VXFS_ISBLK(vip)) 898c2ecf20Sopenharmony_ci ret |= S_IFBLK; 908c2ecf20Sopenharmony_ci if (VXFS_ISLNK(vip)) 918c2ecf20Sopenharmony_ci ret |= S_IFLNK; 928c2ecf20Sopenharmony_ci if (VXFS_ISREG(vip)) 938c2ecf20Sopenharmony_ci ret |= S_IFREG; 948c2ecf20Sopenharmony_ci if (VXFS_ISSOC(vip)) 958c2ecf20Sopenharmony_ci ret |= S_IFSOCK; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci return (ret); 988c2ecf20Sopenharmony_ci} 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_cistatic inline void dip2vip_cpy(struct vxfs_sb_info *sbi, 1018c2ecf20Sopenharmony_ci struct vxfs_inode_info *vip, struct vxfs_dinode *dip) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci struct inode *inode = &vip->vfs_inode; 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci vip->vii_mode = fs32_to_cpu(sbi, dip->vdi_mode); 1068c2ecf20Sopenharmony_ci vip->vii_nlink = fs32_to_cpu(sbi, dip->vdi_nlink); 1078c2ecf20Sopenharmony_ci vip->vii_uid = fs32_to_cpu(sbi, dip->vdi_uid); 1088c2ecf20Sopenharmony_ci vip->vii_gid = fs32_to_cpu(sbi, dip->vdi_gid); 1098c2ecf20Sopenharmony_ci vip->vii_size = fs64_to_cpu(sbi, dip->vdi_size); 1108c2ecf20Sopenharmony_ci vip->vii_atime = fs32_to_cpu(sbi, dip->vdi_atime); 1118c2ecf20Sopenharmony_ci vip->vii_autime = fs32_to_cpu(sbi, dip->vdi_autime); 1128c2ecf20Sopenharmony_ci vip->vii_mtime = fs32_to_cpu(sbi, dip->vdi_mtime); 1138c2ecf20Sopenharmony_ci vip->vii_mutime = fs32_to_cpu(sbi, dip->vdi_mutime); 1148c2ecf20Sopenharmony_ci vip->vii_ctime = fs32_to_cpu(sbi, dip->vdi_ctime); 1158c2ecf20Sopenharmony_ci vip->vii_cutime = fs32_to_cpu(sbi, dip->vdi_cutime); 1168c2ecf20Sopenharmony_ci vip->vii_orgtype = dip->vdi_orgtype; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci vip->vii_blocks = fs32_to_cpu(sbi, dip->vdi_blocks); 1198c2ecf20Sopenharmony_ci vip->vii_gen = fs32_to_cpu(sbi, dip->vdi_gen); 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci if (VXFS_ISDIR(vip)) 1228c2ecf20Sopenharmony_ci vip->vii_dotdot = fs32_to_cpu(sbi, dip->vdi_dotdot); 1238c2ecf20Sopenharmony_ci else if (!VXFS_ISREG(vip) && !VXFS_ISLNK(vip)) 1248c2ecf20Sopenharmony_ci vip->vii_rdev = fs32_to_cpu(sbi, dip->vdi_rdev); 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci /* don't endian swap the fields that differ by orgtype */ 1278c2ecf20Sopenharmony_ci memcpy(&vip->vii_org, &dip->vdi_org, sizeof(vip->vii_org)); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci inode->i_mode = vxfs_transmod(vip); 1308c2ecf20Sopenharmony_ci i_uid_write(inode, (uid_t)vip->vii_uid); 1318c2ecf20Sopenharmony_ci i_gid_write(inode, (gid_t)vip->vii_gid); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci set_nlink(inode, vip->vii_nlink); 1348c2ecf20Sopenharmony_ci inode->i_size = vip->vii_size; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci inode->i_atime.tv_sec = vip->vii_atime; 1378c2ecf20Sopenharmony_ci inode->i_ctime.tv_sec = vip->vii_ctime; 1388c2ecf20Sopenharmony_ci inode->i_mtime.tv_sec = vip->vii_mtime; 1398c2ecf20Sopenharmony_ci inode->i_atime.tv_nsec = 0; 1408c2ecf20Sopenharmony_ci inode->i_ctime.tv_nsec = 0; 1418c2ecf20Sopenharmony_ci inode->i_mtime.tv_nsec = 0; 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci inode->i_blocks = vip->vii_blocks; 1448c2ecf20Sopenharmony_ci inode->i_generation = vip->vii_gen; 1458c2ecf20Sopenharmony_ci} 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci/** 1488c2ecf20Sopenharmony_ci * vxfs_blkiget - find inode based on extent # 1498c2ecf20Sopenharmony_ci * @sbp: superblock of the filesystem we search in 1508c2ecf20Sopenharmony_ci * @extent: number of the extent to search 1518c2ecf20Sopenharmony_ci * @ino: inode number to search 1528c2ecf20Sopenharmony_ci * 1538c2ecf20Sopenharmony_ci * Description: 1548c2ecf20Sopenharmony_ci * vxfs_blkiget searches inode @ino in the filesystem described by 1558c2ecf20Sopenharmony_ci * @sbp in the extent @extent. 1568c2ecf20Sopenharmony_ci * Returns the matching VxFS inode on success, else a NULL pointer. 1578c2ecf20Sopenharmony_ci * 1588c2ecf20Sopenharmony_ci * NOTE: 1598c2ecf20Sopenharmony_ci * While __vxfs_iget uses the pagecache vxfs_blkiget uses the 1608c2ecf20Sopenharmony_ci * buffercache. This function should not be used outside the 1618c2ecf20Sopenharmony_ci * read_super() method, otherwise the data may be incoherent. 1628c2ecf20Sopenharmony_ci */ 1638c2ecf20Sopenharmony_cistruct inode * 1648c2ecf20Sopenharmony_civxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino) 1658c2ecf20Sopenharmony_ci{ 1668c2ecf20Sopenharmony_ci struct buffer_head *bp; 1678c2ecf20Sopenharmony_ci struct inode *inode; 1688c2ecf20Sopenharmony_ci u_long block, offset; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci inode = new_inode(sbp); 1718c2ecf20Sopenharmony_ci if (!inode) 1728c2ecf20Sopenharmony_ci return NULL; 1738c2ecf20Sopenharmony_ci inode->i_ino = get_next_ino(); 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci block = extent + ((ino * VXFS_ISIZE) / sbp->s_blocksize); 1768c2ecf20Sopenharmony_ci offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE); 1778c2ecf20Sopenharmony_ci bp = sb_bread(sbp, block); 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci if (bp && buffer_mapped(bp)) { 1808c2ecf20Sopenharmony_ci struct vxfs_inode_info *vip = VXFS_INO(inode); 1818c2ecf20Sopenharmony_ci struct vxfs_dinode *dip; 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci dip = (struct vxfs_dinode *)(bp->b_data + offset); 1848c2ecf20Sopenharmony_ci dip2vip_cpy(VXFS_SBI(sbp), vip, dip); 1858c2ecf20Sopenharmony_ci vip->vfs_inode.i_mapping->a_ops = &vxfs_aops; 1868c2ecf20Sopenharmony_ci#ifdef DIAGNOSTIC 1878c2ecf20Sopenharmony_ci vxfs_dumpi(vip, ino); 1888c2ecf20Sopenharmony_ci#endif 1898c2ecf20Sopenharmony_ci brelse(bp); 1908c2ecf20Sopenharmony_ci return inode; 1918c2ecf20Sopenharmony_ci } 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci printk(KERN_WARNING "vxfs: unable to read block %ld\n", block); 1948c2ecf20Sopenharmony_ci brelse(bp); 1958c2ecf20Sopenharmony_ci iput(inode); 1968c2ecf20Sopenharmony_ci return NULL; 1978c2ecf20Sopenharmony_ci} 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci/** 2008c2ecf20Sopenharmony_ci * __vxfs_iget - generic find inode facility 2018c2ecf20Sopenharmony_ci * @ilistp: inode list 2028c2ecf20Sopenharmony_ci * @vip: VxFS inode to fill in 2038c2ecf20Sopenharmony_ci * @ino: inode number 2048c2ecf20Sopenharmony_ci * 2058c2ecf20Sopenharmony_ci * Description: 2068c2ecf20Sopenharmony_ci * Search the for inode number @ino in the filesystem 2078c2ecf20Sopenharmony_ci * described by @sbp. Use the specified inode table (@ilistp). 2088c2ecf20Sopenharmony_ci * Returns the matching inode on success, else an error code. 2098c2ecf20Sopenharmony_ci */ 2108c2ecf20Sopenharmony_cistatic int 2118c2ecf20Sopenharmony_ci__vxfs_iget(struct inode *ilistp, struct vxfs_inode_info *vip, ino_t ino) 2128c2ecf20Sopenharmony_ci{ 2138c2ecf20Sopenharmony_ci struct page *pp; 2148c2ecf20Sopenharmony_ci u_long offset; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci offset = (ino % (PAGE_SIZE / VXFS_ISIZE)) * VXFS_ISIZE; 2178c2ecf20Sopenharmony_ci pp = vxfs_get_page(ilistp->i_mapping, ino * VXFS_ISIZE / PAGE_SIZE); 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci if (!IS_ERR(pp)) { 2208c2ecf20Sopenharmony_ci struct vxfs_dinode *dip; 2218c2ecf20Sopenharmony_ci caddr_t kaddr = (char *)page_address(pp); 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci dip = (struct vxfs_dinode *)(kaddr + offset); 2248c2ecf20Sopenharmony_ci dip2vip_cpy(VXFS_SBI(ilistp->i_sb), vip, dip); 2258c2ecf20Sopenharmony_ci vip->vfs_inode.i_mapping->a_ops = &vxfs_aops; 2268c2ecf20Sopenharmony_ci#ifdef DIAGNOSTIC 2278c2ecf20Sopenharmony_ci vxfs_dumpi(vip, ino); 2288c2ecf20Sopenharmony_ci#endif 2298c2ecf20Sopenharmony_ci vxfs_put_page(pp); 2308c2ecf20Sopenharmony_ci return 0; 2318c2ecf20Sopenharmony_ci } 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci printk(KERN_WARNING "vxfs: error on page 0x%p for inode %ld\n", 2348c2ecf20Sopenharmony_ci pp, (unsigned long)ino); 2358c2ecf20Sopenharmony_ci return PTR_ERR(pp); 2368c2ecf20Sopenharmony_ci} 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci/** 2398c2ecf20Sopenharmony_ci * vxfs_stiget - find inode using the structural inode list 2408c2ecf20Sopenharmony_ci * @sbp: VFS superblock 2418c2ecf20Sopenharmony_ci * @ino: inode # 2428c2ecf20Sopenharmony_ci * 2438c2ecf20Sopenharmony_ci * Description: 2448c2ecf20Sopenharmony_ci * Find inode @ino in the filesystem described by @sbp using 2458c2ecf20Sopenharmony_ci * the structural inode list. 2468c2ecf20Sopenharmony_ci * Returns the matching inode on success, else a NULL pointer. 2478c2ecf20Sopenharmony_ci */ 2488c2ecf20Sopenharmony_cistruct inode * 2498c2ecf20Sopenharmony_civxfs_stiget(struct super_block *sbp, ino_t ino) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci struct inode *inode; 2528c2ecf20Sopenharmony_ci int error; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci inode = new_inode(sbp); 2558c2ecf20Sopenharmony_ci if (!inode) 2568c2ecf20Sopenharmony_ci return NULL; 2578c2ecf20Sopenharmony_ci inode->i_ino = get_next_ino(); 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci error = __vxfs_iget(VXFS_SBI(sbp)->vsi_stilist, VXFS_INO(inode), ino); 2608c2ecf20Sopenharmony_ci if (error) { 2618c2ecf20Sopenharmony_ci iput(inode); 2628c2ecf20Sopenharmony_ci return NULL; 2638c2ecf20Sopenharmony_ci } 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci return inode; 2668c2ecf20Sopenharmony_ci} 2678c2ecf20Sopenharmony_ci 2688c2ecf20Sopenharmony_ci/** 2698c2ecf20Sopenharmony_ci * vxfs_iget - get an inode 2708c2ecf20Sopenharmony_ci * @sbp: the superblock to get the inode for 2718c2ecf20Sopenharmony_ci * @ino: the number of the inode to get 2728c2ecf20Sopenharmony_ci * 2738c2ecf20Sopenharmony_ci * Description: 2748c2ecf20Sopenharmony_ci * vxfs_read_inode creates an inode, reads the disk inode for @ino and fills 2758c2ecf20Sopenharmony_ci * in all relevant fields in the new inode. 2768c2ecf20Sopenharmony_ci */ 2778c2ecf20Sopenharmony_cistruct inode * 2788c2ecf20Sopenharmony_civxfs_iget(struct super_block *sbp, ino_t ino) 2798c2ecf20Sopenharmony_ci{ 2808c2ecf20Sopenharmony_ci struct vxfs_inode_info *vip; 2818c2ecf20Sopenharmony_ci const struct address_space_operations *aops; 2828c2ecf20Sopenharmony_ci struct inode *ip; 2838c2ecf20Sopenharmony_ci int error; 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci ip = iget_locked(sbp, ino); 2868c2ecf20Sopenharmony_ci if (!ip) 2878c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 2888c2ecf20Sopenharmony_ci if (!(ip->i_state & I_NEW)) 2898c2ecf20Sopenharmony_ci return ip; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci vip = VXFS_INO(ip); 2928c2ecf20Sopenharmony_ci error = __vxfs_iget(VXFS_SBI(sbp)->vsi_ilist, vip, ino); 2938c2ecf20Sopenharmony_ci if (error) { 2948c2ecf20Sopenharmony_ci iget_failed(ip); 2958c2ecf20Sopenharmony_ci return ERR_PTR(error); 2968c2ecf20Sopenharmony_ci } 2978c2ecf20Sopenharmony_ci 2988c2ecf20Sopenharmony_ci if (VXFS_ISIMMED(vip)) 2998c2ecf20Sopenharmony_ci aops = &vxfs_immed_aops; 3008c2ecf20Sopenharmony_ci else 3018c2ecf20Sopenharmony_ci aops = &vxfs_aops; 3028c2ecf20Sopenharmony_ci 3038c2ecf20Sopenharmony_ci if (S_ISREG(ip->i_mode)) { 3048c2ecf20Sopenharmony_ci ip->i_fop = &generic_ro_fops; 3058c2ecf20Sopenharmony_ci ip->i_mapping->a_ops = aops; 3068c2ecf20Sopenharmony_ci } else if (S_ISDIR(ip->i_mode)) { 3078c2ecf20Sopenharmony_ci ip->i_op = &vxfs_dir_inode_ops; 3088c2ecf20Sopenharmony_ci ip->i_fop = &vxfs_dir_operations; 3098c2ecf20Sopenharmony_ci ip->i_mapping->a_ops = aops; 3108c2ecf20Sopenharmony_ci } else if (S_ISLNK(ip->i_mode)) { 3118c2ecf20Sopenharmony_ci if (!VXFS_ISIMMED(vip)) { 3128c2ecf20Sopenharmony_ci ip->i_op = &page_symlink_inode_operations; 3138c2ecf20Sopenharmony_ci inode_nohighmem(ip); 3148c2ecf20Sopenharmony_ci ip->i_mapping->a_ops = &vxfs_aops; 3158c2ecf20Sopenharmony_ci } else { 3168c2ecf20Sopenharmony_ci ip->i_op = &simple_symlink_inode_operations; 3178c2ecf20Sopenharmony_ci ip->i_link = vip->vii_immed.vi_immed; 3188c2ecf20Sopenharmony_ci nd_terminate_link(ip->i_link, ip->i_size, 3198c2ecf20Sopenharmony_ci sizeof(vip->vii_immed.vi_immed) - 1); 3208c2ecf20Sopenharmony_ci } 3218c2ecf20Sopenharmony_ci } else 3228c2ecf20Sopenharmony_ci init_special_inode(ip, ip->i_mode, old_decode_dev(vip->vii_rdev)); 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci unlock_new_inode(ip); 3258c2ecf20Sopenharmony_ci return ip; 3268c2ecf20Sopenharmony_ci} 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci/** 3298c2ecf20Sopenharmony_ci * vxfs_evict_inode - remove inode from main memory 3308c2ecf20Sopenharmony_ci * @ip: inode to discard. 3318c2ecf20Sopenharmony_ci * 3328c2ecf20Sopenharmony_ci * Description: 3338c2ecf20Sopenharmony_ci * vxfs_evict_inode() is called on the final iput and frees the private 3348c2ecf20Sopenharmony_ci * inode area. 3358c2ecf20Sopenharmony_ci */ 3368c2ecf20Sopenharmony_civoid 3378c2ecf20Sopenharmony_civxfs_evict_inode(struct inode *ip) 3388c2ecf20Sopenharmony_ci{ 3398c2ecf20Sopenharmony_ci truncate_inode_pages_final(&ip->i_data); 3408c2ecf20Sopenharmony_ci clear_inode(ip); 3418c2ecf20Sopenharmony_ci} 342