diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/backref.c | 48 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 1 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 9 | ||||
-rw-r--r-- | fs/btrfs/file.c | 62 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 52 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 8 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 2 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 5 | ||||
-rw-r--r-- | fs/debugfs/inode.c | 69 | ||||
-rw-r--r-- | fs/dlm/user.c | 1 | ||||
-rw-r--r-- | fs/ext4/extents.c | 2 | ||||
-rw-r--r-- | fs/ext4/ialloc.c | 10 | ||||
-rw-r--r-- | fs/ext4/inode.c | 39 | ||||
-rw-r--r-- | fs/ext4/super.c | 1 | ||||
-rw-r--r-- | fs/fcntl.c | 4 | ||||
-rw-r--r-- | fs/fuse/dir.c | 51 | ||||
-rw-r--r-- | fs/lockd/clntlock.c | 13 | ||||
-rw-r--r-- | fs/lockd/clntproc.c | 5 | ||||
-rw-r--r-- | fs/namei.c | 10 | ||||
-rw-r--r-- | fs/nfs/inode.c | 11 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 8 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 2 | ||||
-rw-r--r-- | fs/nfs/super.c | 4 | ||||
-rw-r--r-- | fs/nfsd/nfs4proc.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 5 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 5 | ||||
-rw-r--r-- | fs/ocfs2/refcounttree.c | 5 | ||||
-rw-r--r-- | fs/open.c | 2 | ||||
-rw-r--r-- | fs/reiserfs/procfs.c | 99 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_dinode.h | 3 | ||||
-rw-r--r-- | fs/xfs/xfs_inode.c | 31 | ||||
-rw-r--r-- | fs/xfs/xfs_log_recover.c | 13 |
34 files changed, 305 insertions, 282 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index eaf133384a8f..8bc5e8ccb091 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -36,16 +36,23 @@ static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb, | |||
36 | u64 extent_item_pos, | 36 | u64 extent_item_pos, |
37 | struct extent_inode_elem **eie) | 37 | struct extent_inode_elem **eie) |
38 | { | 38 | { |
39 | u64 data_offset; | 39 | u64 offset = 0; |
40 | u64 data_len; | ||
41 | struct extent_inode_elem *e; | 40 | struct extent_inode_elem *e; |
42 | 41 | ||
43 | data_offset = btrfs_file_extent_offset(eb, fi); | 42 | if (!btrfs_file_extent_compression(eb, fi) && |
44 | data_len = btrfs_file_extent_num_bytes(eb, fi); | 43 | !btrfs_file_extent_encryption(eb, fi) && |
44 | !btrfs_file_extent_other_encoding(eb, fi)) { | ||
45 | u64 data_offset; | ||
46 | u64 data_len; | ||
45 | 47 | ||
46 | if (extent_item_pos < data_offset || | 48 | data_offset = btrfs_file_extent_offset(eb, fi); |
47 | extent_item_pos >= data_offset + data_len) | 49 | data_len = btrfs_file_extent_num_bytes(eb, fi); |
48 | return 1; | 50 | |
51 | if (extent_item_pos < data_offset || | ||
52 | extent_item_pos >= data_offset + data_len) | ||
53 | return 1; | ||
54 | offset = extent_item_pos - data_offset; | ||
55 | } | ||
49 | 56 | ||
50 | e = kmalloc(sizeof(*e), GFP_NOFS); | 57 | e = kmalloc(sizeof(*e), GFP_NOFS); |
51 | if (!e) | 58 | if (!e) |
@@ -53,7 +60,7 @@ static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb, | |||
53 | 60 | ||
54 | e->next = *eie; | 61 | e->next = *eie; |
55 | e->inum = key->objectid; | 62 | e->inum = key->objectid; |
56 | e->offset = key->offset + (extent_item_pos - data_offset); | 63 | e->offset = key->offset + offset; |
57 | *eie = e; | 64 | *eie = e; |
58 | 65 | ||
59 | return 0; | 66 | return 0; |
@@ -189,7 +196,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, | |||
189 | struct extent_buffer *eb; | 196 | struct extent_buffer *eb; |
190 | struct btrfs_key key; | 197 | struct btrfs_key key; |
191 | struct btrfs_file_extent_item *fi; | 198 | struct btrfs_file_extent_item *fi; |
192 | struct extent_inode_elem *eie = NULL; | 199 | struct extent_inode_elem *eie = NULL, *old = NULL; |
193 | u64 disk_byte; | 200 | u64 disk_byte; |
194 | 201 | ||
195 | if (level != 0) { | 202 | if (level != 0) { |
@@ -223,6 +230,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, | |||
223 | 230 | ||
224 | if (disk_byte == wanted_disk_byte) { | 231 | if (disk_byte == wanted_disk_byte) { |
225 | eie = NULL; | 232 | eie = NULL; |
233 | old = NULL; | ||
226 | if (extent_item_pos) { | 234 | if (extent_item_pos) { |
227 | ret = check_extent_in_eb(&key, eb, fi, | 235 | ret = check_extent_in_eb(&key, eb, fi, |
228 | *extent_item_pos, | 236 | *extent_item_pos, |
@@ -230,18 +238,20 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, | |||
230 | if (ret < 0) | 238 | if (ret < 0) |
231 | break; | 239 | break; |
232 | } | 240 | } |
233 | if (!ret) { | 241 | if (ret > 0) |
234 | ret = ulist_add(parents, eb->start, | 242 | goto next; |
235 | (uintptr_t)eie, GFP_NOFS); | 243 | ret = ulist_add_merge(parents, eb->start, |
236 | if (ret < 0) | 244 | (uintptr_t)eie, |
237 | break; | 245 | (u64 *)&old, GFP_NOFS); |
238 | if (!extent_item_pos) { | 246 | if (ret < 0) |
239 | ret = btrfs_next_old_leaf(root, path, | 247 | break; |
240 | time_seq); | 248 | if (!ret && extent_item_pos) { |
241 | continue; | 249 | while (old->next) |
242 | } | 250 | old = old->next; |
251 | old->next = eie; | ||
243 | } | 252 | } |
244 | } | 253 | } |
254 | next: | ||
245 | ret = btrfs_next_old_item(root, path, time_seq); | 255 | ret = btrfs_next_old_item(root, path, time_seq); |
246 | } | 256 | } |
247 | 257 | ||
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 5bf4c39e2ad6..ed504607d8ec 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -1271,7 +1271,6 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct extent_buffer *eb, | |||
1271 | BUG_ON(!eb_rewin); | 1271 | BUG_ON(!eb_rewin); |
1272 | } | 1272 | } |
1273 | 1273 | ||
1274 | extent_buffer_get(eb_rewin); | ||
1275 | btrfs_tree_read_unlock(eb); | 1274 | btrfs_tree_read_unlock(eb); |
1276 | free_extent_buffer(eb); | 1275 | free_extent_buffer(eb); |
1277 | 1276 | ||
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 583d98bd065e..fe443fece851 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -4048,7 +4048,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4048 | } | 4048 | } |
4049 | 4049 | ||
4050 | while (!end) { | 4050 | while (!end) { |
4051 | u64 offset_in_extent; | 4051 | u64 offset_in_extent = 0; |
4052 | 4052 | ||
4053 | /* break if the extent we found is outside the range */ | 4053 | /* break if the extent we found is outside the range */ |
4054 | if (em->start >= max || extent_map_end(em) < off) | 4054 | if (em->start >= max || extent_map_end(em) < off) |
@@ -4064,9 +4064,12 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
4064 | 4064 | ||
4065 | /* | 4065 | /* |
4066 | * record the offset from the start of the extent | 4066 | * record the offset from the start of the extent |
4067 | * for adjusting the disk offset below | 4067 | * for adjusting the disk offset below. Only do this if the |
4068 | * extent isn't compressed since our in ram offset may be past | ||
4069 | * what we have actually allocated on disk. | ||
4068 | */ | 4070 | */ |
4069 | offset_in_extent = em_start - em->start; | 4071 | if (!test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) |
4072 | offset_in_extent = em_start - em->start; | ||
4070 | em_end = extent_map_end(em); | 4073 | em_end = extent_map_end(em); |
4071 | em_len = em_end - em_start; | 4074 | em_len = em_end - em_start; |
4072 | emflags = em->flags; | 4075 | emflags = em->flags; |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index a005fe2c072a..8e686a427ce2 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -596,20 +596,29 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
596 | if (no_splits) | 596 | if (no_splits) |
597 | goto next; | 597 | goto next; |
598 | 598 | ||
599 | if (em->block_start < EXTENT_MAP_LAST_BYTE && | 599 | if (em->start < start) { |
600 | em->start < start) { | ||
601 | split->start = em->start; | 600 | split->start = em->start; |
602 | split->len = start - em->start; | 601 | split->len = start - em->start; |
603 | split->orig_start = em->orig_start; | ||
604 | split->block_start = em->block_start; | ||
605 | 602 | ||
606 | if (compressed) | 603 | if (em->block_start < EXTENT_MAP_LAST_BYTE) { |
607 | split->block_len = em->block_len; | 604 | split->orig_start = em->orig_start; |
608 | else | 605 | split->block_start = em->block_start; |
609 | split->block_len = split->len; | 606 | |
610 | split->ram_bytes = em->ram_bytes; | 607 | if (compressed) |
611 | split->orig_block_len = max(split->block_len, | 608 | split->block_len = em->block_len; |
612 | em->orig_block_len); | 609 | else |
610 | split->block_len = split->len; | ||
611 | split->orig_block_len = max(split->block_len, | ||
612 | em->orig_block_len); | ||
613 | split->ram_bytes = em->ram_bytes; | ||
614 | } else { | ||
615 | split->orig_start = split->start; | ||
616 | split->block_len = 0; | ||
617 | split->block_start = em->block_start; | ||
618 | split->orig_block_len = 0; | ||
619 | split->ram_bytes = split->len; | ||
620 | } | ||
621 | |||
613 | split->generation = gen; | 622 | split->generation = gen; |
614 | split->bdev = em->bdev; | 623 | split->bdev = em->bdev; |
615 | split->flags = flags; | 624 | split->flags = flags; |
@@ -620,8 +629,7 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
620 | split = split2; | 629 | split = split2; |
621 | split2 = NULL; | 630 | split2 = NULL; |
622 | } | 631 | } |
623 | if (em->block_start < EXTENT_MAP_LAST_BYTE && | 632 | if (testend && em->start + em->len > start + len) { |
624 | testend && em->start + em->len > start + len) { | ||
625 | u64 diff = start + len - em->start; | 633 | u64 diff = start + len - em->start; |
626 | 634 | ||
627 | split->start = start + len; | 635 | split->start = start + len; |
@@ -630,18 +638,28 @@ void btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, | |||
630 | split->flags = flags; | 638 | split->flags = flags; |
631 | split->compress_type = em->compress_type; | 639 | split->compress_type = em->compress_type; |
632 | split->generation = gen; | 640 | split->generation = gen; |
633 | split->orig_block_len = max(em->block_len, | 641 | |
642 | if (em->block_start < EXTENT_MAP_LAST_BYTE) { | ||
643 | split->orig_block_len = max(em->block_len, | ||
634 | em->orig_block_len); | 644 | em->orig_block_len); |
635 | split->ram_bytes = em->ram_bytes; | ||
636 | 645 | ||
637 | if (compressed) { | 646 | split->ram_bytes = em->ram_bytes; |
638 | split->block_len = em->block_len; | 647 | if (compressed) { |
639 | split->block_start = em->block_start; | 648 | split->block_len = em->block_len; |
640 | split->orig_start = em->orig_start; | 649 | split->block_start = em->block_start; |
650 | split->orig_start = em->orig_start; | ||
651 | } else { | ||
652 | split->block_len = split->len; | ||
653 | split->block_start = em->block_start | ||
654 | + diff; | ||
655 | split->orig_start = em->orig_start; | ||
656 | } | ||
641 | } else { | 657 | } else { |
642 | split->block_len = split->len; | 658 | split->ram_bytes = split->len; |
643 | split->block_start = em->block_start + diff; | 659 | split->orig_start = split->start; |
644 | split->orig_start = em->orig_start; | 660 | split->block_len = 0; |
661 | split->block_start = em->block_start; | ||
662 | split->orig_block_len = 0; | ||
645 | } | 663 | } |
646 | 664 | ||
647 | ret = add_extent_mapping(em_tree, split, modified); | 665 | ret = add_extent_mapping(em_tree, split, modified); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 6d1b93c8aafb..021694c08181 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2166,16 +2166,23 @@ static noinline int record_one_backref(u64 inum, u64 offset, u64 root_id, | |||
2166 | if (btrfs_file_extent_disk_bytenr(leaf, extent) != old->bytenr) | 2166 | if (btrfs_file_extent_disk_bytenr(leaf, extent) != old->bytenr) |
2167 | continue; | 2167 | continue; |
2168 | 2168 | ||
2169 | extent_offset = btrfs_file_extent_offset(leaf, extent); | 2169 | /* |
2170 | if (key.offset - extent_offset != offset) | 2170 | * 'offset' refers to the exact key.offset, |
2171 | * NOT the 'offset' field in btrfs_extent_data_ref, ie. | ||
2172 | * (key.offset - extent_offset). | ||
2173 | */ | ||
2174 | if (key.offset != offset) | ||
2171 | continue; | 2175 | continue; |
2172 | 2176 | ||
2177 | extent_offset = btrfs_file_extent_offset(leaf, extent); | ||
2173 | num_bytes = btrfs_file_extent_num_bytes(leaf, extent); | 2178 | num_bytes = btrfs_file_extent_num_bytes(leaf, extent); |
2179 | |||
2174 | if (extent_offset >= old->extent_offset + old->offset + | 2180 | if (extent_offset >= old->extent_offset + old->offset + |
2175 | old->len || extent_offset + num_bytes <= | 2181 | old->len || extent_offset + num_bytes <= |
2176 | old->extent_offset + old->offset) | 2182 | old->extent_offset + old->offset) |
2177 | continue; | 2183 | continue; |
2178 | 2184 | ||
2185 | ret = 0; | ||
2179 | break; | 2186 | break; |
2180 | } | 2187 | } |
2181 | 2188 | ||
@@ -2187,7 +2194,7 @@ static noinline int record_one_backref(u64 inum, u64 offset, u64 root_id, | |||
2187 | 2194 | ||
2188 | backref->root_id = root_id; | 2195 | backref->root_id = root_id; |
2189 | backref->inum = inum; | 2196 | backref->inum = inum; |
2190 | backref->file_pos = offset + extent_offset; | 2197 | backref->file_pos = offset; |
2191 | backref->num_bytes = num_bytes; | 2198 | backref->num_bytes = num_bytes; |
2192 | backref->extent_offset = extent_offset; | 2199 | backref->extent_offset = extent_offset; |
2193 | backref->generation = btrfs_file_extent_generation(leaf, extent); | 2200 | backref->generation = btrfs_file_extent_generation(leaf, extent); |
@@ -2210,7 +2217,8 @@ static noinline bool record_extent_backrefs(struct btrfs_path *path, | |||
2210 | new->path = path; | 2217 | new->path = path; |
2211 | 2218 | ||
2212 | list_for_each_entry_safe(old, tmp, &new->head, list) { | 2219 | list_for_each_entry_safe(old, tmp, &new->head, list) { |
2213 | ret = iterate_inodes_from_logical(old->bytenr, fs_info, | 2220 | ret = iterate_inodes_from_logical(old->bytenr + |
2221 | old->extent_offset, fs_info, | ||
2214 | path, record_one_backref, | 2222 | path, record_one_backref, |
2215 | old); | 2223 | old); |
2216 | BUG_ON(ret < 0 && ret != -ENOENT); | 2224 | BUG_ON(ret < 0 && ret != -ENOENT); |
@@ -4391,9 +4399,6 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) | |||
4391 | int mask = attr->ia_valid; | 4399 | int mask = attr->ia_valid; |
4392 | int ret; | 4400 | int ret; |
4393 | 4401 | ||
4394 | if (newsize == oldsize) | ||
4395 | return 0; | ||
4396 | |||
4397 | /* | 4402 | /* |
4398 | * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a | 4403 | * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a |
4399 | * special case where we need to update the times despite not having | 4404 | * special case where we need to update the times despite not having |
@@ -5165,14 +5170,31 @@ next: | |||
5165 | } | 5170 | } |
5166 | 5171 | ||
5167 | /* Reached end of directory/root. Bump pos past the last item. */ | 5172 | /* Reached end of directory/root. Bump pos past the last item. */ |
5168 | if (key_type == BTRFS_DIR_INDEX_KEY) | 5173 | ctx->pos++; |
5169 | /* | 5174 | |
5170 | * 32-bit glibc will use getdents64, but then strtol - | 5175 | /* |
5171 | * so the last number we can serve is this. | 5176 | * Stop new entries from being returned after we return the last |
5172 | */ | 5177 | * entry. |
5173 | ctx->pos = 0x7fffffff; | 5178 | * |
5174 | else | 5179 | * New directory entries are assigned a strictly increasing |
5175 | ctx->pos++; | 5180 | * offset. This means that new entries created during readdir |
5181 | * are *guaranteed* to be seen in the future by that readdir. | ||
5182 | * This has broken buggy programs which operate on names as | ||
5183 | * they're returned by readdir. Until we re-use freed offsets | ||
5184 | * we have this hack to stop new entries from being returned | ||
5185 | * under the assumption that they'll never reach this huge | ||
5186 | * offset. | ||
5187 | * | ||
5188 | * This is being careful not to overflow 32bit loff_t unless the | ||
5189 | * last entry requires it because doing so has broken 32bit apps | ||
5190 | * in the past. | ||
5191 | */ | ||
5192 | if (key_type == BTRFS_DIR_INDEX_KEY) { | ||
5193 | if (ctx->pos >= INT_MAX) | ||
5194 | ctx->pos = LLONG_MAX; | ||
5195 | else | ||
5196 | ctx->pos = INT_MAX; | ||
5197 | } | ||
5176 | nopos: | 5198 | nopos: |
5177 | ret = 0; | 5199 | ret = 0; |
5178 | err: | 5200 | err: |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index d58cce77fc6c..af1931a5960d 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -983,12 +983,12 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, | |||
983 | * a dirty root struct and adds it into the list of dead roots that need to | 983 | * a dirty root struct and adds it into the list of dead roots that need to |
984 | * be deleted | 984 | * be deleted |
985 | */ | 985 | */ |
986 | int btrfs_add_dead_root(struct btrfs_root *root) | 986 | void btrfs_add_dead_root(struct btrfs_root *root) |
987 | { | 987 | { |
988 | spin_lock(&root->fs_info->trans_lock); | 988 | spin_lock(&root->fs_info->trans_lock); |
989 | list_add_tail(&root->root_list, &root->fs_info->dead_roots); | 989 | if (list_empty(&root->root_list)) |
990 | list_add_tail(&root->root_list, &root->fs_info->dead_roots); | ||
990 | spin_unlock(&root->fs_info->trans_lock); | 991 | spin_unlock(&root->fs_info->trans_lock); |
991 | return 0; | ||
992 | } | 992 | } |
993 | 993 | ||
994 | /* | 994 | /* |
@@ -1925,7 +1925,7 @@ int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root) | |||
1925 | } | 1925 | } |
1926 | root = list_first_entry(&fs_info->dead_roots, | 1926 | root = list_first_entry(&fs_info->dead_roots, |
1927 | struct btrfs_root, root_list); | 1927 | struct btrfs_root, root_list); |
1928 | list_del(&root->root_list); | 1928 | list_del_init(&root->root_list); |
1929 | spin_unlock(&fs_info->trans_lock); | 1929 | spin_unlock(&fs_info->trans_lock); |
1930 | 1930 | ||
1931 | pr_debug("btrfs: cleaner removing %llu\n", | 1931 | pr_debug("btrfs: cleaner removing %llu\n", |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 005b0375d18c..defbc4269897 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -143,7 +143,7 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid); | |||
143 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | 143 | int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, |
144 | struct btrfs_root *root); | 144 | struct btrfs_root *root); |
145 | 145 | ||
146 | int btrfs_add_dead_root(struct btrfs_root *root); | 146 | void btrfs_add_dead_root(struct btrfs_root *root); |
147 | int btrfs_defrag_root(struct btrfs_root *root); | 147 | int btrfs_defrag_root(struct btrfs_root *root); |
148 | int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root); | 148 | int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root); |
149 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | 149 | int btrfs_commit_transaction(struct btrfs_trans_handle *trans, |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 2c6791493637..ff60d8978ae2 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -3746,8 +3746,9 @@ next_slot: | |||
3746 | } | 3746 | } |
3747 | 3747 | ||
3748 | log_extents: | 3748 | log_extents: |
3749 | btrfs_release_path(path); | ||
3750 | btrfs_release_path(dst_path); | ||
3749 | if (fast_search) { | 3751 | if (fast_search) { |
3750 | btrfs_release_path(dst_path); | ||
3751 | ret = btrfs_log_changed_extents(trans, root, inode, dst_path); | 3752 | ret = btrfs_log_changed_extents(trans, root, inode, dst_path); |
3752 | if (ret) { | 3753 | if (ret) { |
3753 | err = ret; | 3754 | err = ret; |
@@ -3764,8 +3765,6 @@ log_extents: | |||
3764 | } | 3765 | } |
3765 | 3766 | ||
3766 | if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) { | 3767 | if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) { |
3767 | btrfs_release_path(path); | ||
3768 | btrfs_release_path(dst_path); | ||
3769 | ret = log_directory_changes(trans, root, inode, path, dst_path); | 3768 | ret = log_directory_changes(trans, root, inode, path, dst_path); |
3770 | if (ret) { | 3769 | if (ret) { |
3771 | err = ret; | 3770 | err = ret; |
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 4888cb3fdef7..c7c83ff0f752 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c | |||
@@ -533,8 +533,7 @@ EXPORT_SYMBOL_GPL(debugfs_remove); | |||
533 | */ | 533 | */ |
534 | void debugfs_remove_recursive(struct dentry *dentry) | 534 | void debugfs_remove_recursive(struct dentry *dentry) |
535 | { | 535 | { |
536 | struct dentry *child; | 536 | struct dentry *child, *next, *parent; |
537 | struct dentry *parent; | ||
538 | 537 | ||
539 | if (IS_ERR_OR_NULL(dentry)) | 538 | if (IS_ERR_OR_NULL(dentry)) |
540 | return; | 539 | return; |
@@ -544,61 +543,37 @@ void debugfs_remove_recursive(struct dentry *dentry) | |||
544 | return; | 543 | return; |
545 | 544 | ||
546 | parent = dentry; | 545 | parent = dentry; |
546 | down: | ||
547 | mutex_lock(&parent->d_inode->i_mutex); | 547 | mutex_lock(&parent->d_inode->i_mutex); |
548 | list_for_each_entry_safe(child, next, &parent->d_subdirs, d_u.d_child) { | ||
549 | if (!debugfs_positive(child)) | ||
550 | continue; | ||
548 | 551 | ||
549 | while (1) { | 552 | /* perhaps simple_empty(child) makes more sense */ |
550 | /* | ||
551 | * When all dentries under "parent" has been removed, | ||
552 | * walk up the tree until we reach our starting point. | ||
553 | */ | ||
554 | if (list_empty(&parent->d_subdirs)) { | ||
555 | mutex_unlock(&parent->d_inode->i_mutex); | ||
556 | if (parent == dentry) | ||
557 | break; | ||
558 | parent = parent->d_parent; | ||
559 | mutex_lock(&parent->d_inode->i_mutex); | ||
560 | } | ||
561 | child = list_entry(parent->d_subdirs.next, struct dentry, | ||
562 | d_u.d_child); | ||
563 | next_sibling: | ||
564 | |||
565 | /* | ||
566 | * If "child" isn't empty, walk down the tree and | ||
567 | * remove all its descendants first. | ||
568 | */ | ||
569 | if (!list_empty(&child->d_subdirs)) { | 553 | if (!list_empty(&child->d_subdirs)) { |
570 | mutex_unlock(&parent->d_inode->i_mutex); | 554 | mutex_unlock(&parent->d_inode->i_mutex); |
571 | parent = child; | 555 | parent = child; |
572 | mutex_lock(&parent->d_inode->i_mutex); | 556 | goto down; |
573 | continue; | ||
574 | } | 557 | } |
575 | __debugfs_remove(child, parent); | 558 | up: |
576 | if (parent->d_subdirs.next == &child->d_u.d_child) { | 559 | if (!__debugfs_remove(child, parent)) |
577 | /* | 560 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); |
578 | * Try the next sibling. | ||
579 | */ | ||
580 | if (child->d_u.d_child.next != &parent->d_subdirs) { | ||
581 | child = list_entry(child->d_u.d_child.next, | ||
582 | struct dentry, | ||
583 | d_u.d_child); | ||
584 | goto next_sibling; | ||
585 | } | ||
586 | |||
587 | /* | ||
588 | * Avoid infinite loop if we fail to remove | ||
589 | * one dentry. | ||
590 | */ | ||
591 | mutex_unlock(&parent->d_inode->i_mutex); | ||
592 | break; | ||
593 | } | ||
594 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); | ||
595 | } | 561 | } |
596 | 562 | ||
597 | parent = dentry->d_parent; | 563 | mutex_unlock(&parent->d_inode->i_mutex); |
564 | child = parent; | ||
565 | parent = parent->d_parent; | ||
598 | mutex_lock(&parent->d_inode->i_mutex); | 566 | mutex_lock(&parent->d_inode->i_mutex); |
599 | __debugfs_remove(dentry, parent); | 567 | |
568 | if (child != dentry) { | ||
569 | next = list_entry(child->d_u.d_child.next, struct dentry, | ||
570 | d_u.d_child); | ||
571 | goto up; | ||
572 | } | ||
573 | |||
574 | if (!__debugfs_remove(child, parent)) | ||
575 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); | ||
600 | mutex_unlock(&parent->d_inode->i_mutex); | 576 | mutex_unlock(&parent->d_inode->i_mutex); |
601 | simple_release_fs(&debugfs_mount, &debugfs_mount_count); | ||
602 | } | 577 | } |
603 | EXPORT_SYMBOL_GPL(debugfs_remove_recursive); | 578 | EXPORT_SYMBOL_GPL(debugfs_remove_recursive); |
604 | 579 | ||
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 911649a47dd5..812149119fa3 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
@@ -686,7 +686,6 @@ static int device_close(struct inode *inode, struct file *file) | |||
686 | device_remove_lockspace() */ | 686 | device_remove_lockspace() */ |
687 | 687 | ||
688 | sigprocmask(SIG_SETMASK, &tmpsig, NULL); | 688 | sigprocmask(SIG_SETMASK, &tmpsig, NULL); |
689 | recalc_sigpending(); | ||
690 | 689 | ||
691 | return 0; | 690 | return 0; |
692 | } | 691 | } |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index a61873808f76..72ba4705d4fa 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -4412,7 +4412,7 @@ void ext4_ext_truncate(handle_t *handle, struct inode *inode) | |||
4412 | retry: | 4412 | retry: |
4413 | err = ext4_es_remove_extent(inode, last_block, | 4413 | err = ext4_es_remove_extent(inode, last_block, |
4414 | EXT_MAX_BLOCKS - last_block); | 4414 | EXT_MAX_BLOCKS - last_block); |
4415 | if (err == ENOMEM) { | 4415 | if (err == -ENOMEM) { |
4416 | cond_resched(); | 4416 | cond_resched(); |
4417 | congestion_wait(BLK_RW_ASYNC, HZ/50); | 4417 | congestion_wait(BLK_RW_ASYNC, HZ/50); |
4418 | goto retry; | 4418 | goto retry; |
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index f03598c6ffd3..8bf5999875ee 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
@@ -734,11 +734,8 @@ repeat_in_this_group: | |||
734 | ino = ext4_find_next_zero_bit((unsigned long *) | 734 | ino = ext4_find_next_zero_bit((unsigned long *) |
735 | inode_bitmap_bh->b_data, | 735 | inode_bitmap_bh->b_data, |
736 | EXT4_INODES_PER_GROUP(sb), ino); | 736 | EXT4_INODES_PER_GROUP(sb), ino); |
737 | if (ino >= EXT4_INODES_PER_GROUP(sb)) { | 737 | if (ino >= EXT4_INODES_PER_GROUP(sb)) |
738 | if (++group == ngroups) | 738 | goto next_group; |
739 | group = 0; | ||
740 | continue; | ||
741 | } | ||
742 | if (group == 0 && (ino+1) < EXT4_FIRST_INO(sb)) { | 739 | if (group == 0 && (ino+1) < EXT4_FIRST_INO(sb)) { |
743 | ext4_error(sb, "reserved inode found cleared - " | 740 | ext4_error(sb, "reserved inode found cleared - " |
744 | "inode=%lu", ino + 1); | 741 | "inode=%lu", ino + 1); |
@@ -769,6 +766,9 @@ repeat_in_this_group: | |||
769 | goto got; /* we grabbed the inode! */ | 766 | goto got; /* we grabbed the inode! */ |
770 | if (ino < EXT4_INODES_PER_GROUP(sb)) | 767 | if (ino < EXT4_INODES_PER_GROUP(sb)) |
771 | goto repeat_in_this_group; | 768 | goto repeat_in_this_group; |
769 | next_group: | ||
770 | if (++group == ngroups) | ||
771 | group = 0; | ||
772 | } | 772 | } |
773 | err = -ENOSPC; | 773 | err = -ENOSPC; |
774 | goto out; | 774 | goto out; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index ba33c67d6e48..dd32a2eacd0d 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -555,14 +555,13 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode, | |||
555 | int ret; | 555 | int ret; |
556 | unsigned long long status; | 556 | unsigned long long status; |
557 | 557 | ||
558 | #ifdef ES_AGGRESSIVE_TEST | 558 | if (unlikely(retval != map->m_len)) { |
559 | if (retval != map->m_len) { | 559 | ext4_warning(inode->i_sb, |
560 | printk("ES len assertion failed for inode: %lu " | 560 | "ES len assertion failed for inode " |
561 | "retval %d != map->m_len %d " | 561 | "%lu: retval %d != map->m_len %d", |
562 | "in %s (lookup)\n", inode->i_ino, retval, | 562 | inode->i_ino, retval, map->m_len); |
563 | map->m_len, __func__); | 563 | WARN_ON(1); |
564 | } | 564 | } |
565 | #endif | ||
566 | 565 | ||
567 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? | 566 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? |
568 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; | 567 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; |
@@ -656,14 +655,13 @@ found: | |||
656 | int ret; | 655 | int ret; |
657 | unsigned long long status; | 656 | unsigned long long status; |
658 | 657 | ||
659 | #ifdef ES_AGGRESSIVE_TEST | 658 | if (unlikely(retval != map->m_len)) { |
660 | if (retval != map->m_len) { | 659 | ext4_warning(inode->i_sb, |
661 | printk("ES len assertion failed for inode: %lu " | 660 | "ES len assertion failed for inode " |
662 | "retval %d != map->m_len %d " | 661 | "%lu: retval %d != map->m_len %d", |
663 | "in %s (allocation)\n", inode->i_ino, retval, | 662 | inode->i_ino, retval, map->m_len); |
664 | map->m_len, __func__); | 663 | WARN_ON(1); |
665 | } | 664 | } |
666 | #endif | ||
667 | 665 | ||
668 | /* | 666 | /* |
669 | * If the extent has been zeroed out, we don't need to update | 667 | * If the extent has been zeroed out, we don't need to update |
@@ -1637,14 +1635,13 @@ add_delayed: | |||
1637 | int ret; | 1635 | int ret; |
1638 | unsigned long long status; | 1636 | unsigned long long status; |
1639 | 1637 | ||
1640 | #ifdef ES_AGGRESSIVE_TEST | 1638 | if (unlikely(retval != map->m_len)) { |
1641 | if (retval != map->m_len) { | 1639 | ext4_warning(inode->i_sb, |
1642 | printk("ES len assertion failed for inode: %lu " | 1640 | "ES len assertion failed for inode " |
1643 | "retval %d != map->m_len %d " | 1641 | "%lu: retval %d != map->m_len %d", |
1644 | "in %s (lookup)\n", inode->i_ino, retval, | 1642 | inode->i_ino, retval, map->m_len); |
1645 | map->m_len, __func__); | 1643 | WARN_ON(1); |
1646 | } | 1644 | } |
1647 | #endif | ||
1648 | 1645 | ||
1649 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? | 1646 | status = map->m_flags & EXT4_MAP_UNWRITTEN ? |
1650 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; | 1647 | EXTENT_STATUS_UNWRITTEN : EXTENT_STATUS_WRITTEN; |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index bca26f34edf4..36b141e420b7 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -5481,6 +5481,7 @@ static void __exit ext4_exit_fs(void) | |||
5481 | kset_unregister(ext4_kset); | 5481 | kset_unregister(ext4_kset); |
5482 | ext4_exit_system_zone(); | 5482 | ext4_exit_system_zone(); |
5483 | ext4_exit_pageio(); | 5483 | ext4_exit_pageio(); |
5484 | ext4_exit_es(); | ||
5484 | } | 5485 | } |
5485 | 5486 | ||
5486 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); | 5487 | MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); |
diff --git a/fs/fcntl.c b/fs/fcntl.c index 6599222536eb..65343c3741ff 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -730,14 +730,14 @@ static int __init fcntl_init(void) | |||
730 | * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY | 730 | * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY |
731 | * is defined as O_NONBLOCK on some platforms and not on others. | 731 | * is defined as O_NONBLOCK on some platforms and not on others. |
732 | */ | 732 | */ |
733 | BUILD_BUG_ON(19 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( | 733 | BUILD_BUG_ON(20 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( |
734 | O_RDONLY | O_WRONLY | O_RDWR | | 734 | O_RDONLY | O_WRONLY | O_RDWR | |
735 | O_CREAT | O_EXCL | O_NOCTTY | | 735 | O_CREAT | O_EXCL | O_NOCTTY | |
736 | O_TRUNC | O_APPEND | /* O_NONBLOCK | */ | 736 | O_TRUNC | O_APPEND | /* O_NONBLOCK | */ |
737 | __O_SYNC | O_DSYNC | FASYNC | | 737 | __O_SYNC | O_DSYNC | FASYNC | |
738 | O_DIRECT | O_LARGEFILE | O_DIRECTORY | | 738 | O_DIRECT | O_LARGEFILE | O_DIRECTORY | |
739 | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | | 739 | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | |
740 | __FMODE_EXEC | O_PATH | 740 | __FMODE_EXEC | O_PATH | __O_TMPFILE |
741 | )); | 741 | )); |
742 | 742 | ||
743 | fasync_cache = kmem_cache_create("fasync_cache", | 743 | fasync_cache = kmem_cache_create("fasync_cache", |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 0eda52738ec4..72a5d5b04494 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -1223,30 +1223,46 @@ static int fuse_direntplus_link(struct file *file, | |||
1223 | if (name.name[1] == '.' && name.len == 2) | 1223 | if (name.name[1] == '.' && name.len == 2) |
1224 | return 0; | 1224 | return 0; |
1225 | } | 1225 | } |
1226 | |||
1227 | if (invalid_nodeid(o->nodeid)) | ||
1228 | return -EIO; | ||
1229 | if (!fuse_valid_type(o->attr.mode)) | ||
1230 | return -EIO; | ||
1231 | |||
1226 | fc = get_fuse_conn(dir); | 1232 | fc = get_fuse_conn(dir); |
1227 | 1233 | ||
1228 | name.hash = full_name_hash(name.name, name.len); | 1234 | name.hash = full_name_hash(name.name, name.len); |
1229 | dentry = d_lookup(parent, &name); | 1235 | dentry = d_lookup(parent, &name); |
1230 | if (dentry && dentry->d_inode) { | 1236 | if (dentry) { |
1231 | inode = dentry->d_inode; | 1237 | inode = dentry->d_inode; |
1232 | if (get_node_id(inode) == o->nodeid) { | 1238 | if (!inode) { |
1239 | d_drop(dentry); | ||
1240 | } else if (get_node_id(inode) != o->nodeid || | ||
1241 | ((o->attr.mode ^ inode->i_mode) & S_IFMT)) { | ||
1242 | err = d_invalidate(dentry); | ||
1243 | if (err) | ||
1244 | goto out; | ||
1245 | } else if (is_bad_inode(inode)) { | ||
1246 | err = -EIO; | ||
1247 | goto out; | ||
1248 | } else { | ||
1233 | struct fuse_inode *fi; | 1249 | struct fuse_inode *fi; |
1234 | fi = get_fuse_inode(inode); | 1250 | fi = get_fuse_inode(inode); |
1235 | spin_lock(&fc->lock); | 1251 | spin_lock(&fc->lock); |
1236 | fi->nlookup++; | 1252 | fi->nlookup++; |
1237 | spin_unlock(&fc->lock); | 1253 | spin_unlock(&fc->lock); |
1238 | 1254 | ||
1255 | fuse_change_attributes(inode, &o->attr, | ||
1256 | entry_attr_timeout(o), | ||
1257 | attr_version); | ||
1258 | |||
1239 | /* | 1259 | /* |
1240 | * The other branch to 'found' comes via fuse_iget() | 1260 | * The other branch to 'found' comes via fuse_iget() |
1241 | * which bumps nlookup inside | 1261 | * which bumps nlookup inside |
1242 | */ | 1262 | */ |
1243 | goto found; | 1263 | goto found; |
1244 | } | 1264 | } |
1245 | err = d_invalidate(dentry); | ||
1246 | if (err) | ||
1247 | goto out; | ||
1248 | dput(dentry); | 1265 | dput(dentry); |
1249 | dentry = NULL; | ||
1250 | } | 1266 | } |
1251 | 1267 | ||
1252 | dentry = d_alloc(parent, &name); | 1268 | dentry = d_alloc(parent, &name); |
@@ -1259,25 +1275,30 @@ static int fuse_direntplus_link(struct file *file, | |||
1259 | if (!inode) | 1275 | if (!inode) |
1260 | goto out; | 1276 | goto out; |
1261 | 1277 | ||
1262 | alias = d_materialise_unique(dentry, inode); | 1278 | if (S_ISDIR(inode->i_mode)) { |
1263 | err = PTR_ERR(alias); | 1279 | mutex_lock(&fc->inst_mutex); |
1264 | if (IS_ERR(alias)) | 1280 | alias = fuse_d_add_directory(dentry, inode); |
1265 | goto out; | 1281 | mutex_unlock(&fc->inst_mutex); |
1282 | err = PTR_ERR(alias); | ||
1283 | if (IS_ERR(alias)) { | ||
1284 | iput(inode); | ||
1285 | goto out; | ||
1286 | } | ||
1287 | } else { | ||
1288 | alias = d_splice_alias(inode, dentry); | ||
1289 | } | ||
1290 | |||
1266 | if (alias) { | 1291 | if (alias) { |
1267 | dput(dentry); | 1292 | dput(dentry); |
1268 | dentry = alias; | 1293 | dentry = alias; |
1269 | } | 1294 | } |
1270 | 1295 | ||
1271 | found: | 1296 | found: |
1272 | fuse_change_attributes(inode, &o->attr, entry_attr_timeout(o), | ||
1273 | attr_version); | ||
1274 | |||
1275 | fuse_change_entry_timeout(dentry, o); | 1297 | fuse_change_entry_timeout(dentry, o); |
1276 | 1298 | ||
1277 | err = 0; | 1299 | err = 0; |
1278 | out: | 1300 | out: |
1279 | if (dentry) | 1301 | dput(dentry); |
1280 | dput(dentry); | ||
1281 | return err; | 1302 | return err; |
1282 | } | 1303 | } |
1283 | 1304 | ||
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 01bfe7662751..41e491b8e5d7 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
@@ -64,12 +64,17 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init) | |||
64 | nlm_init->protocol, nlm_version, | 64 | nlm_init->protocol, nlm_version, |
65 | nlm_init->hostname, nlm_init->noresvport, | 65 | nlm_init->hostname, nlm_init->noresvport, |
66 | nlm_init->net); | 66 | nlm_init->net); |
67 | if (host == NULL) { | 67 | if (host == NULL) |
68 | lockd_down(nlm_init->net); | 68 | goto out_nohost; |
69 | return ERR_PTR(-ENOLCK); | 69 | if (host->h_rpcclnt == NULL && nlm_bind_host(host) == NULL) |
70 | } | 70 | goto out_nobind; |
71 | 71 | ||
72 | return host; | 72 | return host; |
73 | out_nobind: | ||
74 | nlmclnt_release_host(host); | ||
75 | out_nohost: | ||
76 | lockd_down(nlm_init->net); | ||
77 | return ERR_PTR(-ENOLCK); | ||
73 | } | 78 | } |
74 | EXPORT_SYMBOL_GPL(nlmclnt_init); | 79 | EXPORT_SYMBOL_GPL(nlmclnt_init); |
75 | 80 | ||
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 9760ecb9b60f..acd394716349 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
@@ -125,14 +125,15 @@ static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl) | |||
125 | { | 125 | { |
126 | struct nlm_args *argp = &req->a_args; | 126 | struct nlm_args *argp = &req->a_args; |
127 | struct nlm_lock *lock = &argp->lock; | 127 | struct nlm_lock *lock = &argp->lock; |
128 | char *nodename = req->a_host->h_rpcclnt->cl_nodename; | ||
128 | 129 | ||
129 | nlmclnt_next_cookie(&argp->cookie); | 130 | nlmclnt_next_cookie(&argp->cookie); |
130 | memcpy(&lock->fh, NFS_FH(file_inode(fl->fl_file)), sizeof(struct nfs_fh)); | 131 | memcpy(&lock->fh, NFS_FH(file_inode(fl->fl_file)), sizeof(struct nfs_fh)); |
131 | lock->caller = utsname()->nodename; | 132 | lock->caller = nodename; |
132 | lock->oh.data = req->a_owner; | 133 | lock->oh.data = req->a_owner; |
133 | lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s", | 134 | lock->oh.len = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s", |
134 | (unsigned int)fl->fl_u.nfs_fl.owner->pid, | 135 | (unsigned int)fl->fl_u.nfs_fl.owner->pid, |
135 | utsname()->nodename); | 136 | nodename); |
136 | lock->svid = fl->fl_u.nfs_fl.owner->pid; | 137 | lock->svid = fl->fl_u.nfs_fl.owner->pid; |
137 | lock->fl.fl_start = fl->fl_start; | 138 | lock->fl.fl_start = fl->fl_start; |
138 | lock->fl.fl_end = fl->fl_end; | 139 | lock->fl.fl_end = fl->fl_end; |
diff --git a/fs/namei.c b/fs/namei.c index 8b61d103a8a7..89a612e392eb 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -3671,15 +3671,11 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, | |||
3671 | if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) | 3671 | if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) |
3672 | return -EINVAL; | 3672 | return -EINVAL; |
3673 | /* | 3673 | /* |
3674 | * To use null names we require CAP_DAC_READ_SEARCH | 3674 | * Using empty names is equivalent to using AT_SYMLINK_FOLLOW |
3675 | * This ensures that not everyone will be able to create | 3675 | * on /proc/self/fd/<fd>. |
3676 | * handlink using the passed filedescriptor. | ||
3677 | */ | 3676 | */ |
3678 | if (flags & AT_EMPTY_PATH) { | 3677 | if (flags & AT_EMPTY_PATH) |
3679 | if (!capable(CAP_DAC_READ_SEARCH)) | ||
3680 | return -ENOENT; | ||
3681 | how = LOOKUP_EMPTY; | 3678 | how = LOOKUP_EMPTY; |
3682 | } | ||
3683 | 3679 | ||
3684 | if (flags & AT_SYMLINK_FOLLOW) | 3680 | if (flags & AT_SYMLINK_FOLLOW) |
3685 | how |= LOOKUP_FOLLOW; | 3681 | how |= LOOKUP_FOLLOW; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index af6e806044d7..941246f2b43d 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -463,7 +463,6 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st | |||
463 | unlock_new_inode(inode); | 463 | unlock_new_inode(inode); |
464 | } else | 464 | } else |
465 | nfs_refresh_inode(inode, fattr); | 465 | nfs_refresh_inode(inode, fattr); |
466 | nfs_setsecurity(inode, fattr, label); | ||
467 | dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", | 466 | dprintk("NFS: nfs_fhget(%s/%Ld fh_crc=0x%08x ct=%d)\n", |
468 | inode->i_sb->s_id, | 467 | inode->i_sb->s_id, |
469 | (long long)NFS_FILEID(inode), | 468 | (long long)NFS_FILEID(inode), |
@@ -963,9 +962,15 @@ EXPORT_SYMBOL_GPL(nfs_revalidate_inode); | |||
963 | static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping) | 962 | static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping) |
964 | { | 963 | { |
965 | struct nfs_inode *nfsi = NFS_I(inode); | 964 | struct nfs_inode *nfsi = NFS_I(inode); |
966 | 965 | int ret; | |
966 | |||
967 | if (mapping->nrpages != 0) { | 967 | if (mapping->nrpages != 0) { |
968 | int ret = invalidate_inode_pages2(mapping); | 968 | if (S_ISREG(inode->i_mode)) { |
969 | ret = nfs_sync_mapping(mapping); | ||
970 | if (ret < 0) | ||
971 | return ret; | ||
972 | } | ||
973 | ret = invalidate_inode_pages2(mapping); | ||
969 | if (ret < 0) | 974 | if (ret < 0) |
970 | return ret; | 975 | return ret; |
971 | } | 976 | } |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index cf11799297c4..108a774095f7 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -3071,15 +3071,13 @@ struct rpc_clnt * | |||
3071 | nfs4_proc_lookup_mountpoint(struct inode *dir, struct qstr *name, | 3071 | nfs4_proc_lookup_mountpoint(struct inode *dir, struct qstr *name, |
3072 | struct nfs_fh *fhandle, struct nfs_fattr *fattr) | 3072 | struct nfs_fh *fhandle, struct nfs_fattr *fattr) |
3073 | { | 3073 | { |
3074 | struct rpc_clnt *client = NFS_CLIENT(dir); | ||
3074 | int status; | 3075 | int status; |
3075 | struct rpc_clnt *client = rpc_clone_client(NFS_CLIENT(dir)); | ||
3076 | 3076 | ||
3077 | status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, NULL); | 3077 | status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, NULL); |
3078 | if (status < 0) { | 3078 | if (status < 0) |
3079 | rpc_shutdown_client(client); | ||
3080 | return ERR_PTR(status); | 3079 | return ERR_PTR(status); |
3081 | } | 3080 | return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client; |
3082 | return client; | ||
3083 | } | 3081 | } |
3084 | 3082 | ||
3085 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) | 3083 | static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry) |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index c74d6168db99..3850b018815f 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -1118,11 +1118,11 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, | |||
1118 | len, ((char *)p - (char *)q) + 4); | 1118 | len, ((char *)p - (char *)q) + 4); |
1119 | BUG(); | 1119 | BUG(); |
1120 | } | 1120 | } |
1121 | len = (char *)p - (char *)q - (bmval_len << 2); | ||
1122 | *q++ = htonl(bmval0); | 1121 | *q++ = htonl(bmval0); |
1123 | *q++ = htonl(bmval1); | 1122 | *q++ = htonl(bmval1); |
1124 | if (bmval_len == 3) | 1123 | if (bmval_len == 3) |
1125 | *q++ = htonl(bmval2); | 1124 | *q++ = htonl(bmval2); |
1125 | len = (char *)p - (char *)(q + 1); | ||
1126 | *q = htonl(len); | 1126 | *q = htonl(len); |
1127 | 1127 | ||
1128 | /* out: */ | 1128 | /* out: */ |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 71fdc0dfa0d2..f6db66d8f647 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -2478,6 +2478,10 @@ struct dentry *nfs_fs_mount_common(struct nfs_server *server, | |||
2478 | if (server->flags & NFS_MOUNT_NOAC) | 2478 | if (server->flags & NFS_MOUNT_NOAC) |
2479 | sb_mntdata.mntflags |= MS_SYNCHRONOUS; | 2479 | sb_mntdata.mntflags |= MS_SYNCHRONOUS; |
2480 | 2480 | ||
2481 | if (mount_info->cloned != NULL && mount_info->cloned->sb != NULL) | ||
2482 | if (mount_info->cloned->sb->s_flags & MS_SYNCHRONOUS) | ||
2483 | sb_mntdata.mntflags |= MS_SYNCHRONOUS; | ||
2484 | |||
2481 | /* Get a superblock - note that we may end up sharing one that already exists */ | 2485 | /* Get a superblock - note that we may end up sharing one that already exists */ |
2482 | s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata); | 2486 | s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata); |
2483 | if (IS_ERR(s)) { | 2487 | if (IS_ERR(s)) { |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 0d4c410e4589..419572f33b72 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -1524,7 +1524,7 @@ static inline u32 nfsd4_write_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) | |||
1524 | static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) | 1524 | static inline u32 nfsd4_exchange_id_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) |
1525 | { | 1525 | { |
1526 | return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\ | 1526 | return (op_encode_hdr_size + 2 + 1 + /* eir_clientid, eir_sequenceid */\ |
1527 | 1 + 1 + 0 + /* eir_flags, spr_how, SP4_NONE (for now) */\ | 1527 | 1 + 1 + 2 + /* eir_flags, spr_how, spo_must_enforce & _allow */\ |
1528 | 2 + /*eir_server_owner.so_minor_id */\ | 1528 | 2 + /*eir_server_owner.so_minor_id */\ |
1529 | /* eir_server_owner.so_major_id<> */\ | 1529 | /* eir_server_owner.so_major_id<> */\ |
1530 | XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\ | 1530 | XDR_QUADLEN(NFS4_OPAQUE_LIMIT) + 1 +\ |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 280acef6f0dc..43f42290e5df 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1264,6 +1264,8 @@ static bool svc_rqst_integrity_protected(struct svc_rqst *rqstp) | |||
1264 | struct svc_cred *cr = &rqstp->rq_cred; | 1264 | struct svc_cred *cr = &rqstp->rq_cred; |
1265 | u32 service; | 1265 | u32 service; |
1266 | 1266 | ||
1267 | if (!cr->cr_gss_mech) | ||
1268 | return false; | ||
1267 | service = gss_pseudoflavor_to_service(cr->cr_gss_mech, cr->cr_flavor); | 1269 | service = gss_pseudoflavor_to_service(cr->cr_gss_mech, cr->cr_flavor); |
1268 | return service == RPC_GSS_SVC_INTEGRITY || | 1270 | return service == RPC_GSS_SVC_INTEGRITY || |
1269 | service == RPC_GSS_SVC_PRIVACY; | 1271 | service == RPC_GSS_SVC_PRIVACY; |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 0c0f3ea90de5..c2a4701d7286 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -3360,7 +3360,8 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, | |||
3360 | 8 /* eir_clientid */ + | 3360 | 8 /* eir_clientid */ + |
3361 | 4 /* eir_sequenceid */ + | 3361 | 4 /* eir_sequenceid */ + |
3362 | 4 /* eir_flags */ + | 3362 | 4 /* eir_flags */ + |
3363 | 4 /* spr_how (SP4_NONE) */ + | 3363 | 4 /* spr_how */ + |
3364 | 8 /* spo_must_enforce, spo_must_allow */ + | ||
3364 | 8 /* so_minor_id */ + | 3365 | 8 /* so_minor_id */ + |
3365 | 4 /* so_major_id.len */ + | 3366 | 4 /* so_major_id.len */ + |
3366 | (XDR_QUADLEN(major_id_sz) * 4) + | 3367 | (XDR_QUADLEN(major_id_sz) * 4) + |
@@ -3372,8 +3373,6 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr, | |||
3372 | WRITE32(exid->seqid); | 3373 | WRITE32(exid->seqid); |
3373 | WRITE32(exid->flags); | 3374 | WRITE32(exid->flags); |
3374 | 3375 | ||
3375 | /* state_protect4_r. Currently only support SP4_NONE */ | ||
3376 | BUG_ON(exid->spa_how != SP4_NONE); | ||
3377 | WRITE32(exid->spa_how); | 3376 | WRITE32(exid->spa_how); |
3378 | switch (exid->spa_how) { | 3377 | switch (exid->spa_how) { |
3379 | case SP4_NONE: | 3378 | case SP4_NONE: |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 8ff6a0019b0b..c827acb0e943 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -830,9 +830,10 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, umode_t type, | |||
830 | flags = O_WRONLY|O_LARGEFILE; | 830 | flags = O_WRONLY|O_LARGEFILE; |
831 | } | 831 | } |
832 | *filp = dentry_open(&path, flags, current_cred()); | 832 | *filp = dentry_open(&path, flags, current_cred()); |
833 | if (IS_ERR(*filp)) | 833 | if (IS_ERR(*filp)) { |
834 | host_err = PTR_ERR(*filp); | 834 | host_err = PTR_ERR(*filp); |
835 | else { | 835 | *filp = NULL; |
836 | } else { | ||
836 | host_err = ima_file_check(*filp, may_flags); | 837 | host_err = ima_file_check(*filp, may_flags); |
837 | 838 | ||
838 | if (may_flags & NFSD_MAY_64BIT_COOKIE) | 839 | if (may_flags & NFSD_MAY_64BIT_COOKIE) |
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index 998b17eda09d..9f6b96a09615 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
@@ -2965,6 +2965,11 @@ int ocfs2_duplicate_clusters_by_page(handle_t *handle, | |||
2965 | to = map_end & (PAGE_CACHE_SIZE - 1); | 2965 | to = map_end & (PAGE_CACHE_SIZE - 1); |
2966 | 2966 | ||
2967 | page = find_or_create_page(mapping, page_index, GFP_NOFS); | 2967 | page = find_or_create_page(mapping, page_index, GFP_NOFS); |
2968 | if (!page) { | ||
2969 | ret = -ENOMEM; | ||
2970 | mlog_errno(ret); | ||
2971 | break; | ||
2972 | } | ||
2968 | 2973 | ||
2969 | /* | 2974 | /* |
2970 | * In case PAGE_CACHE_SIZE <= CLUSTER_SIZE, This page | 2975 | * In case PAGE_CACHE_SIZE <= CLUSTER_SIZE, This page |
@@ -823,7 +823,7 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
823 | int lookup_flags = 0; | 823 | int lookup_flags = 0; |
824 | int acc_mode; | 824 | int acc_mode; |
825 | 825 | ||
826 | if (flags & O_CREAT) | 826 | if (flags & (O_CREAT | __O_TMPFILE)) |
827 | op->mode = (mode & S_IALLUGO) | S_IFREG; | 827 | op->mode = (mode & S_IALLUGO) | S_IFREG; |
828 | else | 828 | else |
829 | op->mode = 0; | 829 | op->mode = 0; |
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 33532f79b4f7..a958444a75fc 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c | |||
@@ -19,12 +19,13 @@ | |||
19 | /* | 19 | /* |
20 | * LOCKING: | 20 | * LOCKING: |
21 | * | 21 | * |
22 | * We rely on new Alexander Viro's super-block locking. | 22 | * These guys are evicted from procfs as the very first step in ->kill_sb(). |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | static int show_version(struct seq_file *m, struct super_block *sb) | 26 | static int show_version(struct seq_file *m, void *unused) |
27 | { | 27 | { |
28 | struct super_block *sb = m->private; | ||
28 | char *format; | 29 | char *format; |
29 | 30 | ||
30 | if (REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6)) { | 31 | if (REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6)) { |
@@ -66,8 +67,9 @@ static int show_version(struct seq_file *m, struct super_block *sb) | |||
66 | #define DJP( x ) le32_to_cpu( jp -> x ) | 67 | #define DJP( x ) le32_to_cpu( jp -> x ) |
67 | #define JF( x ) ( r -> s_journal -> x ) | 68 | #define JF( x ) ( r -> s_journal -> x ) |
68 | 69 | ||
69 | static int show_super(struct seq_file *m, struct super_block *sb) | 70 | static int show_super(struct seq_file *m, void *unused) |
70 | { | 71 | { |
72 | struct super_block *sb = m->private; | ||
71 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 73 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
72 | 74 | ||
73 | seq_printf(m, "state: \t%s\n" | 75 | seq_printf(m, "state: \t%s\n" |
@@ -128,8 +130,9 @@ static int show_super(struct seq_file *m, struct super_block *sb) | |||
128 | return 0; | 130 | return 0; |
129 | } | 131 | } |
130 | 132 | ||
131 | static int show_per_level(struct seq_file *m, struct super_block *sb) | 133 | static int show_per_level(struct seq_file *m, void *unused) |
132 | { | 134 | { |
135 | struct super_block *sb = m->private; | ||
133 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 136 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
134 | int level; | 137 | int level; |
135 | 138 | ||
@@ -186,8 +189,9 @@ static int show_per_level(struct seq_file *m, struct super_block *sb) | |||
186 | return 0; | 189 | return 0; |
187 | } | 190 | } |
188 | 191 | ||
189 | static int show_bitmap(struct seq_file *m, struct super_block *sb) | 192 | static int show_bitmap(struct seq_file *m, void *unused) |
190 | { | 193 | { |
194 | struct super_block *sb = m->private; | ||
191 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 195 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
192 | 196 | ||
193 | seq_printf(m, "free_block: %lu\n" | 197 | seq_printf(m, "free_block: %lu\n" |
@@ -218,8 +222,9 @@ static int show_bitmap(struct seq_file *m, struct super_block *sb) | |||
218 | return 0; | 222 | return 0; |
219 | } | 223 | } |
220 | 224 | ||
221 | static int show_on_disk_super(struct seq_file *m, struct super_block *sb) | 225 | static int show_on_disk_super(struct seq_file *m, void *unused) |
222 | { | 226 | { |
227 | struct super_block *sb = m->private; | ||
223 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); | 228 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); |
224 | struct reiserfs_super_block *rs = sb_info->s_rs; | 229 | struct reiserfs_super_block *rs = sb_info->s_rs; |
225 | int hash_code = DFL(s_hash_function_code); | 230 | int hash_code = DFL(s_hash_function_code); |
@@ -261,8 +266,9 @@ static int show_on_disk_super(struct seq_file *m, struct super_block *sb) | |||
261 | return 0; | 266 | return 0; |
262 | } | 267 | } |
263 | 268 | ||
264 | static int show_oidmap(struct seq_file *m, struct super_block *sb) | 269 | static int show_oidmap(struct seq_file *m, void *unused) |
265 | { | 270 | { |
271 | struct super_block *sb = m->private; | ||
266 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); | 272 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); |
267 | struct reiserfs_super_block *rs = sb_info->s_rs; | 273 | struct reiserfs_super_block *rs = sb_info->s_rs; |
268 | unsigned int mapsize = le16_to_cpu(rs->s_v1.s_oid_cursize); | 274 | unsigned int mapsize = le16_to_cpu(rs->s_v1.s_oid_cursize); |
@@ -291,8 +297,9 @@ static int show_oidmap(struct seq_file *m, struct super_block *sb) | |||
291 | return 0; | 297 | return 0; |
292 | } | 298 | } |
293 | 299 | ||
294 | static int show_journal(struct seq_file *m, struct super_block *sb) | 300 | static int show_journal(struct seq_file *m, void *unused) |
295 | { | 301 | { |
302 | struct super_block *sb = m->private; | ||
296 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 303 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
297 | struct reiserfs_super_block *rs = r->s_rs; | 304 | struct reiserfs_super_block *rs = r->s_rs; |
298 | struct journal_params *jp = &rs->s_v1.s_journal; | 305 | struct journal_params *jp = &rs->s_v1.s_journal; |
@@ -383,92 +390,24 @@ static int show_journal(struct seq_file *m, struct super_block *sb) | |||
383 | return 0; | 390 | return 0; |
384 | } | 391 | } |
385 | 392 | ||
386 | /* iterator */ | ||
387 | static int test_sb(struct super_block *sb, void *data) | ||
388 | { | ||
389 | return data == sb; | ||
390 | } | ||
391 | |||
392 | static int set_sb(struct super_block *sb, void *data) | ||
393 | { | ||
394 | return -ENOENT; | ||
395 | } | ||
396 | |||
397 | struct reiserfs_seq_private { | ||
398 | struct super_block *sb; | ||
399 | int (*show) (struct seq_file *, struct super_block *); | ||
400 | }; | ||
401 | |||
402 | static void *r_start(struct seq_file *m, loff_t * pos) | ||
403 | { | ||
404 | struct reiserfs_seq_private *priv = m->private; | ||
405 | loff_t l = *pos; | ||
406 | |||
407 | if (l) | ||
408 | return NULL; | ||
409 | |||
410 | if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, 0, priv->sb))) | ||
411 | return NULL; | ||
412 | |||
413 | up_write(&priv->sb->s_umount); | ||
414 | return priv->sb; | ||
415 | } | ||
416 | |||
417 | static void *r_next(struct seq_file *m, void *v, loff_t * pos) | ||
418 | { | ||
419 | ++*pos; | ||
420 | if (v) | ||
421 | deactivate_super(v); | ||
422 | return NULL; | ||
423 | } | ||
424 | |||
425 | static void r_stop(struct seq_file *m, void *v) | ||
426 | { | ||
427 | if (v) | ||
428 | deactivate_super(v); | ||
429 | } | ||
430 | |||
431 | static int r_show(struct seq_file *m, void *v) | ||
432 | { | ||
433 | struct reiserfs_seq_private *priv = m->private; | ||
434 | return priv->show(m, v); | ||
435 | } | ||
436 | |||
437 | static const struct seq_operations r_ops = { | ||
438 | .start = r_start, | ||
439 | .next = r_next, | ||
440 | .stop = r_stop, | ||
441 | .show = r_show, | ||
442 | }; | ||
443 | |||
444 | static int r_open(struct inode *inode, struct file *file) | 393 | static int r_open(struct inode *inode, struct file *file) |
445 | { | 394 | { |
446 | struct reiserfs_seq_private *priv; | 395 | return single_open(file, PDE_DATA(inode), |
447 | int ret = seq_open_private(file, &r_ops, | 396 | proc_get_parent_data(inode)); |
448 | sizeof(struct reiserfs_seq_private)); | ||
449 | |||
450 | if (!ret) { | ||
451 | struct seq_file *m = file->private_data; | ||
452 | priv = m->private; | ||
453 | priv->sb = proc_get_parent_data(inode); | ||
454 | priv->show = PDE_DATA(inode); | ||
455 | } | ||
456 | return ret; | ||
457 | } | 397 | } |
458 | 398 | ||
459 | static const struct file_operations r_file_operations = { | 399 | static const struct file_operations r_file_operations = { |
460 | .open = r_open, | 400 | .open = r_open, |
461 | .read = seq_read, | 401 | .read = seq_read, |
462 | .llseek = seq_lseek, | 402 | .llseek = seq_lseek, |
463 | .release = seq_release_private, | 403 | .release = single_release, |
464 | .owner = THIS_MODULE, | ||
465 | }; | 404 | }; |
466 | 405 | ||
467 | static struct proc_dir_entry *proc_info_root = NULL; | 406 | static struct proc_dir_entry *proc_info_root = NULL; |
468 | static const char proc_info_root_name[] = "fs/reiserfs"; | 407 | static const char proc_info_root_name[] = "fs/reiserfs"; |
469 | 408 | ||
470 | static void add_file(struct super_block *sb, char *name, | 409 | static void add_file(struct super_block *sb, char *name, |
471 | int (*func) (struct seq_file *, struct super_block *)) | 410 | int (*func) (struct seq_file *, void *)) |
472 | { | 411 | { |
473 | proc_create_data(name, 0, REISERFS_SB(sb)->procdir, | 412 | proc_create_data(name, 0, REISERFS_SB(sb)->procdir, |
474 | &r_file_operations, func); | 413 | &r_file_operations, func); |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index f8a23c3078f8..e2e202a07b31 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -499,6 +499,7 @@ int remove_save_link(struct inode *inode, int truncate) | |||
499 | static void reiserfs_kill_sb(struct super_block *s) | 499 | static void reiserfs_kill_sb(struct super_block *s) |
500 | { | 500 | { |
501 | if (REISERFS_SB(s)) { | 501 | if (REISERFS_SB(s)) { |
502 | reiserfs_proc_info_done(s); | ||
502 | /* | 503 | /* |
503 | * Force any pending inode evictions to occur now. Any | 504 | * Force any pending inode evictions to occur now. Any |
504 | * inodes to be removed that have extended attributes | 505 | * inodes to be removed that have extended attributes |
@@ -554,8 +555,6 @@ static void reiserfs_put_super(struct super_block *s) | |||
554 | REISERFS_SB(s)->reserved_blocks); | 555 | REISERFS_SB(s)->reserved_blocks); |
555 | } | 556 | } |
556 | 557 | ||
557 | reiserfs_proc_info_done(s); | ||
558 | |||
559 | reiserfs_write_unlock(s); | 558 | reiserfs_write_unlock(s); |
560 | mutex_destroy(&REISERFS_SB(s)->lock); | 559 | mutex_destroy(&REISERFS_SB(s)->lock); |
561 | kfree(s->s_fs_info); | 560 | kfree(s->s_fs_info); |
diff --git a/fs/xfs/xfs_dinode.h b/fs/xfs/xfs_dinode.h index 07d735a80a0f..e5869b50dc41 100644 --- a/fs/xfs/xfs_dinode.h +++ b/fs/xfs/xfs_dinode.h | |||
@@ -39,6 +39,9 @@ typedef struct xfs_timestamp { | |||
39 | * There is a very similar struct icdinode in xfs_inode which matches the | 39 | * There is a very similar struct icdinode in xfs_inode which matches the |
40 | * layout of the first 96 bytes of this structure, but is kept in native | 40 | * layout of the first 96 bytes of this structure, but is kept in native |
41 | * format instead of big endian. | 41 | * format instead of big endian. |
42 | * | ||
43 | * Note: di_flushiter is only used by v1/2 inodes - it's effectively a zeroed | ||
44 | * padding field for v3 inodes. | ||
42 | */ | 45 | */ |
43 | typedef struct xfs_dinode { | 46 | typedef struct xfs_dinode { |
44 | __be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */ | 47 | __be16 di_magic; /* inode magic # = XFS_DINODE_MAGIC */ |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index b78481f99d9d..bb262c25c8de 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -896,7 +896,6 @@ xfs_dinode_to_disk( | |||
896 | to->di_projid_lo = cpu_to_be16(from->di_projid_lo); | 896 | to->di_projid_lo = cpu_to_be16(from->di_projid_lo); |
897 | to->di_projid_hi = cpu_to_be16(from->di_projid_hi); | 897 | to->di_projid_hi = cpu_to_be16(from->di_projid_hi); |
898 | memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); | 898 | memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); |
899 | to->di_flushiter = cpu_to_be16(from->di_flushiter); | ||
900 | to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); | 899 | to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); |
901 | to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); | 900 | to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); |
902 | to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); | 901 | to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); |
@@ -924,6 +923,9 @@ xfs_dinode_to_disk( | |||
924 | to->di_lsn = cpu_to_be64(from->di_lsn); | 923 | to->di_lsn = cpu_to_be64(from->di_lsn); |
925 | memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); | 924 | memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2)); |
926 | uuid_copy(&to->di_uuid, &from->di_uuid); | 925 | uuid_copy(&to->di_uuid, &from->di_uuid); |
926 | to->di_flushiter = 0; | ||
927 | } else { | ||
928 | to->di_flushiter = cpu_to_be16(from->di_flushiter); | ||
927 | } | 929 | } |
928 | } | 930 | } |
929 | 931 | ||
@@ -1029,10 +1031,14 @@ xfs_dinode_calc_crc( | |||
1029 | /* | 1031 | /* |
1030 | * Read the disk inode attributes into the in-core inode structure. | 1032 | * Read the disk inode attributes into the in-core inode structure. |
1031 | * | 1033 | * |
1032 | * If we are initialising a new inode and we are not utilising the | 1034 | * For version 5 superblocks, if we are initialising a new inode and we are not |
1033 | * XFS_MOUNT_IKEEP inode cluster mode, we can simple build the new inode core | 1035 | * utilising the XFS_MOUNT_IKEEP inode cluster mode, we can simple build the new |
1034 | * with a random generation number. If we are keeping inodes around, we need to | 1036 | * inode core with a random generation number. If we are keeping inodes around, |
1035 | * read the inode cluster to get the existing generation number off disk. | 1037 | * we need to read the inode cluster to get the existing generation number off |
1038 | * disk. Further, if we are using version 4 superblocks (i.e. v1/v2 inode | ||
1039 | * format) then log recovery is dependent on the di_flushiter field being | ||
1040 | * initialised from the current on-disk value and hence we must also read the | ||
1041 | * inode off disk. | ||
1036 | */ | 1042 | */ |
1037 | int | 1043 | int |
1038 | xfs_iread( | 1044 | xfs_iread( |
@@ -1054,6 +1060,7 @@ xfs_iread( | |||
1054 | 1060 | ||
1055 | /* shortcut IO on inode allocation if possible */ | 1061 | /* shortcut IO on inode allocation if possible */ |
1056 | if ((iget_flags & XFS_IGET_CREATE) && | 1062 | if ((iget_flags & XFS_IGET_CREATE) && |
1063 | xfs_sb_version_hascrc(&mp->m_sb) && | ||
1057 | !(mp->m_flags & XFS_MOUNT_IKEEP)) { | 1064 | !(mp->m_flags & XFS_MOUNT_IKEEP)) { |
1058 | /* initialise the on-disk inode core */ | 1065 | /* initialise the on-disk inode core */ |
1059 | memset(&ip->i_d, 0, sizeof(ip->i_d)); | 1066 | memset(&ip->i_d, 0, sizeof(ip->i_d)); |
@@ -2882,12 +2889,18 @@ xfs_iflush_int( | |||
2882 | __func__, ip->i_ino, ip->i_d.di_forkoff, ip); | 2889 | __func__, ip->i_ino, ip->i_d.di_forkoff, ip); |
2883 | goto corrupt_out; | 2890 | goto corrupt_out; |
2884 | } | 2891 | } |
2892 | |||
2885 | /* | 2893 | /* |
2886 | * bump the flush iteration count, used to detect flushes which | 2894 | * Inode item log recovery for v1/v2 inodes are dependent on the |
2887 | * postdate a log record during recovery. This is redundant as we now | 2895 | * di_flushiter count for correct sequencing. We bump the flush |
2888 | * log every change and hence this can't happen. Still, it doesn't hurt. | 2896 | * iteration count so we can detect flushes which postdate a log record |
2897 | * during recovery. This is redundant as we now log every change and | ||
2898 | * hence this can't happen but we need to still do it to ensure | ||
2899 | * backwards compatibility with old kernels that predate logging all | ||
2900 | * inode changes. | ||
2889 | */ | 2901 | */ |
2890 | ip->i_d.di_flushiter++; | 2902 | if (ip->i_d.di_version < 3) |
2903 | ip->i_d.di_flushiter++; | ||
2891 | 2904 | ||
2892 | /* | 2905 | /* |
2893 | * Copy the dirty parts of the inode into the on-disk | 2906 | * Copy the dirty parts of the inode into the on-disk |
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 6fcc910a50b9..7681b19aa5dc 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c | |||
@@ -2592,8 +2592,16 @@ xlog_recover_inode_pass2( | |||
2592 | goto error; | 2592 | goto error; |
2593 | } | 2593 | } |
2594 | 2594 | ||
2595 | /* Skip replay when the on disk inode is newer than the log one */ | 2595 | /* |
2596 | if (dicp->di_flushiter < be16_to_cpu(dip->di_flushiter)) { | 2596 | * di_flushiter is only valid for v1/2 inodes. All changes for v3 inodes |
2597 | * are transactional and if ordering is necessary we can determine that | ||
2598 | * more accurately by the LSN field in the V3 inode core. Don't trust | ||
2599 | * the inode versions we might be changing them here - use the | ||
2600 | * superblock flag to determine whether we need to look at di_flushiter | ||
2601 | * to skip replay when the on disk inode is newer than the log one | ||
2602 | */ | ||
2603 | if (!xfs_sb_version_hascrc(&mp->m_sb) && | ||
2604 | dicp->di_flushiter < be16_to_cpu(dip->di_flushiter)) { | ||
2597 | /* | 2605 | /* |
2598 | * Deal with the wrap case, DI_MAX_FLUSH is less | 2606 | * Deal with the wrap case, DI_MAX_FLUSH is less |
2599 | * than smaller numbers | 2607 | * than smaller numbers |
@@ -2608,6 +2616,7 @@ xlog_recover_inode_pass2( | |||
2608 | goto error; | 2616 | goto error; |
2609 | } | 2617 | } |
2610 | } | 2618 | } |
2619 | |||
2611 | /* Take the opportunity to reset the flush iteration count */ | 2620 | /* Take the opportunity to reset the flush iteration count */ |
2612 | dicp->di_flushiter = 0; | 2621 | dicp->di_flushiter = 0; |
2613 | 2622 | ||