Add more vmalloc fallbacks to memory allocations
David Sterba
maintainercover Add more vmalloc fallbacks to memory allocations
Hi,
inspired by a recent fix where we tried to kmalloc a 64k nodesize buffer, without the vmalloc fallback, and failed. This series add the "kmalloc-first and vmalloc-fallback" logic to more places, namely to the buffers used during send. If the memory is not fragmented, kmalloc succeeds and does not take the resources required for the mappings.
----------------------------------------------------------------
The following changes since commit 56f23fdbb600e6087db7b009775b95ce07cc3195:
Btrfs: fix file/data loss caused by fsync after rename and new inode (2016-04-06 17:01:44 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux.git dev/kvalloc
for you to fetch changes up to c3e3930516c4d14ed1d6d70964fbc4f3faa36844:
btrfs: clone: use vmalloc only as fallback for nodesize bufer (2016-04-11 19:06:39 +0200)
----------------------------------------------------------------
David Sterba (6):
btrfs: send: use vmalloc only as fallback for send_buf
btrfs: send: use vmalloc only as fallback for read_buf
btrfs: send: use temporary variable to store allocation size
btrfs: send: use vmalloc only as fallback for clone_roots
btrfs: send: use vmalloc only as fallback for clone_sources_tmp
btrfs: clone: use vmalloc only as fallback for nodesize bufer
fs/btrfs/ioctl.c | 13 ++++++++----- fs/btrfs/send.c | 56 +++++++++++++++++++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 26 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-
David Sterba
maintainerPATCH 1/6 btrfs: send: use vmalloc only as fallback for send_buf
--- fs/btrfs/send.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
fs/btrfs/send.c +7 -4
@@ -6022,10 +6022,13 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) sctx->clone_roots_cnt = arg->clone_sources_count; sctx->send_max_size =BTRFS_SEND_BUF_SIZE ; - sctx->send_buf =vmalloc (sctx->send_max_size); + sctx->send_buf =kmalloc (sctx->send_max_size,GFP_KERNEL | __GFP_NOWARN);if (!sctx->send_buf) { - ret = -ENOMEM ; - goto out; + sctx->send_buf =vmalloc (sctx->send_max_size); +if (!sctx->send_buf) { + ret = -ENOMEM ; + goto out; + } } sctx->read_buf =vmalloc (BTRFS_SEND_READ_SIZE );
@@ -6214,7 +6217,7 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)fput (sctx->send_filp);vfree (sctx->clone_roots); -vfree (sctx->send_buf); +kvfree (sctx->send_buf);vfree (sctx->read_buf);name_cache_free (sctx);
Signature · 6 lines
2.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-
David Sterba
maintainerPATCH 2/6 btrfs: send: use vmalloc only as fallback for read_buf
In reply to David Sterba--- fs/btrfs/send.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
fs/btrfs/send.c +7 -4
@@ -6031,10 +6031,13 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) } } - sctx->read_buf =vmalloc (BTRFS_SEND_READ_SIZE ); + sctx->read_buf =kmalloc (BTRFS_SEND_READ_SIZE ,GFP_KERNEL | __GFP_NOWARN);if (!sctx->read_buf) { - ret = -ENOMEM ; - goto out; + sctx->read_buf =vmalloc (BTRFS_SEND_READ_SIZE ); +if (!sctx->read_buf) { + ret = -ENOMEM ; + goto out; + } } sctx->pending_dir_moves =RB_ROOT ;
@@ -6218,7 +6221,7 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)vfree (sctx->clone_roots);kvfree (sctx->send_buf); -vfree (sctx->read_buf); +kvfree (sctx->read_buf);name_cache_free (sctx);
Signature · 6 lines
2.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-
David Sterba
maintainerPATCH 3/6 btrfs: send: use temporary variable to store allocation size
In reply to David SterbaWe're going to use the argument multiple times later.
--- fs/btrfs/send.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
fs/btrfs/send.c +8 -6
@@ -5939,6 +5939,7 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)u32 i;u64 *clone_sources_tmp =NULL ;int clone_sources_to_rollback =0 ; +unsigned alloc_size;int sort_clone_roots =0 ;int index;
@@ -6044,24 +6045,25 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) sctx->waiting_dir_moves =RB_ROOT ; sctx->orphan_dirs =RB_ROOT ; - sctx->clone_roots =vzalloc (sizeof (struct clone_root ) * - (arg->clone_sources_count +1 )); + alloc_size =sizeof (struct clone_root ) * (arg->clone_sources_count +1 ); + + sctx->clone_roots =vzalloc (alloc_size);if (!sctx->clone_roots) { ret = -ENOMEM ; goto out; } + alloc_size = arg->clone_sources_count *sizeof (*arg->clone_sources); +if (arg->clone_sources_count) { - clone_sources_tmp =vmalloc (arg->clone_sources_count * -sizeof (*arg->clone_sources)); + clone_sources_tmp =vmalloc (alloc_size);if (!clone_sources_tmp) { ret = -ENOMEM ; goto out; } ret =copy_from_user (clone_sources_tmp, arg->clone_sources, - arg->clone_sources_count * -sizeof (*arg->clone_sources)); + alloc_size);if (ret) { ret = -EFAULT ; goto out;
Signature · 6 lines
2.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-
David Sterba
maintainerPATCH 4/6 btrfs: send: use vmalloc only as fallback for clone_roots
In reply to David Sterba--- fs/btrfs/send.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
fs/btrfs/send.c +7 -4
@@ -6047,10 +6047,13 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) alloc_size =sizeof (struct clone_root ) * (arg->clone_sources_count +1 ); - sctx->clone_roots =vzalloc (alloc_size); + sctx->clone_roots =kzalloc (alloc_size,GFP_KERNEL | __GFP_NOWARN);if (!sctx->clone_roots) { - ret = -ENOMEM ; - goto out; + sctx->clone_roots =vzalloc (alloc_size); +if (!sctx->clone_roots) { + ret = -ENOMEM ; + goto out; + } } alloc_size = arg->clone_sources_count *sizeof (*arg->clone_sources);
@@ -6221,7 +6224,7 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)if (sctx->send_filp)fput (sctx->send_filp); -vfree (sctx->clone_roots); +kvfree (sctx->clone_roots);kvfree (sctx->send_buf);kvfree (sctx->read_buf);
Signature · 6 lines
2.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-
David Sterba
maintainerPATCH 5/6 btrfs: send: use vmalloc only as fallback for clone_sources_tmp
In reply to David Sterba--- fs/btrfs/send.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
fs/btrfs/send.c +8 -5
@@ -6059,10 +6059,13 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) alloc_size = arg->clone_sources_count *sizeof (*arg->clone_sources);if (arg->clone_sources_count) { - clone_sources_tmp =vmalloc (alloc_size); + clone_sources_tmp =kmalloc (alloc_size,GFP_KERNEL | __GFP_NOWARN);if (!clone_sources_tmp) { - ret = -ENOMEM ; - goto out; + clone_sources_tmp =vmalloc (alloc_size); +if (!clone_sources_tmp) { + ret = -ENOMEM ; + goto out; + } } ret = copy_from_user(clone_sources_tmp, arg->clone_sources,
@@ -6100,7 +6103,7 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_) sctx->clone_roots[i].root = clone_root; clone_sources_to_rollback = i +1 ; } -vfree (clone_sources_tmp); +kvfree (clone_sources_tmp); clone_sources_tmp =NULL ; }
@@ -6218,7 +6221,7 @@ long btrfs_ioctl_send(struct file *mnt_file, void __user *arg_)btrfs_root_dec_send_in_progress (sctx->parent_root);kfree (arg); -vfree (clone_sources_tmp); +kvfree (clone_sources_tmp);if (sctx) {if (sctx->send_filp)
Signature · 6 lines
2.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-
David Sterba
maintainerPATCH 6/6 btrfs: clone: use vmalloc only as fallback for nodesize bufer
In reply to David Sterba--- fs/btrfs/ioctl.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
fs/btrfs/ioctl.c +8 -5
@@ -3468,13 +3468,16 @@ static int btrfs_clone(struct inode *src, struct inode *inode,u64 last_dest_end = destoff; ret = -ENOMEM ; - buf =vmalloc (root->nodesize); -if (!buf) -return ret; + buf =kmalloc (root->nodesize,GFP_KERNEL | __GFP_NOWARN); +if (!buf) { + buf =vmalloc (root->nodesize); +if (!buf) +return ret; + } path =btrfs_alloc_path ();if (!path) { -vfree (buf); +kvfree (buf);return ret; }
@@ -3775,7 +3778,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, out:btrfs_free_path (path); -vfree (buf); +kvfree (buf);return ret; }
Signature · 6 lines
2.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-