/* * Read a directory. */ int xfs_readdir( xfs_inode_t *dp, void *dirent, size_t bufsize, xfs_off_t *offset, filldir_t filldir) { int rval; /* return value */ int v; /* type-checking value */ trace_xfs_readdir(dp); if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return XFS_ERROR(EIO); ASSERT(S_ISDIR(dp->i_d.di_mode)); XFS_STATS_INC(xs_dir_getdents); if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_getdents(dp, dirent, offset, filldir); else if ((rval = xfs_dir2_isblock(NULL, dp, &v))) ; else if (v) rval = xfs_dir2_block_getdents(dp, dirent, offset, filldir); else rval = xfs_dir2_leaf_getdents(dp, dirent, bufsize, offset, filldir); return rval; }
/* * Read a directory. */ int xfs_dir_getdents( xfs_trans_t *tp, xfs_inode_t *dp, uio_t *uio, /* caller's buffer control */ int *eofp) /* out: eof reached */ { int alignment; /* alignment required for ABI */ xfs_dirent_t *dbp; /* malloc'ed buffer */ xfs_dir2_put_t put; /* entry formatting routine */ int rval; /* return value */ int v; /* type-checking value */ ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); XFS_STATS_INC(xs_dir_getdents); /* * If our caller has given us a single contiguous aligned memory buffer, * just work directly within that buffer. If it's in user memory, * lock it down first. */ alignment = sizeof(xfs_off_t) - 1; if ((uio->uio_iovcnt == 1) && (((__psint_t)uio->uio_iov[0].iov_base & alignment) == 0) && ((uio->uio_iov[0].iov_len & alignment) == 0)) { dbp = NULL; put = xfs_dir2_put_dirent64_direct; } else { dbp = kmem_alloc(sizeof(*dbp) + MAXNAMELEN, KM_SLEEP); put = xfs_dir2_put_dirent64_uio; } *eofp = 0; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_getdents(dp, uio, eofp, dbp, put); else if ((rval = xfs_dir2_isblock(tp, dp, &v))) ; else if (v) rval = xfs_dir2_block_getdents(tp, dp, uio, eofp, dbp, put); else rval = xfs_dir2_leaf_getdents(tp, dp, uio, eofp, dbp, put); if (dbp != NULL) kmem_free(dbp, sizeof(*dbp) + MAXNAMELEN); return rval; }
/* * Read a directory. */ int xfs_readdir( xfs_inode_t *dp, void *dirent, size_t bufsize, xfs_off_t *offset, filldir_t filldir) { int rval; /* return value */ int v; /* type-checking value */ if (!(dp->i_d.di_mode & S_IFDIR)) return XFS_ERROR(ENOTDIR); //TODO: find suitable replacement //trace_xfs_readdir(dp); //TODO: handle shutdown? if (XFS_FORCED_SHUTDOWN(dp->i_mount)) return XFS_ERROR(EIO); ASSERT((dp->i_d.di_mode & S_IFMT) == S_IFDIR); //TODO: do we need this? XFS_STATS_INC(xs_dir_getdents); if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_getdents(dp, dirent, offset, filldir); else if ((rval = xfs_dir2_isblock(NULL, dp, &v))) ; else if (v) rval = xfs_dir2_block_getdents(dp, dirent, offset, filldir); else rval = xfs_dir2_leaf_getdents(dp, dirent, bufsize, offset, filldir); return rval; }