]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
Make xfs_repair support > 512 byte sector sizes properly
authorBarry Naujok <bnaujok@sgi.com>
Thu, 19 Jul 2007 16:04:12 +0000 (16:04 +0000)
committerBarry Naujok <bnaujok@sgi.com>
Thu, 19 Jul 2007 16:04:12 +0000 (16:04 +0000)
Merge of master-melb:xfs-cmds:29181a by kenmcd.

  Fix up SET_COUNT macro

include/libxfs.h
include/libxlog.h
libxlog/xfs_log_recover.c
repair/phase2.c
repair/xfs_repair.c

index b55c72dc3bfbe8fd55f5af48604e1cb84408e109..1c0a62ed62afdf0d66ebce12940f316811399f2d 100644 (file)
@@ -243,9 +243,9 @@ enum xfs_buf_flags_t {      /* b_flags bits */
 #define XFS_BUF_COUNT(bp)              ((bp)->b_bcount)
 #define XFS_BUF_TARGET(bp)             ((bp)->b_dev)
 #define XFS_BUF_SET_PTR(bp,p,cnt)      ((bp)->b_addr = (char *)(p)); \
-                                               XFS_BUF_SETCOUNT(bp,cnt)
+                                               XFS_BUF_SET_COUNT(bp,cnt)
 #define XFS_BUF_SET_ADDR(bp,blk)       ((bp)->b_blkno = (blk))
-#define XFS_BUF_SETCOUNT(bp,cnt)       ((bp)->b_bcount = (cnt))
+#define XFS_BUF_SET_COUNT(bp,cnt)      ((bp)->b_bcount = (cnt))
 
 #define XFS_BUF_FSPRIVATE(bp,type)     ((type)(bp)->b_fsprivate)
 #define XFS_BUF_SET_FSPRIVATE(bp,val)  (bp)->b_fsprivate = (void *)(val)
@@ -512,7 +512,7 @@ extern int  libxfs_bmap_finish (xfs_trans_t **, xfs_bmap_free_t *,
 extern void    libxfs_bmap_cancel(xfs_bmap_free_t *);
 extern int     libxfs_bmap_next_offset (xfs_trans_t *, xfs_inode_t *,
                                xfs_fileoff_t *, int);
-extern int     libxfs_bmap_last_offset(xfs_trans_t *, xfs_inode_t *, 
+extern int     libxfs_bmap_last_offset(xfs_trans_t *, xfs_inode_t *,
                                xfs_fileoff_t *, int);
 extern int     libxfs_bunmapi (xfs_trans_t *, xfs_inode_t *, xfs_fileoff_t,
                                xfs_filblks_t, int, xfs_extnum_t,
index 2717d38da109dc27443c34843176850a867e3e64..f7f14f9979182e2c83b237b7e02ab732fe8d3d85 100644 (file)
@@ -44,6 +44,8 @@ typedef struct log {
        int             l_grant_write_cycle;    /* */
        int             l_grant_write_bytes;    /* */
        uint            l_sectbb_log;   /* log2 of sector size in bbs */
+       uint            l_sectbb_mask;  /* sector size (in BBs)
+                                        * alignment mask */
 } xlog_t;
 
 #include <xfs/xfs_log_recover.h>
@@ -79,13 +81,6 @@ extern void xlog_warn(char *fmt,...);
 extern void xlog_exit(char *fmt,...);
 extern void xlog_panic(char *fmt,...);
 
-#define xlog_get_bp(log,bbs)   libxfs_getbufr(x.logdev, (xfs_daddr_t)-1, (bbs))
-#define xlog_put_bp(bp)                libxfs_putbufr(bp)
-#define xlog_bread(log,blkno,bbs,bp)   \
-       (libxfs_readbufr(x.logdev,      \
-                       (log)->l_logBBstart+(blkno), bp, (bbs), 1), 0)
-#define xlog_align(log,blkno,nbblks,bp)        XFS_BUF_PTR(bp)
-
 #define kmem_zalloc(size, foo)                 calloc(size,1)
 #define kmem_alloc(size, foo)                  calloc(size,1)
 #define kmem_free(ptr, foo)                    free(ptr)
@@ -99,6 +94,10 @@ extern int   print_record_header;
 /* libxfs parameters */
 extern libxfs_init_t   x;
 
+extern struct xfs_buf *xlog_get_bp(xlog_t *, int);
+extern void     xlog_put_bp(struct xfs_buf *);
+extern int      xlog_bread(xlog_t *, xfs_daddr_t, int, struct xfs_buf *);
+
 extern int  xlog_find_zeroed(xlog_t *log, xfs_daddr_t *blk_no);
 extern int  xlog_find_cycle_start(xlog_t *log, xfs_buf_t *bp,
                xfs_daddr_t first_blk, xfs_daddr_t *last_blk, uint cycle);
index b26b0e1ca7d04f52e08c2e70850f6e217aabe9ec..91a1a50b869873fd5bf20abea2dbd19236564db1 100644 (file)
 #define xlog_clear_stale_blocks(log, tail_lsn)         (0)
 #define xfs_readonly_buftarg(buftarg)                  (0)
 
+
+/*
+ * Sector aligned buffer routines for buffer create/read/write/access
+ */
+
+#define XLOG_SECTOR_ROUNDUP_BBCOUNT(log, bbs)  \
+       ( ((log)->l_sectbb_mask && (bbs & (log)->l_sectbb_mask)) ? \
+       ((bbs + (log)->l_sectbb_mask + 1) & ~(log)->l_sectbb_mask) : (bbs) )
+#define XLOG_SECTOR_ROUNDDOWN_BLKNO(log, bno)  ((bno) & ~(log)->l_sectbb_mask)
+
+xfs_buf_t *
+xlog_get_bp(
+       xlog_t          *log,
+       int             num_bblks)
+{
+       ASSERT(num_bblks > 0);
+
+       if (log->l_sectbb_log) {
+               if (num_bblks > 1)
+                       num_bblks += XLOG_SECTOR_ROUNDUP_BBCOUNT(log, 1);
+               num_bblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, num_bblks);
+       }
+       return libxfs_getbufr(log->l_dev, (xfs_daddr_t)-1, num_bblks);
+}
+
+void
+xlog_put_bp(
+       xfs_buf_t       *bp)
+{
+       libxfs_putbufr(bp);
+}
+
+
+/*
+ * nbblks should be uint, but oh well.  Just want to catch that 32-bit length.
+ */
+int
+xlog_bread(
+       xlog_t          *log,
+       xfs_daddr_t     blk_no,
+       int             nbblks,
+       xfs_buf_t       *bp)
+{
+       if (log->l_sectbb_log) {
+               blk_no = XLOG_SECTOR_ROUNDDOWN_BLKNO(log, blk_no);
+               nbblks = XLOG_SECTOR_ROUNDUP_BBCOUNT(log, nbblks);
+       }
+
+       ASSERT(nbblks > 0);
+       ASSERT(BBTOB(nbblks) <= XFS_BUF_SIZE(bp));
+       ASSERT(bp);
+
+       XFS_BUF_SET_ADDR(bp, log->l_logBBstart + blk_no);
+       XFS_BUF_SET_COUNT(bp, BBTOB(nbblks));
+
+       return libxfs_readbufr(log->l_dev, XFS_BUF_ADDR(bp), bp, nbblks, 0);
+}
+
+
+static xfs_caddr_t
+xlog_align(
+       xlog_t          *log,
+       xfs_daddr_t     blk_no,
+       int             nbblks,
+       xfs_buf_t       *bp)
+{
+       xfs_caddr_t     ptr;
+
+       if (!log->l_sectbb_log)
+               return XFS_BUF_PTR(bp);
+
+       ptr = XFS_BUF_PTR(bp) + BBTOB((int)blk_no & log->l_sectbb_mask);
+       ASSERT(XFS_BUF_SIZE(bp) >=
+               BBTOB(nbblks + (blk_no & log->l_sectbb_mask)));
+       return ptr;
+}
+
+
 /*
  * This routine finds (to an approximation) the first block in the physical
  * log which contains the given cycle.  It uses a binary search algorithm.
index e9adef25dc2eee74019257e82b18f2e7cc6712b0..d4ceceafaafc14f3c5948107670163f2048ed23d 100644 (file)
@@ -50,6 +50,16 @@ zero_log(xfs_mount_t *mp)
        log.l_logBBsize = x.logBBsize;
        log.l_logBBstart = x.logBBstart;
        log.l_mp = mp;
+       if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) {
+               log.l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
+               ASSERT(log.l_sectbb_log <= mp->m_sectbb_log);
+               /* for larger sector sizes, must have v2 or external log */
+               ASSERT(log.l_sectbb_log == 0 ||
+                       log.l_logBBstart == 0 ||
+                       XFS_SB_VERSION_HASLOGV2(&mp->m_sb));
+               ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT);
+       }
+       log.l_sectbb_mask = (1 << log.l_sectbb_log) - 1;
 
        if ((error = xlog_find_tail(&log, &head_blk, &tail_blk, 0))) {
                do_warn(_("zero_log: cannot find log head/tail "
index 7013b378ce1163a7a0386cf63c126019ec4dd0af..dd5b6247b67fdbc91cb24f0284fa2c7843e96f53 100644 (file)
@@ -266,7 +266,6 @@ process_args(int argc, char **argv)
                case 't':
                        report_interval = (int) strtol(optarg, 0, 0);
                        break;
-
                case '?':
                        usage();
                }
@@ -497,7 +496,8 @@ main(int argc, char **argv)
        }
 
        /* prepare the mount structure */
-       sbp = libxfs_readbuf(x.ddev, XFS_SB_DADDR, 1, 0);
+       sbp = libxfs_readbuf(x.ddev, XFS_SB_DADDR,
+                               1 << (XFS_MAX_SECTORSIZE_LOG - BBSHIFT), 0);
        memset(&xfs_m, 0, sizeof(xfs_mount_t));
        sb = &xfs_m.m_sb;
        libxfs_xlate_sb(XFS_BUF_PTR(sbp), sb, 1, XFS_SB_ALL_BITS);
@@ -511,6 +511,7 @@ main(int argc, char **argv)
                exit(1);
        }
        libxfs_putbuf(sbp);
+       libxfs_purgebuf(sbp);
 
        /*
         * set XFS-independent status vars from the mount/sb structure