瀏覽代碼

dm verity fec: fix GFP flags used with mempool_alloc()

mempool_alloc() cannot fail for GFP_NOIO allocation, so there is no
point testing for failure.

One place the code tested for failure was passing "0" as the GFP
flags.  This is most unusual and is probably meant to be GFP_NOIO,
so that is changed.

Also, allocation from ->extra_pool and ->prealloc_pool are repeated
before releasing the previous allocation.  This can deadlock if the code
is servicing a write under high memory pressure.  To avoid deadlocks,
change these to use GFP_NOWAIT and leave the error handling in place.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
NeilBrown 8 年之前
父節點
當前提交
34c96507e8
共有 1 個文件被更改,包括 5 次插入16 次删除
  1. 5 16
      drivers/md/dm-verity-fec.c

+ 5 - 16
drivers/md/dm-verity-fec.c

@@ -308,19 +308,14 @@ static int fec_alloc_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio)
 {
 {
 	unsigned n;
 	unsigned n;
 
 
-	if (!fio->rs) {
-		fio->rs = mempool_alloc(v->fec->rs_pool, 0);
-		if (unlikely(!fio->rs)) {
-			DMERR("failed to allocate RS");
-			return -ENOMEM;
-		}
-	}
+	if (!fio->rs)
+		fio->rs = mempool_alloc(v->fec->rs_pool, GFP_NOIO);
 
 
 	fec_for_each_prealloc_buffer(n) {
 	fec_for_each_prealloc_buffer(n) {
 		if (fio->bufs[n])
 		if (fio->bufs[n])
 			continue;
 			continue;
 
 
-		fio->bufs[n] = mempool_alloc(v->fec->prealloc_pool, GFP_NOIO);
+		fio->bufs[n] = mempool_alloc(v->fec->prealloc_pool, GFP_NOWAIT);
 		if (unlikely(!fio->bufs[n])) {
 		if (unlikely(!fio->bufs[n])) {
 			DMERR("failed to allocate FEC buffer");
 			DMERR("failed to allocate FEC buffer");
 			return -ENOMEM;
 			return -ENOMEM;
@@ -332,22 +327,16 @@ static int fec_alloc_bufs(struct dm_verity *v, struct dm_verity_fec_io *fio)
 		if (fio->bufs[n])
 		if (fio->bufs[n])
 			continue;
 			continue;
 
 
-		fio->bufs[n] = mempool_alloc(v->fec->extra_pool, GFP_NOIO);
+		fio->bufs[n] = mempool_alloc(v->fec->extra_pool, GFP_NOWAIT);
 		/* we can manage with even one buffer if necessary */
 		/* we can manage with even one buffer if necessary */
 		if (unlikely(!fio->bufs[n]))
 		if (unlikely(!fio->bufs[n]))
 			break;
 			break;
 	}
 	}
 	fio->nbufs = n;
 	fio->nbufs = n;
 
 
-	if (!fio->output) {
+	if (!fio->output)
 		fio->output = mempool_alloc(v->fec->output_pool, GFP_NOIO);
 		fio->output = mempool_alloc(v->fec->output_pool, GFP_NOIO);
 
 
-		if (!fio->output) {
-			DMERR("failed to allocate FEC page");
-			return -ENOMEM;
-		}
-	}
-
 	return 0;
 	return 0;
 }
 }