Hi Tim,
There is another problem in XFS recovery on non-XFS native
endian machines.
xlog_recover_do_inode_buffer () {
....
logged_nextp = (xfs_agino_t *)
((char *)(item->ri_buf[item_index].i_addr) +
(next_unlinked_offset -reg_buf_offset));
...
buffer_nextp = (xfs_agino_t *)xfs_buf_offset(bp,
next_unlinked_offset);
INT_SET(*buffer_nextp, ARCH_CONVERT, *logged_nextp);
}
Please note that all the fields in the log (rather all the data in the
log) is already converted into proper endian format. However,
INT_SET(*buffer_nextp, ARCH_CONVERT, *logged_nextp);
converts it again which is wrong. It should be ARCH_NOCONVERT here.
Here is why, then we don't see any problem in recovery:
xlog_recover_process_iunlinks ()
...
} else {
xlog_recover_clear_agi_bucket(mp, agno,
bucket);
agino = NULLAGINO;
}
This code assumes that if you detect any bad inode, just clear off the
AGI unlinked tree. I have seen this code been hit in recovery. It has
potential of loosing the inode and corresponding data blocks forever.
The xfs_logprint shows CLEAR_AGI_BUCKET after recovery once in a while.
The code assumes this to be bad inode. However, the truth is that most
of the time this has been done because of double native conversion.
I have patch for it on pretty old build (2.6.7) and, hence, not submitting.
Regards,
Shailendra
Timothy Shimmin wrote:
The change here is to allow a dirty log XFS filesystem be replayed on a same
endian machine but of different word size (eg. i386 and x86_64).
--Tim
inode items and EFI/EFDs have different ondisk format for 32bit and 64bit
kernels
allow recovery to handle both versions and do the necessary decoding
Date: Wed May 24 15:09:04 AEST 2006
Workarea: snort.melbourne.sgi.com:/home/tes/isms/xfs-linux-3264
Inspected by: nathans@xxxxxxx
The following file(s) were checked into:
longdrop.melbourne.sgi.com:/isms/xfs-kern/xfs-linux-melb
Modid: xfs-linux-melb:xfs-kern:26011a
xfs_extfree_item.h - 1.21 - changed
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/>
xfs_extfree_item.h.diff?r1=text&tr1=1.21&r2=text&tr2=1.20&f=h
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/xfs_extfree_item.h.diff?r1=text&tr1=1.21&r2=text&tr2=1.20&f=h
- 32 and 64 bit variants of the EFIs and EFDs format structures.
At the moment, the EFD format variants are just used to test if the
data on recovery is of a valid size.
xfs_extfree_item.c - 1.63 - changed
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/>
xfs_extfree_item.c.diff?r1=text&tr1=1.63&r2=text&tr2=1.62&f=h
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/xfs_extfree_item.c.diff?r1=text&tr1=1.63&r2=text&tr2=1.62&f=h
- Code to convert the 32 bit and 64 bit versions of EFIs to the native
version.
We don't convert the EFDs extents because their extents are never
used.
xfs_inode_item.c - 1.126 - changed
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/>
xfs_inode_item.c.diff?r1=text&tr1=1.126&r2=text&tr2=1.125&f=h
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/xfs_inode_item.c.diff?r1=text&tr1=1.126&r2=text&tr2=1.125&f=h
- Code to convert the 32 bit and 64 bit versions of inode_log_format
structures.
xfs_inode_item.h - 1.48 - changed
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/>
xfs_inode_item.h.diff?r1=text&tr1=1.48&r2=text&tr2=1.47&f=h
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/xfs_inode_item.h.diff?r1=text&tr1=1.48&r2=text&tr2=1.47&f=h
- 32 and 64 bit variants of the inode log format structures.
Delete the structure for the v1 variant which was used on IRIX 5.3.
xfs_log_recover.c - 1.308 - changed
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/>
xfs_log_recover.c.diff?r1=text&tr1=1.308&r2=text&tr2=1.307&f=h
http://oss.sgi.com/cgi-bin/cvsweb.cgi/xfs-linux/xfs_log_recover.c.diff?r1=text&tr1=1.308&r2=text&tr2=1.307&f=h
- Decode the inode log format structs for recovery.
Decode the EFI log format structs for recovery.
|