1 /*-
2 * Copyright 2000 Hans Reiser
3 * See README for licensing and copyright details
4 *
5 * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron@club-internet.fr>
6 *
7 * $FreeBSD$
8 */
9
10 #include <gnu/fs/reiserfs/reiserfs_fs.h>
11
12 static vop_access_t reiserfs_access;
13 static vop_bmap_t reiserfs_bmap;
14 static vop_getattr_t reiserfs_getattr;
15 static vop_open_t reiserfs_open;
16 static vop_pathconf_t reiserfs_pathconf;
17 static vop_readlink_t reiserfs_readlink;
18 static vop_strategy_t reiserfs_strategy;
19 static vop_vptofh_t reiserfs_vptofh;
20
21 /* Global vfs data structures for ReiserFS */
22 struct vop_vector reiserfs_vnodeops = {
23 .vop_default = &default_vnodeops,
24
25 .vop_access = reiserfs_access,
26 .vop_bmap = reiserfs_bmap,
27 .vop_cachedlookup = reiserfs_lookup,
28 .vop_getattr = reiserfs_getattr,
29 .vop_inactive = reiserfs_inactive,
30 .vop_lookup = vfs_cache_lookup,
31 .vop_open = reiserfs_open,
32 .vop_reclaim = reiserfs_reclaim,
33 .vop_read = reiserfs_read,
34 .vop_readdir = reiserfs_readdir,
35 .vop_readlink = reiserfs_readlink,
36 .vop_pathconf = reiserfs_pathconf,
37 .vop_strategy = reiserfs_strategy,
38 .vop_vptofh = reiserfs_vptofh,
39 };
40
41 struct vop_vector reiserfs_specops = {
42 .vop_default = &default_vnodeops,
43
44 .vop_access = reiserfs_access,
45 .vop_getattr = reiserfs_getattr,
46 .vop_inactive = reiserfs_inactive,
47 .vop_reclaim = reiserfs_reclaim,
48 };
49
50 /* -------------------------------------------------------------------
51 * vnode operations
52 * -------------------------------------------------------------------*/
53
54 static int
55 reiserfs_access(struct vop_access_args *ap)
56 {
57 int error;
58 struct vnode *vp = ap->a_vp;
59 struct reiserfs_node *ip = VTOI(vp);
60 accmode_t accmode = ap->a_accmode;
61
62 /*
63 * Disallow write attempts on read-only file systems; unless the file
64 * is a socket, fifo, or a block or character device resident on the
65 * file system.
66 */
67 if (accmode & VWRITE) {
68 switch (vp->v_type) {
69 case VDIR:
70 case VLNK:
71 case VREG:
72 if (vp->v_mount->mnt_flag & MNT_RDONLY) {
73 reiserfs_log(LOG_DEBUG,
74 "no write access (read-only fs)\n");
75 return (EROFS);
76 }
77 break;
78 default:
79 break;
80 }
81 }
82
83 /* If immutable bit set, nobody gets to write it. */
84 if ((accmode & VWRITE) && (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT))) {
85 reiserfs_log(LOG_DEBUG, "no write access (immutable)\n");
86 return (EPERM);
87 }
88
89 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid,
90 ap->a_accmode, ap->a_cred, NULL);
91 return (error);
92 }
93
94 static int
95 reiserfs_getattr(struct vop_getattr_args *ap)
96 {
97 struct vnode *vp = ap->a_vp;
98 struct vattr *vap = ap->a_vap;
99 struct reiserfs_node *ip = VTOI(vp);
100
101 vap->va_fsid = dev2udev(ip->i_dev);
102 vap->va_fileid = ip->i_number;
103 vap->va_mode = ip->i_mode & ~S_IFMT;
104 vap->va_nlink = ip->i_nlink;
105 vap->va_uid = ip->i_uid;
106 vap->va_gid = ip->i_gid;
107 //XXX vap->va_rdev = ip->i_rdev;
108 vap->va_size = ip->i_size;
109 vap->va_atime = ip->i_atime;
110 vap->va_mtime = ip->i_mtime;
111 vap->va_ctime = ip->i_ctime;
112 vap->va_flags = ip->i_flags;
113 vap->va_gen = ip->i_generation;
114 vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
115 vap->va_bytes = dbtob((u_quad_t)ip->i_blocks);
116 vap->va_type = vp->v_type;
117 //XXX vap->va_filerev = ip->i_modrev;
118
119 return (0);
120 }
121
122 /* Return POSIX pathconf information applicable to ReiserFS filesystems */
123 static int
124 reiserfs_pathconf(struct vop_pathconf_args *ap)
125 {
126 switch (ap->a_name) {
127 case _PC_LINK_MAX:
128 *ap->a_retval = REISERFS_LINK_MAX;
129 return (0);
130 case _PC_NAME_MAX:
131 *ap->a_retval =
132 REISERFS_MAX_NAME(VTOI(ap->a_vp)->i_reiserfs->s_blocksize);
133 return (0);
134 case _PC_PATH_MAX:
135 *ap->a_retval = PATH_MAX;
136 return (0);
137 case _PC_PIPE_BUF:
138 *ap->a_retval = PIPE_BUF;
139 return (0);
140 case _PC_CHOWN_RESTRICTED:
141 *ap->a_retval = 1;
142 return (0);
143 case _PC_NO_TRUNC:
144 *ap->a_retval = 1;
145 return (0);
146 default:
147 return (EINVAL);
148 }
149 }
150
151 static int
152 reiserfs_open(struct vop_open_args *ap)
153 {
154 /* Files marked append-only must be opened for appending. */
155 if ((VTOI(ap->a_vp)->i_flags & APPEND) &&
156 (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE)
157 return (EPERM);
158
159 vnode_create_vobject(ap->a_vp, VTOI(ap->a_vp)->i_size, ap->a_td);
160
161 return (0);
162 }
163
164 /* Return target name of a symbolic link */
165 static int
166 reiserfs_readlink(struct vop_readlink_args *ap)
167 {
168 struct vnode *vp = ap->a_vp;
169
170 reiserfs_log(LOG_DEBUG, "redirect to VOP_READ()\n");
171 return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred));
172 }
173
174 /* Bmap converts the logical block number of a file to its physical
175 * block number on the disk. */
176 static int
177 reiserfs_bmap(ap)
178 struct vop_bmap_args /* {
179 struct vnode *a_vp;
180 daddr_t a_bn;
181 struct bufobj **a_bop;
182 daddr_t *a_bnp;
183 int *a_runp;
184 int *a_runb;
185 } */ *ap;
186 {
187 daddr_t blkno;
188 struct buf *bp;
189 struct cpu_key key;
190 struct item_head *ih;
191
192 struct vnode *vp = ap->a_vp;
193 struct reiserfs_node *ip = VTOI(vp);
194 struct reiserfs_sb_info *sbi = ip->i_reiserfs;
195 INITIALIZE_PATH(path);
196
197 /* Prepare the key to look for the 'block'-th block of file
198 * (XXX we suppose that statfs.f_iosize == sbi->s_blocksize) */
199 make_cpu_key(&key, ip, (off_t)ap->a_bn * sbi->s_blocksize + 1,
200 TYPE_ANY, 3);
201
202 /* Search item */
203 if (search_for_position_by_key(sbi, &key, &path) != POSITION_FOUND) {
204 reiserfs_log(LOG_DEBUG, "position not found\n");
205 pathrelse(&path);
206 return (ENOENT);
207 }
208
209 bp = get_last_bp(&path);
210 ih = get_ih(&path);
211
212 if (is_indirect_le_ih(ih)) {
213 /* Indirect item can be read by the underlying layer, instead of
214 * VOP_STRATEGY. */
215 int i;
216 uint32_t *ind_item = (uint32_t *)B_I_PITEM(bp, ih);
217 reiserfs_log(LOG_DEBUG, "found an INDIRECT item\n");
218 blkno = get_block_num(ind_item, path.pos_in_item);
219
220 /* Read-ahead */
221 if (ap->a_runb) {
222 uint32_t count = 0;
223 for (i = path.pos_in_item - 1; i >= 0; --i) {
224 if ((blkno - get_block_num(ind_item, i)) !=
225 count + 1)
226 break;
227 ++count;
228 }
229
230 /*
231 * This count isn't expressed in DEV_BSIZE base but
232 * in fs' own block base
233 * (see sys/vm/vnode_pager.c:vnode_pager_addr())
234 */
235 *ap->a_runb = count;
236 reiserfs_log(LOG_DEBUG,
237 " read-ahead: %d blocks before\n", *ap->a_runb);
238 }
239 if (ap->a_runp) {
240 uint32_t count = 0;
241 /*
242 * ih is an uint32_t array, that's why we use
243 * its length (in bytes) divided by 4 to know
244 * the number of items
245 */
246 for (i = path.pos_in_item + 1;
247 i < ih_item_len(ih) / 4; ++i) {
248 if ((get_block_num(ind_item, i) - blkno) !=
249 count + 1)
250 break;
251 ++count;
252 }
253
254 /*
255 * This count isn't expressed in DEV_BSIZE base but
256 * in fs' own block base
257 * (see sys/vm/vnode_pager.c:vnode_pager_addr()) */
258 *ap->a_runp = count;
259 reiserfs_log(LOG_DEBUG,
260 " read-ahead: %d blocks after\n", *ap->a_runp);
261 }
262
263 /* Indirect items can be read using the device VOP_STRATEGY */
264 if (ap->a_bop)
265 *ap->a_bop = &VTOI(ap->a_vp)->i_devvp->v_bufobj;
266
267 /* Convert the block number into DEV_BSIZE base */
268 blkno *= btodb(sbi->s_blocksize);
269 } else {
270 /*
271 * Direct item are not DEV_BSIZE aligned, VOP_STRATEGY will
272 * have to handle this case specifically
273 */
274 reiserfs_log(LOG_DEBUG, "found a DIRECT item\n");
275 blkno = ap->a_bn;
276
277 if (ap->a_runp)
278 *ap->a_runp = 0;
279 if (ap->a_runb)
280 *ap->a_runb = 0;
281
282 /* Direct item must be read by reiserfs_strategy */
283 if (ap->a_bop)
284 *ap->a_bop = &vp->v_bufobj;
285 }
286
287 if (ap->a_bnp)
288 *ap->a_bnp = blkno;
289
290 pathrelse(&path);
291
292 if (ap->a_bnp) {
293 reiserfs_log(LOG_DEBUG, "logical block: %ju (%ju),"
294 " physical block: %ju (%ju)\n",
295 (intmax_t)ap->a_bn,
296 (intmax_t)(ap->a_bn / btodb(sbi->s_blocksize)),
297 (intmax_t)*ap->a_bnp,
298 (intmax_t)(*ap->a_bnp / btodb(sbi->s_blocksize)));
299 }
300
301 return (0);
302 }
303
304 /* Does simply the same as reiserfs_read. It's called when reiserfs_bmap find
305 * an direct item. */
306 static int
307 reiserfs_strategy(struct vop_strategy_args /* {
308 struct vnode *a_vp;
309 struct buf *a_bp;
310 } */ *ap)
311 {
312 int error;
313 struct uio auio;
314 struct iovec aiov;
315 struct reiserfs_node *ip;
316 struct buf *bp = ap->a_bp;
317 struct vnode *vp = ap->a_vp;
318
319 reiserfs_log(LOG_DEBUG, "logical block: %ju,"
320 " physical block: %ju\n", (intmax_t)bp->b_lblkno,
321 (intmax_t)bp->b_blkno);
322
323 ip = VTOI(vp);
324
325 if (bp->b_iocmd == BIO_READ) {
326 /* Prepare the uio structure */
327 reiserfs_log(LOG_DEBUG, "prepare uio structure\n");
328 aiov.iov_base = bp->b_data;
329 aiov.iov_len = MIN(bp->b_bcount, ip->i_size);
330 reiserfs_log(LOG_DEBUG, " vector length: %ju\n",
331 (intmax_t)aiov.iov_len);
332
333 auio.uio_iov = &aiov;
334 auio.uio_iovcnt = 1;
335 auio.uio_offset = 0;
336 auio.uio_rw = UIO_READ;
337 auio.uio_segflg = UIO_SYSSPACE;
338 auio.uio_td = curthread;
339 auio.uio_resid = bp->b_bcount;
340 reiserfs_log(LOG_DEBUG, " buffer length: %u\n",
341 auio.uio_resid);
342
343 reiserfs_log(LOG_DEBUG, "reading block #%ju\n",
344 (intmax_t)bp->b_blkno);
345 error = reiserfs_get_block(ip, bp->b_blkno, 0, &auio);
346 } else {
347 /* No write support yet */
348 error = (EOPNOTSUPP);
349 bp->b_error = error;
350 bp->b_ioflags |= BIO_ERROR;
351 }
352
353 if (error) {
354 bp->b_ioflags |= BIO_ERROR;
355 bp->b_error = error;
356 }
357
358 bufdone(bp);
359 return (0);
360 }
361
362 /*
363 * Vnode pointer to File handle
364 */
365 static int
366 reiserfs_vptofh(struct vop_vptofh_args /* {
367 struct vnode *a_vp;
368 struct fid *a_fhp;
369 } */ *ap)
370 {
371 struct rfid *rfhp;
372 struct reiserfs_node *ip;
373
374 ip = VTOI(ap->a_vp);
375 reiserfs_log(LOG_DEBUG,
376 "fill *fhp with inode (dirid=%d, objectid=%d)\n",
377 ip->i_ino, ip->i_number);
378
379 rfhp = (struct rfid *)ap->a_fhp;
380 rfhp->rfid_len = sizeof(struct rfid);
381 rfhp->rfid_dirid = ip->i_ino;
382 rfhp->rfid_objectid = ip->i_number;
383 rfhp->rfid_gen = ip->i_generation;
384
385 reiserfs_log(LOG_DEBUG, "return it\n");
386 return (0);
387 }
Cache object: e5bd86f48f851e5898c91dffd878c16f
|