2 * Copyright 2000 Hans Reiser
3 * See README for licensing and copyright details
5 * Ported to FreeBSD by Jean-Sébastien Pédron <jspedron@club-internet.fr>
10 #include <gnu/fs/reiserfs/reiserfs_fs.h>
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;
20 /* Global vfs data structures for ReiserFS */
21 struct vop_vector reiserfs_vnodeops = {
22 .vop_default = &default_vnodeops,
24 .vop_access = reiserfs_access,
25 .vop_bmap = reiserfs_bmap,
26 .vop_cachedlookup = reiserfs_lookup,
27 .vop_getattr = reiserfs_getattr,
28 .vop_inactive = reiserfs_inactive,
29 .vop_lookup = vfs_cache_lookup,
30 .vop_open = reiserfs_open,
31 .vop_reclaim = reiserfs_reclaim,
32 .vop_read = reiserfs_read,
33 .vop_readdir = reiserfs_readdir,
34 .vop_readlink = reiserfs_readlink,
35 .vop_pathconf = reiserfs_pathconf,
36 .vop_strategy = reiserfs_strategy,
39 struct vop_vector reiserfs_specops = {
40 .vop_default = &default_vnodeops,
42 .vop_access = reiserfs_access,
43 .vop_getattr = reiserfs_getattr,
44 .vop_inactive = reiserfs_inactive,
45 .vop_reclaim = reiserfs_reclaim,
48 /* -------------------------------------------------------------------
50 * -------------------------------------------------------------------*/
53 reiserfs_access(struct vop_access_args *ap)
56 struct vnode *vp = ap->a_vp;
57 struct reiserfs_node *ip = VTOI(vp);
58 mode_t mode = ap->a_mode;
61 * Disallow write attempts on read-only file systems; unless the file
62 * is a socket, fifo, or a block or character device resident on the
70 if (vp->v_mount->mnt_flag & MNT_RDONLY) {
71 reiserfs_log(LOG_DEBUG,
72 "no write access (read-only fs)\n");
81 /* If immutable bit set, nobody gets to write it. */
82 if ((mode & VWRITE) && (ip->i_flags & (IMMUTABLE | SF_SNAPSHOT))) {
83 reiserfs_log(LOG_DEBUG, "no write access (immutable)\n");
87 error = vaccess(vp->v_type, ip->i_mode, ip->i_uid, ip->i_gid,
88 ap->a_mode, ap->a_cred, NULL);
93 reiserfs_getattr(struct vop_getattr_args *ap)
95 struct vnode *vp = ap->a_vp;
96 struct vattr *vap = ap->a_vap;
97 struct reiserfs_node *ip = VTOI(vp);
99 vap->va_fsid = dev2udev(ip->i_dev);
100 vap->va_fileid = ip->i_number;
101 vap->va_mode = ip->i_mode & ~S_IFMT;
102 vap->va_nlink = ip->i_nlink;
103 vap->va_uid = ip->i_uid;
104 vap->va_gid = ip->i_gid;
105 //XXX vap->va_rdev = ip->i_rdev;
106 vap->va_size = ip->i_size;
107 vap->va_atime = ip->i_atime;
108 vap->va_mtime = ip->i_mtime;
109 vap->va_ctime = ip->i_ctime;
110 vap->va_flags = ip->i_flags;
111 vap->va_gen = ip->i_generation;
112 vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
113 vap->va_bytes = dbtob((u_quad_t)ip->i_blocks);
114 vap->va_type = vp->v_type;
115 //XXX vap->va_filerev = ip->i_modrev;
120 /* Return POSIX pathconf information applicable to ReiserFS filesystems */
122 reiserfs_pathconf(struct vop_pathconf_args *ap)
124 switch (ap->a_name) {
126 *ap->a_retval = REISERFS_LINK_MAX;
130 REISERFS_MAX_NAME(VTOI(ap->a_vp)->i_reiserfs->s_blocksize);
133 *ap->a_retval = PATH_MAX;
136 *ap->a_retval = PIPE_BUF;
138 case _PC_CHOWN_RESTRICTED:
150 reiserfs_open(struct vop_open_args *ap)
152 /* Files marked append-only must be opened for appending. */
153 if ((VTOI(ap->a_vp)->i_flags & APPEND) &&
154 (ap->a_mode & (FWRITE | O_APPEND)) == FWRITE)
157 vnode_create_vobject_off(ap->a_vp, VTOI(ap->a_vp)->i_size, ap->a_td);
162 /* Return target name of a symbolic link */
164 reiserfs_readlink(struct vop_readlink_args *ap)
166 struct vnode *vp = ap->a_vp;
168 reiserfs_log(LOG_DEBUG, "redirect to VOP_READ()\n");
169 return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred));
172 /* Bmap converts the logical block number of a file to its physical
173 * block number on the disk. */
176 struct vop_bmap_args /* {
179 struct bufobj **a_bop;
188 struct item_head *ih;
190 struct vnode *vp = ap->a_vp;
191 struct reiserfs_node *ip = VTOI(vp);
192 struct reiserfs_sb_info *sbi = ip->i_reiserfs;
193 INITIALIZE_PATH(path);
195 /* Prepare the key to look for the 'block'-th block of file
196 * (XXX we suppose that statfs.f_iosize == sbi->s_blocksize) */
197 make_cpu_key(&key, ip, (off_t)ap->a_bn * sbi->s_blocksize + 1,
201 if (search_for_position_by_key(sbi, &key, &path) != POSITION_FOUND) {
202 reiserfs_log(LOG_DEBUG, "position not found\n");
207 bp = get_last_bp(&path);
210 if (is_indirect_le_ih(ih)) {
211 /* Indirect item can be read by the underlying layer, instead of
214 uint32_t *ind_item = (uint32_t *)B_I_PITEM(bp, ih);
215 reiserfs_log(LOG_DEBUG, "found an INDIRECT item\n");
216 blkno = get_block_num(ind_item, path.pos_in_item);
221 for (i = path.pos_in_item - 1; i >= 0; --i) {
222 if ((blkno - get_block_num(ind_item, i)) !=
229 * This count isn't expressed in DEV_BSIZE base but
230 * in fs' own block base
231 * (see sys/vm/vnode_pager.c:vnode_pager_addr())
234 reiserfs_log(LOG_DEBUG,
235 " read-ahead: %d blocks before\n", *ap->a_runb);
240 * ih is an uint32_t array, that's why we use
241 * its length (in bytes) divided by 4 to know
242 * the number of items
244 for (i = path.pos_in_item + 1;
245 i < ih_item_len(ih) / 4; ++i) {
246 if ((get_block_num(ind_item, i) - blkno) !=
253 * This count isn't expressed in DEV_BSIZE base but
254 * in fs' own block base
255 * (see sys/vm/vnode_pager.c:vnode_pager_addr()) */
257 reiserfs_log(LOG_DEBUG,
258 " read-ahead: %d blocks after\n", *ap->a_runp);
261 /* Indirect items can be read using the device VOP_STRATEGY */
263 *ap->a_bop = &VTOI(ap->a_vp)->i_devvp->v_bufobj;
265 /* Convert the block number into DEV_BSIZE base */
266 blkno *= btodb(sbi->s_blocksize);
269 * Direct item are not DEV_BSIZE aligned, VOP_STRATEGY will
270 * have to handle this case specifically
272 reiserfs_log(LOG_DEBUG, "found a DIRECT item\n");
280 /* Direct item must be read by reiserfs_strategy */
282 *ap->a_bop = &vp->v_bufobj;
291 reiserfs_log(LOG_DEBUG, "logical block: %ju (%ju),"
292 " physical block: %ju (%ju)\n",
294 (intmax_t)(ap->a_bn / btodb(sbi->s_blocksize)),
295 (intmax_t)*ap->a_bnp,
296 (intmax_t)(*ap->a_bnp / btodb(sbi->s_blocksize)));
302 /* Does simply the same as reiserfs_read. It's called when reiserfs_bmap find
305 reiserfs_strategy(struct vop_strategy_args /* {
313 struct reiserfs_node *ip;
314 struct buf *bp = ap->a_bp;
315 struct vnode *vp = ap->a_vp;
317 reiserfs_log(LOG_DEBUG, "logical block: %ju,"
318 " physical block: %ju\n", (intmax_t)bp->b_lblkno,
319 (intmax_t)bp->b_blkno);
323 if (bp->b_iocmd == BIO_READ) {
324 /* Prepare the uio structure */
325 reiserfs_log(LOG_DEBUG, "prepare uio structure\n");
326 aiov.iov_base = bp->b_data;
327 aiov.iov_len = MIN(bp->b_bcount, ip->i_size);
328 reiserfs_log(LOG_DEBUG, " vector length: %ju\n",
329 (intmax_t)aiov.iov_len);
331 auio.uio_iov = &aiov;
334 auio.uio_rw = UIO_READ;
335 auio.uio_segflg = UIO_SYSSPACE;
336 auio.uio_td = curthread;
337 auio.uio_resid = bp->b_bcount;
338 reiserfs_log(LOG_DEBUG, " buffer length: %u\n",
341 reiserfs_log(LOG_DEBUG, "reading block #%ju\n",
342 (intmax_t)bp->b_blkno);
343 error = reiserfs_get_block(ip, bp->b_blkno, 0, &auio);
345 /* No write support yet */
346 error = (EOPNOTSUPP);
348 bp->b_ioflags |= BIO_ERROR;