📄 cdfs_gnodeops.c
字号:
* Since directories cannot be interleaved, datainbuf * and tsize will both equal MAXBSIZE, We are only * interested in bn and offinbuf. */ bn = cdfs_ibmap(gp, lbn, &datainbuf, &offinbuf); datainbuf = MIN(datainbuf, gp->g_size - isodir_offset); bp = bread(dev, bn, fs->fs_ibsize, (struct gnode *)NULL); if (bp->b_flags & B_ERROR) { error = EIO; brelse(bp); goto out; } if (isiso) tmp_iso_dir = (struct iso_dir *) ((unsigned int)bp->b_un.b_addr + offinbuf); else tmp_hsg_dir = (struct hsg_dir *) ((unsigned int)bp->b_un.b_addr + offinbuf); wasdot = 0; tsize = datainbuf; iso_secsize_resid = ISO_SECSIZE;; do { skip_file = 0; switch(fs->fs_format) { case ISO_9660: if (tmp_iso_dir->dir_file_flags&ISO_FLG_DIR) { bcopy(tmp_iso_dir->dir_extent_lsb, iso_convert_int.incoming, sizeof(int)); gen_dir->d_ino = (iso_convert_int.outgoing + tmp_iso_dir->dir_xar) * lbs; if (tmp_iso_dir->dir_name[0] == '\0') { gen_dir->d_namlen = 1; bcopy(".", gen_dir->d_name, 1); gen_dir->d_name[1] = '\0'; wasdot = 1; } else if (wasdot) { gen_dir->d_namlen = 2; bcopy("..", gen_dir->d_name, 2); gen_dir->d_name[2] = '\0'; wasdot = 0; } else { gen_dir->d_namlen = tmp_iso_dir->dir_namelen; bcopy(tmp_iso_dir->dir_name, gen_dir->d_name, tmp_iso_dir->dir_namelen); gen_dir->d_name[tmp_iso_dir->dir_namelen] = '\0'; } } else { int length; /* * If associated file, or volume seq number * does not match file primary volume descriptor * volume sequence number, skip over file. */ if ((tmp_iso_dir->dir_file_flags&ISO_FLG_ASSOC) || tmp_iso_dir->dir_vol_seq_no_lsb != ISOFS_VOLSEQNUM(fs)) { skip_file = 1; length = 0; } /* * Subtract version number if appropriate */ if ((gp->g_mp)->m_flags & M_NOVERSION) { for(length = 0; length < tmp_iso_dir->dir_namelen; length++) if (tmp_iso_dir->dir_name[length] == ';') break; } else length = tmp_iso_dir->dir_namelen; gen_dir->d_ino = diskaddr + isodir_offset; gen_dir->d_namlen = length; bcopy(tmp_iso_dir->dir_name, gen_dir->d_name, length); gen_dir->d_name[length] = '\0'; } isodir_reclen = (unsigned int)tmp_iso_dir->dir_len; tmp_iso_dir = (struct iso_dir *) ((unsigned int)tmp_iso_dir + isodir_reclen); break; default: /* HSG */ if (tmp_hsg_dir->dir_file_flags&ISO_FLG_DIR) { bcopy(tmp_hsg_dir->dir_extent_lsb, iso_convert_int.incoming, sizeof(int)); gen_dir->d_ino = (iso_convert_int.outgoing + tmp_hsg_dir->dir_xar) * lbs; if (tmp_hsg_dir->dir_name[0] == '\0') { gen_dir->d_namlen = 1; bcopy(".", gen_dir->d_name, 1); gen_dir->d_name[1] = '\0'; wasdot = 1; } else if (wasdot) { gen_dir->d_namlen = 2; bcopy("..", gen_dir->d_name, 2); gen_dir->d_name[2] = '\0'; wasdot = 0; } else { gen_dir->d_namlen = tmp_hsg_dir->dir_namelen; bcopy(tmp_hsg_dir->dir_name, gen_dir->d_name, tmp_hsg_dir->dir_namelen); gen_dir->d_name[tmp_hsg_dir->dir_namelen] = '\0'; } } else { int length; /* * If associated file, or volume seq number * does not match file primary volume descriptor * volume sequence number, skip over file. */ if ((tmp_hsg_dir->dir_file_flags&ISO_FLG_ASSOC) || tmp_hsg_dir->dir_vol_seq_no_lsb != ISOFS_VOLSEQNUM(fs)) { skip_file = 1; length = 0; } /* * Subtract version number if appropriate */ if ((gp->g_mp)->m_flags & M_NOVERSION) { for(length = 0; length < tmp_hsg_dir->dir_namelen; length++) if (tmp_hsg_dir->dir_name[length] == ';') break; } else length = tmp_hsg_dir->dir_namelen; gen_dir->d_ino = diskaddr + isodir_offset; gen_dir->d_namlen = length; bcopy(tmp_hsg_dir->dir_name, gen_dir->d_name, length); gen_dir->d_name[length] = '\0'; } isodir_reclen = (unsigned int)tmp_hsg_dir->dir_len; tmp_hsg_dir = (struct hsg_dir *) ((unsigned int)tmp_hsg_dir + isodir_reclen); } /* switch */ if (skip_file) gen_dir->d_reclen = 0; else gen_dir->d_reclen = DIRSIZ(gen_dir); iso_secsize_resid -= gen_dir->d_reclen; isodir_offset += isodir_reclen; tsize -= isodir_reclen; if (tsize <= 0) { gen_dir->d_reclen += iso_secsize_resid; } else if (isodir_offset % ISO_SECSIZE == 0) { gen_dir->d_reclen += iso_secsize_resid; } else if ((isiso && (tmp_iso_dir->dir_len == 0)) || (!isiso && (tmp_hsg_dir->dir_len == 0))) { gen_dir->d_reclen += iso_secsize_resid; isodir_reclen = (ISO_SECSIZE - isodir_offset % ISO_SECSIZE); tsize -= isodir_reclen; isodir_offset += isodir_reclen; if (isiso) tmp_iso_dir = (struct iso_dir *) ((unsigned int)tmp_iso_dir + isodir_reclen); else tmp_hsg_dir = (struct hsg_dir *) ((unsigned int)tmp_hsg_dir + isodir_reclen); } if (isodebug) { printf("ino %d reclen %d namelen %d\nname %s\n", gen_dir->d_ino, gen_dir->d_reclen, gen_dir->d_namlen, gen_dir->d_name); } u.u_error = uiomove(gen_dir, gen_dir->d_reclen, UIO_READ, uio); ubuf_size -= gen_dir->d_reclen; if (isodir_offset % ISO_SECSIZE == 0 || tsize <= 0) { iso_secsize_resid = ISO_SECSIZE; dirblkstotransfer--; } } while (u.u_error == 0 && dirblkstotransfer > 0 && tsize > 0); brelse(bp); } while (u.u_error == 0 && ubuf_size > 0 && dirblkstotransfer > 0); if (error == 0) error = u.u_error;out: KM_FREE(gen_dir, KM_TEMP); return (error);}intcdfs_rlock(gp, ld, cmd, fp) struct gnode *gp; struct flock *ld; int cmd; struct file *fp;{ extern int kernel_locking; /* Sys-V locking: default is kernel */ /* kernel == 1; daemon == 0 */ /* * There are two mechanisms by which iso Sys-V locking * are supported. The default support is kernel based * and the optional support is daemon based, and requires * that nfs is configured and that daemon based locking * has been enabled (via nfssetup). */ if (kernel_locking) { /* kernel based locking */ switch(cmd) { case F_GETLK: /* get region lock */ if (u.u_error = getflck (fp, ld)) { break; } break; default: if (cmd == F_SETLK) { u.u_error = setflck (fp, ld, 0); } else { u.u_error = setflck (fp, ld, 1); } break; } /* End switch */ } else { /* daemon based locking */ u.u_error = klm_drlock (gp, ld, cmd, fp->f_cred); } return (u.u_error); }#ifdef notdef cdfs_biodone(bp)struct buf *bp;{ struct iso_strat *stratp; int ind; extern struct iso_strat iso_strat_begin; for(stratp = iso_strat_begin.strat_forw; stratp != &iso_strat_begin; stratp = stratp->strat_forw) { for (ind = 0; ind < stratp->strat_numbufhdr; ind++) { if ((stratp->strat_bufhdr[ind] == bp) || ((stratp->strat_bufhdr[ind])->b_flags & B_DONE && (stratp->strat_bufhdr[ind])->b_flags & B_BUSY)) { bp->b_un.b_addr = stratp->strat_save_baddr[ind]; if (bp->b_flags & B_ERROR) { stratp->strat_bp->b_flags |= B_ERROR; stratp->strat_bp->b_error = bp->b_error; } brelse(bp); if (--stratp->strat_outstanding == 0) { biodone(stratp->strat_bp); remque(stratp); KM_FREE(stratp, KM_TEMP); return(0); } } } }}cdfs_strategy(bp)struct buf *bp;{ struct buf *tbuf = NULL; int used_buf_headers; struct gnode *gp = bp->b_gp; struct fs *fs; int lbs; int ind; int offset; int total_transfer_size; int bn, lbn, length, amount_transfered; int saveaffinity; struct iso_strat *iso_strat; extern struct iso_strat iso_strat_begin; if (gp == NULL) panic("cdfs_strategy: null gp"); fs = FS(gp); lbs = ISOFS_LBS(fs); offset = bp->b_blkno; if (G_TO_DIR(gp)->iso_dir_file_unit_size) { KM_ALLOC(iso_strat, struct iso_strat *, sizeof(struct iso_strat), KM_TEMP, KM_NOARG); length = ISO_SECSIZE; } else length = bp->b_bcount; total_transfer_size = bp->b_bcount; used_buf_headers = amount_transfered = 0; while (amount_transfered < total_transfer_size) { used_buf_headers++; lbn = offset / lbs; bn = cdfs_setuptransfer(gp, lbn, &ind, &ind, lbs); if (length != bp->b_bcount) { tbuf = geteblk(length); iso_strat->strat_save_baddr[used_buf_headers-1] = tbuf->b_un.b_addr; iso_strat->strat_bufhdr[used_buf_headers - 1] = tbuf; tbuf->b_un.b_addr = (caddr_t) ((unsigned int)bp->b_un.b_addr + amount_transfered); tbuf->b_dev = gp->g_dev; tbuf->b_blkno = bn; tbuf->b_flags |= (bp->b_flags | B_CALL); tbuf->b_iodone = cdfs_biodone; tbuf->b_proc = bp->b_proc; tbuf->b_gp = bp->b_gp; tbuf->b_pfcent = bp->b_pfcent; } else bp->b_blkno = bn; /* * Schedule transfer */ STRATEGY((struct gnode *)NULL, gp->g_dev, (tbuf != NULL ? tbuf : bp), saveaffinity); amount_transfered += length; offset += length; } if (tbuf) { iso_strat->strat_outstanding = iso_strat->strat_numbufhdr = used_buf_headers; iso_strat->strat_bp = bp; insque(iso_strat, &iso_strat_begin); }}#endif notdef
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -