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 12static vop_access_t reiserfs_access; 13static vop_bmap_t reiserfs_bmap; 14static vop_getattr_t reiserfs_getattr; 15static vop_open_t reiserfs_open; 16static vop_pathconf_t reiserfs_pathconf; 17static vop_readlink_t reiserfs_readlink; 18static vop_strategy_t reiserfs_strategy; 19static vop_vptofh_t reiserfs_vptofh; 20 21/* Global vfs data structures for ReiserFS */ 22struct 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 41struct 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 54static int 55reiserfs_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 94static int 95reiserfs_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 */ 123static int 124reiserfs_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 151static int 152reiserfs_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 */ 165static int 166reiserfs_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. */ 176static int 177reiserfs_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. */ 306static int 307reiserfs_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 */ 365static int 366reiserfs_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} 388