int xfs_readfile_btree(xfs_inode_t *ip, void *buffer, off_t offset, size_t len, int *last_extent) { xfs_extnum_t nextents; xfs_extnum_t extent; xfs_ifork_t *dp; xfs_bmbt_rec_host_t *ep; xfs_bmbt_irec_t rec; xfs_mount_t *mp = ip->i_mount; /* filesystem mount point */ xfs_fsize_t size = ip->i_d.di_size; int error; if (offset >= size) return 0; if (offset + len > size) len = size - offset; dp = XFS_IFORK_PTR(ip, XFS_DATA_FORK); if (!(dp->if_flags & XFS_IFEXTENTS) && (error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK))) return error; nextents = XFS_IFORK_NEXTENTS(ip, XFS_DATA_FORK); for (extent=0; extent<nextents; extent++) { ep = xfs_iext_get_ext(dp, extent); xfs_bmbt_get_all(ep, &rec); if (extent_overlaps_buffer(mp, rec, offset, len)) { error = copy_extent_to_buffer(mp, rec, buffer, offset, len); if (error) return error; } } return len; }
void libxfs_iprint( xfs_inode_t *ip) { struct xfs_icdinode *dip; xfs_bmbt_rec_host_t *ep; xfs_extnum_t i; xfs_extnum_t nextents; printf("Inode %lx\n", (unsigned long)ip); printf(" i_ino %llx\n", (unsigned long long)ip->i_ino); if (ip->i_df.if_flags & XFS_IFEXTENTS) printf("EXTENTS "); printf("\n"); printf(" i_df.if_bytes %d\n", ip->i_df.if_bytes); printf(" i_df.if_u1.if_extents/if_data %lx\n", (unsigned long)ip->i_df.if_u1.if_extents); if (ip->i_df.if_flags & XFS_IFEXTENTS) { nextents = ip->i_df.if_bytes / (uint)sizeof(*ep); for (ep = ip->i_df.if_u1.if_extents, i = 0; i < nextents; i++, ep++) { xfs_bmbt_irec_t rec; xfs_bmbt_get_all(ep, &rec); printf("\t%d: startoff %llu, startblock 0x%llx," " blockcount %llu, state %d\n", i, (unsigned long long)rec.br_startoff, (unsigned long long)rec.br_startblock, (unsigned long long)rec.br_blockcount, (int)rec.br_state); } } printf(" i_df.if_broot %lx\n", (unsigned long)ip->i_df.if_broot); printf(" i_df.if_broot_bytes %x\n", ip->i_df.if_broot_bytes); dip = &ip->i_d; printf("\nOn disk portion\n"); printf(" di_mode %o\n", VFS_I(ip)->i_mode); printf(" di_version %x\n", (uint)dip->di_version); switch (ip->i_d.di_format) { case XFS_DINODE_FMT_LOCAL: printf(" Inline inode\n"); break; case XFS_DINODE_FMT_EXTENTS: printf(" Extents inode\n"); break; case XFS_DINODE_FMT_BTREE: printf(" B-tree inode\n"); break; default: printf(" Other inode\n"); break; } printf(" di_nlink %x\n", VFS_I(ip)->i_nlink); printf(" di_uid %d\n", dip->di_uid); printf(" di_gid %d\n", dip->di_gid); printf(" di_nextents %d\n", dip->di_nextents); printf(" di_size %llu\n", (unsigned long long)dip->di_size); printf(" di_gen %x\n", VFS_I(ip)->i_generation); printf(" di_extsize %d\n", dip->di_extsize); printf(" di_flags %x\n", dip->di_flags); printf(" di_nblocks %llu\n", (unsigned long long)dip->di_nblocks); }
void libxfs_iprint(xfs_inode_t *ip) { xfs_dinode_core_t *dip; xfs_bmbt_rec_t *ep; xfs_extnum_t i; xfs_extnum_t nextents; printf("Inode %p\n", ip); printf(" i_dev %x\n", (uint)ip->i_dev); printf(" i_ino %Lx\n", ip->i_ino); if (ip->i_df.if_flags & XFS_IFEXTENTS) printf("EXTENTS "); printf("\n"); printf(" i_df.if_bytes %d\n", ip->i_df.if_bytes); printf(" i_df.if_u1.if_extents/if_data %p\n", ip->i_df.if_u1.if_extents); if (ip->i_df.if_flags & XFS_IFEXTENTS) { nextents = ip->i_df.if_bytes / (uint)sizeof(*ep); for (ep = ip->i_df.if_u1.if_extents, i = 0; i < nextents; i++, ep++) { xfs_bmbt_irec_t rec; xfs_bmbt_get_all(ep, &rec); printf("\t%d: startoff %Lu, startblock 0x%Lx," " blockcount %Lu, state %d\n", i, (xfs_dfiloff_t)rec.br_startoff, (xfs_dfsbno_t)rec.br_startblock, (xfs_dfilblks_t)rec.br_blockcount, (int)rec.br_state); } } printf(" i_df.if_broot %p\n", ip->i_df.if_broot); printf(" i_df.if_broot_bytes %x\n", ip->i_df.if_broot_bytes); dip = &(ip->i_d); printf("\nOn disk portion\n"); printf(" di_magic %x\n", dip->di_magic); printf(" di_mode %o\n", dip->di_mode); printf(" di_version %x\n", (uint)dip->di_version); switch (ip->i_d.di_format) { case XFS_DINODE_FMT_LOCAL: printf(" Inline inode\n"); break; case XFS_DINODE_FMT_EXTENTS: printf(" Extents inode\n"); break; case XFS_DINODE_FMT_BTREE: printf(" B-tree inode\n"); break; default: printf(" Other inode\n"); break; } printf(" di_nlink %x\n", dip->di_nlink); printf(" di_uid %d\n", dip->di_uid); printf(" di_gid %d\n", dip->di_gid); printf(" di_nextents %d\n", dip->di_nextents); printf(" di_size %Ld\n", dip->di_size); printf(" di_gen %x\n", dip->di_gen); printf(" di_extsize %d\n", dip->di_extsize); printf(" di_flags %x\n", dip->di_flags); printf(" di_nblocks %Ld\n", dip->di_nblocks); }
/* * xfs_get_file_extents() * This routine creates the cononical forms of all the extents * for the given file and returns them to the user. * * RETURNS: * 0 on success * non zero on failure */ int xfs_get_file_extents( sysarg_t sysarg_file_id, sysarg_t sysarg_extents_addr, sysarg_t sysarg_count) { int i, recsize, num_extents = 0; int error = 0; dev_t fs_dev; xfs_ino_t ino; xfs_inode_t *ip; xfs_bmbt_rec_t *ep; xfs_bmbt_irec_t thisrec; grio_bmbt_irec_t *grec; grio_file_id_t fileid; xfs_caddr_t extents, count; if (copy_from_user(&fileid, SYSARG_TO_PTR(sysarg_file_id), sizeof(grio_file_id_t))) { error = -XFS_ERROR(EFAULT); return( error ); } fs_dev = fileid.fs_dev; ino = fileid.ino; /* * Get sysarg arguements */ extents = (xfs_caddr_t)SYSARG_TO_PTR(sysarg_extents_addr); count = (xfs_caddr_t)SYSARG_TO_PTR(sysarg_count); /* * Get the inode */ if (!(ip = xfs_get_inode( fs_dev, ino ))) { error = -XFS_ERROR(ENOENT); if (copy_to_user((xfs_caddr_t)count, &num_extents, sizeof( num_extents))) { error = -XFS_ERROR(EFAULT); } return( error ); } /* * Get the number of extents in the file. */ num_extents = ip->i_d.di_nextents; if (num_extents) { /* * Copy the extents if they exist. */ ASSERT(num_extents < XFS_MAX_INCORE_EXTENTS); /* * Read in the file extents from disk if necessary. */ if (!(ip->i_df.if_flags & XFS_IFEXTENTS)) { error = xfs_iread_extents(NULL, ip, XFS_DATA_FORK); if (error) { goto out; } } recsize = sizeof(grio_bmbt_irec_t) * num_extents; grec = kmem_alloc(recsize, KM_SLEEP ); ep = ip->i_df.if_u1.if_extents; ASSERT( ep ); for (i = 0; i < num_extents; i++, ep++) { /* * copy extent numbers; */ xfs_bmbt_get_all(ep, &thisrec); grec[i].br_startoff = thisrec.br_startoff; grec[i].br_startblock = thisrec.br_startblock; grec[i].br_blockcount = thisrec.br_blockcount; } if (copy_to_user((xfs_caddr_t)extents, grec, recsize )) { error = -XFS_ERROR(EFAULT); } kmem_free(grec, recsize); } /* * copy out to user space along with count. */ if (copy_to_user((xfs_caddr_t)count, &num_extents, sizeof( num_extents))) { error = -XFS_ERROR(EFAULT); } out: xfs_iunlock( ip, XFS_ILOCK_SHARED ); IRELE( ip ); return( error ); }