2 * Copyright (c) 2000-2001 Christoph Hellwig.
3 * Copyright (c) 2016 Krzysztof Blaszkowski
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer,
11 * without modification.
12 * 2. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
15 * Alternatively, this software may be distributed under the terms of the
16 * GNU General Public License ("GPL").
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * Veritas filesystem driver - inode routines.
35 #include <linux/buffer_head.h>
36 #include <linux/pagemap.h>
37 #include <linux/kernel.h>
38 #include <linux/slab.h>
39 #include <linux/namei.h>
42 #include "vxfs_inode.h"
43 #include "vxfs_extern.h"
48 * Dump inode contents (partially).
51 vxfs_dumpi(struct vxfs_inode_info
*vip
, ino_t ino
)
53 printk(KERN_DEBUG
"\n\n");
55 printk(KERN_DEBUG
"dumping vxfs inode %ld\n", ino
);
57 printk(KERN_DEBUG
"dumping unknown vxfs inode\n");
59 printk(KERN_DEBUG
"---------------------------\n");
60 printk(KERN_DEBUG
"mode is %x\n", vip
->vii_mode
);
61 printk(KERN_DEBUG
"nlink:%u, uid:%u, gid:%u\n",
62 vip
->vii_nlink
, vip
->vii_uid
, vip
->vii_gid
);
63 printk(KERN_DEBUG
"size:%Lx, blocks:%u\n",
64 vip
->vii_size
, vip
->vii_blocks
);
65 printk(KERN_DEBUG
"orgtype:%u\n", vip
->vii_orgtype
);
70 * vxfs_transmod - mode for a VxFS inode
74 * vxfs_transmod returns a Linux mode_t for a given
75 * VxFS inode structure.
77 static __inline__ umode_t
78 vxfs_transmod(struct vxfs_inode_info
*vip
)
80 umode_t ret
= vip
->vii_mode
& ~VXFS_TYPE_MASK
;
100 static inline void dip2vip_cpy(struct vxfs_sb_info
*sbi
,
101 struct vxfs_inode_info
*vip
, struct vxfs_dinode
*dip
)
103 struct inode
*inode
= &vip
->vfs_inode
;
105 vip
->vii_mode
= fs32_to_cpu(sbi
, dip
->vdi_mode
);
106 vip
->vii_nlink
= fs32_to_cpu(sbi
, dip
->vdi_nlink
);
107 vip
->vii_uid
= fs32_to_cpu(sbi
, dip
->vdi_uid
);
108 vip
->vii_gid
= fs32_to_cpu(sbi
, dip
->vdi_gid
);
109 vip
->vii_size
= fs64_to_cpu(sbi
, dip
->vdi_size
);
110 vip
->vii_atime
= fs32_to_cpu(sbi
, dip
->vdi_atime
);
111 vip
->vii_autime
= fs32_to_cpu(sbi
, dip
->vdi_autime
);
112 vip
->vii_mtime
= fs32_to_cpu(sbi
, dip
->vdi_mtime
);
113 vip
->vii_mutime
= fs32_to_cpu(sbi
, dip
->vdi_mutime
);
114 vip
->vii_ctime
= fs32_to_cpu(sbi
, dip
->vdi_ctime
);
115 vip
->vii_cutime
= fs32_to_cpu(sbi
, dip
->vdi_cutime
);
116 vip
->vii_orgtype
= dip
->vdi_orgtype
;
118 vip
->vii_blocks
= fs32_to_cpu(sbi
, dip
->vdi_blocks
);
119 vip
->vii_gen
= fs32_to_cpu(sbi
, dip
->vdi_gen
);
122 vip
->vii_dotdot
= fs32_to_cpu(sbi
, dip
->vdi_dotdot
);
123 else if (!VXFS_ISREG(vip
) && !VXFS_ISLNK(vip
))
124 vip
->vii_rdev
= fs32_to_cpu(sbi
, dip
->vdi_rdev
);
126 /* don't endian swap the fields that differ by orgtype */
127 memcpy(&vip
->vii_org
, &dip
->vdi_org
, sizeof(vip
->vii_org
));
129 inode
->i_mode
= vxfs_transmod(vip
);
130 i_uid_write(inode
, (uid_t
)vip
->vii_uid
);
131 i_gid_write(inode
, (gid_t
)vip
->vii_gid
);
133 set_nlink(inode
, vip
->vii_nlink
);
134 inode
->i_size
= vip
->vii_size
;
136 inode
->i_atime
.tv_sec
= vip
->vii_atime
;
137 inode
->i_ctime
.tv_sec
= vip
->vii_ctime
;
138 inode
->i_mtime
.tv_sec
= vip
->vii_mtime
;
139 inode
->i_atime
.tv_nsec
= 0;
140 inode
->i_ctime
.tv_nsec
= 0;
141 inode
->i_mtime
.tv_nsec
= 0;
143 inode
->i_blocks
= vip
->vii_blocks
;
144 inode
->i_generation
= vip
->vii_gen
;
148 * vxfs_blkiget - find inode based on extent #
149 * @sbp: superblock of the filesystem we search in
150 * @extent: number of the extent to search
151 * @ino: inode number to search
154 * vxfs_blkiget searches inode @ino in the filesystem described by
155 * @sbp in the extent @extent.
156 * Returns the matching VxFS inode on success, else a NULL pointer.
159 * While __vxfs_iget uses the pagecache vxfs_blkiget uses the
160 * buffercache. This function should not be used outside the
161 * read_super() method, otherwise the data may be incoherent.
164 vxfs_blkiget(struct super_block
*sbp
, u_long extent
, ino_t ino
)
166 struct buffer_head
*bp
;
168 u_long block
, offset
;
170 inode
= new_inode(sbp
);
173 inode
->i_ino
= get_next_ino();
175 block
= extent
+ ((ino
* VXFS_ISIZE
) / sbp
->s_blocksize
);
176 offset
= ((ino
% (sbp
->s_blocksize
/ VXFS_ISIZE
)) * VXFS_ISIZE
);
177 bp
= sb_bread(sbp
, block
);
179 if (bp
&& buffer_mapped(bp
)) {
180 struct vxfs_inode_info
*vip
= VXFS_INO(inode
);
181 struct vxfs_dinode
*dip
;
183 dip
= (struct vxfs_dinode
*)(bp
->b_data
+ offset
);
184 dip2vip_cpy(VXFS_SBI(sbp
), vip
, dip
);
185 vip
->vfs_inode
.i_mapping
->a_ops
= &vxfs_aops
;
187 vxfs_dumpi(vip
, ino
);
193 printk(KERN_WARNING
"vxfs: unable to read block %ld\n", block
);
200 * __vxfs_iget - generic find inode facility
201 * @ilistp: inode list
202 * @vip: VxFS inode to fill in
206 * Search the for inode number @ino in the filesystem
207 * described by @sbp. Use the specified inode table (@ilistp).
208 * Returns the matching inode on success, else an error code.
211 __vxfs_iget(struct inode
*ilistp
, struct vxfs_inode_info
*vip
, ino_t ino
)
216 offset
= (ino
% (PAGE_SIZE
/ VXFS_ISIZE
)) * VXFS_ISIZE
;
217 pp
= vxfs_get_page(ilistp
->i_mapping
, ino
* VXFS_ISIZE
/ PAGE_SIZE
);
220 struct vxfs_dinode
*dip
;
221 caddr_t kaddr
= (char *)page_address(pp
);
223 dip
= (struct vxfs_dinode
*)(kaddr
+ offset
);
224 dip2vip_cpy(VXFS_SBI(ilistp
->i_sb
), vip
, dip
);
225 vip
->vfs_inode
.i_mapping
->a_ops
= &vxfs_aops
;
227 vxfs_dumpi(vip
, ino
);
233 printk(KERN_WARNING
"vxfs: error on page 0x%p for inode %ld\n",
234 pp
, (unsigned long)ino
);
239 * vxfs_stiget - find inode using the structural inode list
240 * @sbp: VFS superblock
244 * Find inode @ino in the filesystem described by @sbp using
245 * the structural inode list.
246 * Returns the matching inode on success, else a NULL pointer.
249 vxfs_stiget(struct super_block
*sbp
, ino_t ino
)
254 inode
= new_inode(sbp
);
257 inode
->i_ino
= get_next_ino();
259 error
= __vxfs_iget(VXFS_SBI(sbp
)->vsi_stilist
, VXFS_INO(inode
), ino
);
269 * vxfs_iget - get an inode
270 * @sbp: the superblock to get the inode for
271 * @ino: the number of the inode to get
274 * vxfs_read_inode creates an inode, reads the disk inode for @ino and fills
275 * in all relevant fields in the new inode.
278 vxfs_iget(struct super_block
*sbp
, ino_t ino
)
280 struct vxfs_inode_info
*vip
;
281 const struct address_space_operations
*aops
;
285 ip
= iget_locked(sbp
, ino
);
287 return ERR_PTR(-ENOMEM
);
288 if (!(ip
->i_state
& I_NEW
))
292 error
= __vxfs_iget(VXFS_SBI(sbp
)->vsi_ilist
, vip
, ino
);
295 return ERR_PTR(error
);
298 if (VXFS_ISIMMED(vip
))
299 aops
= &vxfs_immed_aops
;
303 if (S_ISREG(ip
->i_mode
)) {
304 ip
->i_fop
= &generic_ro_fops
;
305 ip
->i_mapping
->a_ops
= aops
;
306 } else if (S_ISDIR(ip
->i_mode
)) {
307 ip
->i_op
= &vxfs_dir_inode_ops
;
308 ip
->i_fop
= &vxfs_dir_operations
;
309 ip
->i_mapping
->a_ops
= aops
;
310 } else if (S_ISLNK(ip
->i_mode
)) {
311 if (!VXFS_ISIMMED(vip
)) {
312 ip
->i_op
= &page_symlink_inode_operations
;
314 ip
->i_mapping
->a_ops
= &vxfs_aops
;
316 ip
->i_op
= &simple_symlink_inode_operations
;
317 ip
->i_link
= vip
->vii_immed
.vi_immed
;
318 nd_terminate_link(ip
->i_link
, ip
->i_size
,
319 sizeof(vip
->vii_immed
.vi_immed
) - 1);
322 init_special_inode(ip
, ip
->i_mode
, old_decode_dev(vip
->vii_rdev
));
324 unlock_new_inode(ip
);
329 * vxfs_evict_inode - remove inode from main memory
330 * @ip: inode to discard.
333 * vxfs_evict_inode() is called on the final iput and frees the private
337 vxfs_evict_inode(struct inode
*ip
)
339 truncate_inode_pages_final(&ip
->i_data
);