Commit 04806257 authored by Christoph Hellwig's avatar Christoph Hellwig

[XFS] use kmem_alloc for noaddr buffers

SGI Modid: xfs-linux:xfs-kern:167609a
parent 347f6162
...@@ -334,10 +334,14 @@ pagebuf_free( ...@@ -334,10 +334,14 @@ pagebuf_free(
if (pb->pb_flags & _PBF_MEM_ALLOCATED) { if (pb->pb_flags & _PBF_MEM_ALLOCATED) {
if (pb->pb_pages) { if (pb->pb_pages) {
/* release the pages in the address list */ if (pb->pb_flags & _PBF_MEM_SLAB) {
if ((pb->pb_pages[0]) && /*
(pb->pb_flags & _PBF_MEM_SLAB)) { * XXX: bp->pb_count_desired might be incorrect
kfree(pb->pb_addr); * (see pagebuf_associate_memory for details),
* but fortunately the Linux version of
* kmem_free ignores the len argument..
*/
kmem_free(pb->pb_addr, pb->pb_count_desired);
} else { } else {
_pagebuf_freepages(pb); _pagebuf_freepages(pb);
} }
...@@ -843,54 +847,54 @@ pagebuf_associate_memory( ...@@ -843,54 +847,54 @@ pagebuf_associate_memory(
return 0; return 0;
} }
page_buf_t * xfs_buf_t *
pagebuf_get_no_daddr( pagebuf_get_no_daddr(
size_t len, size_t len,
pb_target_t *target) xfs_buftarg_t *target)
{ {
int rval; size_t malloc_len = len;
void *rmem = NULL; xfs_buf_t *bp;
page_buf_flags_t flags = PBF_FORCEIO; void *data;
page_buf_t *pb; int error;
size_t tlen = 0;
if (unlikely(len > 0x20000)) if (unlikely(len > 0x20000))
return NULL; goto fail;
pb = pagebuf_allocate(flags); bp = pagebuf_allocate(0);
if (!pb) if (unlikely(bp == NULL))
return NULL; goto fail;
_pagebuf_initialize(bp, target, 0, len, PBF_FORCEIO);
_pagebuf_initialize(pb, target, 0, len, flags);
try_again:
do { data = kmem_alloc(malloc_len, KM_SLEEP);
if (tlen == 0) { if (unlikely(data == NULL))
tlen = len; /* first time */ goto fail_free_buf;
} else {
kfree(rmem); /* free the mem from the previous try */ /* check whether alignment matches.. */
tlen <<= 1; /* double the size and try again */ if ((__psunsigned_t)data !=
} ((__psunsigned_t)data & ~target->pbr_smask)) {
if ((rmem = kmalloc(tlen, GFP_KERNEL)) == 0) { /* .. else double the size and try again */
pagebuf_free(pb); kmem_free(data, malloc_len);
return NULL; malloc_len <<= 1;
} goto try_again;
} while ((size_t)rmem != ((size_t)rmem & ~target->pbr_smask));
if ((rval = pagebuf_associate_memory(pb, rmem, len)) != 0) {
kfree(rmem);
pagebuf_free(pb);
return NULL;
} }
/* otherwise pagebuf_free just ignores it */
pb->pb_flags |= (_PBF_MEM_ALLOCATED | _PBF_MEM_SLAB);
PB_CLEAR_OWNER(pb);
up(&pb->pb_sema); /* Return unlocked pagebuf */
PB_TRACE(pb, "no_daddr", rmem); error = pagebuf_associate_memory(bp, data, len);
if (error)
goto fail_free_mem;
bp->pb_flags |= (_PBF_MEM_ALLOCATED | _PBF_MEM_SLAB);
return pb; pagebuf_unlock(bp);
}
PB_TRACE(bp, "no_daddr", data);
return bp;
fail_free_mem:
kmem_free(data, malloc_len);
fail_free_buf:
pagebuf_free(bp);
fail:
return NULL;
}
/* /*
* pagebuf_hold * pagebuf_hold
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment