1 /* $OpenBSD: ext2fs_subr.c,v 1.38 2024/10/08 02:58:26 jsg Exp $ */
2 /* $NetBSD: ext2fs_subr.c,v 1.1 1997/06/11 09:34:03 bouyer Exp $ */
3
4 /*
5 * Copyright (c) 1997 Manuel Bouyer.
6 * Copyright (c) 1982, 1986, 1989, 1993
7 * The Regents of the University of California. All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * @(#)ffs_subr.c 8.2 (Berkeley) 9/21/93
34 * Modified for ext2fs by Manuel Bouyer.
35 */
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/vnode.h>
40 #include <sys/mount.h>
41 #include <sys/buf.h>
42 #include <sys/specdev.h>
43
44 #include <ufs/ufs/quota.h>
45 #include <ufs/ufs/inode.h>
46 #include <ufs/ufs/ufsmount.h>
47
48 #include <ufs/ext2fs/ext2fs.h>
49 #include <ufs/ext2fs/ext2fs_extern.h>
50 #include <ufs/ext2fs/ext2fs_extents.h>
51
52 #ifdef _KERNEL
53
54 /*
55 * Return buffer with the contents of block "offset" from the beginning of
56 * directory "ip". If "res" is non-zero, fill it in with a pointer to the
57 * remaining space in the directory.
58 */
59 int
ext2fs_bufatoff(struct inode * ip,off_t offset,char ** res,struct buf ** bpp)60 ext2fs_bufatoff(struct inode *ip, off_t offset, char **res, struct buf **bpp)
61 {
62 struct vnode *vp;
63 struct m_ext2fs *fs;
64 struct buf *bp;
65 daddr_t lbn, pos;
66 int error;
67
68 vp = ITOV(ip);
69 fs = ip->i_e2fs;
70 lbn = lblkno(fs, offset);
71
72 if (ip->i_e2din->e2di_flags & EXT4_EXTENTS) {
73 struct ext4_extent_path path;
74 struct ext4_extent *ep;
75
76 memset(&path, 0, sizeof path);
77 if (ext4_ext_find_extent(fs, ip, lbn, &path) == NULL ||
78 (ep = path.ep_ext) == NULL)
79 goto normal;
80
81 if (path.ep_bp != NULL) {
82 brelse(path.ep_bp);
83 path.ep_bp = NULL;
84 }
85 pos = lbn - ep->e_blk + (((daddr_t)ep->e_start_hi << 32) | ep->e_start_lo);
86 error = bread(ip->i_devvp, fsbtodb(fs, pos), fs->e2fs_bsize, &bp);
87 if (error) {
88 brelse(bp);
89 return (error);
90 }
91
92 if (res)
93 *res = (char *)bp->b_data + blkoff(fs, offset);
94
95 *bpp = bp;
96
97 return (0);
98 }
99
100 normal:
101 *bpp = NULL;
102 if ((error = bread(vp, lbn, fs->e2fs_bsize, &bp)) != 0) {
103 brelse(bp);
104 return (error);
105 }
106 if (res)
107 *res = (char *)bp->b_data + blkoff(fs, offset);
108 *bpp = bp;
109 return (0);
110 }
111 #endif
112
113 /*
114 * Initialize the vnode associated with a new inode, handle aliased vnodes.
115 */
116 int
ext2fs_vinit(struct mount * mp,struct vnode ** vpp)117 ext2fs_vinit(struct mount *mp, struct vnode **vpp)
118 {
119 struct inode *ip;
120 struct vnode *vp, *nvp;
121 struct timeval tv;
122
123 vp = *vpp;
124 ip = VTOI(vp);
125 vp->v_type = IFTOVT(ip->i_e2fs_mode);
126
127 switch(vp->v_type) {
128 case VCHR:
129 case VBLK:
130 vp->v_op = &ext2fs_specvops;
131
132 nvp = checkalias(vp, letoh32(ip->i_e2din->e2di_rdev), mp);
133 if (nvp != NULL) {
134 /*
135 * Discard unneeded vnode, but save its inode. Note
136 * that the lock is carried over in the inode to the
137 * replacement vnode.
138 */
139 nvp->v_data = vp->v_data;
140 vp->v_data = NULL;
141 vp->v_op = &spec_vops;
142 #ifdef VFSLCKDEBUG
143 vp->v_flag &= ~VLOCKSWORK;
144 #endif
145 vrele(vp);
146 vgone(vp);
147 /* Reinitialize aliased vnode. */
148 vp = nvp;
149 ip->i_vnode = vp;
150 }
151
152 break;
153
154 case VFIFO:
155 #ifdef FIFO
156 vp->v_op = &ext2fs_fifovops;
157 break;
158 #else
159 return (EOPNOTSUPP);
160 #endif /* FIFO */
161
162 default:
163
164 break;
165 }
166
167 if (ip->i_number == EXT2_ROOTINO)
168 vp->v_flag |= VROOT;
169
170 /* Initialize modrev times */
171 getmicrouptime(&tv);
172 ip->i_modrev = (u_quad_t)tv.tv_sec << 32;
173 ip->i_modrev |= (u_quad_t)tv.tv_usec * 4294;
174
175 *vpp = vp;
176
177 return (0);
178 }
179