Loading fs/xfs/scrub/attr.c +43 −46 Original line number Diff line number Diff line Loading @@ -31,6 +31,9 @@ xchk_xattr_buf_cleanup( ab->freemap = NULL; kvfree(ab->usedmap); ab->usedmap = NULL; kvfree(ab->value); ab->value = NULL; ab->value_sz = 0; } /* Loading @@ -44,54 +47,45 @@ xchk_setup_xattr_buf( size_t value_size, gfp_t flags) { size_t sz = value_size; size_t bmp_sz; struct xchk_xattr_buf *ab = sc->buf; unsigned long *old_usedmap = NULL; unsigned long *old_freemap = NULL; void *new_val; bmp_sz = sizeof(long) * BITS_TO_LONGS(sc->mp->m_attr_geo->blksize); /* * If there's already a buffer, figure out if we need to reallocate it * to accommodate a larger size. */ if (ab) { if (sz <= ab->sz) return 0; old_freemap = ab->freemap; old_usedmap = ab->usedmap; kvfree(ab); sc->buf = NULL; } if (ab) goto resize_value; /* * Don't zero the buffer upon allocation to avoid runtime overhead. * All users must be careful never to read uninitialized contents. */ ab = kvmalloc(sizeof(*ab) + sz, flags); ab = kvzalloc(sizeof(struct xchk_xattr_buf), flags); if (!ab) return -ENOMEM; ab->sz = sz; sc->buf = ab; sc->buf_cleanup = xchk_xattr_buf_cleanup; if (old_usedmap) { ab->usedmap = old_usedmap; } else { ab->usedmap = kvmalloc(bmp_sz, flags); if (!ab->usedmap) return -ENOMEM; } if (old_freemap) { ab->freemap = old_freemap; } else { ab->freemap = kvmalloc(bmp_sz, flags); if (!ab->freemap) return -ENOMEM; resize_value: if (ab->value_sz >= value_size) return 0; if (ab->value) { kvfree(ab->value); ab->value = NULL; ab->value_sz = 0; } new_val = kvmalloc(value_size, flags); if (!new_val) return -ENOMEM; ab->value = new_val; ab->value_sz = value_size; return 0; } Loading Loading @@ -140,11 +134,24 @@ xchk_xattr_listent( int namelen, int valuelen) { struct xfs_da_args args = { .op_flags = XFS_DA_OP_NOTIME, .attr_filter = flags & XFS_ATTR_NSP_ONDISK_MASK, .geo = context->dp->i_mount->m_attr_geo, .whichfork = XFS_ATTR_FORK, .dp = context->dp, .name = name, .namelen = namelen, .hashval = xfs_da_hashname(name, namelen), .trans = context->tp, .valuelen = valuelen, }; struct xchk_xattr_buf *ab; struct xchk_xattr *sx; struct xfs_da_args args = { NULL }; int error = 0; sx = container_of(context, struct xchk_xattr, context); ab = sx->sc->buf; if (xchk_should_terminate(sx->sc, &error)) { context->seen_enough = error; Loading Loading @@ -182,17 +189,7 @@ xchk_xattr_listent( return; } args.op_flags = XFS_DA_OP_NOTIME; args.attr_filter = flags & XFS_ATTR_NSP_ONDISK_MASK; args.geo = context->dp->i_mount->m_attr_geo; args.whichfork = XFS_ATTR_FORK; args.dp = context->dp; args.name = name; args.namelen = namelen; args.hashval = xfs_da_hashname(args.name, args.namelen); args.trans = context->tp; args.value = xchk_xattr_valuebuf(sx->sc); args.valuelen = valuelen; args.value = ab->value; error = xfs_attr_get_ilocked(&args); /* ENODATA means the hash lookup failed and the attr is bad */ Loading fs/xfs/scrub/attr.h +3 −18 Original line number Diff line number Diff line Loading @@ -16,24 +16,9 @@ struct xchk_xattr_buf { /* Bitmap of free space in xattr leaf blocks. */ unsigned long *freemap; /* Size of @buf, in bytes. */ size_t sz; /* * Memory buffer -- used for extracting attr values while walking the * attributes. */ uint8_t buf[]; /* Memory buffer used to extract xattr values. */ void *value; size_t value_sz; }; /* A place to store attribute values. */ static inline uint8_t * xchk_xattr_valuebuf( struct xfs_scrub *sc) { struct xchk_xattr_buf *ab = sc->buf; return ab->buf; } #endif /* __XFS_SCRUB_ATTR_H__ */ Loading
fs/xfs/scrub/attr.c +43 −46 Original line number Diff line number Diff line Loading @@ -31,6 +31,9 @@ xchk_xattr_buf_cleanup( ab->freemap = NULL; kvfree(ab->usedmap); ab->usedmap = NULL; kvfree(ab->value); ab->value = NULL; ab->value_sz = 0; } /* Loading @@ -44,54 +47,45 @@ xchk_setup_xattr_buf( size_t value_size, gfp_t flags) { size_t sz = value_size; size_t bmp_sz; struct xchk_xattr_buf *ab = sc->buf; unsigned long *old_usedmap = NULL; unsigned long *old_freemap = NULL; void *new_val; bmp_sz = sizeof(long) * BITS_TO_LONGS(sc->mp->m_attr_geo->blksize); /* * If there's already a buffer, figure out if we need to reallocate it * to accommodate a larger size. */ if (ab) { if (sz <= ab->sz) return 0; old_freemap = ab->freemap; old_usedmap = ab->usedmap; kvfree(ab); sc->buf = NULL; } if (ab) goto resize_value; /* * Don't zero the buffer upon allocation to avoid runtime overhead. * All users must be careful never to read uninitialized contents. */ ab = kvmalloc(sizeof(*ab) + sz, flags); ab = kvzalloc(sizeof(struct xchk_xattr_buf), flags); if (!ab) return -ENOMEM; ab->sz = sz; sc->buf = ab; sc->buf_cleanup = xchk_xattr_buf_cleanup; if (old_usedmap) { ab->usedmap = old_usedmap; } else { ab->usedmap = kvmalloc(bmp_sz, flags); if (!ab->usedmap) return -ENOMEM; } if (old_freemap) { ab->freemap = old_freemap; } else { ab->freemap = kvmalloc(bmp_sz, flags); if (!ab->freemap) return -ENOMEM; resize_value: if (ab->value_sz >= value_size) return 0; if (ab->value) { kvfree(ab->value); ab->value = NULL; ab->value_sz = 0; } new_val = kvmalloc(value_size, flags); if (!new_val) return -ENOMEM; ab->value = new_val; ab->value_sz = value_size; return 0; } Loading Loading @@ -140,11 +134,24 @@ xchk_xattr_listent( int namelen, int valuelen) { struct xfs_da_args args = { .op_flags = XFS_DA_OP_NOTIME, .attr_filter = flags & XFS_ATTR_NSP_ONDISK_MASK, .geo = context->dp->i_mount->m_attr_geo, .whichfork = XFS_ATTR_FORK, .dp = context->dp, .name = name, .namelen = namelen, .hashval = xfs_da_hashname(name, namelen), .trans = context->tp, .valuelen = valuelen, }; struct xchk_xattr_buf *ab; struct xchk_xattr *sx; struct xfs_da_args args = { NULL }; int error = 0; sx = container_of(context, struct xchk_xattr, context); ab = sx->sc->buf; if (xchk_should_terminate(sx->sc, &error)) { context->seen_enough = error; Loading Loading @@ -182,17 +189,7 @@ xchk_xattr_listent( return; } args.op_flags = XFS_DA_OP_NOTIME; args.attr_filter = flags & XFS_ATTR_NSP_ONDISK_MASK; args.geo = context->dp->i_mount->m_attr_geo; args.whichfork = XFS_ATTR_FORK; args.dp = context->dp; args.name = name; args.namelen = namelen; args.hashval = xfs_da_hashname(args.name, args.namelen); args.trans = context->tp; args.value = xchk_xattr_valuebuf(sx->sc); args.valuelen = valuelen; args.value = ab->value; error = xfs_attr_get_ilocked(&args); /* ENODATA means the hash lookup failed and the attr is bad */ Loading
fs/xfs/scrub/attr.h +3 −18 Original line number Diff line number Diff line Loading @@ -16,24 +16,9 @@ struct xchk_xattr_buf { /* Bitmap of free space in xattr leaf blocks. */ unsigned long *freemap; /* Size of @buf, in bytes. */ size_t sz; /* * Memory buffer -- used for extracting attr values while walking the * attributes. */ uint8_t buf[]; /* Memory buffer used to extract xattr values. */ void *value; size_t value_sz; }; /* A place to store attribute values. */ static inline uint8_t * xchk_xattr_valuebuf( struct xfs_scrub *sc) { struct xchk_xattr_buf *ab = sc->buf; return ab->buf; } #endif /* __XFS_SCRUB_ATTR_H__ */