From 8d703987407acfcbd992ba4a7926f2d76ca3779c Mon Sep 17 00:00:00 2001 From: Brian Behlendorf Date: Thu, 23 Mar 2017 18:26:50 -0700 Subject: [PATCH] Retry zfs_znode_alloc() in zfs_mknode() For historical reasons zfs_mknode() was written such that it could never fail. This poses a problem for Linux since zfs_znode_alloc() could potentually failure due to low memory. Handle this gracefully by retrying zfs_znode_alloc() until it succeeds, direct reclaim will eventually be able to allocate memory. Reviewed-by: George Melikov Reviewed-by: loli10K Signed-off-by: Brian Behlendorf Closes #5535 Closes #5908 --- module/zfs/zfs_znode.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index 1597940e67..93437afb3b 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -915,7 +915,18 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, dmu_tx_t *tx, cred_t *cr, VERIFY(sa_replace_all_by_template(sa_hdl, sa_attrs, cnt, tx) == 0); if (!(flag & IS_ROOT_NODE)) { - *zpp = zfs_znode_alloc(zfsvfs, db, 0, obj_type, obj, sa_hdl); + /* + * The call to zfs_znode_alloc() may fail if memory is low + * via the call path: alloc_inode() -> inode_init_always() -> + * security_inode_alloc() -> inode_alloc_security(). Since + * the existing code is written such that zfs_mknode() can + * not fail retry until sufficient memory has been reclaimed. + */ + do { + *zpp = zfs_znode_alloc(zfsvfs, db, 0, obj_type, obj, + sa_hdl); + } while (*zpp == NULL); + VERIFY(*zpp != NULL); VERIFY(dzp != NULL); } else {