Skip to content

Commit 5c80c71

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: Btrfs: set i_size properly when fallocating and we already btrfs: unlock on error in btrfs_file_llseek() btrfs: btrfs_permission's RO check shouldn't apply to device nodes Btrfs: truncate pages from clone ioctl target range Btrfs: fix uninitialized sync_pending Btrfs: fix wrong free space information btrfs: memory leak in btrfs_add_inode_defrag() Btrfs: use plain page_address() in header fields setget functions Btrfs: forced readonly when btrfs_drop_snapshot() fails Btrfs: check if there is enough space for balancing smarter Btrfs: fix a bug of balance on full multi-disk partitions Btrfs: fix an oops of log replay Btrfs: detect wether a device supports discard Btrfs: force unplugs when switching from high to regular priority bios
2 parents 01fa4ba + 81d86e1 commit 5c80c71

File tree

9 files changed

+183
-43
lines changed

9 files changed

+183
-43
lines changed

fs/btrfs/ctree.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,17 +1415,15 @@ void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val);
14151415
#define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \
14161416
static inline u##bits btrfs_##name(struct extent_buffer *eb) \
14171417
{ \
1418-
type *p = kmap_atomic(eb->first_page, KM_USER0); \
1418+
type *p = page_address(eb->first_page); \
14191419
u##bits res = le##bits##_to_cpu(p->member); \
1420-
kunmap_atomic(p, KM_USER0); \
14211420
return res; \
14221421
} \
14231422
static inline void btrfs_set_##name(struct extent_buffer *eb, \
14241423
u##bits val) \
14251424
{ \
1426-
type *p = kmap_atomic(eb->first_page, KM_USER0); \
1425+
type *p = page_address(eb->first_page); \
14271426
p->member = cpu_to_le##bits(val); \
1428-
kunmap_atomic(p, KM_USER0); \
14291427
}
14301428

14311429
#define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \
@@ -2367,8 +2365,8 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
23672365
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
23682366
int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
23692367
int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf);
2370-
int btrfs_drop_snapshot(struct btrfs_root *root,
2371-
struct btrfs_block_rsv *block_rsv, int update_ref);
2368+
void btrfs_drop_snapshot(struct btrfs_root *root,
2369+
struct btrfs_block_rsv *block_rsv, int update_ref);
23722370
int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
23732371
struct btrfs_root *root,
23742372
struct extent_buffer *node,

fs/btrfs/extent-tree.c

Lines changed: 59 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1782,18 +1782,26 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
17821782

17831783

17841784
for (i = 0; i < multi->num_stripes; i++, stripe++) {
1785+
if (!stripe->dev->can_discard)
1786+
continue;
1787+
17851788
ret = btrfs_issue_discard(stripe->dev->bdev,
17861789
stripe->physical,
17871790
stripe->length);
17881791
if (!ret)
17891792
discarded_bytes += stripe->length;
17901793
else if (ret != -EOPNOTSUPP)
17911794
break;
1795+
1796+
/*
1797+
* Just in case we get back EOPNOTSUPP for some reason,
1798+
* just ignore the return value so we don't screw up
1799+
* people calling discard_extent.
1800+
*/
1801+
ret = 0;
17921802
}
17931803
kfree(multi);
17941804
}
1795-
if (discarded_bytes && ret == -EOPNOTSUPP)
1796-
ret = 0;
17971805

17981806
if (actual_bytes)
17991807
*actual_bytes = discarded_bytes;
@@ -6269,8 +6277,8 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans,
62696277
* also make sure backrefs for the shared block and all lower level
62706278
* blocks are properly updated.
62716279
*/
6272-
int btrfs_drop_snapshot(struct btrfs_root *root,
6273-
struct btrfs_block_rsv *block_rsv, int update_ref)
6280+
void btrfs_drop_snapshot(struct btrfs_root *root,
6281+
struct btrfs_block_rsv *block_rsv, int update_ref)
62746282
{
62756283
struct btrfs_path *path;
62766284
struct btrfs_trans_handle *trans;
@@ -6283,13 +6291,16 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
62836291
int level;
62846292

62856293
path = btrfs_alloc_path();
6286-
if (!path)
6287-
return -ENOMEM;
6294+
if (!path) {
6295+
err = -ENOMEM;
6296+
goto out;
6297+
}
62886298

62896299
wc = kzalloc(sizeof(*wc), GFP_NOFS);
62906300
if (!wc) {
62916301
btrfs_free_path(path);
6292-
return -ENOMEM;
6302+
err = -ENOMEM;
6303+
goto out;
62936304
}
62946305

62956306
trans = btrfs_start_transaction(tree_root, 0);
@@ -6318,7 +6329,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
63186329
path->lowest_level = 0;
63196330
if (ret < 0) {
63206331
err = ret;
6321-
goto out;
6332+
goto out_free;
63226333
}
63236334
WARN_ON(ret > 0);
63246335

@@ -6425,11 +6436,14 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
64256436
free_extent_buffer(root->commit_root);
64266437
kfree(root);
64276438
}
6428-
out:
6439+
out_free:
64296440
btrfs_end_transaction_throttle(trans, tree_root);
64306441
kfree(wc);
64316442
btrfs_free_path(path);
6432-
return err;
6443+
out:
6444+
if (err)
6445+
btrfs_std_error(root->fs_info, err);
6446+
return;
64336447
}
64346448

64356449
/*
@@ -6720,6 +6734,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
67206734
struct btrfs_space_info *space_info;
67216735
struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;
67226736
struct btrfs_device *device;
6737+
u64 min_free;
6738+
int index;
6739+
int dev_nr = 0;
6740+
int dev_min = 1;
67236741
int full = 0;
67246742
int ret = 0;
67256743

@@ -6729,8 +6747,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
67296747
if (!block_group)
67306748
return -1;
67316749

6750+
min_free = btrfs_block_group_used(&block_group->item);
6751+
67326752
/* no bytes used, we're good */
6733-
if (!btrfs_block_group_used(&block_group->item))
6753+
if (!min_free)
67346754
goto out;
67356755

67366756
space_info = block_group->space_info;
@@ -6746,10 +6766,9 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
67466766
* all of the extents from this block group. If we can, we're good
67476767
*/
67486768
if ((space_info->total_bytes != block_group->key.offset) &&
6749-
(space_info->bytes_used + space_info->bytes_reserved +
6750-
space_info->bytes_pinned + space_info->bytes_readonly +
6751-
btrfs_block_group_used(&block_group->item) <
6752-
space_info->total_bytes)) {
6769+
(space_info->bytes_used + space_info->bytes_reserved +
6770+
space_info->bytes_pinned + space_info->bytes_readonly +
6771+
min_free < space_info->total_bytes)) {
67536772
spin_unlock(&space_info->lock);
67546773
goto out;
67556774
}
@@ -6766,9 +6785,29 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
67666785
if (full)
67676786
goto out;
67686787

6788+
/*
6789+
* index:
6790+
* 0: raid10
6791+
* 1: raid1
6792+
* 2: dup
6793+
* 3: raid0
6794+
* 4: single
6795+
*/
6796+
index = get_block_group_index(block_group);
6797+
if (index == 0) {
6798+
dev_min = 4;
6799+
min_free /= 2;
6800+
} else if (index == 1) {
6801+
dev_min = 2;
6802+
} else if (index == 2) {
6803+
min_free *= 2;
6804+
} else if (index == 3) {
6805+
dev_min = fs_devices->rw_devices;
6806+
min_free /= dev_min;
6807+
}
6808+
67696809
mutex_lock(&root->fs_info->chunk_mutex);
67706810
list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) {
6771-
u64 min_free = btrfs_block_group_used(&block_group->item);
67726811
u64 dev_offset;
67736812

67746813
/*
@@ -6779,7 +6818,11 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
67796818
ret = find_free_dev_extent(NULL, device, min_free,
67806819
&dev_offset, NULL);
67816820
if (!ret)
6821+
dev_nr++;
6822+
6823+
if (dev_nr >= dev_min)
67826824
break;
6825+
67836826
ret = -1;
67846827
}
67856828
}

fs/btrfs/file.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
150150
spin_lock(&root->fs_info->defrag_inodes_lock);
151151
if (!BTRFS_I(inode)->in_defrag)
152152
__btrfs_add_inode_defrag(inode, defrag);
153+
else
154+
kfree(defrag);
153155
spin_unlock(&root->fs_info->defrag_inodes_lock);
154156
return 0;
155157
}
@@ -1638,11 +1640,15 @@ static long btrfs_fallocate(struct file *file, int mode,
16381640

16391641
cur_offset = alloc_start;
16401642
while (1) {
1643+
u64 actual_end;
1644+
16411645
em = btrfs_get_extent(inode, NULL, 0, cur_offset,
16421646
alloc_end - cur_offset, 0);
16431647
BUG_ON(IS_ERR_OR_NULL(em));
16441648
last_byte = min(extent_map_end(em), alloc_end);
1649+
actual_end = min_t(u64, extent_map_end(em), offset + len);
16451650
last_byte = (last_byte + mask) & ~mask;
1651+
16461652
if (em->block_start == EXTENT_MAP_HOLE ||
16471653
(cur_offset >= inode->i_size &&
16481654
!test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
@@ -1655,6 +1661,16 @@ static long btrfs_fallocate(struct file *file, int mode,
16551661
free_extent_map(em);
16561662
break;
16571663
}
1664+
} else if (actual_end > inode->i_size &&
1665+
!(mode & FALLOC_FL_KEEP_SIZE)) {
1666+
/*
1667+
* We didn't need to allocate any more space, but we
1668+
* still extended the size of the file so we need to
1669+
* update i_size.
1670+
*/
1671+
inode->i_ctime = CURRENT_TIME;
1672+
i_size_write(inode, actual_end);
1673+
btrfs_ordered_update_i_size(inode, actual_end, NULL);
16581674
}
16591675
free_extent_map(em);
16601676

@@ -1804,10 +1820,14 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin)
18041820
}
18051821
}
18061822

1807-
if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET))
1808-
return -EINVAL;
1809-
if (offset > inode->i_sb->s_maxbytes)
1810-
return -EINVAL;
1823+
if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) {
1824+
ret = -EINVAL;
1825+
goto out;
1826+
}
1827+
if (offset > inode->i_sb->s_maxbytes) {
1828+
ret = -EINVAL;
1829+
goto out;
1830+
}
18111831

18121832
/* Special lock needed here? */
18131833
if (offset != file->f_pos) {

fs/btrfs/free-space-cache.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,9 +1168,9 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl)
11681168
div64_u64(extent_bytes, (sizeof(struct btrfs_free_space)));
11691169
}
11701170

1171-
static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
1172-
struct btrfs_free_space *info, u64 offset,
1173-
u64 bytes)
1171+
static inline void __bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
1172+
struct btrfs_free_space *info,
1173+
u64 offset, u64 bytes)
11741174
{
11751175
unsigned long start, count;
11761176

@@ -1181,6 +1181,13 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
11811181
bitmap_clear(info->bitmap, start, count);
11821182

11831183
info->bytes -= bytes;
1184+
}
1185+
1186+
static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
1187+
struct btrfs_free_space *info, u64 offset,
1188+
u64 bytes)
1189+
{
1190+
__bitmap_clear_bits(ctl, info, offset, bytes);
11841191
ctl->free_space -= bytes;
11851192
}
11861193

@@ -1984,7 +1991,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
19841991
return 0;
19851992

19861993
ret = search_start;
1987-
bitmap_clear_bits(ctl, entry, ret, bytes);
1994+
__bitmap_clear_bits(ctl, entry, ret, bytes);
19881995

19891996
return ret;
19901997
}
@@ -2039,7 +2046,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
20392046
continue;
20402047
}
20412048
} else {
2042-
20432049
ret = entry->offset;
20442050

20452051
entry->offset += bytes;

fs/btrfs/inode.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7354,11 +7354,15 @@ static int btrfs_set_page_dirty(struct page *page)
73547354
static int btrfs_permission(struct inode *inode, int mask)
73557355
{
73567356
struct btrfs_root *root = BTRFS_I(inode)->root;
7357+
umode_t mode = inode->i_mode;
73577358

7358-
if (btrfs_root_readonly(root) && (mask & MAY_WRITE))
7359-
return -EROFS;
7360-
if ((BTRFS_I(inode)->flags & BTRFS_INODE_READONLY) && (mask & MAY_WRITE))
7361-
return -EACCES;
7359+
if (mask & MAY_WRITE &&
7360+
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) {
7361+
if (btrfs_root_readonly(root))
7362+
return -EROFS;
7363+
if (BTRFS_I(inode)->flags & BTRFS_INODE_READONLY)
7364+
return -EACCES;
7365+
}
73627366
return generic_permission(inode, mask);
73637367
}
73647368

fs/btrfs/ioctl.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2236,6 +2236,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
22362236
btrfs_wait_ordered_range(src, off, len);
22372237
}
22382238

2239+
/* truncate page cache pages from target inode range */
2240+
truncate_inode_pages_range(&inode->i_data, off,
2241+
ALIGN(off + len, PAGE_CACHE_SIZE) - 1);
2242+
22392243
/* clone data */
22402244
key.objectid = btrfs_ino(src);
22412245
key.type = BTRFS_EXTENT_DATA_KEY;

fs/btrfs/tree-log.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -799,14 +799,15 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
799799
struct extent_buffer *eb, int slot,
800800
struct btrfs_key *key)
801801
{
802-
struct inode *dir;
803-
int ret;
804802
struct btrfs_inode_ref *ref;
803+
struct btrfs_dir_item *di;
804+
struct inode *dir;
805805
struct inode *inode;
806-
char *name;
807-
int namelen;
808806
unsigned long ref_ptr;
809807
unsigned long ref_end;
808+
char *name;
809+
int namelen;
810+
int ret;
810811
int search_done = 0;
811812

812813
/*
@@ -909,6 +910,25 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
909910
}
910911
btrfs_release_path(path);
911912

913+
/* look for a conflicting sequence number */
914+
di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir),
915+
btrfs_inode_ref_index(eb, ref),
916+
name, namelen, 0);
917+
if (di && !IS_ERR(di)) {
918+
ret = drop_one_dir_item(trans, root, path, dir, di);
919+
BUG_ON(ret);
920+
}
921+
btrfs_release_path(path);
922+
923+
/* look for a conflicing name */
924+
di = btrfs_lookup_dir_item(trans, root, path, btrfs_ino(dir),
925+
name, namelen, 0);
926+
if (di && !IS_ERR(di)) {
927+
ret = drop_one_dir_item(trans, root, path, dir, di);
928+
BUG_ON(ret);
929+
}
930+
btrfs_release_path(path);
931+
912932
insert:
913933
/* insert our name */
914934
ret = btrfs_add_link(trans, dir, inode, name, namelen, 0,

0 commit comments

Comments
 (0)