int xfs_readlink( struct xfs_inode *ip, char *link) { struct xfs_mount *mp = ip->i_mount; xfs_fsize_t pathlen; int error = 0; trace_xfs_readlink(ip); if (XFS_FORCED_SHUTDOWN(mp)) return XFS_ERROR(EIO); xfs_ilock(ip, XFS_ILOCK_SHARED); pathlen = ip->i_d.di_size; if (!pathlen) goto out; if (pathlen < 0 || pathlen > MAXPATHLEN) { xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)", __func__, (unsigned long long) ip->i_ino, (long long) pathlen); ASSERT(0); error = XFS_ERROR(EFSCORRUPTED); goto out; } if (ip->i_df.if_flags & XFS_IFINLINE) { memcpy(link, ip->i_df.if_u1.if_data, pathlen); link[pathlen] = '\0'; } else { error = xfs_readlink_bmap(ip, link); } out: xfs_iunlock(ip, XFS_ILOCK_SHARED); return error; }
int xfs_readlink( struct xfs_inode *ip, char *link) { struct xfs_mount *mp = ip->i_mount; xfs_fsize_t pathlen; int error = 0; trace_xfs_readlink(ip); ASSERT(!(ip->i_df.if_flags & XFS_IFINLINE)); if (XFS_FORCED_SHUTDOWN(mp)) return -EIO; xfs_ilock(ip, XFS_ILOCK_SHARED); pathlen = ip->i_d.di_size; if (!pathlen) goto out; if (pathlen < 0 || pathlen > XFS_SYMLINK_MAXLEN) { xfs_alert(mp, "%s: inode (%llu) bad symlink length (%lld)", __func__, (unsigned long long) ip->i_ino, (long long) pathlen); ASSERT(0); error = -EFSCORRUPTED; goto out; } error = xfs_readlink_bmap_ilocked(ip, link); out: xfs_iunlock(ip, XFS_ILOCK_SHARED); return error; }