diff options
author | David Sterba <dsterba@suse.com> | 2017-07-21 19:15:58 +0200 |
---|---|---|
committer | David Sterba <dsterba@suse.com> | 2017-07-21 19:15:58 +0200 |
commit | 5fb70abd400927134356cb6e4c6330ab3ac15b4b (patch) | |
tree | 752f7e19c2c0685234f8cabaea3845b9ba9d2e75 /fs | |
parent | e166dd52dfa5101e0dad7c828c2cc0c9bd2c36b9 (diff) | |
parent | 6e838efadaa69df728a15448dd7465f472f445ca (diff) |
Merge branch 'dev/gfp-alloc' into for-next-next-v4.14-20170721
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/dev-replace.c | 74 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 20 | ||||
-rw-r--r-- | fs/btrfs/super.c | 15 |
3 files changed, 59 insertions, 50 deletions
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index bee3edeea7a3..7a93a3e1a847 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c @@ -639,11 +639,39 @@ static void btrfs_dev_replace_update_device_in_mapping_tree( write_unlock(&em_tree->lock); } +/* + * Read progress of device replace status according to the state and last + * stored position. The value format is the same as for + * btrfs_dev_replace::progress_1000 + */ +static u64 btrfs_dev_replace_progress(struct btrfs_fs_info *fs_info) +{ + struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; + u64 ret = 0; + + switch (dev_replace->replace_state) { + case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: + case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED: + ret = 0; + break; + case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: + ret = 1000; + break; + case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: + case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: + ret = div64_u64(dev_replace->cursor_left, + div_u64(btrfs_device_get_total_bytes( + dev_replace->srcdev), 1000)); + break; + } + + return ret; +} + void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info, struct btrfs_ioctl_dev_replace_args *args) { struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; - struct btrfs_device *srcdev; btrfs_dev_replace_lock(dev_replace, 0); /* even if !dev_replace_is_valid, the values are good enough for @@ -656,21 +684,7 @@ void btrfs_dev_replace_status(struct btrfs_fs_info *fs_info, atomic64_read(&dev_replace->num_write_errors); args->status.num_uncorrectable_read_errors = atomic64_read(&dev_replace->num_uncorrectable_read_errors); - switch (dev_replace->replace_state) { - case BTRFS_IOCTL_DEV_REPLACE_STATE_NEVER_STARTED: - case BTRFS_IOCTL_DEV_REPLACE_STATE_CANCELED: - args->status.progress_1000 = 0; - break; - case BTRFS_IOCTL_DEV_REPLACE_STATE_FINISHED: - args->status.progress_1000 = 1000; - break; - case BTRFS_IOCTL_DEV_REPLACE_STATE_STARTED: - case BTRFS_IOCTL_DEV_REPLACE_STATE_SUSPENDED: - srcdev = dev_replace->srcdev; - args->status.progress_1000 = div64_u64(dev_replace->cursor_left, - div_u64(btrfs_device_get_total_bytes(srcdev), 1000)); - break; - } + args->status.progress_1000 = btrfs_dev_replace_progress(fs_info); btrfs_dev_replace_unlock(dev_replace, 0); } @@ -795,25 +809,19 @@ static int btrfs_dev_replace_kthread(void *data) { struct btrfs_fs_info *fs_info = data; struct btrfs_dev_replace *dev_replace = &fs_info->dev_replace; - struct btrfs_ioctl_dev_replace_args *status_args; u64 progress; - status_args = kzalloc(sizeof(*status_args), GFP_KERNEL); - if (status_args) { - btrfs_dev_replace_status(fs_info, status_args); - progress = status_args->status.progress_1000; - kfree(status_args); - progress = div_u64(progress, 10); - btrfs_info_in_rcu(fs_info, - "continuing dev_replace from %s (devid %llu) to %s @%u%%", - dev_replace->srcdev->missing ? "<missing disk>" : - rcu_str_deref(dev_replace->srcdev->name), - dev_replace->srcdev->devid, - dev_replace->tgtdev ? - rcu_str_deref(dev_replace->tgtdev->name) : - "<missing target disk>", - (unsigned int)progress); - } + progress = btrfs_dev_replace_progress(fs_info); + progress = div_u64(progress, 10); + btrfs_info_in_rcu(fs_info, + "continuing dev_replace from %s (devid %llu) to %s @%u%%", + dev_replace->srcdev->missing ? "<missing disk>" + : rcu_str_deref(dev_replace->srcdev->name), + dev_replace->srcdev->devid, + dev_replace->tgtdev ? rcu_str_deref(dev_replace->tgtdev->name) + : "<missing target disk>", + (unsigned int)progress); + btrfs_dev_replace_continue_on_mount(fs_info); clear_bit(BTRFS_FS_EXCL_OP, &fs_info->flags); diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 3e744dd17ac5..496e873b14de 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1273,20 +1273,19 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, extent_thresh = SZ_256K; /* - * if we were not given a file, allocate a readahead - * context + * If we were not given a file, allocate a readahead context. As + * readahead is just an optimization, defrag will work without it so + * we don't error out. */ if (!file) { - ra = kzalloc(sizeof(*ra), GFP_NOFS); - if (!ra) - return -ENOMEM; - file_ra_state_init(ra, inode->i_mapping); + ra = kzalloc(sizeof(*ra), GFP_KERNEL); + if (ra) + file_ra_state_init(ra, inode->i_mapping); } else { ra = &file->f_ra; } - pages = kmalloc_array(max_cluster, sizeof(struct page *), - GFP_NOFS); + pages = kmalloc_array(max_cluster, sizeof(struct page *), GFP_KERNEL); if (!pages) { ret = -ENOMEM; goto out_ra; @@ -1364,8 +1363,9 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, if (i + cluster > ra_index) { ra_index = max(i, ra_index); - btrfs_force_ra(inode->i_mapping, ra, file, ra_index, - cluster); + if (ra) + btrfs_force_ra(inode->i_mapping, ra, file, + ra_index, cluster); ra_index += cluster; } diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 9e64e403443b..eb0aeb81d576 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -426,7 +426,7 @@ int btrfs_parse_options(struct btrfs_fs_info *info, char *options, * strsep changes the string, duplicate it because parse_options * gets called twice */ - options = kstrdup(options, GFP_NOFS); + options = kstrdup(options, GFP_KERNEL); if (!options) return -ENOMEM; @@ -952,7 +952,7 @@ static char *get_subvol_name_from_objectid(struct btrfs_fs_info *fs_info, } path->leave_spinning = 1; - name = kmalloc(PATH_MAX, GFP_NOFS); + name = kmalloc(PATH_MAX, GFP_KERNEL); if (!name) { ret = -ENOMEM; goto err; @@ -1339,10 +1339,11 @@ static char *setup_root_args(char *args) char *buf, *dst, *sep; if (!args) - return kstrdup("subvolid=0", GFP_NOFS); + return kstrdup("subvolid=0", GFP_KERNEL); /* The worst case is that we add ",subvolid=0" to the end. */ - buf = dst = kmalloc(strlen(args) + strlen(",subvolid=0") + 1, GFP_NOFS); + buf = dst = kmalloc(strlen(args) + strlen(",subvolid=0") + 1, + GFP_KERNEL); if (!buf) return NULL; @@ -1571,7 +1572,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, * it for searching for existing supers, so this lets us do that and * then open_ctree will properly initialize everything later. */ - fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); + fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_KERNEL); if (!fs_info) { error = -ENOMEM; goto error_sec_opts; @@ -1579,8 +1580,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, fs_info->fs_devices = fs_devices; - fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); - fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); + fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); + fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_KERNEL); security_init_mnt_opts(&fs_info->security_opts); if (!fs_info->super_copy || !fs_info->super_for_commit) { error = -ENOMEM; |