/*
- * fsys_xfs.c - an implementation for the SGI XFS file system
+ * fs_xfs.c - an implementation for the SGI XFS file system
*
- * Copyright (C) 2001 Ethan Benson
+ * Copyright (C) 2001, 2002 Ethan Benson
*
* Adapted from Grub
*
- * Copyright (C) 2001 Serguei Tzukanov
+ * Copyright (C) 2001 Serguei Tzukanov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "types.h"
#include "fs.h"
#include "xfs/xfs.h"
#include "errors.h"
+#include "debug.h"
+#include "bootinfo.h"
#define SECTOR_BITS 9
int xfs_dir (char *dirname);
/* Exported in struct fs_t */
-static int xfs_open(struct boot_file_t *file, const char *dev_name,
- struct partition_t *part, const char *file_name);
+static int xfs_open(struct boot_file_t *file,
+ struct partition_t *part, struct boot_fspec_t *fspec);
static int xfs_read(struct boot_file_t *file, unsigned int size, void *buffer);
static int xfs_seek(struct boot_file_t *file, unsigned int newpos);
static int xfs_close(struct boot_file_t *file);
struct boot_file_t *xfs_file;
static char FSYS_BUF[32768];
-__u64 partition_offset;
+uint64_t partition_offset;
int errnum;
static int
-xfs_open(struct boot_file_t *file, const char *dev_name,
- struct partition_t *part, const char *file_name)
+xfs_open(struct boot_file_t *file,
+ struct partition_t *part, struct boot_fspec_t *fspec)
{
static char buffer[1024];
if (part)
{
DEBUG_F("Determining offset for partition %d\n", part->part_number);
- partition_offset = ((__u64)(part->part_start)) * ((__u64)part->blocksize);
+ partition_offset = ((uint64_t) part->part_start) * part->blocksize;
DEBUG_F("%Lu = %lu * %hu\n", partition_offset,
part->part_start,
part->blocksize);
else
partition_offset = 0;
- sprintf(buffer, "%s:%d", dev_name, 0); /* 0 is full disk in OF */
+ strncpy(buffer, fspec->dev, 1020);
+ if (_machine != _MACH_bplan)
+ strcat(buffer, ":0"); /* 0 is full disk in (non-buggy) OF */
DEBUG_F("Trying to open dev_name=%s; filename=%s; partition offset=%Lu\n",
- buffer, file_name, partition_offset);
+ buffer, fspec->file, partition_offset);
file->of_device = prom_open(buffer);
if (file->of_device == PROM_INVALID_HANDLE || file->of_device == NULL)
DEBUG_F("%p was successfully opened\n", file->of_device);
xfs_file = file;
-
+
if (xfs_mount() != 1)
{
DEBUG_F("Couldn't open XFS @ %s/%Lu\n", buffer, partition_offset);
return FILE_ERR_BAD_FSYS;
}
- DEBUG_F("Attempting to open %s\n", file_name);
- strcpy(buffer, file_name); /* xfs_dir modifies argument */
+ DEBUG_F("Attempting to open %s\n", fspec->file);
+ strcpy(buffer, fspec->file); /* xfs_dir modifies argument */
if(!xfs_dir(buffer))
{
DEBUG_F("xfs_dir() failed. errnum = %d\n", errnum);
return errnum;
}
- DEBUG_F("Successfully opened %s\n", file_name);
+ DEBUG_F("Successfully opened %s\n", fspec->file);
DEBUG_LEAVE(FILE_ERR_OK);
return FILE_ERR_OK;
}
static int
-read_disk_block(struct boot_file_t *file, __u32 block, __u32 start,
- __u32 length, void *buf)
+read_disk_block(struct boot_file_t *file, uint64_t block, int start,
+ int length, void *buf)
{
- unsigned long long pos = block * 512;
+ uint64_t pos = block * 512;
pos += partition_offset + start;
- DEBUG_F("Reading %u bytes, starting at block %u, disk offset %Lu\n",
+ DEBUG_F("Reading %d bytes, starting at block %Lu, disk offset %Lu\n",
length, block, pos);
if (!prom_lseek(file->of_device, pos)) {
DEBUG_F("prom_lseek failed\n");
}
/* XFS is big endian, powerpc is big endian */
-
-static inline __const__ __uint16_t
-le16 (__uint16_t x)
-{
- return x;
-}
-
-static inline __const__ __uint32_t
-le32 (__uint32_t x)
-{
- return x;
-}
-
-static inline __const__ __uint64_t
-le64 (__uint64_t x)
-{
- return x;
-}
+#define le16(x) (x)
+#define le32(x) (x)
+#define le64(x) (x)
static xfs_fsblock_t
xt_start (xfs_bmbt_rec_32_t *r)
{
- return (((xfs_fsblock_t)(le32 (r->l1) & mask32lo(9))) << 43) |
+ return (((xfs_fsblock_t)(le32 (r->l1) & mask32lo(9))) << 43) |
(((xfs_fsblock_t)le32 (r->l2)) << 11) |
(((xfs_fsblock_t)le32 (r->l3)) >> 21);
}
++name;
++namelen;
sfe = (xfs_dir2_sf_entry_t *)
- (inode->di_u.di_c
+ (inode->di_u.di_c
+ sizeof(xfs_dir2_sf_hdr_t)
- xfs.i8param);
break;
offset = xad->offset;
xadlen = xad->len;
if (isinxt (xfs_file->pos >> xfs.blklog, offset, xadlen)) {
- endofcur = (offset + xadlen) << xfs.blklog;
+ endofcur = (offset + xadlen) << xfs.blklog;
toread = (endofcur >= endpos)
? len : (endofcur - xfs_file->pos);
read_disk_block(xfs_file, fsb2daddr (xad->start),
}
continue;
}
- endofprev = offset + xadlen;
+ endofprev = offset + xadlen;
}
return xfs_file->pos - startpos;
}
}
-/*
+/*
* Local variables:
- * c-file-style: "K&R"
+ * c-file-style: "k&r"
* c-basic-offset: 8
* End:
*/