/* * NAME: jfs_statfs(vfsp, sfsp, crp) * * FUNCTION: get file system status <sfsp> from vfs <vfsp> * * PARAMETER: vfsp - virtual file system * sfsp - file status information structure * crp - credential * * RETURN: zero on success, non-zero on failure * * serialization: statfs() and extendfs() serializes by inode lock * of the inode map for both inode map and block allocation map. * All other access to fragment allocation map is serialized * under VMM locking. * * note: percolation of file system information: * support struct statfs (sys/statfs.h) for get file system status * service call statfs(). * (XPG4.2 defines struct statvfs in sys/statvfs.h for statvfs() * which requires statfs() and additional information) */ jfs_statfs( register struct vfs *vfsp, register struct statfs *statfsp, struct ucred *crp) { register int32 rc; register inode_t *ipmnt; /* mount inode */ inode_t *ipimap, *ipbmap; cbuf_t *bpsuper; struct superblock *sb = NULL; int32 fsck_length, log_length; NOISE(1,("jfs_statfs: vfs:0x%08x\n", vfsp)); /* * get the file system stats from the superblock */ ipimap = (struct inode *)vfsp->vfs_data; ipmnt = ipimap->i_ipmnt; if (rc = readSuper(ipmnt, &bpsuper)) goto out; sb = (struct superblock *)(bpsuper->cm_cdata); /* bcopy(sb->s_fname, statfsp->f_fname, sizeof(sb->s_fname)); */ bcopy(sb->s_fpack, statfsp->f_fpack, sizeof(sb->s_fpack)); statfsp->f_bsize = PSIZE; /* preferred i/o block size */ statfsp->f_fsize = sb->s_bsize; /* fundamental block size */ fsck_length = lengthPXD(&(sb->s_fsckpxd)); log_length = lengthPXD(&(sb->s_logpxd)); rawRelease(bpsuper); /* statfs()/extendfs() serialized by inode lock of the inode map * for both inode map and block allocation map. */ IREAD_LOCK(ipimap); /* * get the block stats from the bmap */ ipbmap = ipmnt->i_ipbmap; statfsp->f_blocks = (ipbmap->i_bmap->db_mapsize + fsck_length + log_length) >> ipbmap->i_bmap->db_l2nbperpage; statfsp->f_bfree = statfsp->f_bavail = ipbmap->i_bmap->db_nfree >> ipbmap->i_bmap->db_l2nbperpage; /* * get the file stats from the ipimap */ statfsp->f_files = ipimap->i_imap->im_numinos; statfsp->f_ffree = ipimap->i_imap->im_numfree; /* * fill in from vfs */ statfsp->f_fsid = vfsp->vfs_fsid; statfsp->f_vfstype = MNT_XJFS; statfsp->f_vfsnumber = vfsp->vfs_number; statfsp->f_name_max = JFS_NAME_MAX; /* * fields in the statfs structure that we don't fill in ... * long f_version; version/type of statfs, 0 for now long f_type; type of info, 0 for now long f_vfsoff; reserved, for vfs specific data offset long f_vfslen; reserved, for len of vfs specific data long f_vfsvers; reserved, for vers of vfs specific data */ out: IREAD_UNLOCK(ipimap); return rc; }
/* * NAME: dasd_write * * FUNCTION: Write to direct access file descriptor * * PARAMETERS: * offset - Starting byte offset for write request * pdata - Starting address of user data buffer * plen - On entry, number of bytes to be write * On exit, number of bytes actually write * vfsp - pointer to vfs structure * * RETURNS: 0 for success; Other indicates failure */ int32 dasd_write( int64 offset, caddr_t pdata, int64 *plen, struct vfs *vfsp) { int64 blocknum; cbuf_t *bp; dio_t *dp; inode_t *dummy_inode; int64 erroff; int64 fbytes; int64 lbytes; int64 mbytes; int64 nbytes = *plen; int32 rc; dummy_inode = getDummyInode(vfsp); /* If offset does not start on sector boundary, calculate number of * bytes in first partial sector. */ if (offset & (vfsp->vfs_bsize - 1)) { fbytes = MIN(nbytes, CM_BSIZE - (offset & CM_OFFSET)); nbytes -= fbytes; } else fbytes = 0; /* If write does not end on sector boundary, calculate number of * bytes in last sector */ if (nbytes & vfsp->vfs_bsize - 1) lbytes = nbytes & CM_OFFSET; else lbytes = 0; mbytes = nbytes - lbytes; nbytes = 0; /* Now counting bytes actually written */ /* First (partial) block */ if (fbytes) { if (rc = rawRead(dummy_inode, offset, &bp)) goto out1; if (rc = copyin(pdata, bp->cm_cdata+(offset & CM_OFFSET), fbytes)) { rawRelease(bp); goto out1; } if (rc = rawWrite(dummy_inode, bp, 1)) goto out1; nbytes = fbytes; offset += fbytes; pdata += fbytes; } /* Write full sectors */ if (mbytes) { blocknum = offset >> dummy_inode->i_l2pbsize; if (rc = dioStart(dummy_inode, &dp)) goto out1; (void) dioWrite(dp, blocknum, mbytes, offset, pdata, 0); if (rc = dioEnd(dp, &erroff)) { nbytes += (erroff - offset); goto out1; } nbytes += mbytes; offset += mbytes; pdata += mbytes; } /* Write last (partial) block */ if (lbytes) { if (rc = rawRead(dummy_inode, offset, &bp)) goto out1; if (rc = copyin(pdata, bp->cm_cdata, lbytes)) { rawRelease(bp); goto out1; } if (rc = rawWrite(dummy_inode, bp, 1)) goto out1; nbytes = +lbytes; } out1: releDummyInode(dummy_inode); *plen = nbytes; return (rc); }