1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2000-2001 Christoph Hellwig. 4 * Copyright (c) 2016 Krzysztof Blaszkowski 5 */ 6 7 /* 8 * Veritas filesystem driver - inode routines. 9 */ 10 #include <linux/fs.h> 11 #include <linux/buffer_head.h> 12 #include <linux/pagemap.h> 13 #include <linux/kernel.h> 14 #include <linux/slab.h> 15 #include <linux/namei.h> 16 17 #include "vxfs.h" 18 #include "vxfs_inode.h" 19 #include "vxfs_extern.h" 20 21 22 #ifdef DIAGNOSTIC 23 /* 24 * Dump inode contents (partially). 25 */ 26 void 27 vxfs_dumpi(struct vxfs_inode_info *vip, ino_t ino) 28 { 29 printk(KERN_DEBUG "\n\n"); 30 if (ino) 31 printk(KERN_DEBUG "dumping vxfs inode %ld\n", ino); 32 else 33 printk(KERN_DEBUG "dumping unknown vxfs inode\n"); 34 35 printk(KERN_DEBUG "---------------------------\n"); 36 printk(KERN_DEBUG "mode is %x\n", vip->vii_mode); 37 printk(KERN_DEBUG "nlink:%u, uid:%u, gid:%u\n", 38 vip->vii_nlink, vip->vii_uid, vip->vii_gid); 39 printk(KERN_DEBUG "size:%Lx, blocks:%u\n", 40 vip->vii_size, vip->vii_blocks); 41 printk(KERN_DEBUG "orgtype:%u\n", vip->vii_orgtype); 42 } 43 #endif 44 45 /** 46 * vxfs_transmod - mode for a VxFS inode 47 * @vip: VxFS inode 48 * 49 * Description: 50 * vxfs_transmod returns a Linux mode_t for a given 51 * VxFS inode structure. 52 */ 53 static __inline__ umode_t 54 vxfs_transmod(struct vxfs_inode_info *vip) 55 { 56 umode_t ret = vip->vii_mode & ~VXFS_TYPE_MASK; 57 58 if (VXFS_ISFIFO(vip)) 59 ret |= S_IFIFO; 60 if (VXFS_ISCHR(vip)) 61 ret |= S_IFCHR; 62 if (VXFS_ISDIR(vip)) 63 ret |= S_IFDIR; 64 if (VXFS_ISBLK(vip)) 65 ret |= S_IFBLK; 66 if (VXFS_ISLNK(vip)) 67 ret |= S_IFLNK; 68 if (VXFS_ISREG(vip)) 69 ret |= S_IFREG; 70 if (VXFS_ISSOC(vip)) 71 ret |= S_IFSOCK; 72 73 return (ret); 74 } 75 76 static inline void dip2vip_cpy(struct vxfs_sb_info *sbi, 77 struct vxfs_inode_info *vip, struct vxfs_dinode *dip) 78 { 79 struct inode *inode = &vip->vfs_inode; 80 81 vip->vii_mode = fs32_to_cpu(sbi, dip->vdi_mode); 82 vip->vii_nlink = fs32_to_cpu(sbi, dip->vdi_nlink); 83 vip->vii_uid = fs32_to_cpu(sbi, dip->vdi_uid); 84 vip->vii_gid = fs32_to_cpu(sbi, dip->vdi_gid); 85 vip->vii_size = fs64_to_cpu(sbi, dip->vdi_size); 86 vip->vii_atime = fs32_to_cpu(sbi, dip->vdi_atime); 87 vip->vii_autime = fs32_to_cpu(sbi, dip->vdi_autime); 88 vip->vii_mtime = fs32_to_cpu(sbi, dip->vdi_mtime); 89 vip->vii_mutime = fs32_to_cpu(sbi, dip->vdi_mutime); 90 vip->vii_ctime = fs32_to_cpu(sbi, dip->vdi_ctime); 91 vip->vii_cutime = fs32_to_cpu(sbi, dip->vdi_cutime); 92 vip->vii_orgtype = dip->vdi_orgtype; 93 94 vip->vii_blocks = fs32_to_cpu(sbi, dip->vdi_blocks); 95 vip->vii_gen = fs32_to_cpu(sbi, dip->vdi_gen); 96 97 if (VXFS_ISDIR(vip)) 98 vip->vii_dotdot = fs32_to_cpu(sbi, dip->vdi_dotdot); 99 else if (!VXFS_ISREG(vip) && !VXFS_ISLNK(vip)) 100 vip->vii_rdev = fs32_to_cpu(sbi, dip->vdi_rdev); 101 102 /* don't endian swap the fields that differ by orgtype */ 103 memcpy(&vip->vii_org, &dip->vdi_org, sizeof(vip->vii_org)); 104 105 inode->i_mode = vxfs_transmod(vip); 106 i_uid_write(inode, (uid_t)vip->vii_uid); 107 i_gid_write(inode, (gid_t)vip->vii_gid); 108 109 set_nlink(inode, vip->vii_nlink); 110 inode->i_size = vip->vii_size; 111 112 inode->i_atime.tv_sec = vip->vii_atime; 113 inode_set_ctime(inode, vip->vii_ctime, 0); 114 inode->i_mtime.tv_sec = vip->vii_mtime; 115 inode->i_atime.tv_nsec = 0; 116 inode->i_mtime.tv_nsec = 0; 117 118 inode->i_blocks = vip->vii_blocks; 119 inode->i_generation = vip->vii_gen; 120 } 121 122 /** 123 * vxfs_blkiget - find inode based on extent # 124 * @sbp: superblock of the filesystem we search in 125 * @extent: number of the extent to search 126 * @ino: inode number to search 127 * 128 * Description: 129 * vxfs_blkiget searches inode @ino in the filesystem described by 130 * @sbp in the extent @extent. 131 * Returns the matching VxFS inode on success, else a NULL pointer. 132 * 133 * NOTE: 134 * While __vxfs_iget uses the pagecache vxfs_blkiget uses the 135 * buffercache. This function should not be used outside the 136 * read_super() method, otherwise the data may be incoherent. 137 */ 138 struct inode * 139 vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino) 140 { 141 struct buffer_head *bp; 142 struct inode *inode; 143 u_long block, offset; 144 145 inode = new_inode(sbp); 146 if (!inode) 147 return NULL; 148 inode->i_ino = get_next_ino(); 149 150 block = extent + ((ino * VXFS_ISIZE) / sbp->s_blocksize); 151 offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE); 152 bp = sb_bread(sbp, block); 153 154 if (bp && buffer_mapped(bp)) { 155 struct vxfs_inode_info *vip = VXFS_INO(inode); 156 struct vxfs_dinode *dip; 157 158 dip = (struct vxfs_dinode *)(bp->b_data + offset); 159 dip2vip_cpy(VXFS_SBI(sbp), vip, dip); 160 vip->vfs_inode.i_mapping->a_ops = &vxfs_aops; 161 #ifdef DIAGNOSTIC 162 vxfs_dumpi(vip, ino); 163 #endif 164 brelse(bp); 165 return inode; 166 } 167 168 printk(KERN_WARNING "vxfs: unable to read block %ld\n", block); 169 brelse(bp); 170 iput(inode); 171 return NULL; 172 } 173 174 /** 175 * __vxfs_iget - generic find inode facility 176 * @ilistp: inode list 177 * @vip: VxFS inode to fill in 178 * @ino: inode number 179 * 180 * Description: 181 * Search the for inode number @ino in the filesystem 182 * described by @sbp. Use the specified inode table (@ilistp). 183 * Returns the matching inode on success, else an error code. 184 */ 185 static int 186 __vxfs_iget(struct inode *ilistp, struct vxfs_inode_info *vip, ino_t ino) 187 { 188 struct page *pp; 189 u_long offset; 190 191 offset = (ino % (PAGE_SIZE / VXFS_ISIZE)) * VXFS_ISIZE; 192 pp = vxfs_get_page(ilistp->i_mapping, ino * VXFS_ISIZE / PAGE_SIZE); 193 194 if (!IS_ERR(pp)) { 195 struct vxfs_dinode *dip; 196 caddr_t kaddr = (char *)page_address(pp); 197 198 dip = (struct vxfs_dinode *)(kaddr + offset); 199 dip2vip_cpy(VXFS_SBI(ilistp->i_sb), vip, dip); 200 vip->vfs_inode.i_mapping->a_ops = &vxfs_aops; 201 #ifdef DIAGNOSTIC 202 vxfs_dumpi(vip, ino); 203 #endif 204 vxfs_put_page(pp); 205 return 0; 206 } 207 208 printk(KERN_WARNING "vxfs: error on page 0x%p for inode %ld\n", 209 pp, (unsigned long)ino); 210 return PTR_ERR(pp); 211 } 212 213 /** 214 * vxfs_stiget - find inode using the structural inode list 215 * @sbp: VFS superblock 216 * @ino: inode # 217 * 218 * Description: 219 * Find inode @ino in the filesystem described by @sbp using 220 * the structural inode list. 221 * Returns the matching inode on success, else a NULL pointer. 222 */ 223 struct inode * 224 vxfs_stiget(struct super_block *sbp, ino_t ino) 225 { 226 struct inode *inode; 227 int error; 228 229 inode = new_inode(sbp); 230 if (!inode) 231 return NULL; 232 inode->i_ino = get_next_ino(); 233 234 error = __vxfs_iget(VXFS_SBI(sbp)->vsi_stilist, VXFS_INO(inode), ino); 235 if (error) { 236 iput(inode); 237 return NULL; 238 } 239 240 return inode; 241 } 242 243 /** 244 * vxfs_iget - get an inode 245 * @sbp: the superblock to get the inode for 246 * @ino: the number of the inode to get 247 * 248 * Description: 249 * vxfs_read_inode creates an inode, reads the disk inode for @ino and fills 250 * in all relevant fields in the new inode. 251 */ 252 struct inode * 253 vxfs_iget(struct super_block *sbp, ino_t ino) 254 { 255 struct vxfs_inode_info *vip; 256 const struct address_space_operations *aops; 257 struct inode *ip; 258 int error; 259 260 ip = iget_locked(sbp, ino); 261 if (!ip) 262 return ERR_PTR(-ENOMEM); 263 if (!(ip->i_state & I_NEW)) 264 return ip; 265 266 vip = VXFS_INO(ip); 267 error = __vxfs_iget(VXFS_SBI(sbp)->vsi_ilist, vip, ino); 268 if (error) { 269 iget_failed(ip); 270 return ERR_PTR(error); 271 } 272 273 if (VXFS_ISIMMED(vip)) 274 aops = &vxfs_immed_aops; 275 else 276 aops = &vxfs_aops; 277 278 if (S_ISREG(ip->i_mode)) { 279 ip->i_fop = &generic_ro_fops; 280 ip->i_mapping->a_ops = aops; 281 } else if (S_ISDIR(ip->i_mode)) { 282 ip->i_op = &vxfs_dir_inode_ops; 283 ip->i_fop = &vxfs_dir_operations; 284 ip->i_mapping->a_ops = aops; 285 } else if (S_ISLNK(ip->i_mode)) { 286 if (!VXFS_ISIMMED(vip)) { 287 ip->i_op = &page_symlink_inode_operations; 288 inode_nohighmem(ip); 289 ip->i_mapping->a_ops = &vxfs_aops; 290 } else { 291 ip->i_op = &simple_symlink_inode_operations; 292 ip->i_link = vip->vii_immed.vi_immed; 293 nd_terminate_link(ip->i_link, ip->i_size, 294 sizeof(vip->vii_immed.vi_immed) - 1); 295 } 296 } else 297 init_special_inode(ip, ip->i_mode, old_decode_dev(vip->vii_rdev)); 298 299 unlock_new_inode(ip); 300 return ip; 301 } 302 303 /** 304 * vxfs_evict_inode - remove inode from main memory 305 * @ip: inode to discard. 306 * 307 * Description: 308 * vxfs_evict_inode() is called on the final iput and frees the private 309 * inode area. 310 */ 311 void 312 vxfs_evict_inode(struct inode *ip) 313 { 314 truncate_inode_pages_final(&ip->i_data); 315 clear_inode(ip); 316 } 317