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,55 +847,55 @@ pagebuf_associate_memory( ...@@ -843,55 +847,55 @@ 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))
goto fail;
bp = pagebuf_allocate(0);
if (unlikely(bp == NULL))
goto fail;
_pagebuf_initialize(bp, target, 0, len, PBF_FORCEIO);
try_again:
data = kmem_alloc(malloc_len, KM_SLEEP);
if (unlikely(data == NULL))
goto fail_free_buf;
/* check whether alignment matches.. */
if ((__psunsigned_t)data !=
((__psunsigned_t)data & ~target->pbr_smask)) {
/* .. else double the size and try again */
kmem_free(data, malloc_len);
malloc_len <<= 1;
goto try_again;
}
error = pagebuf_associate_memory(bp, data, len);
if (error)
goto fail_free_mem;
bp->pb_flags |= (_PBF_MEM_ALLOCATED | _PBF_MEM_SLAB);
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; return NULL;
pb = pagebuf_allocate(flags);
if (!pb)
return NULL;
_pagebuf_initialize(pb, target, 0, len, flags);
do {
if (tlen == 0) {
tlen = len; /* first time */
} else {
kfree(rmem); /* free the mem from the previous try */
tlen <<= 1; /* double the size and try again */
}
if ((rmem = kmalloc(tlen, GFP_KERNEL)) == 0) {
pagebuf_free(pb);
return NULL;
}
} 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);
return pb;
} }
/* /*
* 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