diff options
Diffstat (limited to 'fs')
53 files changed, 758 insertions, 497 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 2d3e32ebfd15..8729cf68d2fe 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -1552,7 +1552,6 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, | |||
1552 | { | 1552 | { |
1553 | int ret; | 1553 | int ret; |
1554 | int type; | 1554 | int type; |
1555 | struct btrfs_tree_block_info *info; | ||
1556 | struct btrfs_extent_inline_ref *eiref; | 1555 | struct btrfs_extent_inline_ref *eiref; |
1557 | 1556 | ||
1558 | if (*ptr == (unsigned long)-1) | 1557 | if (*ptr == (unsigned long)-1) |
@@ -1573,9 +1572,17 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, | |||
1573 | } | 1572 | } |
1574 | 1573 | ||
1575 | /* we can treat both ref types equally here */ | 1574 | /* we can treat both ref types equally here */ |
1576 | info = (struct btrfs_tree_block_info *)(ei + 1); | ||
1577 | *out_root = btrfs_extent_inline_ref_offset(eb, eiref); | 1575 | *out_root = btrfs_extent_inline_ref_offset(eb, eiref); |
1578 | *out_level = btrfs_tree_block_level(eb, info); | 1576 | |
1577 | if (key->type == BTRFS_EXTENT_ITEM_KEY) { | ||
1578 | struct btrfs_tree_block_info *info; | ||
1579 | |||
1580 | info = (struct btrfs_tree_block_info *)(ei + 1); | ||
1581 | *out_level = btrfs_tree_block_level(eb, info); | ||
1582 | } else { | ||
1583 | ASSERT(key->type == BTRFS_METADATA_ITEM_KEY); | ||
1584 | *out_level = (u8)key->offset; | ||
1585 | } | ||
1579 | 1586 | ||
1580 | if (ret == 1) | 1587 | if (ret == 1) |
1581 | *ptr = (unsigned long)-1; | 1588 | *ptr = (unsigned long)-1; |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 7e607416755a..0b180708bf79 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1171,6 +1171,7 @@ struct btrfs_space_info { | |||
1171 | struct percpu_counter total_bytes_pinned; | 1171 | struct percpu_counter total_bytes_pinned; |
1172 | 1172 | ||
1173 | struct list_head list; | 1173 | struct list_head list; |
1174 | /* Protected by the spinlock 'lock'. */ | ||
1174 | struct list_head ro_bgs; | 1175 | struct list_head ro_bgs; |
1175 | 1176 | ||
1176 | struct rw_semaphore groups_sem; | 1177 | struct rw_semaphore groups_sem; |
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c index 054577bddaf2..de4e70fb3cbb 100644 --- a/fs/btrfs/delayed-inode.c +++ b/fs/btrfs/delayed-inode.c | |||
@@ -1857,6 +1857,14 @@ int btrfs_delayed_delete_inode_ref(struct inode *inode) | |||
1857 | { | 1857 | { |
1858 | struct btrfs_delayed_node *delayed_node; | 1858 | struct btrfs_delayed_node *delayed_node; |
1859 | 1859 | ||
1860 | /* | ||
1861 | * we don't do delayed inode updates during log recovery because it | ||
1862 | * leads to enospc problems. This means we also can't do | ||
1863 | * delayed inode refs | ||
1864 | */ | ||
1865 | if (BTRFS_I(inode)->root->fs_info->log_root_recovering) | ||
1866 | return -EAGAIN; | ||
1867 | |||
1860 | delayed_node = btrfs_get_or_create_delayed_node(inode); | 1868 | delayed_node = btrfs_get_or_create_delayed_node(inode); |
1861 | if (IS_ERR(delayed_node)) | 1869 | if (IS_ERR(delayed_node)) |
1862 | return PTR_ERR(delayed_node); | 1870 | return PTR_ERR(delayed_node); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index a80b97100d90..a684086c3c81 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3139,9 +3139,11 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, | |||
3139 | struct extent_buffer *leaf; | 3139 | struct extent_buffer *leaf; |
3140 | 3140 | ||
3141 | ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); | 3141 | ret = btrfs_search_slot(trans, extent_root, &cache->key, path, 0, 1); |
3142 | if (ret < 0) | 3142 | if (ret) { |
3143 | if (ret > 0) | ||
3144 | ret = -ENOENT; | ||
3143 | goto fail; | 3145 | goto fail; |
3144 | BUG_ON(ret); /* Corruption */ | 3146 | } |
3145 | 3147 | ||
3146 | leaf = path->nodes[0]; | 3148 | leaf = path->nodes[0]; |
3147 | bi = btrfs_item_ptr_offset(leaf, path->slots[0]); | 3149 | bi = btrfs_item_ptr_offset(leaf, path->slots[0]); |
@@ -3149,11 +3151,9 @@ static int write_one_cache_group(struct btrfs_trans_handle *trans, | |||
3149 | btrfs_mark_buffer_dirty(leaf); | 3151 | btrfs_mark_buffer_dirty(leaf); |
3150 | btrfs_release_path(path); | 3152 | btrfs_release_path(path); |
3151 | fail: | 3153 | fail: |
3152 | if (ret) { | 3154 | if (ret) |
3153 | btrfs_abort_transaction(trans, root, ret); | 3155 | btrfs_abort_transaction(trans, root, ret); |
3154 | return ret; | 3156 | return ret; |
3155 | } | ||
3156 | return 0; | ||
3157 | 3157 | ||
3158 | } | 3158 | } |
3159 | 3159 | ||
@@ -9422,7 +9422,6 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
9422 | * are still on the list after taking the semaphore | 9422 | * are still on the list after taking the semaphore |
9423 | */ | 9423 | */ |
9424 | list_del_init(&block_group->list); | 9424 | list_del_init(&block_group->list); |
9425 | list_del_init(&block_group->ro_list); | ||
9426 | if (list_empty(&block_group->space_info->block_groups[index])) { | 9425 | if (list_empty(&block_group->space_info->block_groups[index])) { |
9427 | kobj = block_group->space_info->block_group_kobjs[index]; | 9426 | kobj = block_group->space_info->block_group_kobjs[index]; |
9428 | block_group->space_info->block_group_kobjs[index] = NULL; | 9427 | block_group->space_info->block_group_kobjs[index] = NULL; |
@@ -9464,6 +9463,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
9464 | btrfs_remove_free_space_cache(block_group); | 9463 | btrfs_remove_free_space_cache(block_group); |
9465 | 9464 | ||
9466 | spin_lock(&block_group->space_info->lock); | 9465 | spin_lock(&block_group->space_info->lock); |
9466 | list_del_init(&block_group->ro_list); | ||
9467 | block_group->space_info->total_bytes -= block_group->key.offset; | 9467 | block_group->space_info->total_bytes -= block_group->key.offset; |
9468 | block_group->space_info->bytes_readonly -= block_group->key.offset; | 9468 | block_group->space_info->bytes_readonly -= block_group->key.offset; |
9469 | block_group->space_info->disk_total -= block_group->key.offset * factor; | 9469 | block_group->space_info->disk_total -= block_group->key.offset * factor; |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 4ebabd237153..790dbae3343c 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -2190,7 +2190,7 @@ void btrfs_free_io_failure_record(struct inode *inode, u64 start, u64 end) | |||
2190 | 2190 | ||
2191 | next = next_state(state); | 2191 | next = next_state(state); |
2192 | 2192 | ||
2193 | failrec = (struct io_failure_record *)state->private; | 2193 | failrec = (struct io_failure_record *)(unsigned long)state->private; |
2194 | free_extent_state(state); | 2194 | free_extent_state(state); |
2195 | kfree(failrec); | 2195 | kfree(failrec); |
2196 | 2196 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index e687bb0dc73a..8bf326affb94 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -6255,8 +6255,10 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) | |||
6255 | 6255 | ||
6256 | out_fail: | 6256 | out_fail: |
6257 | btrfs_end_transaction(trans, root); | 6257 | btrfs_end_transaction(trans, root); |
6258 | if (drop_on_err) | 6258 | if (drop_on_err) { |
6259 | inode_dec_link_count(inode); | ||
6259 | iput(inode); | 6260 | iput(inode); |
6261 | } | ||
6260 | btrfs_balance_delayed_items(root); | 6262 | btrfs_balance_delayed_items(root); |
6261 | btrfs_btree_balance_dirty(root); | 6263 | btrfs_btree_balance_dirty(root); |
6262 | return err; | 6264 | return err; |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index f2bb13a23f86..e427cb7ee12c 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -2607,9 +2607,9 @@ static int scrub_extent_for_parity(struct scrub_parity *sparity, | |||
2607 | ret = scrub_pages_for_parity(sparity, logical, l, physical, dev, | 2607 | ret = scrub_pages_for_parity(sparity, logical, l, physical, dev, |
2608 | flags, gen, mirror_num, | 2608 | flags, gen, mirror_num, |
2609 | have_csum ? csum : NULL); | 2609 | have_csum ? csum : NULL); |
2610 | skip: | ||
2611 | if (ret) | 2610 | if (ret) |
2612 | return ret; | 2611 | return ret; |
2612 | skip: | ||
2613 | len -= l; | 2613 | len -= l; |
2614 | logical += l; | 2614 | logical += l; |
2615 | physical += l; | 2615 | physical += l; |
@@ -3053,7 +3053,7 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, | |||
3053 | 3053 | ||
3054 | ppath = btrfs_alloc_path(); | 3054 | ppath = btrfs_alloc_path(); |
3055 | if (!ppath) { | 3055 | if (!ppath) { |
3056 | btrfs_free_path(ppath); | 3056 | btrfs_free_path(path); |
3057 | return -ENOMEM; | 3057 | return -ENOMEM; |
3058 | } | 3058 | } |
3059 | 3059 | ||
@@ -3065,6 +3065,8 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx, | |||
3065 | path->search_commit_root = 1; | 3065 | path->search_commit_root = 1; |
3066 | path->skip_locking = 1; | 3066 | path->skip_locking = 1; |
3067 | 3067 | ||
3068 | ppath->search_commit_root = 1; | ||
3069 | ppath->skip_locking = 1; | ||
3068 | /* | 3070 | /* |
3069 | * trigger the readahead for extent tree csum tree and wait for | 3071 | * trigger the readahead for extent tree csum tree and wait for |
3070 | * completion. During readahead, the scrub is officially paused | 3072 | * completion. During readahead, the scrub is officially paused |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 60f7cbe815e9..6f49b2872a64 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -1000,10 +1000,20 @@ int btrfs_sync_fs(struct super_block *sb, int wait) | |||
1000 | */ | 1000 | */ |
1001 | if (fs_info->pending_changes == 0) | 1001 | if (fs_info->pending_changes == 0) |
1002 | return 0; | 1002 | return 0; |
1003 | /* | ||
1004 | * A non-blocking test if the fs is frozen. We must not | ||
1005 | * start a new transaction here otherwise a deadlock | ||
1006 | * happens. The pending operations are delayed to the | ||
1007 | * next commit after thawing. | ||
1008 | */ | ||
1009 | if (__sb_start_write(sb, SB_FREEZE_WRITE, false)) | ||
1010 | __sb_end_write(sb, SB_FREEZE_WRITE); | ||
1011 | else | ||
1012 | return 0; | ||
1003 | trans = btrfs_start_transaction(root, 0); | 1013 | trans = btrfs_start_transaction(root, 0); |
1004 | } else { | ||
1005 | return PTR_ERR(trans); | ||
1006 | } | 1014 | } |
1015 | if (IS_ERR(trans)) | ||
1016 | return PTR_ERR(trans); | ||
1007 | } | 1017 | } |
1008 | return btrfs_commit_transaction(trans, root); | 1018 | return btrfs_commit_transaction(trans, root); |
1009 | } | 1019 | } |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index a605d4e2f2bc..e88b59d13439 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -2118,7 +2118,7 @@ void btrfs_apply_pending_changes(struct btrfs_fs_info *fs_info) | |||
2118 | unsigned long prev; | 2118 | unsigned long prev; |
2119 | unsigned long bit; | 2119 | unsigned long bit; |
2120 | 2120 | ||
2121 | prev = cmpxchg(&fs_info->pending_changes, 0, 0); | 2121 | prev = xchg(&fs_info->pending_changes, 0); |
2122 | if (!prev) | 2122 | if (!prev) |
2123 | return; | 2123 | return; |
2124 | 2124 | ||
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index f5013d92a7e6..c81c0e004588 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c | |||
@@ -1416,7 +1416,7 @@ void ceph_fill_inline_data(struct inode *inode, struct page *locked_page, | |||
1416 | } | 1416 | } |
1417 | } | 1417 | } |
1418 | 1418 | ||
1419 | dout("fill_inline_data %p %llx.%llx len %lu locked_page %p\n", | 1419 | dout("fill_inline_data %p %llx.%llx len %zu locked_page %p\n", |
1420 | inode, ceph_vinop(inode), len, locked_page); | 1420 | inode, ceph_vinop(inode), len, locked_page); |
1421 | 1421 | ||
1422 | if (len > 0) { | 1422 | if (len > 0) { |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 6e139111fdb2..22b289a3b1c4 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -661,16 +661,16 @@ set_credits(struct TCP_Server_Info *server, const int val) | |||
661 | server->ops->set_credits(server, val); | 661 | server->ops->set_credits(server, val); |
662 | } | 662 | } |
663 | 663 | ||
664 | static inline __u64 | 664 | static inline __le64 |
665 | get_next_mid64(struct TCP_Server_Info *server) | 665 | get_next_mid64(struct TCP_Server_Info *server) |
666 | { | 666 | { |
667 | return server->ops->get_next_mid(server); | 667 | return cpu_to_le64(server->ops->get_next_mid(server)); |
668 | } | 668 | } |
669 | 669 | ||
670 | static inline __le16 | 670 | static inline __le16 |
671 | get_next_mid(struct TCP_Server_Info *server) | 671 | get_next_mid(struct TCP_Server_Info *server) |
672 | { | 672 | { |
673 | __u16 mid = get_next_mid64(server); | 673 | __u16 mid = server->ops->get_next_mid(server); |
674 | /* | 674 | /* |
675 | * The value in the SMB header should be little endian for easy | 675 | * The value in the SMB header should be little endian for easy |
676 | * on-the-wire decoding. | 676 | * on-the-wire decoding. |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 45cb59bcc791..8b7898b7670f 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
@@ -86,21 +86,16 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, | |||
86 | } | 86 | } |
87 | 87 | ||
88 | src_inode = file_inode(src_file.file); | 88 | src_inode = file_inode(src_file.file); |
89 | rc = -EINVAL; | ||
90 | if (S_ISDIR(src_inode->i_mode)) | ||
91 | goto out_fput; | ||
89 | 92 | ||
90 | /* | 93 | /* |
91 | * Note: cifs case is easier than btrfs since server responsible for | 94 | * Note: cifs case is easier than btrfs since server responsible for |
92 | * checks for proper open modes and file type and if it wants | 95 | * checks for proper open modes and file type and if it wants |
93 | * server could even support copy of range where source = target | 96 | * server could even support copy of range where source = target |
94 | */ | 97 | */ |
95 | 98 | lock_two_nondirectories(target_inode, src_inode); | |
96 | /* so we do not deadlock racing two ioctls on same files */ | ||
97 | if (target_inode < src_inode) { | ||
98 | mutex_lock_nested(&target_inode->i_mutex, I_MUTEX_PARENT); | ||
99 | mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_CHILD); | ||
100 | } else { | ||
101 | mutex_lock_nested(&src_inode->i_mutex, I_MUTEX_PARENT); | ||
102 | mutex_lock_nested(&target_inode->i_mutex, I_MUTEX_CHILD); | ||
103 | } | ||
104 | 99 | ||
105 | /* determine range to clone */ | 100 | /* determine range to clone */ |
106 | rc = -EINVAL; | 101 | rc = -EINVAL; |
@@ -124,13 +119,7 @@ static long cifs_ioctl_clone(unsigned int xid, struct file *dst_file, | |||
124 | out_unlock: | 119 | out_unlock: |
125 | /* although unlocking in the reverse order from locking is not | 120 | /* although unlocking in the reverse order from locking is not |
126 | strictly necessary here it is a little cleaner to be consistent */ | 121 | strictly necessary here it is a little cleaner to be consistent */ |
127 | if (target_inode < src_inode) { | 122 | unlock_two_nondirectories(src_inode, target_inode); |
128 | mutex_unlock(&src_inode->i_mutex); | ||
129 | mutex_unlock(&target_inode->i_mutex); | ||
130 | } else { | ||
131 | mutex_unlock(&target_inode->i_mutex); | ||
132 | mutex_unlock(&src_inode->i_mutex); | ||
133 | } | ||
134 | out_fput: | 123 | out_fput: |
135 | fdput(src_file); | 124 | fdput(src_file); |
136 | out_drop_write: | 125 | out_drop_write: |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index b333ff60781d..abae6dd2c6b9 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
@@ -926,6 +926,7 @@ cifs_NTtimeToUnix(__le64 ntutc) | |||
926 | 926 | ||
927 | /* Subtract the NTFS time offset, then convert to 1s intervals. */ | 927 | /* Subtract the NTFS time offset, then convert to 1s intervals. */ |
928 | s64 t = le64_to_cpu(ntutc) - NTFS_TIME_OFFSET; | 928 | s64 t = le64_to_cpu(ntutc) - NTFS_TIME_OFFSET; |
929 | u64 abs_t; | ||
929 | 930 | ||
930 | /* | 931 | /* |
931 | * Unfortunately can not use normal 64 bit division on 32 bit arch, but | 932 | * Unfortunately can not use normal 64 bit division on 32 bit arch, but |
@@ -933,13 +934,14 @@ cifs_NTtimeToUnix(__le64 ntutc) | |||
933 | * to special case them | 934 | * to special case them |
934 | */ | 935 | */ |
935 | if (t < 0) { | 936 | if (t < 0) { |
936 | t = -t; | 937 | abs_t = -t; |
937 | ts.tv_nsec = (long)(do_div(t, 10000000) * 100); | 938 | ts.tv_nsec = (long)(do_div(abs_t, 10000000) * 100); |
938 | ts.tv_nsec = -ts.tv_nsec; | 939 | ts.tv_nsec = -ts.tv_nsec; |
939 | ts.tv_sec = -t; | 940 | ts.tv_sec = -abs_t; |
940 | } else { | 941 | } else { |
941 | ts.tv_nsec = (long)do_div(t, 10000000) * 100; | 942 | abs_t = t; |
942 | ts.tv_sec = t; | 943 | ts.tv_nsec = (long)do_div(abs_t, 10000000) * 100; |
944 | ts.tv_sec = abs_t; | ||
943 | } | 945 | } |
944 | 946 | ||
945 | return ts; | 947 | return ts; |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 8eaf20a80649..c295338e0a98 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -69,7 +69,8 @@ static inline void dump_cifs_file_struct(struct file *file, char *label) | |||
69 | * Attempt to preload the dcache with the results from the FIND_FIRST/NEXT | 69 | * Attempt to preload the dcache with the results from the FIND_FIRST/NEXT |
70 | * | 70 | * |
71 | * Find the dentry that matches "name". If there isn't one, create one. If it's | 71 | * Find the dentry that matches "name". If there isn't one, create one. If it's |
72 | * a negative dentry or the uniqueid changed, then drop it and recreate it. | 72 | * a negative dentry or the uniqueid or filetype(mode) changed, |
73 | * then drop it and recreate it. | ||
73 | */ | 74 | */ |
74 | static void | 75 | static void |
75 | cifs_prime_dcache(struct dentry *parent, struct qstr *name, | 76 | cifs_prime_dcache(struct dentry *parent, struct qstr *name, |
@@ -97,8 +98,11 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, | |||
97 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) | 98 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) |
98 | fattr->cf_uniqueid = CIFS_I(inode)->uniqueid; | 99 | fattr->cf_uniqueid = CIFS_I(inode)->uniqueid; |
99 | 100 | ||
100 | /* update inode in place if i_ino didn't change */ | 101 | /* update inode in place |
101 | if (CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) { | 102 | * if both i_ino and i_mode didn't change */ |
103 | if (CIFS_I(inode)->uniqueid == fattr->cf_uniqueid && | ||
104 | (inode->i_mode & S_IFMT) == | ||
105 | (fattr->cf_mode & S_IFMT)) { | ||
102 | cifs_fattr_to_inode(inode, fattr); | 106 | cifs_fattr_to_inode(inode, fattr); |
103 | goto out; | 107 | goto out; |
104 | } | 108 | } |
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c index f1cefc9763ed..689f035915cf 100644 --- a/fs/cifs/smb2misc.c +++ b/fs/cifs/smb2misc.c | |||
@@ -32,12 +32,14 @@ | |||
32 | static int | 32 | static int |
33 | check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid) | 33 | check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid) |
34 | { | 34 | { |
35 | __u64 wire_mid = le64_to_cpu(hdr->MessageId); | ||
36 | |||
35 | /* | 37 | /* |
36 | * Make sure that this really is an SMB, that it is a response, | 38 | * Make sure that this really is an SMB, that it is a response, |
37 | * and that the message ids match. | 39 | * and that the message ids match. |
38 | */ | 40 | */ |
39 | if ((*(__le32 *)hdr->ProtocolId == SMB2_PROTO_NUMBER) && | 41 | if ((*(__le32 *)hdr->ProtocolId == SMB2_PROTO_NUMBER) && |
40 | (mid == hdr->MessageId)) { | 42 | (mid == wire_mid)) { |
41 | if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR) | 43 | if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR) |
42 | return 0; | 44 | return 0; |
43 | else { | 45 | else { |
@@ -51,11 +53,11 @@ check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid) | |||
51 | if (*(__le32 *)hdr->ProtocolId != SMB2_PROTO_NUMBER) | 53 | if (*(__le32 *)hdr->ProtocolId != SMB2_PROTO_NUMBER) |
52 | cifs_dbg(VFS, "Bad protocol string signature header %x\n", | 54 | cifs_dbg(VFS, "Bad protocol string signature header %x\n", |
53 | *(unsigned int *) hdr->ProtocolId); | 55 | *(unsigned int *) hdr->ProtocolId); |
54 | if (mid != hdr->MessageId) | 56 | if (mid != wire_mid) |
55 | cifs_dbg(VFS, "Mids do not match: %llu and %llu\n", | 57 | cifs_dbg(VFS, "Mids do not match: %llu and %llu\n", |
56 | mid, hdr->MessageId); | 58 | mid, wire_mid); |
57 | } | 59 | } |
58 | cifs_dbg(VFS, "Bad SMB detected. The Mid=%llu\n", hdr->MessageId); | 60 | cifs_dbg(VFS, "Bad SMB detected. The Mid=%llu\n", wire_mid); |
59 | return 1; | 61 | return 1; |
60 | } | 62 | } |
61 | 63 | ||
@@ -95,7 +97,7 @@ smb2_check_message(char *buf, unsigned int length) | |||
95 | { | 97 | { |
96 | struct smb2_hdr *hdr = (struct smb2_hdr *)buf; | 98 | struct smb2_hdr *hdr = (struct smb2_hdr *)buf; |
97 | struct smb2_pdu *pdu = (struct smb2_pdu *)hdr; | 99 | struct smb2_pdu *pdu = (struct smb2_pdu *)hdr; |
98 | __u64 mid = hdr->MessageId; | 100 | __u64 mid = le64_to_cpu(hdr->MessageId); |
99 | __u32 len = get_rfc1002_length(buf); | 101 | __u32 len = get_rfc1002_length(buf); |
100 | __u32 clc_len; /* calculated length */ | 102 | __u32 clc_len; /* calculated length */ |
101 | int command; | 103 | int command; |
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 93fd0586f9ec..96b5d40a2ece 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -176,10 +176,11 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf) | |||
176 | { | 176 | { |
177 | struct mid_q_entry *mid; | 177 | struct mid_q_entry *mid; |
178 | struct smb2_hdr *hdr = (struct smb2_hdr *)buf; | 178 | struct smb2_hdr *hdr = (struct smb2_hdr *)buf; |
179 | __u64 wire_mid = le64_to_cpu(hdr->MessageId); | ||
179 | 180 | ||
180 | spin_lock(&GlobalMid_Lock); | 181 | spin_lock(&GlobalMid_Lock); |
181 | list_for_each_entry(mid, &server->pending_mid_q, qhead) { | 182 | list_for_each_entry(mid, &server->pending_mid_q, qhead) { |
182 | if ((mid->mid == hdr->MessageId) && | 183 | if ((mid->mid == wire_mid) && |
183 | (mid->mid_state == MID_REQUEST_SUBMITTED) && | 184 | (mid->mid_state == MID_REQUEST_SUBMITTED) && |
184 | (mid->command == hdr->Command)) { | 185 | (mid->command == hdr->Command)) { |
185 | spin_unlock(&GlobalMid_Lock); | 186 | spin_unlock(&GlobalMid_Lock); |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index ce858477002a..70867d54fb8b 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
@@ -110,7 +110,7 @@ struct smb2_hdr { | |||
110 | __le16 CreditRequest; /* CreditResponse */ | 110 | __le16 CreditRequest; /* CreditResponse */ |
111 | __le32 Flags; | 111 | __le32 Flags; |
112 | __le32 NextCommand; | 112 | __le32 NextCommand; |
113 | __u64 MessageId; /* opaque - so can stay little endian */ | 113 | __le64 MessageId; |
114 | __le32 ProcessId; | 114 | __le32 ProcessId; |
115 | __u32 TreeId; /* opaque - so do not make little endian */ | 115 | __u32 TreeId; /* opaque - so do not make little endian */ |
116 | __u64 SessionId; /* opaque - so do not make little endian */ | 116 | __u64 SessionId; /* opaque - so do not make little endian */ |
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c index 5111e7272db6..d4c5b6f109a7 100644 --- a/fs/cifs/smb2transport.c +++ b/fs/cifs/smb2transport.c | |||
@@ -490,7 +490,7 @@ smb2_mid_entry_alloc(const struct smb2_hdr *smb_buffer, | |||
490 | return temp; | 490 | return temp; |
491 | else { | 491 | else { |
492 | memset(temp, 0, sizeof(struct mid_q_entry)); | 492 | memset(temp, 0, sizeof(struct mid_q_entry)); |
493 | temp->mid = smb_buffer->MessageId; /* always LE */ | 493 | temp->mid = le64_to_cpu(smb_buffer->MessageId); |
494 | temp->pid = current->pid; | 494 | temp->pid = current->pid; |
495 | temp->command = smb_buffer->Command; /* Always LE */ | 495 | temp->command = smb_buffer->Command; /* Always LE */ |
496 | temp->when_alloc = jiffies; | 496 | temp->when_alloc = jiffies; |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e5d3eadf47b1..bed43081720f 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -5166,8 +5166,8 @@ int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
5166 | 5166 | ||
5167 | /* fallback to generic here if not in extents fmt */ | 5167 | /* fallback to generic here if not in extents fmt */ |
5168 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) | 5168 | if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) |
5169 | return __generic_block_fiemap(inode, fieinfo, start, len, | 5169 | return generic_block_fiemap(inode, fieinfo, start, len, |
5170 | ext4_get_block); | 5170 | ext4_get_block); |
5171 | 5171 | ||
5172 | if (fiemap_check_flags(fieinfo, EXT4_FIEMAP_FLAGS)) | 5172 | if (fiemap_check_flags(fieinfo, EXT4_FIEMAP_FLAGS)) |
5173 | return -EBADR; | 5173 | return -EBADR; |
diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 513c12cf444c..8131be8c0af3 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c | |||
@@ -273,19 +273,24 @@ static int ext4_file_open(struct inode * inode, struct file * filp) | |||
273 | * we determine this extent as a data or a hole according to whether the | 273 | * we determine this extent as a data or a hole according to whether the |
274 | * page cache has data or not. | 274 | * page cache has data or not. |
275 | */ | 275 | */ |
276 | static int ext4_find_unwritten_pgoff(struct inode *inode, int whence, | 276 | static int ext4_find_unwritten_pgoff(struct inode *inode, |
277 | loff_t endoff, loff_t *offset) | 277 | int whence, |
278 | struct ext4_map_blocks *map, | ||
279 | loff_t *offset) | ||
278 | { | 280 | { |
279 | struct pagevec pvec; | 281 | struct pagevec pvec; |
282 | unsigned int blkbits; | ||
280 | pgoff_t index; | 283 | pgoff_t index; |
281 | pgoff_t end; | 284 | pgoff_t end; |
285 | loff_t endoff; | ||
282 | loff_t startoff; | 286 | loff_t startoff; |
283 | loff_t lastoff; | 287 | loff_t lastoff; |
284 | int found = 0; | 288 | int found = 0; |
285 | 289 | ||
290 | blkbits = inode->i_sb->s_blocksize_bits; | ||
286 | startoff = *offset; | 291 | startoff = *offset; |
287 | lastoff = startoff; | 292 | lastoff = startoff; |
288 | 293 | endoff = (loff_t)(map->m_lblk + map->m_len) << blkbits; | |
289 | 294 | ||
290 | index = startoff >> PAGE_CACHE_SHIFT; | 295 | index = startoff >> PAGE_CACHE_SHIFT; |
291 | end = endoff >> PAGE_CACHE_SHIFT; | 296 | end = endoff >> PAGE_CACHE_SHIFT; |
@@ -403,144 +408,147 @@ out: | |||
403 | static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) | 408 | static loff_t ext4_seek_data(struct file *file, loff_t offset, loff_t maxsize) |
404 | { | 409 | { |
405 | struct inode *inode = file->f_mapping->host; | 410 | struct inode *inode = file->f_mapping->host; |
406 | struct fiemap_extent_info fie; | 411 | struct ext4_map_blocks map; |
407 | struct fiemap_extent ext[2]; | 412 | struct extent_status es; |
408 | loff_t next; | 413 | ext4_lblk_t start, last, end; |
409 | int i, ret = 0; | 414 | loff_t dataoff, isize; |
415 | int blkbits; | ||
416 | int ret = 0; | ||
410 | 417 | ||
411 | mutex_lock(&inode->i_mutex); | 418 | mutex_lock(&inode->i_mutex); |
412 | if (offset >= inode->i_size) { | 419 | |
420 | isize = i_size_read(inode); | ||
421 | if (offset >= isize) { | ||
413 | mutex_unlock(&inode->i_mutex); | 422 | mutex_unlock(&inode->i_mutex); |
414 | return -ENXIO; | 423 | return -ENXIO; |
415 | } | 424 | } |
416 | fie.fi_flags = 0; | 425 | |
417 | fie.fi_extents_max = 2; | 426 | blkbits = inode->i_sb->s_blocksize_bits; |
418 | fie.fi_extents_start = (struct fiemap_extent __user *) &ext; | 427 | start = offset >> blkbits; |
419 | while (1) { | 428 | last = start; |
420 | mm_segment_t old_fs = get_fs(); | 429 | end = isize >> blkbits; |
421 | 430 | dataoff = offset; | |
422 | fie.fi_extents_mapped = 0; | 431 | |
423 | memset(ext, 0, sizeof(*ext) * fie.fi_extents_max); | 432 | do { |
424 | 433 | map.m_lblk = last; | |
425 | set_fs(get_ds()); | 434 | map.m_len = end - last + 1; |
426 | ret = ext4_fiemap(inode, &fie, offset, maxsize - offset); | 435 | ret = ext4_map_blocks(NULL, inode, &map, 0); |
427 | set_fs(old_fs); | 436 | if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) { |
428 | if (ret) | 437 | if (last != start) |
438 | dataoff = (loff_t)last << blkbits; | ||
429 | break; | 439 | break; |
440 | } | ||
430 | 441 | ||
431 | /* No extents found, EOF */ | 442 | /* |
432 | if (!fie.fi_extents_mapped) { | 443 | * If there is a delay extent at this offset, |
433 | ret = -ENXIO; | 444 | * it will be as a data. |
445 | */ | ||
446 | ext4_es_find_delayed_extent_range(inode, last, last, &es); | ||
447 | if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) { | ||
448 | if (last != start) | ||
449 | dataoff = (loff_t)last << blkbits; | ||
434 | break; | 450 | break; |
435 | } | 451 | } |
436 | for (i = 0; i < fie.fi_extents_mapped; i++) { | ||
437 | next = (loff_t)(ext[i].fe_length + ext[i].fe_logical); | ||
438 | 452 | ||
439 | if (offset < (loff_t)ext[i].fe_logical) | 453 | /* |
440 | offset = (loff_t)ext[i].fe_logical; | 454 | * If there is a unwritten extent at this offset, |
441 | /* | 455 | * it will be as a data or a hole according to page |
442 | * If extent is not unwritten, then it contains valid | 456 | * cache that has data or not. |
443 | * data, mapped or delayed. | 457 | */ |
444 | */ | 458 | if (map.m_flags & EXT4_MAP_UNWRITTEN) { |
445 | if (!(ext[i].fe_flags & FIEMAP_EXTENT_UNWRITTEN)) | 459 | int unwritten; |
446 | goto out; | 460 | unwritten = ext4_find_unwritten_pgoff(inode, SEEK_DATA, |
461 | &map, &dataoff); | ||
462 | if (unwritten) | ||
463 | break; | ||
464 | } | ||
447 | 465 | ||
448 | /* | 466 | last++; |
449 | * If there is a unwritten extent at this offset, | 467 | dataoff = (loff_t)last << blkbits; |
450 | * it will be as a data or a hole according to page | 468 | } while (last <= end); |
451 | * cache that has data or not. | ||
452 | */ | ||
453 | if (ext4_find_unwritten_pgoff(inode, SEEK_DATA, | ||
454 | next, &offset)) | ||
455 | goto out; | ||
456 | 469 | ||
457 | if (ext[i].fe_flags & FIEMAP_EXTENT_LAST) { | ||
458 | ret = -ENXIO; | ||
459 | goto out; | ||
460 | } | ||
461 | offset = next; | ||
462 | } | ||
463 | } | ||
464 | if (offset > inode->i_size) | ||
465 | offset = inode->i_size; | ||
466 | out: | ||
467 | mutex_unlock(&inode->i_mutex); | 470 | mutex_unlock(&inode->i_mutex); |
468 | if (ret) | ||
469 | return ret; | ||
470 | 471 | ||
471 | return vfs_setpos(file, offset, maxsize); | 472 | if (dataoff > isize) |
473 | return -ENXIO; | ||
474 | |||
475 | return vfs_setpos(file, dataoff, maxsize); | ||
472 | } | 476 | } |
473 | 477 | ||
474 | /* | 478 | /* |
475 | * ext4_seek_hole() retrieves the offset for SEEK_HOLE | 479 | * ext4_seek_hole() retrieves the offset for SEEK_HOLE. |
476 | */ | 480 | */ |
477 | static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) | 481 | static loff_t ext4_seek_hole(struct file *file, loff_t offset, loff_t maxsize) |
478 | { | 482 | { |
479 | struct inode *inode = file->f_mapping->host; | 483 | struct inode *inode = file->f_mapping->host; |
480 | struct fiemap_extent_info fie; | 484 | struct ext4_map_blocks map; |
481 | struct fiemap_extent ext[2]; | 485 | struct extent_status es; |
482 | loff_t next; | 486 | ext4_lblk_t start, last, end; |
483 | int i, ret = 0; | 487 | loff_t holeoff, isize; |
488 | int blkbits; | ||
489 | int ret = 0; | ||
484 | 490 | ||
485 | mutex_lock(&inode->i_mutex); | 491 | mutex_lock(&inode->i_mutex); |
486 | if (offset >= inode->i_size) { | 492 | |
493 | isize = i_size_read(inode); | ||
494 | if (offset >= isize) { | ||
487 | mutex_unlock(&inode->i_mutex); | 495 | mutex_unlock(&inode->i_mutex); |
488 | return -ENXIO; | 496 | return -ENXIO; |
489 | } | 497 | } |
490 | 498 | ||
491 | fie.fi_flags = 0; | 499 | blkbits = inode->i_sb->s_blocksize_bits; |
492 | fie.fi_extents_max = 2; | 500 | start = offset >> blkbits; |
493 | fie.fi_extents_start = (struct fiemap_extent __user *)&ext; | 501 | last = start; |
494 | while (1) { | 502 | end = isize >> blkbits; |
495 | mm_segment_t old_fs = get_fs(); | 503 | holeoff = offset; |
496 | |||
497 | fie.fi_extents_mapped = 0; | ||
498 | memset(ext, 0, sizeof(*ext)); | ||
499 | 504 | ||
500 | set_fs(get_ds()); | 505 | do { |
501 | ret = ext4_fiemap(inode, &fie, offset, maxsize - offset); | 506 | map.m_lblk = last; |
502 | set_fs(old_fs); | 507 | map.m_len = end - last + 1; |
503 | if (ret) | 508 | ret = ext4_map_blocks(NULL, inode, &map, 0); |
504 | break; | 509 | if (ret > 0 && !(map.m_flags & EXT4_MAP_UNWRITTEN)) { |
510 | last += ret; | ||
511 | holeoff = (loff_t)last << blkbits; | ||
512 | continue; | ||
513 | } | ||
505 | 514 | ||
506 | /* No extents found */ | 515 | /* |
507 | if (!fie.fi_extents_mapped) | 516 | * If there is a delay extent at this offset, |
508 | break; | 517 | * we will skip this extent. |
518 | */ | ||
519 | ext4_es_find_delayed_extent_range(inode, last, last, &es); | ||
520 | if (es.es_len != 0 && in_range(last, es.es_lblk, es.es_len)) { | ||
521 | last = es.es_lblk + es.es_len; | ||
522 | holeoff = (loff_t)last << blkbits; | ||
523 | continue; | ||
524 | } | ||
509 | 525 | ||
510 | for (i = 0; i < fie.fi_extents_mapped; i++) { | 526 | /* |
511 | next = (loff_t)(ext[i].fe_logical + ext[i].fe_length); | 527 | * If there is a unwritten extent at this offset, |
512 | /* | 528 | * it will be as a data or a hole according to page |
513 | * If extent is not unwritten, then it contains valid | 529 | * cache that has data or not. |
514 | * data, mapped or delayed. | 530 | */ |
515 | */ | 531 | if (map.m_flags & EXT4_MAP_UNWRITTEN) { |
516 | if (!(ext[i].fe_flags & FIEMAP_EXTENT_UNWRITTEN)) { | 532 | int unwritten; |
517 | if (offset < (loff_t)ext[i].fe_logical) | 533 | unwritten = ext4_find_unwritten_pgoff(inode, SEEK_HOLE, |
518 | goto out; | 534 | &map, &holeoff); |
519 | offset = next; | 535 | if (!unwritten) { |
536 | last += ret; | ||
537 | holeoff = (loff_t)last << blkbits; | ||
520 | continue; | 538 | continue; |
521 | } | 539 | } |
522 | /* | ||
523 | * If there is a unwritten extent at this offset, | ||
524 | * it will be as a data or a hole according to page | ||
525 | * cache that has data or not. | ||
526 | */ | ||
527 | if (ext4_find_unwritten_pgoff(inode, SEEK_HOLE, | ||
528 | next, &offset)) | ||
529 | goto out; | ||
530 | |||
531 | offset = next; | ||
532 | if (ext[i].fe_flags & FIEMAP_EXTENT_LAST) | ||
533 | goto out; | ||
534 | } | 540 | } |
535 | } | 541 | |
536 | if (offset > inode->i_size) | 542 | /* find a hole */ |
537 | offset = inode->i_size; | 543 | break; |
538 | out: | 544 | } while (last <= end); |
545 | |||
539 | mutex_unlock(&inode->i_mutex); | 546 | mutex_unlock(&inode->i_mutex); |
540 | if (ret) | ||
541 | return ret; | ||
542 | 547 | ||
543 | return vfs_setpos(file, offset, maxsize); | 548 | if (holeoff > isize) |
549 | holeoff = isize; | ||
550 | |||
551 | return vfs_setpos(file, holeoff, maxsize); | ||
544 | } | 552 | } |
545 | 553 | ||
546 | /* | 554 | /* |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index bf76f405a5f9..8a8ec6293b19 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -24,6 +24,18 @@ int ext4_resize_begin(struct super_block *sb) | |||
24 | return -EPERM; | 24 | return -EPERM; |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * If we are not using the primary superblock/GDT copy don't resize, | ||
28 | * because the user tools have no way of handling this. Probably a | ||
29 | * bad time to do it anyways. | ||
30 | */ | ||
31 | if (EXT4_SB(sb)->s_sbh->b_blocknr != | ||
32 | le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) { | ||
33 | ext4_warning(sb, "won't resize using backup superblock at %llu", | ||
34 | (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr); | ||
35 | return -EPERM; | ||
36 | } | ||
37 | |||
38 | /* | ||
27 | * We are not allowed to do online-resizing on a filesystem mounted | 39 | * We are not allowed to do online-resizing on a filesystem mounted |
28 | * with error, because it can destroy the filesystem easily. | 40 | * with error, because it can destroy the filesystem easily. |
29 | */ | 41 | */ |
@@ -758,18 +770,6 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
758 | "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n", | 770 | "EXT4-fs: ext4_add_new_gdb: adding group block %lu\n", |
759 | gdb_num); | 771 | gdb_num); |
760 | 772 | ||
761 | /* | ||
762 | * If we are not using the primary superblock/GDT copy don't resize, | ||
763 | * because the user tools have no way of handling this. Probably a | ||
764 | * bad time to do it anyways. | ||
765 | */ | ||
766 | if (EXT4_SB(sb)->s_sbh->b_blocknr != | ||
767 | le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block)) { | ||
768 | ext4_warning(sb, "won't resize using backup superblock at %llu", | ||
769 | (unsigned long long)EXT4_SB(sb)->s_sbh->b_blocknr); | ||
770 | return -EPERM; | ||
771 | } | ||
772 | |||
773 | gdb_bh = sb_bread(sb, gdblock); | 773 | gdb_bh = sb_bread(sb, gdblock); |
774 | if (!gdb_bh) | 774 | if (!gdb_bh) |
775 | return -EIO; | 775 | return -EIO; |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 43c92b1685cb..74c5f53595fb 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -3482,7 +3482,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3482 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, | 3482 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, |
3483 | EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) && | 3483 | EXT4_FEATURE_RO_COMPAT_METADATA_CSUM) && |
3484 | EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) | 3484 | EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) |
3485 | ext4_warning(sb, KERN_INFO "metadata_csum and uninit_bg are " | 3485 | ext4_warning(sb, "metadata_csum and uninit_bg are " |
3486 | "redundant flags; please run fsck."); | 3486 | "redundant flags; please run fsck."); |
3487 | 3487 | ||
3488 | /* Check for a known checksum algorithm */ | 3488 | /* Check for a known checksum algorithm */ |
diff --git a/fs/fcntl.c b/fs/fcntl.c index 99d440a4a6ba..ee85cd4e136a 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -740,14 +740,15 @@ static int __init fcntl_init(void) | |||
740 | * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY | 740 | * Exceptions: O_NONBLOCK is a two bit define on parisc; O_NDELAY |
741 | * is defined as O_NONBLOCK on some platforms and not on others. | 741 | * is defined as O_NONBLOCK on some platforms and not on others. |
742 | */ | 742 | */ |
743 | BUILD_BUG_ON(20 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( | 743 | BUILD_BUG_ON(21 - 1 /* for O_RDONLY being 0 */ != HWEIGHT32( |
744 | O_RDONLY | O_WRONLY | O_RDWR | | 744 | O_RDONLY | O_WRONLY | O_RDWR | |
745 | O_CREAT | O_EXCL | O_NOCTTY | | 745 | O_CREAT | O_EXCL | O_NOCTTY | |
746 | O_TRUNC | O_APPEND | /* O_NONBLOCK | */ | 746 | O_TRUNC | O_APPEND | /* O_NONBLOCK | */ |
747 | __O_SYNC | O_DSYNC | FASYNC | | 747 | __O_SYNC | O_DSYNC | FASYNC | |
748 | O_DIRECT | O_LARGEFILE | O_DIRECTORY | | 748 | O_DIRECT | O_LARGEFILE | O_DIRECTORY | |
749 | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | | 749 | O_NOFOLLOW | O_NOATIME | O_CLOEXEC | |
750 | __FMODE_EXEC | O_PATH | __O_TMPFILE | 750 | __FMODE_EXEC | O_PATH | __O_TMPFILE | |
751 | __FMODE_NONOTIFY | ||
751 | )); | 752 | )); |
752 | 753 | ||
753 | fasync_cache = kmem_cache_create("fasync_cache", | 754 | fasync_cache = kmem_cache_create("fasync_cache", |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index ba1107977f2e..ed19a7d622fa 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -131,6 +131,13 @@ static void fuse_req_init_context(struct fuse_req *req) | |||
131 | req->in.h.pid = current->pid; | 131 | req->in.h.pid = current->pid; |
132 | } | 132 | } |
133 | 133 | ||
134 | void fuse_set_initialized(struct fuse_conn *fc) | ||
135 | { | ||
136 | /* Make sure stores before this are seen on another CPU */ | ||
137 | smp_wmb(); | ||
138 | fc->initialized = 1; | ||
139 | } | ||
140 | |||
134 | static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background) | 141 | static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background) |
135 | { | 142 | { |
136 | return !fc->initialized || (for_background && fc->blocked); | 143 | return !fc->initialized || (for_background && fc->blocked); |
@@ -155,6 +162,8 @@ static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages, | |||
155 | if (intr) | 162 | if (intr) |
156 | goto out; | 163 | goto out; |
157 | } | 164 | } |
165 | /* Matches smp_wmb() in fuse_set_initialized() */ | ||
166 | smp_rmb(); | ||
158 | 167 | ||
159 | err = -ENOTCONN; | 168 | err = -ENOTCONN; |
160 | if (!fc->connected) | 169 | if (!fc->connected) |
@@ -253,6 +262,8 @@ struct fuse_req *fuse_get_req_nofail_nopages(struct fuse_conn *fc, | |||
253 | 262 | ||
254 | atomic_inc(&fc->num_waiting); | 263 | atomic_inc(&fc->num_waiting); |
255 | wait_event(fc->blocked_waitq, fc->initialized); | 264 | wait_event(fc->blocked_waitq, fc->initialized); |
265 | /* Matches smp_wmb() in fuse_set_initialized() */ | ||
266 | smp_rmb(); | ||
256 | req = fuse_request_alloc(0); | 267 | req = fuse_request_alloc(0); |
257 | if (!req) | 268 | if (!req) |
258 | req = get_reserved_req(fc, file); | 269 | req = get_reserved_req(fc, file); |
@@ -511,6 +522,39 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) | |||
511 | } | 522 | } |
512 | EXPORT_SYMBOL_GPL(fuse_request_send); | 523 | EXPORT_SYMBOL_GPL(fuse_request_send); |
513 | 524 | ||
525 | static void fuse_adjust_compat(struct fuse_conn *fc, struct fuse_args *args) | ||
526 | { | ||
527 | if (fc->minor < 4 && args->in.h.opcode == FUSE_STATFS) | ||
528 | args->out.args[0].size = FUSE_COMPAT_STATFS_SIZE; | ||
529 | |||
530 | if (fc->minor < 9) { | ||
531 | switch (args->in.h.opcode) { | ||
532 | case FUSE_LOOKUP: | ||
533 | case FUSE_CREATE: | ||
534 | case FUSE_MKNOD: | ||
535 | case FUSE_MKDIR: | ||
536 | case FUSE_SYMLINK: | ||
537 | case FUSE_LINK: | ||
538 | args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; | ||
539 | break; | ||
540 | case FUSE_GETATTR: | ||
541 | case FUSE_SETATTR: | ||
542 | args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; | ||
543 | break; | ||
544 | } | ||
545 | } | ||
546 | if (fc->minor < 12) { | ||
547 | switch (args->in.h.opcode) { | ||
548 | case FUSE_CREATE: | ||
549 | args->in.args[0].size = sizeof(struct fuse_open_in); | ||
550 | break; | ||
551 | case FUSE_MKNOD: | ||
552 | args->in.args[0].size = FUSE_COMPAT_MKNOD_IN_SIZE; | ||
553 | break; | ||
554 | } | ||
555 | } | ||
556 | } | ||
557 | |||
514 | ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) | 558 | ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) |
515 | { | 559 | { |
516 | struct fuse_req *req; | 560 | struct fuse_req *req; |
@@ -520,6 +564,9 @@ ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args) | |||
520 | if (IS_ERR(req)) | 564 | if (IS_ERR(req)) |
521 | return PTR_ERR(req); | 565 | return PTR_ERR(req); |
522 | 566 | ||
567 | /* Needs to be done after fuse_get_req() so that fc->minor is valid */ | ||
568 | fuse_adjust_compat(fc, args); | ||
569 | |||
523 | req->in.h.opcode = args->in.h.opcode; | 570 | req->in.h.opcode = args->in.h.opcode; |
524 | req->in.h.nodeid = args->in.h.nodeid; | 571 | req->in.h.nodeid = args->in.h.nodeid; |
525 | req->in.numargs = args->in.numargs; | 572 | req->in.numargs = args->in.numargs; |
@@ -2127,7 +2174,7 @@ void fuse_abort_conn(struct fuse_conn *fc) | |||
2127 | if (fc->connected) { | 2174 | if (fc->connected) { |
2128 | fc->connected = 0; | 2175 | fc->connected = 0; |
2129 | fc->blocked = 0; | 2176 | fc->blocked = 0; |
2130 | fc->initialized = 1; | 2177 | fuse_set_initialized(fc); |
2131 | end_io_requests(fc); | 2178 | end_io_requests(fc); |
2132 | end_queued_requests(fc); | 2179 | end_queued_requests(fc); |
2133 | end_polls(fc); | 2180 | end_polls(fc); |
@@ -2146,7 +2193,7 @@ int fuse_dev_release(struct inode *inode, struct file *file) | |||
2146 | spin_lock(&fc->lock); | 2193 | spin_lock(&fc->lock); |
2147 | fc->connected = 0; | 2194 | fc->connected = 0; |
2148 | fc->blocked = 0; | 2195 | fc->blocked = 0; |
2149 | fc->initialized = 1; | 2196 | fuse_set_initialized(fc); |
2150 | end_queued_requests(fc); | 2197 | end_queued_requests(fc); |
2151 | end_polls(fc); | 2198 | end_polls(fc); |
2152 | wake_up_all(&fc->blocked_waitq); | 2199 | wake_up_all(&fc->blocked_waitq); |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 252b8a5de8b5..08e7b1a9d5d0 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -156,10 +156,7 @@ static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args, | |||
156 | args->in.args[0].size = name->len + 1; | 156 | args->in.args[0].size = name->len + 1; |
157 | args->in.args[0].value = name->name; | 157 | args->in.args[0].value = name->name; |
158 | args->out.numargs = 1; | 158 | args->out.numargs = 1; |
159 | if (fc->minor < 9) | 159 | args->out.args[0].size = sizeof(struct fuse_entry_out); |
160 | args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; | ||
161 | else | ||
162 | args->out.args[0].size = sizeof(struct fuse_entry_out); | ||
163 | args->out.args[0].value = outarg; | 160 | args->out.args[0].value = outarg; |
164 | } | 161 | } |
165 | 162 | ||
@@ -422,16 +419,12 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
422 | args.in.h.opcode = FUSE_CREATE; | 419 | args.in.h.opcode = FUSE_CREATE; |
423 | args.in.h.nodeid = get_node_id(dir); | 420 | args.in.h.nodeid = get_node_id(dir); |
424 | args.in.numargs = 2; | 421 | args.in.numargs = 2; |
425 | args.in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) : | 422 | args.in.args[0].size = sizeof(inarg); |
426 | sizeof(inarg); | ||
427 | args.in.args[0].value = &inarg; | 423 | args.in.args[0].value = &inarg; |
428 | args.in.args[1].size = entry->d_name.len + 1; | 424 | args.in.args[1].size = entry->d_name.len + 1; |
429 | args.in.args[1].value = entry->d_name.name; | 425 | args.in.args[1].value = entry->d_name.name; |
430 | args.out.numargs = 2; | 426 | args.out.numargs = 2; |
431 | if (fc->minor < 9) | 427 | args.out.args[0].size = sizeof(outentry); |
432 | args.out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; | ||
433 | else | ||
434 | args.out.args[0].size = sizeof(outentry); | ||
435 | args.out.args[0].value = &outentry; | 428 | args.out.args[0].value = &outentry; |
436 | args.out.args[1].size = sizeof(outopen); | 429 | args.out.args[1].size = sizeof(outopen); |
437 | args.out.args[1].value = &outopen; | 430 | args.out.args[1].value = &outopen; |
@@ -539,10 +532,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args, | |||
539 | memset(&outarg, 0, sizeof(outarg)); | 532 | memset(&outarg, 0, sizeof(outarg)); |
540 | args->in.h.nodeid = get_node_id(dir); | 533 | args->in.h.nodeid = get_node_id(dir); |
541 | args->out.numargs = 1; | 534 | args->out.numargs = 1; |
542 | if (fc->minor < 9) | 535 | args->out.args[0].size = sizeof(outarg); |
543 | args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE; | ||
544 | else | ||
545 | args->out.args[0].size = sizeof(outarg); | ||
546 | args->out.args[0].value = &outarg; | 536 | args->out.args[0].value = &outarg; |
547 | err = fuse_simple_request(fc, args); | 537 | err = fuse_simple_request(fc, args); |
548 | if (err) | 538 | if (err) |
@@ -592,8 +582,7 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode, | |||
592 | inarg.umask = current_umask(); | 582 | inarg.umask = current_umask(); |
593 | args.in.h.opcode = FUSE_MKNOD; | 583 | args.in.h.opcode = FUSE_MKNOD; |
594 | args.in.numargs = 2; | 584 | args.in.numargs = 2; |
595 | args.in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE : | 585 | args.in.args[0].size = sizeof(inarg); |
596 | sizeof(inarg); | ||
597 | args.in.args[0].value = &inarg; | 586 | args.in.args[0].value = &inarg; |
598 | args.in.args[1].size = entry->d_name.len + 1; | 587 | args.in.args[1].size = entry->d_name.len + 1; |
599 | args.in.args[1].value = entry->d_name.name; | 588 | args.in.args[1].value = entry->d_name.name; |
@@ -899,10 +888,7 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat, | |||
899 | args.in.args[0].size = sizeof(inarg); | 888 | args.in.args[0].size = sizeof(inarg); |
900 | args.in.args[0].value = &inarg; | 889 | args.in.args[0].value = &inarg; |
901 | args.out.numargs = 1; | 890 | args.out.numargs = 1; |
902 | if (fc->minor < 9) | 891 | args.out.args[0].size = sizeof(outarg); |
903 | args.out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; | ||
904 | else | ||
905 | args.out.args[0].size = sizeof(outarg); | ||
906 | args.out.args[0].value = &outarg; | 892 | args.out.args[0].value = &outarg; |
907 | err = fuse_simple_request(fc, &args); | 893 | err = fuse_simple_request(fc, &args); |
908 | if (!err) { | 894 | if (!err) { |
@@ -1574,10 +1560,7 @@ static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args, | |||
1574 | args->in.args[0].size = sizeof(*inarg_p); | 1560 | args->in.args[0].size = sizeof(*inarg_p); |
1575 | args->in.args[0].value = inarg_p; | 1561 | args->in.args[0].value = inarg_p; |
1576 | args->out.numargs = 1; | 1562 | args->out.numargs = 1; |
1577 | if (fc->minor < 9) | 1563 | args->out.args[0].size = sizeof(*outarg_p); |
1578 | args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE; | ||
1579 | else | ||
1580 | args->out.args[0].size = sizeof(*outarg_p); | ||
1581 | args->out.args[0].value = outarg_p; | 1564 | args->out.args[0].value = outarg_p; |
1582 | } | 1565 | } |
1583 | 1566 | ||
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index e0fc6725d1d0..1cdfb07c1376 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -906,4 +906,6 @@ int fuse_write_inode(struct inode *inode, struct writeback_control *wbc); | |||
906 | int fuse_do_setattr(struct inode *inode, struct iattr *attr, | 906 | int fuse_do_setattr(struct inode *inode, struct iattr *attr, |
907 | struct file *file); | 907 | struct file *file); |
908 | 908 | ||
909 | void fuse_set_initialized(struct fuse_conn *fc); | ||
910 | |||
909 | #endif /* _FS_FUSE_I_H */ | 911 | #endif /* _FS_FUSE_I_H */ |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 6749109f255d..f38256e4476e 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -424,8 +424,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
424 | args.in.h.opcode = FUSE_STATFS; | 424 | args.in.h.opcode = FUSE_STATFS; |
425 | args.in.h.nodeid = get_node_id(dentry->d_inode); | 425 | args.in.h.nodeid = get_node_id(dentry->d_inode); |
426 | args.out.numargs = 1; | 426 | args.out.numargs = 1; |
427 | args.out.args[0].size = | 427 | args.out.args[0].size = sizeof(outarg); |
428 | fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg); | ||
429 | args.out.args[0].value = &outarg; | 428 | args.out.args[0].value = &outarg; |
430 | err = fuse_simple_request(fc, &args); | 429 | err = fuse_simple_request(fc, &args); |
431 | if (!err) | 430 | if (!err) |
@@ -898,7 +897,7 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
898 | fc->max_write = max_t(unsigned, 4096, fc->max_write); | 897 | fc->max_write = max_t(unsigned, 4096, fc->max_write); |
899 | fc->conn_init = 1; | 898 | fc->conn_init = 1; |
900 | } | 899 | } |
901 | fc->initialized = 1; | 900 | fuse_set_initialized(fc); |
902 | wake_up_all(&fc->blocked_waitq); | 901 | wake_up_all(&fc->blocked_waitq); |
903 | } | 902 | } |
904 | 903 | ||
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index c8b148bbdc8b..3e193cb36996 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -667,7 +667,7 @@ static void do_qc(struct gfs2_quota_data *qd, s64 change) | |||
667 | 667 | ||
668 | static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, | 668 | static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, |
669 | s64 change, struct gfs2_quota_data *qd, | 669 | s64 change, struct gfs2_quota_data *qd, |
670 | struct fs_disk_quota *fdq) | 670 | struct qc_dqblk *fdq) |
671 | { | 671 | { |
672 | struct inode *inode = &ip->i_inode; | 672 | struct inode *inode = &ip->i_inode; |
673 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 673 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
@@ -697,16 +697,16 @@ static int gfs2_adjust_quota(struct gfs2_inode *ip, loff_t loc, | |||
697 | be64_add_cpu(&q.qu_value, change); | 697 | be64_add_cpu(&q.qu_value, change); |
698 | qd->qd_qb.qb_value = q.qu_value; | 698 | qd->qd_qb.qb_value = q.qu_value; |
699 | if (fdq) { | 699 | if (fdq) { |
700 | if (fdq->d_fieldmask & FS_DQ_BSOFT) { | 700 | if (fdq->d_fieldmask & QC_SPC_SOFT) { |
701 | q.qu_warn = cpu_to_be64(fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift); | 701 | q.qu_warn = cpu_to_be64(fdq->d_spc_softlimit >> sdp->sd_sb.sb_bsize_shift); |
702 | qd->qd_qb.qb_warn = q.qu_warn; | 702 | qd->qd_qb.qb_warn = q.qu_warn; |
703 | } | 703 | } |
704 | if (fdq->d_fieldmask & FS_DQ_BHARD) { | 704 | if (fdq->d_fieldmask & QC_SPC_HARD) { |
705 | q.qu_limit = cpu_to_be64(fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift); | 705 | q.qu_limit = cpu_to_be64(fdq->d_spc_hardlimit >> sdp->sd_sb.sb_bsize_shift); |
706 | qd->qd_qb.qb_limit = q.qu_limit; | 706 | qd->qd_qb.qb_limit = q.qu_limit; |
707 | } | 707 | } |
708 | if (fdq->d_fieldmask & FS_DQ_BCOUNT) { | 708 | if (fdq->d_fieldmask & QC_SPACE) { |
709 | q.qu_value = cpu_to_be64(fdq->d_bcount >> sdp->sd_fsb2bb_shift); | 709 | q.qu_value = cpu_to_be64(fdq->d_space >> sdp->sd_sb.sb_bsize_shift); |
710 | qd->qd_qb.qb_value = q.qu_value; | 710 | qd->qd_qb.qb_value = q.qu_value; |
711 | } | 711 | } |
712 | } | 712 | } |
@@ -1497,7 +1497,7 @@ static int gfs2_quota_get_xstate(struct super_block *sb, | |||
1497 | } | 1497 | } |
1498 | 1498 | ||
1499 | static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid, | 1499 | static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid, |
1500 | struct fs_disk_quota *fdq) | 1500 | struct qc_dqblk *fdq) |
1501 | { | 1501 | { |
1502 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1502 | struct gfs2_sbd *sdp = sb->s_fs_info; |
1503 | struct gfs2_quota_lvb *qlvb; | 1503 | struct gfs2_quota_lvb *qlvb; |
@@ -1505,7 +1505,7 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid, | |||
1505 | struct gfs2_holder q_gh; | 1505 | struct gfs2_holder q_gh; |
1506 | int error; | 1506 | int error; |
1507 | 1507 | ||
1508 | memset(fdq, 0, sizeof(struct fs_disk_quota)); | 1508 | memset(fdq, 0, sizeof(*fdq)); |
1509 | 1509 | ||
1510 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) | 1510 | if (sdp->sd_args.ar_quota == GFS2_QUOTA_OFF) |
1511 | return -ESRCH; /* Crazy XFS error code */ | 1511 | return -ESRCH; /* Crazy XFS error code */ |
@@ -1522,12 +1522,9 @@ static int gfs2_get_dqblk(struct super_block *sb, struct kqid qid, | |||
1522 | goto out; | 1522 | goto out; |
1523 | 1523 | ||
1524 | qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lksb.sb_lvbptr; | 1524 | qlvb = (struct gfs2_quota_lvb *)qd->qd_gl->gl_lksb.sb_lvbptr; |
1525 | fdq->d_version = FS_DQUOT_VERSION; | 1525 | fdq->d_spc_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_sb.sb_bsize_shift; |
1526 | fdq->d_flags = (qid.type == USRQUOTA) ? FS_USER_QUOTA : FS_GROUP_QUOTA; | 1526 | fdq->d_spc_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_sb.sb_bsize_shift; |
1527 | fdq->d_id = from_kqid_munged(current_user_ns(), qid); | 1527 | fdq->d_space = be64_to_cpu(qlvb->qb_value) << sdp->sd_sb.sb_bsize_shift; |
1528 | fdq->d_blk_hardlimit = be64_to_cpu(qlvb->qb_limit) << sdp->sd_fsb2bb_shift; | ||
1529 | fdq->d_blk_softlimit = be64_to_cpu(qlvb->qb_warn) << sdp->sd_fsb2bb_shift; | ||
1530 | fdq->d_bcount = be64_to_cpu(qlvb->qb_value) << sdp->sd_fsb2bb_shift; | ||
1531 | 1528 | ||
1532 | gfs2_glock_dq_uninit(&q_gh); | 1529 | gfs2_glock_dq_uninit(&q_gh); |
1533 | out: | 1530 | out: |
@@ -1536,10 +1533,10 @@ out: | |||
1536 | } | 1533 | } |
1537 | 1534 | ||
1538 | /* GFS2 only supports a subset of the XFS fields */ | 1535 | /* GFS2 only supports a subset of the XFS fields */ |
1539 | #define GFS2_FIELDMASK (FS_DQ_BSOFT|FS_DQ_BHARD|FS_DQ_BCOUNT) | 1536 | #define GFS2_FIELDMASK (QC_SPC_SOFT|QC_SPC_HARD|QC_SPACE) |
1540 | 1537 | ||
1541 | static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid, | 1538 | static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid, |
1542 | struct fs_disk_quota *fdq) | 1539 | struct qc_dqblk *fdq) |
1543 | { | 1540 | { |
1544 | struct gfs2_sbd *sdp = sb->s_fs_info; | 1541 | struct gfs2_sbd *sdp = sb->s_fs_info; |
1545 | struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode); | 1542 | struct gfs2_inode *ip = GFS2_I(sdp->sd_quota_inode); |
@@ -1583,17 +1580,17 @@ static int gfs2_set_dqblk(struct super_block *sb, struct kqid qid, | |||
1583 | goto out_i; | 1580 | goto out_i; |
1584 | 1581 | ||
1585 | /* If nothing has changed, this is a no-op */ | 1582 | /* If nothing has changed, this is a no-op */ |
1586 | if ((fdq->d_fieldmask & FS_DQ_BSOFT) && | 1583 | if ((fdq->d_fieldmask & QC_SPC_SOFT) && |
1587 | ((fdq->d_blk_softlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_warn))) | 1584 | ((fdq->d_spc_softlimit >> sdp->sd_sb.sb_bsize_shift) == be64_to_cpu(qd->qd_qb.qb_warn))) |
1588 | fdq->d_fieldmask ^= FS_DQ_BSOFT; | 1585 | fdq->d_fieldmask ^= QC_SPC_SOFT; |
1589 | 1586 | ||
1590 | if ((fdq->d_fieldmask & FS_DQ_BHARD) && | 1587 | if ((fdq->d_fieldmask & QC_SPC_HARD) && |
1591 | ((fdq->d_blk_hardlimit >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_limit))) | 1588 | ((fdq->d_spc_hardlimit >> sdp->sd_sb.sb_bsize_shift) == be64_to_cpu(qd->qd_qb.qb_limit))) |
1592 | fdq->d_fieldmask ^= FS_DQ_BHARD; | 1589 | fdq->d_fieldmask ^= QC_SPC_HARD; |
1593 | 1590 | ||
1594 | if ((fdq->d_fieldmask & FS_DQ_BCOUNT) && | 1591 | if ((fdq->d_fieldmask & QC_SPACE) && |
1595 | ((fdq->d_bcount >> sdp->sd_fsb2bb_shift) == be64_to_cpu(qd->qd_qb.qb_value))) | 1592 | ((fdq->d_space >> sdp->sd_sb.sb_bsize_shift) == be64_to_cpu(qd->qd_qb.qb_value))) |
1596 | fdq->d_fieldmask ^= FS_DQ_BCOUNT; | 1593 | fdq->d_fieldmask ^= QC_SPACE; |
1597 | 1594 | ||
1598 | if (fdq->d_fieldmask == 0) | 1595 | if (fdq->d_fieldmask == 0) |
1599 | goto out_i; | 1596 | goto out_i; |
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index bb63254ed848..735d7522a3a9 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c | |||
@@ -362,6 +362,9 @@ repeat: | |||
362 | rs.cont_size = isonum_733(rr->u.CE.size); | 362 | rs.cont_size = isonum_733(rr->u.CE.size); |
363 | break; | 363 | break; |
364 | case SIG('E', 'R'): | 364 | case SIG('E', 'R'): |
365 | /* Invalid length of ER tag id? */ | ||
366 | if (rr->u.ER.len_id + offsetof(struct rock_ridge, u.ER.data) > rr->len) | ||
367 | goto out; | ||
365 | ISOFS_SB(inode->i_sb)->s_rock = 1; | 368 | ISOFS_SB(inode->i_sb)->s_rock = 1; |
366 | printk(KERN_DEBUG "ISO 9660 Extensions: "); | 369 | printk(KERN_DEBUG "ISO 9660 Extensions: "); |
367 | { | 370 | { |
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 37989f02a226..2d881b381d2b 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c | |||
@@ -201,10 +201,14 @@ static unsigned int kernfs_name_hash(const char *name, const void *ns) | |||
201 | static int kernfs_name_compare(unsigned int hash, const char *name, | 201 | static int kernfs_name_compare(unsigned int hash, const char *name, |
202 | const void *ns, const struct kernfs_node *kn) | 202 | const void *ns, const struct kernfs_node *kn) |
203 | { | 203 | { |
204 | if (hash != kn->hash) | 204 | if (hash < kn->hash) |
205 | return hash - kn->hash; | 205 | return -1; |
206 | if (ns != kn->ns) | 206 | if (hash > kn->hash) |
207 | return ns - kn->ns; | 207 | return 1; |
208 | if (ns < kn->ns) | ||
209 | return -1; | ||
210 | if (ns > kn->ns) | ||
211 | return 1; | ||
208 | return strcmp(name, kn->name); | 212 | return strcmp(name, kn->name); |
209 | } | 213 | } |
210 | 214 | ||
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index e94c887da2d7..55505cbe11af 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
@@ -138,10 +138,6 @@ lockd(void *vrqstp) | |||
138 | 138 | ||
139 | dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); | 139 | dprintk("NFS locking service started (ver " LOCKD_VERSION ").\n"); |
140 | 140 | ||
141 | if (!nlm_timeout) | ||
142 | nlm_timeout = LOCKD_DFLT_TIMEO; | ||
143 | nlmsvc_timeout = nlm_timeout * HZ; | ||
144 | |||
145 | /* | 141 | /* |
146 | * The main request loop. We don't terminate until the last | 142 | * The main request loop. We don't terminate until the last |
147 | * NFS mount or NFS daemon has gone away. | 143 | * NFS mount or NFS daemon has gone away. |
@@ -350,6 +346,10 @@ static struct svc_serv *lockd_create_svc(void) | |||
350 | printk(KERN_WARNING | 346 | printk(KERN_WARNING |
351 | "lockd_up: no pid, %d users??\n", nlmsvc_users); | 347 | "lockd_up: no pid, %d users??\n", nlmsvc_users); |
352 | 348 | ||
349 | if (!nlm_timeout) | ||
350 | nlm_timeout = LOCKD_DFLT_TIMEO; | ||
351 | nlmsvc_timeout = nlm_timeout * HZ; | ||
352 | |||
353 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, svc_rpcb_cleanup); | 353 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, svc_rpcb_cleanup); |
354 | if (!serv) { | 354 | if (!serv) { |
355 | printk(KERN_WARNING "lockd_up: create service failed\n"); | 355 | printk(KERN_WARNING "lockd_up: create service failed\n"); |
diff --git a/fs/locks.c b/fs/locks.c index 735b8d3fa78c..59e2f905e4ff 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -1702,7 +1702,7 @@ static int generic_delete_lease(struct file *filp) | |||
1702 | break; | 1702 | break; |
1703 | } | 1703 | } |
1704 | trace_generic_delete_lease(inode, fl); | 1704 | trace_generic_delete_lease(inode, fl); |
1705 | if (fl) | 1705 | if (fl && IS_LEASE(fl)) |
1706 | error = fl->fl_lmops->lm_change(before, F_UNLCK, &dispose); | 1706 | error = fl->fl_lmops->lm_change(before, F_UNLCK, &dispose); |
1707 | spin_unlock(&inode->i_lock); | 1707 | spin_unlock(&inode->i_lock); |
1708 | locks_dispose_list(&dispose); | 1708 | locks_dispose_list(&dispose); |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 10bf07280f4a..294692ff83b1 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -212,6 +212,12 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq, | |||
212 | */ | 212 | */ |
213 | ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) | 213 | ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, struct iov_iter *iter, loff_t pos) |
214 | { | 214 | { |
215 | struct inode *inode = iocb->ki_filp->f_mapping->host; | ||
216 | |||
217 | /* we only support swap file calling nfs_direct_IO */ | ||
218 | if (!IS_SWAPFILE(inode)) | ||
219 | return 0; | ||
220 | |||
215 | #ifndef CONFIG_NFS_SWAP | 221 | #ifndef CONFIG_NFS_SWAP |
216 | dprintk("NFS: nfs_direct_IO (%pD) off/no(%Ld/%lu) EINVAL\n", | 222 | dprintk("NFS: nfs_direct_IO (%pD) off/no(%Ld/%lu) EINVAL\n", |
217 | iocb->ki_filp, (long long) pos, iter->nr_segs); | 223 | iocb->ki_filp, (long long) pos, iter->nr_segs); |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 4bffe637ea32..2211f6ba8736 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -352,8 +352,9 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st | |||
352 | 352 | ||
353 | nfs_attr_check_mountpoint(sb, fattr); | 353 | nfs_attr_check_mountpoint(sb, fattr); |
354 | 354 | ||
355 | if (((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0) && | 355 | if (nfs_attr_use_mounted_on_fileid(fattr)) |
356 | !nfs_attr_use_mounted_on_fileid(fattr)) | 356 | fattr->fileid = fattr->mounted_on_fileid; |
357 | else if ((fattr->valid & NFS_ATTR_FATTR_FILEID) == 0) | ||
357 | goto out_no_inode; | 358 | goto out_no_inode; |
358 | if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0) | 359 | if ((fattr->valid & NFS_ATTR_FATTR_TYPE) == 0) |
359 | goto out_no_inode; | 360 | goto out_no_inode; |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index efaa31c70fbe..b6f34bfa6fe8 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -31,8 +31,6 @@ static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr) | |||
31 | (((fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) && | 31 | (((fattr->valid & NFS_ATTR_FATTR_MOUNTPOINT) == 0) && |
32 | ((fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) == 0))) | 32 | ((fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) == 0))) |
33 | return 0; | 33 | return 0; |
34 | |||
35 | fattr->fileid = fattr->mounted_on_fileid; | ||
36 | return 1; | 34 | return 1; |
37 | } | 35 | } |
38 | 36 | ||
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c index 03311259b0c4..706ad10b8186 100644 --- a/fs/nfs/nfs4client.c +++ b/fs/nfs/nfs4client.c | |||
@@ -228,6 +228,7 @@ static void nfs4_shutdown_client(struct nfs_client *clp) | |||
228 | kfree(clp->cl_serverowner); | 228 | kfree(clp->cl_serverowner); |
229 | kfree(clp->cl_serverscope); | 229 | kfree(clp->cl_serverscope); |
230 | kfree(clp->cl_implid); | 230 | kfree(clp->cl_implid); |
231 | kfree(clp->cl_owner_id); | ||
231 | } | 232 | } |
232 | 233 | ||
233 | void nfs4_free_client(struct nfs_client *clp) | 234 | void nfs4_free_client(struct nfs_client *clp) |
@@ -452,6 +453,14 @@ static void nfs4_swap_callback_idents(struct nfs_client *keep, | |||
452 | spin_unlock(&nn->nfs_client_lock); | 453 | spin_unlock(&nn->nfs_client_lock); |
453 | } | 454 | } |
454 | 455 | ||
456 | static bool nfs4_match_client_owner_id(const struct nfs_client *clp1, | ||
457 | const struct nfs_client *clp2) | ||
458 | { | ||
459 | if (clp1->cl_owner_id == NULL || clp2->cl_owner_id == NULL) | ||
460 | return true; | ||
461 | return strcmp(clp1->cl_owner_id, clp2->cl_owner_id) == 0; | ||
462 | } | ||
463 | |||
455 | /** | 464 | /** |
456 | * nfs40_walk_client_list - Find server that recognizes a client ID | 465 | * nfs40_walk_client_list - Find server that recognizes a client ID |
457 | * | 466 | * |
@@ -483,9 +492,6 @@ int nfs40_walk_client_list(struct nfs_client *new, | |||
483 | if (pos->rpc_ops != new->rpc_ops) | 492 | if (pos->rpc_ops != new->rpc_ops) |
484 | continue; | 493 | continue; |
485 | 494 | ||
486 | if (pos->cl_proto != new->cl_proto) | ||
487 | continue; | ||
488 | |||
489 | if (pos->cl_minorversion != new->cl_minorversion) | 495 | if (pos->cl_minorversion != new->cl_minorversion) |
490 | continue; | 496 | continue; |
491 | 497 | ||
@@ -510,6 +516,9 @@ int nfs40_walk_client_list(struct nfs_client *new, | |||
510 | if (pos->cl_clientid != new->cl_clientid) | 516 | if (pos->cl_clientid != new->cl_clientid) |
511 | continue; | 517 | continue; |
512 | 518 | ||
519 | if (!nfs4_match_client_owner_id(pos, new)) | ||
520 | continue; | ||
521 | |||
513 | atomic_inc(&pos->cl_count); | 522 | atomic_inc(&pos->cl_count); |
514 | spin_unlock(&nn->nfs_client_lock); | 523 | spin_unlock(&nn->nfs_client_lock); |
515 | 524 | ||
@@ -566,20 +575,14 @@ static bool nfs4_match_clientids(struct nfs_client *a, struct nfs_client *b) | |||
566 | } | 575 | } |
567 | 576 | ||
568 | /* | 577 | /* |
569 | * Returns true if the server owners match | 578 | * Returns true if the server major ids match |
570 | */ | 579 | */ |
571 | static bool | 580 | static bool |
572 | nfs4_match_serverowners(struct nfs_client *a, struct nfs_client *b) | 581 | nfs4_check_clientid_trunking(struct nfs_client *a, struct nfs_client *b) |
573 | { | 582 | { |
574 | struct nfs41_server_owner *o1 = a->cl_serverowner; | 583 | struct nfs41_server_owner *o1 = a->cl_serverowner; |
575 | struct nfs41_server_owner *o2 = b->cl_serverowner; | 584 | struct nfs41_server_owner *o2 = b->cl_serverowner; |
576 | 585 | ||
577 | if (o1->minor_id != o2->minor_id) { | ||
578 | dprintk("NFS: --> %s server owner minor IDs do not match\n", | ||
579 | __func__); | ||
580 | return false; | ||
581 | } | ||
582 | |||
583 | if (o1->major_id_sz != o2->major_id_sz) | 586 | if (o1->major_id_sz != o2->major_id_sz) |
584 | goto out_major_mismatch; | 587 | goto out_major_mismatch; |
585 | if (memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0) | 588 | if (memcmp(o1->major_id, o2->major_id, o1->major_id_sz) != 0) |
@@ -621,9 +624,6 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
621 | if (pos->rpc_ops != new->rpc_ops) | 624 | if (pos->rpc_ops != new->rpc_ops) |
622 | continue; | 625 | continue; |
623 | 626 | ||
624 | if (pos->cl_proto != new->cl_proto) | ||
625 | continue; | ||
626 | |||
627 | if (pos->cl_minorversion != new->cl_minorversion) | 627 | if (pos->cl_minorversion != new->cl_minorversion) |
628 | continue; | 628 | continue; |
629 | 629 | ||
@@ -639,7 +639,7 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
639 | prev = pos; | 639 | prev = pos; |
640 | 640 | ||
641 | status = nfs_wait_client_init_complete(pos); | 641 | status = nfs_wait_client_init_complete(pos); |
642 | if (status == 0) { | 642 | if (pos->cl_cons_state == NFS_CS_SESSION_INITING) { |
643 | nfs4_schedule_lease_recovery(pos); | 643 | nfs4_schedule_lease_recovery(pos); |
644 | status = nfs4_wait_clnt_recover(pos); | 644 | status = nfs4_wait_clnt_recover(pos); |
645 | } | 645 | } |
@@ -654,7 +654,19 @@ int nfs41_walk_client_list(struct nfs_client *new, | |||
654 | if (!nfs4_match_clientids(pos, new)) | 654 | if (!nfs4_match_clientids(pos, new)) |
655 | continue; | 655 | continue; |
656 | 656 | ||
657 | if (!nfs4_match_serverowners(pos, new)) | 657 | /* |
658 | * Note that session trunking is just a special subcase of | ||
659 | * client id trunking. In either case, we want to fall back | ||
660 | * to using the existing nfs_client. | ||
661 | */ | ||
662 | if (!nfs4_check_clientid_trunking(pos, new)) | ||
663 | continue; | ||
664 | |||
665 | /* Unlike NFSv4.0, we know that NFSv4.1 always uses the | ||
666 | * uniform string, however someone might switch the | ||
667 | * uniquifier string on us. | ||
668 | */ | ||
669 | if (!nfs4_match_client_owner_id(pos, new)) | ||
658 | continue; | 670 | continue; |
659 | 671 | ||
660 | atomic_inc(&pos->cl_count); | 672 | atomic_inc(&pos->cl_count); |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index e7f8d5ff2581..c347705b0161 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1117,8 +1117,6 @@ static int can_open_delegated(struct nfs_delegation *delegation, fmode_t fmode) | |||
1117 | return 0; | 1117 | return 0; |
1118 | if ((delegation->type & fmode) != fmode) | 1118 | if ((delegation->type & fmode) != fmode) |
1119 | return 0; | 1119 | return 0; |
1120 | if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags)) | ||
1121 | return 0; | ||
1122 | if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) | 1120 | if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) |
1123 | return 0; | 1121 | return 0; |
1124 | nfs_mark_delegation_referenced(delegation); | 1122 | nfs_mark_delegation_referenced(delegation); |
@@ -4917,11 +4915,14 @@ static void nfs4_init_boot_verifier(const struct nfs_client *clp, | |||
4917 | } | 4915 | } |
4918 | 4916 | ||
4919 | static unsigned int | 4917 | static unsigned int |
4920 | nfs4_init_nonuniform_client_string(const struct nfs_client *clp, | 4918 | nfs4_init_nonuniform_client_string(struct nfs_client *clp, |
4921 | char *buf, size_t len) | 4919 | char *buf, size_t len) |
4922 | { | 4920 | { |
4923 | unsigned int result; | 4921 | unsigned int result; |
4924 | 4922 | ||
4923 | if (clp->cl_owner_id != NULL) | ||
4924 | return strlcpy(buf, clp->cl_owner_id, len); | ||
4925 | |||
4925 | rcu_read_lock(); | 4926 | rcu_read_lock(); |
4926 | result = scnprintf(buf, len, "Linux NFSv4.0 %s/%s %s", | 4927 | result = scnprintf(buf, len, "Linux NFSv4.0 %s/%s %s", |
4927 | clp->cl_ipaddr, | 4928 | clp->cl_ipaddr, |
@@ -4930,24 +4931,32 @@ nfs4_init_nonuniform_client_string(const struct nfs_client *clp, | |||
4930 | rpc_peeraddr2str(clp->cl_rpcclient, | 4931 | rpc_peeraddr2str(clp->cl_rpcclient, |
4931 | RPC_DISPLAY_PROTO)); | 4932 | RPC_DISPLAY_PROTO)); |
4932 | rcu_read_unlock(); | 4933 | rcu_read_unlock(); |
4934 | clp->cl_owner_id = kstrdup(buf, GFP_KERNEL); | ||
4933 | return result; | 4935 | return result; |
4934 | } | 4936 | } |
4935 | 4937 | ||
4936 | static unsigned int | 4938 | static unsigned int |
4937 | nfs4_init_uniform_client_string(const struct nfs_client *clp, | 4939 | nfs4_init_uniform_client_string(struct nfs_client *clp, |
4938 | char *buf, size_t len) | 4940 | char *buf, size_t len) |
4939 | { | 4941 | { |
4940 | const char *nodename = clp->cl_rpcclient->cl_nodename; | 4942 | const char *nodename = clp->cl_rpcclient->cl_nodename; |
4943 | unsigned int result; | ||
4944 | |||
4945 | if (clp->cl_owner_id != NULL) | ||
4946 | return strlcpy(buf, clp->cl_owner_id, len); | ||
4941 | 4947 | ||
4942 | if (nfs4_client_id_uniquifier[0] != '\0') | 4948 | if (nfs4_client_id_uniquifier[0] != '\0') |
4943 | return scnprintf(buf, len, "Linux NFSv%u.%u %s/%s", | 4949 | result = scnprintf(buf, len, "Linux NFSv%u.%u %s/%s", |
4944 | clp->rpc_ops->version, | 4950 | clp->rpc_ops->version, |
4945 | clp->cl_minorversion, | 4951 | clp->cl_minorversion, |
4946 | nfs4_client_id_uniquifier, | 4952 | nfs4_client_id_uniquifier, |
4947 | nodename); | 4953 | nodename); |
4948 | return scnprintf(buf, len, "Linux NFSv%u.%u %s", | 4954 | else |
4955 | result = scnprintf(buf, len, "Linux NFSv%u.%u %s", | ||
4949 | clp->rpc_ops->version, clp->cl_minorversion, | 4956 | clp->rpc_ops->version, clp->cl_minorversion, |
4950 | nodename); | 4957 | nodename); |
4958 | clp->cl_owner_id = kstrdup(buf, GFP_KERNEL); | ||
4959 | return result; | ||
4951 | } | 4960 | } |
4952 | 4961 | ||
4953 | /* | 4962 | /* |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 3550a9c87616..c06a1ba80d73 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -3897,11 +3897,11 @@ nfs4_set_delegation(struct nfs4_client *clp, struct svc_fh *fh, | |||
3897 | status = nfs4_setlease(dp); | 3897 | status = nfs4_setlease(dp); |
3898 | goto out; | 3898 | goto out; |
3899 | } | 3899 | } |
3900 | atomic_inc(&fp->fi_delegees); | ||
3901 | if (fp->fi_had_conflict) { | 3900 | if (fp->fi_had_conflict) { |
3902 | status = -EAGAIN; | 3901 | status = -EAGAIN; |
3903 | goto out_unlock; | 3902 | goto out_unlock; |
3904 | } | 3903 | } |
3904 | atomic_inc(&fp->fi_delegees); | ||
3905 | hash_delegation_locked(dp, fp); | 3905 | hash_delegation_locked(dp, fp); |
3906 | status = 0; | 3906 | status = 0; |
3907 | out_unlock: | 3907 | out_unlock: |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index c991616acca9..bff8567aa42d 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -259,16 +259,15 @@ static ssize_t fanotify_read(struct file *file, char __user *buf, | |||
259 | struct fsnotify_event *kevent; | 259 | struct fsnotify_event *kevent; |
260 | char __user *start; | 260 | char __user *start; |
261 | int ret; | 261 | int ret; |
262 | DEFINE_WAIT(wait); | 262 | DEFINE_WAIT_FUNC(wait, woken_wake_function); |
263 | 263 | ||
264 | start = buf; | 264 | start = buf; |
265 | group = file->private_data; | 265 | group = file->private_data; |
266 | 266 | ||
267 | pr_debug("%s: group=%p\n", __func__, group); | 267 | pr_debug("%s: group=%p\n", __func__, group); |
268 | 268 | ||
269 | add_wait_queue(&group->notification_waitq, &wait); | ||
269 | while (1) { | 270 | while (1) { |
270 | prepare_to_wait(&group->notification_waitq, &wait, TASK_INTERRUPTIBLE); | ||
271 | |||
272 | mutex_lock(&group->notification_mutex); | 271 | mutex_lock(&group->notification_mutex); |
273 | kevent = get_one_event(group, count); | 272 | kevent = get_one_event(group, count); |
274 | mutex_unlock(&group->notification_mutex); | 273 | mutex_unlock(&group->notification_mutex); |
@@ -289,7 +288,8 @@ static ssize_t fanotify_read(struct file *file, char __user *buf, | |||
289 | 288 | ||
290 | if (start != buf) | 289 | if (start != buf) |
291 | break; | 290 | break; |
292 | schedule(); | 291 | |
292 | wait_woken(&wait, TASK_INTERRUPTIBLE, MAX_SCHEDULE_TIMEOUT); | ||
293 | continue; | 293 | continue; |
294 | } | 294 | } |
295 | 295 | ||
@@ -318,8 +318,8 @@ static ssize_t fanotify_read(struct file *file, char __user *buf, | |||
318 | buf += ret; | 318 | buf += ret; |
319 | count -= ret; | 319 | count -= ret; |
320 | } | 320 | } |
321 | remove_wait_queue(&group->notification_waitq, &wait); | ||
321 | 322 | ||
322 | finish_wait(&group->notification_waitq, &wait); | ||
323 | if (start != buf && ret != -EFAULT) | 323 | if (start != buf && ret != -EFAULT) |
324 | ret = buf - start; | 324 | ret = buf - start; |
325 | return ret; | 325 | return ret; |
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index 79b5af5e6a7b..cecd875653e4 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
@@ -2023,11 +2023,8 @@ leave: | |||
2023 | dlm_lockres_drop_inflight_ref(dlm, res); | 2023 | dlm_lockres_drop_inflight_ref(dlm, res); |
2024 | spin_unlock(&res->spinlock); | 2024 | spin_unlock(&res->spinlock); |
2025 | 2025 | ||
2026 | if (ret < 0) { | 2026 | if (ret < 0) |
2027 | mlog_errno(ret); | 2027 | mlog_errno(ret); |
2028 | if (newlock) | ||
2029 | dlm_lock_put(newlock); | ||
2030 | } | ||
2031 | 2028 | ||
2032 | return ret; | 2029 | return ret; |
2033 | } | 2030 | } |
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index b931e04e3388..914c121ec890 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c | |||
@@ -94,6 +94,14 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb, | |||
94 | struct inode *inode, | 94 | struct inode *inode, |
95 | const char *symname); | 95 | const char *symname); |
96 | 96 | ||
97 | static int ocfs2_double_lock(struct ocfs2_super *osb, | ||
98 | struct buffer_head **bh1, | ||
99 | struct inode *inode1, | ||
100 | struct buffer_head **bh2, | ||
101 | struct inode *inode2, | ||
102 | int rename); | ||
103 | |||
104 | static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2); | ||
97 | /* An orphan dir name is an 8 byte value, printed as a hex string */ | 105 | /* An orphan dir name is an 8 byte value, printed as a hex string */ |
98 | #define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64))) | 106 | #define OCFS2_ORPHAN_NAMELEN ((int)(2 * sizeof(u64))) |
99 | 107 | ||
@@ -678,8 +686,10 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
678 | { | 686 | { |
679 | handle_t *handle; | 687 | handle_t *handle; |
680 | struct inode *inode = old_dentry->d_inode; | 688 | struct inode *inode = old_dentry->d_inode; |
689 | struct inode *old_dir = old_dentry->d_parent->d_inode; | ||
681 | int err; | 690 | int err; |
682 | struct buffer_head *fe_bh = NULL; | 691 | struct buffer_head *fe_bh = NULL; |
692 | struct buffer_head *old_dir_bh = NULL; | ||
683 | struct buffer_head *parent_fe_bh = NULL; | 693 | struct buffer_head *parent_fe_bh = NULL; |
684 | struct ocfs2_dinode *fe = NULL; | 694 | struct ocfs2_dinode *fe = NULL; |
685 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); | 695 | struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); |
@@ -696,19 +706,33 @@ static int ocfs2_link(struct dentry *old_dentry, | |||
696 | 706 | ||
697 | dquot_initialize(dir); | 707 | dquot_initialize(dir); |
698 | 708 | ||
699 | err = ocfs2_inode_lock_nested(dir, &parent_fe_bh, 1, OI_LS_PARENT); | 709 | err = ocfs2_double_lock(osb, &old_dir_bh, old_dir, |
710 | &parent_fe_bh, dir, 0); | ||
700 | if (err < 0) { | 711 | if (err < 0) { |
701 | if (err != -ENOENT) | 712 | if (err != -ENOENT) |
702 | mlog_errno(err); | 713 | mlog_errno(err); |
703 | return err; | 714 | return err; |
704 | } | 715 | } |
705 | 716 | ||
717 | /* make sure both dirs have bhs | ||
718 | * get an extra ref on old_dir_bh if old==new */ | ||
719 | if (!parent_fe_bh) { | ||
720 | if (old_dir_bh) { | ||
721 | parent_fe_bh = old_dir_bh; | ||
722 | get_bh(parent_fe_bh); | ||
723 | } else { | ||
724 | mlog(ML_ERROR, "%s: no old_dir_bh!\n", osb->uuid_str); | ||
725 | err = -EIO; | ||
726 | goto out; | ||
727 | } | ||
728 | } | ||
729 | |||
706 | if (!dir->i_nlink) { | 730 | if (!dir->i_nlink) { |
707 | err = -ENOENT; | 731 | err = -ENOENT; |
708 | goto out; | 732 | goto out; |
709 | } | 733 | } |
710 | 734 | ||
711 | err = ocfs2_lookup_ino_from_name(dir, old_dentry->d_name.name, | 735 | err = ocfs2_lookup_ino_from_name(old_dir, old_dentry->d_name.name, |
712 | old_dentry->d_name.len, &old_de_ino); | 736 | old_dentry->d_name.len, &old_de_ino); |
713 | if (err) { | 737 | if (err) { |
714 | err = -ENOENT; | 738 | err = -ENOENT; |
@@ -801,10 +825,11 @@ out_unlock_inode: | |||
801 | ocfs2_inode_unlock(inode, 1); | 825 | ocfs2_inode_unlock(inode, 1); |
802 | 826 | ||
803 | out: | 827 | out: |
804 | ocfs2_inode_unlock(dir, 1); | 828 | ocfs2_double_unlock(old_dir, dir); |
805 | 829 | ||
806 | brelse(fe_bh); | 830 | brelse(fe_bh); |
807 | brelse(parent_fe_bh); | 831 | brelse(parent_fe_bh); |
832 | brelse(old_dir_bh); | ||
808 | 833 | ||
809 | ocfs2_free_dir_lookup_result(&lookup); | 834 | ocfs2_free_dir_lookup_result(&lookup); |
810 | 835 | ||
@@ -1072,14 +1097,15 @@ static int ocfs2_check_if_ancestor(struct ocfs2_super *osb, | |||
1072 | } | 1097 | } |
1073 | 1098 | ||
1074 | /* | 1099 | /* |
1075 | * The only place this should be used is rename! | 1100 | * The only place this should be used is rename and link! |
1076 | * if they have the same id, then the 1st one is the only one locked. | 1101 | * if they have the same id, then the 1st one is the only one locked. |
1077 | */ | 1102 | */ |
1078 | static int ocfs2_double_lock(struct ocfs2_super *osb, | 1103 | static int ocfs2_double_lock(struct ocfs2_super *osb, |
1079 | struct buffer_head **bh1, | 1104 | struct buffer_head **bh1, |
1080 | struct inode *inode1, | 1105 | struct inode *inode1, |
1081 | struct buffer_head **bh2, | 1106 | struct buffer_head **bh2, |
1082 | struct inode *inode2) | 1107 | struct inode *inode2, |
1108 | int rename) | ||
1083 | { | 1109 | { |
1084 | int status; | 1110 | int status; |
1085 | int inode1_is_ancestor, inode2_is_ancestor; | 1111 | int inode1_is_ancestor, inode2_is_ancestor; |
@@ -1127,7 +1153,7 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
1127 | } | 1153 | } |
1128 | /* lock id2 */ | 1154 | /* lock id2 */ |
1129 | status = ocfs2_inode_lock_nested(inode2, bh2, 1, | 1155 | status = ocfs2_inode_lock_nested(inode2, bh2, 1, |
1130 | OI_LS_RENAME1); | 1156 | rename == 1 ? OI_LS_RENAME1 : OI_LS_PARENT); |
1131 | if (status < 0) { | 1157 | if (status < 0) { |
1132 | if (status != -ENOENT) | 1158 | if (status != -ENOENT) |
1133 | mlog_errno(status); | 1159 | mlog_errno(status); |
@@ -1136,7 +1162,8 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, | |||
1136 | } | 1162 | } |
1137 | 1163 | ||
1138 | /* lock id1 */ | 1164 | /* lock id1 */ |
1139 | status = ocfs2_inode_lock_nested(inode1, bh1, 1, OI_LS_RENAME2); | 1165 | status = ocfs2_inode_lock_nested(inode1, bh1, 1, |
1166 | rename == 1 ? OI_LS_RENAME2 : OI_LS_PARENT); | ||
1140 | if (status < 0) { | 1167 | if (status < 0) { |
1141 | /* | 1168 | /* |
1142 | * An error return must mean that no cluster locks | 1169 | * An error return must mean that no cluster locks |
@@ -1252,7 +1279,7 @@ static int ocfs2_rename(struct inode *old_dir, | |||
1252 | 1279 | ||
1253 | /* if old and new are the same, this'll just do one lock. */ | 1280 | /* if old and new are the same, this'll just do one lock. */ |
1254 | status = ocfs2_double_lock(osb, &old_dir_bh, old_dir, | 1281 | status = ocfs2_double_lock(osb, &old_dir_bh, old_dir, |
1255 | &new_dir_bh, new_dir); | 1282 | &new_dir_bh, new_dir, 1); |
1256 | if (status < 0) { | 1283 | if (status < 0) { |
1257 | mlog_errno(status); | 1284 | mlog_errno(status); |
1258 | goto bail; | 1285 | goto bail; |
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 8f0acef3d184..69df5b239844 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -2396,30 +2396,25 @@ static inline qsize_t stoqb(qsize_t space) | |||
2396 | } | 2396 | } |
2397 | 2397 | ||
2398 | /* Generic routine for getting common part of quota structure */ | 2398 | /* Generic routine for getting common part of quota structure */ |
2399 | static void do_get_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | 2399 | static void do_get_dqblk(struct dquot *dquot, struct qc_dqblk *di) |
2400 | { | 2400 | { |
2401 | struct mem_dqblk *dm = &dquot->dq_dqb; | 2401 | struct mem_dqblk *dm = &dquot->dq_dqb; |
2402 | 2402 | ||
2403 | memset(di, 0, sizeof(*di)); | 2403 | memset(di, 0, sizeof(*di)); |
2404 | di->d_version = FS_DQUOT_VERSION; | ||
2405 | di->d_flags = dquot->dq_id.type == USRQUOTA ? | ||
2406 | FS_USER_QUOTA : FS_GROUP_QUOTA; | ||
2407 | di->d_id = from_kqid_munged(current_user_ns(), dquot->dq_id); | ||
2408 | |||
2409 | spin_lock(&dq_data_lock); | 2404 | spin_lock(&dq_data_lock); |
2410 | di->d_blk_hardlimit = stoqb(dm->dqb_bhardlimit); | 2405 | di->d_spc_hardlimit = dm->dqb_bhardlimit; |
2411 | di->d_blk_softlimit = stoqb(dm->dqb_bsoftlimit); | 2406 | di->d_spc_softlimit = dm->dqb_bsoftlimit; |
2412 | di->d_ino_hardlimit = dm->dqb_ihardlimit; | 2407 | di->d_ino_hardlimit = dm->dqb_ihardlimit; |
2413 | di->d_ino_softlimit = dm->dqb_isoftlimit; | 2408 | di->d_ino_softlimit = dm->dqb_isoftlimit; |
2414 | di->d_bcount = dm->dqb_curspace + dm->dqb_rsvspace; | 2409 | di->d_space = dm->dqb_curspace + dm->dqb_rsvspace; |
2415 | di->d_icount = dm->dqb_curinodes; | 2410 | di->d_ino_count = dm->dqb_curinodes; |
2416 | di->d_btimer = dm->dqb_btime; | 2411 | di->d_spc_timer = dm->dqb_btime; |
2417 | di->d_itimer = dm->dqb_itime; | 2412 | di->d_ino_timer = dm->dqb_itime; |
2418 | spin_unlock(&dq_data_lock); | 2413 | spin_unlock(&dq_data_lock); |
2419 | } | 2414 | } |
2420 | 2415 | ||
2421 | int dquot_get_dqblk(struct super_block *sb, struct kqid qid, | 2416 | int dquot_get_dqblk(struct super_block *sb, struct kqid qid, |
2422 | struct fs_disk_quota *di) | 2417 | struct qc_dqblk *di) |
2423 | { | 2418 | { |
2424 | struct dquot *dquot; | 2419 | struct dquot *dquot; |
2425 | 2420 | ||
@@ -2433,70 +2428,70 @@ int dquot_get_dqblk(struct super_block *sb, struct kqid qid, | |||
2433 | } | 2428 | } |
2434 | EXPORT_SYMBOL(dquot_get_dqblk); | 2429 | EXPORT_SYMBOL(dquot_get_dqblk); |
2435 | 2430 | ||
2436 | #define VFS_FS_DQ_MASK \ | 2431 | #define VFS_QC_MASK \ |
2437 | (FS_DQ_BCOUNT | FS_DQ_BSOFT | FS_DQ_BHARD | \ | 2432 | (QC_SPACE | QC_SPC_SOFT | QC_SPC_HARD | \ |
2438 | FS_DQ_ICOUNT | FS_DQ_ISOFT | FS_DQ_IHARD | \ | 2433 | QC_INO_COUNT | QC_INO_SOFT | QC_INO_HARD | \ |
2439 | FS_DQ_BTIMER | FS_DQ_ITIMER) | 2434 | QC_SPC_TIMER | QC_INO_TIMER) |
2440 | 2435 | ||
2441 | /* Generic routine for setting common part of quota structure */ | 2436 | /* Generic routine for setting common part of quota structure */ |
2442 | static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | 2437 | static int do_set_dqblk(struct dquot *dquot, struct qc_dqblk *di) |
2443 | { | 2438 | { |
2444 | struct mem_dqblk *dm = &dquot->dq_dqb; | 2439 | struct mem_dqblk *dm = &dquot->dq_dqb; |
2445 | int check_blim = 0, check_ilim = 0; | 2440 | int check_blim = 0, check_ilim = 0; |
2446 | struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type]; | 2441 | struct mem_dqinfo *dqi = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_id.type]; |
2447 | 2442 | ||
2448 | if (di->d_fieldmask & ~VFS_FS_DQ_MASK) | 2443 | if (di->d_fieldmask & ~VFS_QC_MASK) |
2449 | return -EINVAL; | 2444 | return -EINVAL; |
2450 | 2445 | ||
2451 | if (((di->d_fieldmask & FS_DQ_BSOFT) && | 2446 | if (((di->d_fieldmask & QC_SPC_SOFT) && |
2452 | (di->d_blk_softlimit > dqi->dqi_maxblimit)) || | 2447 | stoqb(di->d_spc_softlimit) > dqi->dqi_maxblimit) || |
2453 | ((di->d_fieldmask & FS_DQ_BHARD) && | 2448 | ((di->d_fieldmask & QC_SPC_HARD) && |
2454 | (di->d_blk_hardlimit > dqi->dqi_maxblimit)) || | 2449 | stoqb(di->d_spc_hardlimit) > dqi->dqi_maxblimit) || |
2455 | ((di->d_fieldmask & FS_DQ_ISOFT) && | 2450 | ((di->d_fieldmask & QC_INO_SOFT) && |
2456 | (di->d_ino_softlimit > dqi->dqi_maxilimit)) || | 2451 | (di->d_ino_softlimit > dqi->dqi_maxilimit)) || |
2457 | ((di->d_fieldmask & FS_DQ_IHARD) && | 2452 | ((di->d_fieldmask & QC_INO_HARD) && |
2458 | (di->d_ino_hardlimit > dqi->dqi_maxilimit))) | 2453 | (di->d_ino_hardlimit > dqi->dqi_maxilimit))) |
2459 | return -ERANGE; | 2454 | return -ERANGE; |
2460 | 2455 | ||
2461 | spin_lock(&dq_data_lock); | 2456 | spin_lock(&dq_data_lock); |
2462 | if (di->d_fieldmask & FS_DQ_BCOUNT) { | 2457 | if (di->d_fieldmask & QC_SPACE) { |
2463 | dm->dqb_curspace = di->d_bcount - dm->dqb_rsvspace; | 2458 | dm->dqb_curspace = di->d_space - dm->dqb_rsvspace; |
2464 | check_blim = 1; | 2459 | check_blim = 1; |
2465 | set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); | 2460 | set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); |
2466 | } | 2461 | } |
2467 | 2462 | ||
2468 | if (di->d_fieldmask & FS_DQ_BSOFT) | 2463 | if (di->d_fieldmask & QC_SPC_SOFT) |
2469 | dm->dqb_bsoftlimit = qbtos(di->d_blk_softlimit); | 2464 | dm->dqb_bsoftlimit = di->d_spc_softlimit; |
2470 | if (di->d_fieldmask & FS_DQ_BHARD) | 2465 | if (di->d_fieldmask & QC_SPC_HARD) |
2471 | dm->dqb_bhardlimit = qbtos(di->d_blk_hardlimit); | 2466 | dm->dqb_bhardlimit = di->d_spc_hardlimit; |
2472 | if (di->d_fieldmask & (FS_DQ_BSOFT | FS_DQ_BHARD)) { | 2467 | if (di->d_fieldmask & (QC_SPC_SOFT | QC_SPC_HARD)) { |
2473 | check_blim = 1; | 2468 | check_blim = 1; |
2474 | set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); | 2469 | set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); |
2475 | } | 2470 | } |
2476 | 2471 | ||
2477 | if (di->d_fieldmask & FS_DQ_ICOUNT) { | 2472 | if (di->d_fieldmask & QC_INO_COUNT) { |
2478 | dm->dqb_curinodes = di->d_icount; | 2473 | dm->dqb_curinodes = di->d_ino_count; |
2479 | check_ilim = 1; | 2474 | check_ilim = 1; |
2480 | set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); | 2475 | set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); |
2481 | } | 2476 | } |
2482 | 2477 | ||
2483 | if (di->d_fieldmask & FS_DQ_ISOFT) | 2478 | if (di->d_fieldmask & QC_INO_SOFT) |
2484 | dm->dqb_isoftlimit = di->d_ino_softlimit; | 2479 | dm->dqb_isoftlimit = di->d_ino_softlimit; |
2485 | if (di->d_fieldmask & FS_DQ_IHARD) | 2480 | if (di->d_fieldmask & QC_INO_HARD) |
2486 | dm->dqb_ihardlimit = di->d_ino_hardlimit; | 2481 | dm->dqb_ihardlimit = di->d_ino_hardlimit; |
2487 | if (di->d_fieldmask & (FS_DQ_ISOFT | FS_DQ_IHARD)) { | 2482 | if (di->d_fieldmask & (QC_INO_SOFT | QC_INO_HARD)) { |
2488 | check_ilim = 1; | 2483 | check_ilim = 1; |
2489 | set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); | 2484 | set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); |
2490 | } | 2485 | } |
2491 | 2486 | ||
2492 | if (di->d_fieldmask & FS_DQ_BTIMER) { | 2487 | if (di->d_fieldmask & QC_SPC_TIMER) { |
2493 | dm->dqb_btime = di->d_btimer; | 2488 | dm->dqb_btime = di->d_spc_timer; |
2494 | check_blim = 1; | 2489 | check_blim = 1; |
2495 | set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); | 2490 | set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); |
2496 | } | 2491 | } |
2497 | 2492 | ||
2498 | if (di->d_fieldmask & FS_DQ_ITIMER) { | 2493 | if (di->d_fieldmask & QC_INO_TIMER) { |
2499 | dm->dqb_itime = di->d_itimer; | 2494 | dm->dqb_itime = di->d_ino_timer; |
2500 | check_ilim = 1; | 2495 | check_ilim = 1; |
2501 | set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); | 2496 | set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); |
2502 | } | 2497 | } |
@@ -2506,7 +2501,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2506 | dm->dqb_curspace < dm->dqb_bsoftlimit) { | 2501 | dm->dqb_curspace < dm->dqb_bsoftlimit) { |
2507 | dm->dqb_btime = 0; | 2502 | dm->dqb_btime = 0; |
2508 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); | 2503 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
2509 | } else if (!(di->d_fieldmask & FS_DQ_BTIMER)) | 2504 | } else if (!(di->d_fieldmask & QC_SPC_TIMER)) |
2510 | /* Set grace only if user hasn't provided his own... */ | 2505 | /* Set grace only if user hasn't provided his own... */ |
2511 | dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; | 2506 | dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; |
2512 | } | 2507 | } |
@@ -2515,7 +2510,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2515 | dm->dqb_curinodes < dm->dqb_isoftlimit) { | 2510 | dm->dqb_curinodes < dm->dqb_isoftlimit) { |
2516 | dm->dqb_itime = 0; | 2511 | dm->dqb_itime = 0; |
2517 | clear_bit(DQ_INODES_B, &dquot->dq_flags); | 2512 | clear_bit(DQ_INODES_B, &dquot->dq_flags); |
2518 | } else if (!(di->d_fieldmask & FS_DQ_ITIMER)) | 2513 | } else if (!(di->d_fieldmask & QC_INO_TIMER)) |
2519 | /* Set grace only if user hasn't provided his own... */ | 2514 | /* Set grace only if user hasn't provided his own... */ |
2520 | dm->dqb_itime = get_seconds() + dqi->dqi_igrace; | 2515 | dm->dqb_itime = get_seconds() + dqi->dqi_igrace; |
2521 | } | 2516 | } |
@@ -2531,7 +2526,7 @@ static int do_set_dqblk(struct dquot *dquot, struct fs_disk_quota *di) | |||
2531 | } | 2526 | } |
2532 | 2527 | ||
2533 | int dquot_set_dqblk(struct super_block *sb, struct kqid qid, | 2528 | int dquot_set_dqblk(struct super_block *sb, struct kqid qid, |
2534 | struct fs_disk_quota *di) | 2529 | struct qc_dqblk *di) |
2535 | { | 2530 | { |
2536 | struct dquot *dquot; | 2531 | struct dquot *dquot; |
2537 | int rc; | 2532 | int rc; |
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 2aa4151f99d2..6f3856328eea 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
@@ -118,17 +118,27 @@ static int quota_setinfo(struct super_block *sb, int type, void __user *addr) | |||
118 | return sb->s_qcop->set_info(sb, type, &info); | 118 | return sb->s_qcop->set_info(sb, type, &info); |
119 | } | 119 | } |
120 | 120 | ||
121 | static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src) | 121 | static inline qsize_t qbtos(qsize_t blocks) |
122 | { | ||
123 | return blocks << QIF_DQBLKSIZE_BITS; | ||
124 | } | ||
125 | |||
126 | static inline qsize_t stoqb(qsize_t space) | ||
127 | { | ||
128 | return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS; | ||
129 | } | ||
130 | |||
131 | static void copy_to_if_dqblk(struct if_dqblk *dst, struct qc_dqblk *src) | ||
122 | { | 132 | { |
123 | memset(dst, 0, sizeof(*dst)); | 133 | memset(dst, 0, sizeof(*dst)); |
124 | dst->dqb_bhardlimit = src->d_blk_hardlimit; | 134 | dst->dqb_bhardlimit = stoqb(src->d_spc_hardlimit); |
125 | dst->dqb_bsoftlimit = src->d_blk_softlimit; | 135 | dst->dqb_bsoftlimit = stoqb(src->d_spc_softlimit); |
126 | dst->dqb_curspace = src->d_bcount; | 136 | dst->dqb_curspace = src->d_space; |
127 | dst->dqb_ihardlimit = src->d_ino_hardlimit; | 137 | dst->dqb_ihardlimit = src->d_ino_hardlimit; |
128 | dst->dqb_isoftlimit = src->d_ino_softlimit; | 138 | dst->dqb_isoftlimit = src->d_ino_softlimit; |
129 | dst->dqb_curinodes = src->d_icount; | 139 | dst->dqb_curinodes = src->d_ino_count; |
130 | dst->dqb_btime = src->d_btimer; | 140 | dst->dqb_btime = src->d_spc_timer; |
131 | dst->dqb_itime = src->d_itimer; | 141 | dst->dqb_itime = src->d_ino_timer; |
132 | dst->dqb_valid = QIF_ALL; | 142 | dst->dqb_valid = QIF_ALL; |
133 | } | 143 | } |
134 | 144 | ||
@@ -136,7 +146,7 @@ static int quota_getquota(struct super_block *sb, int type, qid_t id, | |||
136 | void __user *addr) | 146 | void __user *addr) |
137 | { | 147 | { |
138 | struct kqid qid; | 148 | struct kqid qid; |
139 | struct fs_disk_quota fdq; | 149 | struct qc_dqblk fdq; |
140 | struct if_dqblk idq; | 150 | struct if_dqblk idq; |
141 | int ret; | 151 | int ret; |
142 | 152 | ||
@@ -154,36 +164,36 @@ static int quota_getquota(struct super_block *sb, int type, qid_t id, | |||
154 | return 0; | 164 | return 0; |
155 | } | 165 | } |
156 | 166 | ||
157 | static void copy_from_if_dqblk(struct fs_disk_quota *dst, struct if_dqblk *src) | 167 | static void copy_from_if_dqblk(struct qc_dqblk *dst, struct if_dqblk *src) |
158 | { | 168 | { |
159 | dst->d_blk_hardlimit = src->dqb_bhardlimit; | 169 | dst->d_spc_hardlimit = qbtos(src->dqb_bhardlimit); |
160 | dst->d_blk_softlimit = src->dqb_bsoftlimit; | 170 | dst->d_spc_softlimit = qbtos(src->dqb_bsoftlimit); |
161 | dst->d_bcount = src->dqb_curspace; | 171 | dst->d_space = src->dqb_curspace; |
162 | dst->d_ino_hardlimit = src->dqb_ihardlimit; | 172 | dst->d_ino_hardlimit = src->dqb_ihardlimit; |
163 | dst->d_ino_softlimit = src->dqb_isoftlimit; | 173 | dst->d_ino_softlimit = src->dqb_isoftlimit; |
164 | dst->d_icount = src->dqb_curinodes; | 174 | dst->d_ino_count = src->dqb_curinodes; |
165 | dst->d_btimer = src->dqb_btime; | 175 | dst->d_spc_timer = src->dqb_btime; |
166 | dst->d_itimer = src->dqb_itime; | 176 | dst->d_ino_timer = src->dqb_itime; |
167 | 177 | ||
168 | dst->d_fieldmask = 0; | 178 | dst->d_fieldmask = 0; |
169 | if (src->dqb_valid & QIF_BLIMITS) | 179 | if (src->dqb_valid & QIF_BLIMITS) |
170 | dst->d_fieldmask |= FS_DQ_BSOFT | FS_DQ_BHARD; | 180 | dst->d_fieldmask |= QC_SPC_SOFT | QC_SPC_HARD; |
171 | if (src->dqb_valid & QIF_SPACE) | 181 | if (src->dqb_valid & QIF_SPACE) |
172 | dst->d_fieldmask |= FS_DQ_BCOUNT; | 182 | dst->d_fieldmask |= QC_SPACE; |
173 | if (src->dqb_valid & QIF_ILIMITS) | 183 | if (src->dqb_valid & QIF_ILIMITS) |
174 | dst->d_fieldmask |= FS_DQ_ISOFT | FS_DQ_IHARD; | 184 | dst->d_fieldmask |= QC_INO_SOFT | QC_INO_HARD; |
175 | if (src->dqb_valid & QIF_INODES) | 185 | if (src->dqb_valid & QIF_INODES) |
176 | dst->d_fieldmask |= FS_DQ_ICOUNT; | 186 | dst->d_fieldmask |= QC_INO_COUNT; |
177 | if (src->dqb_valid & QIF_BTIME) | 187 | if (src->dqb_valid & QIF_BTIME) |
178 | dst->d_fieldmask |= FS_DQ_BTIMER; | 188 | dst->d_fieldmask |= QC_SPC_TIMER; |
179 | if (src->dqb_valid & QIF_ITIME) | 189 | if (src->dqb_valid & QIF_ITIME) |
180 | dst->d_fieldmask |= FS_DQ_ITIMER; | 190 | dst->d_fieldmask |= QC_INO_TIMER; |
181 | } | 191 | } |
182 | 192 | ||
183 | static int quota_setquota(struct super_block *sb, int type, qid_t id, | 193 | static int quota_setquota(struct super_block *sb, int type, qid_t id, |
184 | void __user *addr) | 194 | void __user *addr) |
185 | { | 195 | { |
186 | struct fs_disk_quota fdq; | 196 | struct qc_dqblk fdq; |
187 | struct if_dqblk idq; | 197 | struct if_dqblk idq; |
188 | struct kqid qid; | 198 | struct kqid qid; |
189 | 199 | ||
@@ -247,10 +257,78 @@ static int quota_getxstatev(struct super_block *sb, void __user *addr) | |||
247 | return ret; | 257 | return ret; |
248 | } | 258 | } |
249 | 259 | ||
260 | /* | ||
261 | * XFS defines BBTOB and BTOBB macros inside fs/xfs/ and we cannot move them | ||
262 | * out of there as xfsprogs rely on definitions being in that header file. So | ||
263 | * just define same functions here for quota purposes. | ||
264 | */ | ||
265 | #define XFS_BB_SHIFT 9 | ||
266 | |||
267 | static inline u64 quota_bbtob(u64 blocks) | ||
268 | { | ||
269 | return blocks << XFS_BB_SHIFT; | ||
270 | } | ||
271 | |||
272 | static inline u64 quota_btobb(u64 bytes) | ||
273 | { | ||
274 | return (bytes + (1 << XFS_BB_SHIFT) - 1) >> XFS_BB_SHIFT; | ||
275 | } | ||
276 | |||
277 | static void copy_from_xfs_dqblk(struct qc_dqblk *dst, struct fs_disk_quota *src) | ||
278 | { | ||
279 | dst->d_spc_hardlimit = quota_bbtob(src->d_blk_hardlimit); | ||
280 | dst->d_spc_softlimit = quota_bbtob(src->d_blk_softlimit); | ||
281 | dst->d_ino_hardlimit = src->d_ino_hardlimit; | ||
282 | dst->d_ino_softlimit = src->d_ino_softlimit; | ||
283 | dst->d_space = quota_bbtob(src->d_bcount); | ||
284 | dst->d_ino_count = src->d_icount; | ||
285 | dst->d_ino_timer = src->d_itimer; | ||
286 | dst->d_spc_timer = src->d_btimer; | ||
287 | dst->d_ino_warns = src->d_iwarns; | ||
288 | dst->d_spc_warns = src->d_bwarns; | ||
289 | dst->d_rt_spc_hardlimit = quota_bbtob(src->d_rtb_hardlimit); | ||
290 | dst->d_rt_spc_softlimit = quota_bbtob(src->d_rtb_softlimit); | ||
291 | dst->d_rt_space = quota_bbtob(src->d_rtbcount); | ||
292 | dst->d_rt_spc_timer = src->d_rtbtimer; | ||
293 | dst->d_rt_spc_warns = src->d_rtbwarns; | ||
294 | dst->d_fieldmask = 0; | ||
295 | if (src->d_fieldmask & FS_DQ_ISOFT) | ||
296 | dst->d_fieldmask |= QC_INO_SOFT; | ||
297 | if (src->d_fieldmask & FS_DQ_IHARD) | ||
298 | dst->d_fieldmask |= QC_INO_HARD; | ||
299 | if (src->d_fieldmask & FS_DQ_BSOFT) | ||
300 | dst->d_fieldmask |= QC_SPC_SOFT; | ||
301 | if (src->d_fieldmask & FS_DQ_BHARD) | ||
302 | dst->d_fieldmask |= QC_SPC_HARD; | ||
303 | if (src->d_fieldmask & FS_DQ_RTBSOFT) | ||
304 | dst->d_fieldmask |= QC_RT_SPC_SOFT; | ||
305 | if (src->d_fieldmask & FS_DQ_RTBHARD) | ||
306 | dst->d_fieldmask |= QC_RT_SPC_HARD; | ||
307 | if (src->d_fieldmask & FS_DQ_BTIMER) | ||
308 | dst->d_fieldmask |= QC_SPC_TIMER; | ||
309 | if (src->d_fieldmask & FS_DQ_ITIMER) | ||
310 | dst->d_fieldmask |= QC_INO_TIMER; | ||
311 | if (src->d_fieldmask & FS_DQ_RTBTIMER) | ||
312 | dst->d_fieldmask |= QC_RT_SPC_TIMER; | ||
313 | if (src->d_fieldmask & FS_DQ_BWARNS) | ||
314 | dst->d_fieldmask |= QC_SPC_WARNS; | ||
315 | if (src->d_fieldmask & FS_DQ_IWARNS) | ||
316 | dst->d_fieldmask |= QC_INO_WARNS; | ||
317 | if (src->d_fieldmask & FS_DQ_RTBWARNS) | ||
318 | dst->d_fieldmask |= QC_RT_SPC_WARNS; | ||
319 | if (src->d_fieldmask & FS_DQ_BCOUNT) | ||
320 | dst->d_fieldmask |= QC_SPACE; | ||
321 | if (src->d_fieldmask & FS_DQ_ICOUNT) | ||
322 | dst->d_fieldmask |= QC_INO_COUNT; | ||
323 | if (src->d_fieldmask & FS_DQ_RTBCOUNT) | ||
324 | dst->d_fieldmask |= QC_RT_SPACE; | ||
325 | } | ||
326 | |||
250 | static int quota_setxquota(struct super_block *sb, int type, qid_t id, | 327 | static int quota_setxquota(struct super_block *sb, int type, qid_t id, |
251 | void __user *addr) | 328 | void __user *addr) |
252 | { | 329 | { |
253 | struct fs_disk_quota fdq; | 330 | struct fs_disk_quota fdq; |
331 | struct qc_dqblk qdq; | ||
254 | struct kqid qid; | 332 | struct kqid qid; |
255 | 333 | ||
256 | if (copy_from_user(&fdq, addr, sizeof(fdq))) | 334 | if (copy_from_user(&fdq, addr, sizeof(fdq))) |
@@ -260,13 +338,44 @@ static int quota_setxquota(struct super_block *sb, int type, qid_t id, | |||
260 | qid = make_kqid(current_user_ns(), type, id); | 338 | qid = make_kqid(current_user_ns(), type, id); |
261 | if (!qid_valid(qid)) | 339 | if (!qid_valid(qid)) |
262 | return -EINVAL; | 340 | return -EINVAL; |
263 | return sb->s_qcop->set_dqblk(sb, qid, &fdq); | 341 | copy_from_xfs_dqblk(&qdq, &fdq); |
342 | return sb->s_qcop->set_dqblk(sb, qid, &qdq); | ||
343 | } | ||
344 | |||
345 | static void copy_to_xfs_dqblk(struct fs_disk_quota *dst, struct qc_dqblk *src, | ||
346 | int type, qid_t id) | ||
347 | { | ||
348 | memset(dst, 0, sizeof(*dst)); | ||
349 | dst->d_version = FS_DQUOT_VERSION; | ||
350 | dst->d_id = id; | ||
351 | if (type == USRQUOTA) | ||
352 | dst->d_flags = FS_USER_QUOTA; | ||
353 | else if (type == PRJQUOTA) | ||
354 | dst->d_flags = FS_PROJ_QUOTA; | ||
355 | else | ||
356 | dst->d_flags = FS_GROUP_QUOTA; | ||
357 | dst->d_blk_hardlimit = quota_btobb(src->d_spc_hardlimit); | ||
358 | dst->d_blk_softlimit = quota_btobb(src->d_spc_softlimit); | ||
359 | dst->d_ino_hardlimit = src->d_ino_hardlimit; | ||
360 | dst->d_ino_softlimit = src->d_ino_softlimit; | ||
361 | dst->d_bcount = quota_btobb(src->d_space); | ||
362 | dst->d_icount = src->d_ino_count; | ||
363 | dst->d_itimer = src->d_ino_timer; | ||
364 | dst->d_btimer = src->d_spc_timer; | ||
365 | dst->d_iwarns = src->d_ino_warns; | ||
366 | dst->d_bwarns = src->d_spc_warns; | ||
367 | dst->d_rtb_hardlimit = quota_btobb(src->d_rt_spc_hardlimit); | ||
368 | dst->d_rtb_softlimit = quota_btobb(src->d_rt_spc_softlimit); | ||
369 | dst->d_rtbcount = quota_btobb(src->d_rt_space); | ||
370 | dst->d_rtbtimer = src->d_rt_spc_timer; | ||
371 | dst->d_rtbwarns = src->d_rt_spc_warns; | ||
264 | } | 372 | } |
265 | 373 | ||
266 | static int quota_getxquota(struct super_block *sb, int type, qid_t id, | 374 | static int quota_getxquota(struct super_block *sb, int type, qid_t id, |
267 | void __user *addr) | 375 | void __user *addr) |
268 | { | 376 | { |
269 | struct fs_disk_quota fdq; | 377 | struct fs_disk_quota fdq; |
378 | struct qc_dqblk qdq; | ||
270 | struct kqid qid; | 379 | struct kqid qid; |
271 | int ret; | 380 | int ret; |
272 | 381 | ||
@@ -275,8 +384,11 @@ static int quota_getxquota(struct super_block *sb, int type, qid_t id, | |||
275 | qid = make_kqid(current_user_ns(), type, id); | 384 | qid = make_kqid(current_user_ns(), type, id); |
276 | if (!qid_valid(qid)) | 385 | if (!qid_valid(qid)) |
277 | return -EINVAL; | 386 | return -EINVAL; |
278 | ret = sb->s_qcop->get_dqblk(sb, qid, &fdq); | 387 | ret = sb->s_qcop->get_dqblk(sb, qid, &qdq); |
279 | if (!ret && copy_to_user(addr, &fdq, sizeof(fdq))) | 388 | if (ret) |
389 | return ret; | ||
390 | copy_to_xfs_dqblk(&fdq, &qdq, type, id); | ||
391 | if (copy_to_user(addr, &fdq, sizeof(fdq))) | ||
280 | return -EFAULT; | 392 | return -EFAULT; |
281 | return ret; | 393 | return ret; |
282 | } | 394 | } |
diff --git a/fs/udf/dir.c b/fs/udf/dir.c index a012c51caffd..05e90edd1992 100644 --- a/fs/udf/dir.c +++ b/fs/udf/dir.c | |||
@@ -57,6 +57,7 @@ static int udf_readdir(struct file *file, struct dir_context *ctx) | |||
57 | sector_t offset; | 57 | sector_t offset; |
58 | int i, num, ret = 0; | 58 | int i, num, ret = 0; |
59 | struct extent_position epos = { NULL, 0, {0, 0} }; | 59 | struct extent_position epos = { NULL, 0, {0, 0} }; |
60 | struct super_block *sb = dir->i_sb; | ||
60 | 61 | ||
61 | if (ctx->pos == 0) { | 62 | if (ctx->pos == 0) { |
62 | if (!dir_emit_dot(file, ctx)) | 63 | if (!dir_emit_dot(file, ctx)) |
@@ -76,16 +77,16 @@ static int udf_readdir(struct file *file, struct dir_context *ctx) | |||
76 | if (nf_pos == 0) | 77 | if (nf_pos == 0) |
77 | nf_pos = udf_ext0_offset(dir); | 78 | nf_pos = udf_ext0_offset(dir); |
78 | 79 | ||
79 | fibh.soffset = fibh.eoffset = nf_pos & (dir->i_sb->s_blocksize - 1); | 80 | fibh.soffset = fibh.eoffset = nf_pos & (sb->s_blocksize - 1); |
80 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 81 | if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
81 | if (inode_bmap(dir, nf_pos >> dir->i_sb->s_blocksize_bits, | 82 | if (inode_bmap(dir, nf_pos >> sb->s_blocksize_bits, |
82 | &epos, &eloc, &elen, &offset) | 83 | &epos, &eloc, &elen, &offset) |
83 | != (EXT_RECORDED_ALLOCATED >> 30)) { | 84 | != (EXT_RECORDED_ALLOCATED >> 30)) { |
84 | ret = -ENOENT; | 85 | ret = -ENOENT; |
85 | goto out; | 86 | goto out; |
86 | } | 87 | } |
87 | block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); | 88 | block = udf_get_lb_pblock(sb, &eloc, offset); |
88 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 89 | if ((++offset << sb->s_blocksize_bits) < elen) { |
89 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 90 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
90 | epos.offset -= sizeof(struct short_ad); | 91 | epos.offset -= sizeof(struct short_ad); |
91 | else if (iinfo->i_alloc_type == | 92 | else if (iinfo->i_alloc_type == |
@@ -95,18 +96,18 @@ static int udf_readdir(struct file *file, struct dir_context *ctx) | |||
95 | offset = 0; | 96 | offset = 0; |
96 | } | 97 | } |
97 | 98 | ||
98 | if (!(fibh.sbh = fibh.ebh = udf_tread(dir->i_sb, block))) { | 99 | if (!(fibh.sbh = fibh.ebh = udf_tread(sb, block))) { |
99 | ret = -EIO; | 100 | ret = -EIO; |
100 | goto out; | 101 | goto out; |
101 | } | 102 | } |
102 | 103 | ||
103 | if (!(offset & ((16 >> (dir->i_sb->s_blocksize_bits - 9)) - 1))) { | 104 | if (!(offset & ((16 >> (sb->s_blocksize_bits - 9)) - 1))) { |
104 | i = 16 >> (dir->i_sb->s_blocksize_bits - 9); | 105 | i = 16 >> (sb->s_blocksize_bits - 9); |
105 | if (i + offset > (elen >> dir->i_sb->s_blocksize_bits)) | 106 | if (i + offset > (elen >> sb->s_blocksize_bits)) |
106 | i = (elen >> dir->i_sb->s_blocksize_bits) - offset; | 107 | i = (elen >> sb->s_blocksize_bits) - offset; |
107 | for (num = 0; i > 0; i--) { | 108 | for (num = 0; i > 0; i--) { |
108 | block = udf_get_lb_pblock(dir->i_sb, &eloc, offset + i); | 109 | block = udf_get_lb_pblock(sb, &eloc, offset + i); |
109 | tmp = udf_tgetblk(dir->i_sb, block); | 110 | tmp = udf_tgetblk(sb, block); |
110 | if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) | 111 | if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp)) |
111 | bha[num++] = tmp; | 112 | bha[num++] = tmp; |
112 | else | 113 | else |
@@ -152,12 +153,12 @@ static int udf_readdir(struct file *file, struct dir_context *ctx) | |||
152 | } | 153 | } |
153 | 154 | ||
154 | if ((cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { | 155 | if ((cfi.fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { |
155 | if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE)) | 156 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNDELETE)) |
156 | continue; | 157 | continue; |
157 | } | 158 | } |
158 | 159 | ||
159 | if ((cfi.fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) { | 160 | if ((cfi.fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) { |
160 | if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE)) | 161 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) |
161 | continue; | 162 | continue; |
162 | } | 163 | } |
163 | 164 | ||
@@ -167,12 +168,12 @@ static int udf_readdir(struct file *file, struct dir_context *ctx) | |||
167 | continue; | 168 | continue; |
168 | } | 169 | } |
169 | 170 | ||
170 | flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); | 171 | flen = udf_get_filename(sb, nameptr, lfi, fname, UDF_NAME_LEN); |
171 | if (!flen) | 172 | if (!flen) |
172 | continue; | 173 | continue; |
173 | 174 | ||
174 | tloc = lelb_to_cpu(cfi.icb.extLocation); | 175 | tloc = lelb_to_cpu(cfi.icb.extLocation); |
175 | iblock = udf_get_lb_pblock(dir->i_sb, &tloc, 0); | 176 | iblock = udf_get_lb_pblock(sb, &tloc, 0); |
176 | if (!dir_emit(ctx, fname, flen, iblock, DT_UNKNOWN)) | 177 | if (!dir_emit(ctx, fname, flen, iblock, DT_UNKNOWN)) |
177 | goto out; | 178 | goto out; |
178 | } /* end while */ | 179 | } /* end while */ |
diff --git a/fs/udf/file.c b/fs/udf/file.c index bb15771b92ae..08f3555fbeac 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c | |||
@@ -224,7 +224,7 @@ out: | |||
224 | static int udf_release_file(struct inode *inode, struct file *filp) | 224 | static int udf_release_file(struct inode *inode, struct file *filp) |
225 | { | 225 | { |
226 | if (filp->f_mode & FMODE_WRITE && | 226 | if (filp->f_mode & FMODE_WRITE && |
227 | atomic_read(&inode->i_writecount) > 1) { | 227 | atomic_read(&inode->i_writecount) == 1) { |
228 | /* | 228 | /* |
229 | * Grab i_mutex to avoid races with writes changing i_size | 229 | * Grab i_mutex to avoid races with writes changing i_size |
230 | * while we are running. | 230 | * while we are running. |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index c9b4df5810d5..5bc71d9a674a 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -1489,6 +1489,20 @@ reread: | |||
1489 | } | 1489 | } |
1490 | inode->i_generation = iinfo->i_unique; | 1490 | inode->i_generation = iinfo->i_unique; |
1491 | 1491 | ||
1492 | /* Sanity checks for files in ICB so that we don't get confused later */ | ||
1493 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) { | ||
1494 | /* | ||
1495 | * For file in ICB data is stored in allocation descriptor | ||
1496 | * so sizes should match | ||
1497 | */ | ||
1498 | if (iinfo->i_lenAlloc != inode->i_size) | ||
1499 | goto out; | ||
1500 | /* File in ICB has to fit in there... */ | ||
1501 | if (inode->i_size > inode->i_sb->s_blocksize - | ||
1502 | udf_file_entry_alloc_offset(inode)) | ||
1503 | goto out; | ||
1504 | } | ||
1505 | |||
1492 | switch (fe->icbTag.fileType) { | 1506 | switch (fe->icbTag.fileType) { |
1493 | case ICBTAG_FILE_TYPE_DIRECTORY: | 1507 | case ICBTAG_FILE_TYPE_DIRECTORY: |
1494 | inode->i_op = &udf_dir_inode_operations; | 1508 | inode->i_op = &udf_dir_inode_operations; |
diff --git a/fs/udf/namei.c b/fs/udf/namei.c index c12e260fd6c4..33b246b82c98 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c | |||
@@ -159,18 +159,19 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
159 | struct udf_inode_info *dinfo = UDF_I(dir); | 159 | struct udf_inode_info *dinfo = UDF_I(dir); |
160 | int isdotdot = child->len == 2 && | 160 | int isdotdot = child->len == 2 && |
161 | child->name[0] == '.' && child->name[1] == '.'; | 161 | child->name[0] == '.' && child->name[1] == '.'; |
162 | struct super_block *sb = dir->i_sb; | ||
162 | 163 | ||
163 | size = udf_ext0_offset(dir) + dir->i_size; | 164 | size = udf_ext0_offset(dir) + dir->i_size; |
164 | f_pos = udf_ext0_offset(dir); | 165 | f_pos = udf_ext0_offset(dir); |
165 | 166 | ||
166 | fibh->sbh = fibh->ebh = NULL; | 167 | fibh->sbh = fibh->ebh = NULL; |
167 | fibh->soffset = fibh->eoffset = f_pos & (dir->i_sb->s_blocksize - 1); | 168 | fibh->soffset = fibh->eoffset = f_pos & (sb->s_blocksize - 1); |
168 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { | 169 | if (dinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) { |
169 | if (inode_bmap(dir, f_pos >> dir->i_sb->s_blocksize_bits, &epos, | 170 | if (inode_bmap(dir, f_pos >> sb->s_blocksize_bits, &epos, |
170 | &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) | 171 | &eloc, &elen, &offset) != (EXT_RECORDED_ALLOCATED >> 30)) |
171 | goto out_err; | 172 | goto out_err; |
172 | block = udf_get_lb_pblock(dir->i_sb, &eloc, offset); | 173 | block = udf_get_lb_pblock(sb, &eloc, offset); |
173 | if ((++offset << dir->i_sb->s_blocksize_bits) < elen) { | 174 | if ((++offset << sb->s_blocksize_bits) < elen) { |
174 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) | 175 | if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) |
175 | epos.offset -= sizeof(struct short_ad); | 176 | epos.offset -= sizeof(struct short_ad); |
176 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) | 177 | else if (dinfo->i_alloc_type == ICBTAG_FLAG_AD_LONG) |
@@ -178,7 +179,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
178 | } else | 179 | } else |
179 | offset = 0; | 180 | offset = 0; |
180 | 181 | ||
181 | fibh->sbh = fibh->ebh = udf_tread(dir->i_sb, block); | 182 | fibh->sbh = fibh->ebh = udf_tread(sb, block); |
182 | if (!fibh->sbh) | 183 | if (!fibh->sbh) |
183 | goto out_err; | 184 | goto out_err; |
184 | } | 185 | } |
@@ -217,12 +218,12 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
217 | } | 218 | } |
218 | 219 | ||
219 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { | 220 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_DELETED) != 0) { |
220 | if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNDELETE)) | 221 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNDELETE)) |
221 | continue; | 222 | continue; |
222 | } | 223 | } |
223 | 224 | ||
224 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) { | 225 | if ((cfi->fileCharacteristics & FID_FILE_CHAR_HIDDEN) != 0) { |
225 | if (!UDF_QUERY_FLAG(dir->i_sb, UDF_FLAG_UNHIDE)) | 226 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_UNHIDE)) |
226 | continue; | 227 | continue; |
227 | } | 228 | } |
228 | 229 | ||
@@ -233,7 +234,7 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir, | |||
233 | if (!lfi) | 234 | if (!lfi) |
234 | continue; | 235 | continue; |
235 | 236 | ||
236 | flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi); | 237 | flen = udf_get_filename(sb, nameptr, lfi, fname, UDF_NAME_LEN); |
237 | if (flen && udf_match(flen, fname, child->len, child->name)) | 238 | if (flen && udf_match(flen, fname, child->len, child->name)) |
238 | goto out_ok; | 239 | goto out_ok; |
239 | } | 240 | } |
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c index 6fb7945c1e6e..ac10ca939f26 100644 --- a/fs/udf/symlink.c +++ b/fs/udf/symlink.c | |||
@@ -30,49 +30,73 @@ | |||
30 | #include <linux/buffer_head.h> | 30 | #include <linux/buffer_head.h> |
31 | #include "udf_i.h" | 31 | #include "udf_i.h" |
32 | 32 | ||
33 | static void udf_pc_to_char(struct super_block *sb, unsigned char *from, | 33 | static int udf_pc_to_char(struct super_block *sb, unsigned char *from, |
34 | int fromlen, unsigned char *to) | 34 | int fromlen, unsigned char *to, int tolen) |
35 | { | 35 | { |
36 | struct pathComponent *pc; | 36 | struct pathComponent *pc; |
37 | int elen = 0; | 37 | int elen = 0; |
38 | int comp_len; | ||
38 | unsigned char *p = to; | 39 | unsigned char *p = to; |
39 | 40 | ||
41 | /* Reserve one byte for terminating \0 */ | ||
42 | tolen--; | ||
40 | while (elen < fromlen) { | 43 | while (elen < fromlen) { |
41 | pc = (struct pathComponent *)(from + elen); | 44 | pc = (struct pathComponent *)(from + elen); |
45 | elen += sizeof(struct pathComponent); | ||
42 | switch (pc->componentType) { | 46 | switch (pc->componentType) { |
43 | case 1: | 47 | case 1: |
44 | /* | 48 | /* |
45 | * Symlink points to some place which should be agreed | 49 | * Symlink points to some place which should be agreed |
46 | * upon between originator and receiver of the media. Ignore. | 50 | * upon between originator and receiver of the media. Ignore. |
47 | */ | 51 | */ |
48 | if (pc->lengthComponentIdent > 0) | 52 | if (pc->lengthComponentIdent > 0) { |
53 | elen += pc->lengthComponentIdent; | ||
49 | break; | 54 | break; |
55 | } | ||
50 | /* Fall through */ | 56 | /* Fall through */ |
51 | case 2: | 57 | case 2: |
58 | if (tolen == 0) | ||
59 | return -ENAMETOOLONG; | ||
52 | p = to; | 60 | p = to; |
53 | *p++ = '/'; | 61 | *p++ = '/'; |
62 | tolen--; | ||
54 | break; | 63 | break; |
55 | case 3: | 64 | case 3: |
65 | if (tolen < 3) | ||
66 | return -ENAMETOOLONG; | ||
56 | memcpy(p, "../", 3); | 67 | memcpy(p, "../", 3); |
57 | p += 3; | 68 | p += 3; |
69 | tolen -= 3; | ||
58 | break; | 70 | break; |
59 | case 4: | 71 | case 4: |
72 | if (tolen < 2) | ||
73 | return -ENAMETOOLONG; | ||
60 | memcpy(p, "./", 2); | 74 | memcpy(p, "./", 2); |
61 | p += 2; | 75 | p += 2; |
76 | tolen -= 2; | ||
62 | /* that would be . - just ignore */ | 77 | /* that would be . - just ignore */ |
63 | break; | 78 | break; |
64 | case 5: | 79 | case 5: |
65 | p += udf_get_filename(sb, pc->componentIdent, p, | 80 | elen += pc->lengthComponentIdent; |
66 | pc->lengthComponentIdent); | 81 | if (elen > fromlen) |
82 | return -EIO; | ||
83 | comp_len = udf_get_filename(sb, pc->componentIdent, | ||
84 | pc->lengthComponentIdent, | ||
85 | p, tolen); | ||
86 | p += comp_len; | ||
87 | tolen -= comp_len; | ||
88 | if (tolen == 0) | ||
89 | return -ENAMETOOLONG; | ||
67 | *p++ = '/'; | 90 | *p++ = '/'; |
91 | tolen--; | ||
68 | break; | 92 | break; |
69 | } | 93 | } |
70 | elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; | ||
71 | } | 94 | } |
72 | if (p > to + 1) | 95 | if (p > to + 1) |
73 | p[-1] = '\0'; | 96 | p[-1] = '\0'; |
74 | else | 97 | else |
75 | p[0] = '\0'; | 98 | p[0] = '\0'; |
99 | return 0; | ||
76 | } | 100 | } |
77 | 101 | ||
78 | static int udf_symlink_filler(struct file *file, struct page *page) | 102 | static int udf_symlink_filler(struct file *file, struct page *page) |
@@ -80,11 +104,17 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
80 | struct inode *inode = page->mapping->host; | 104 | struct inode *inode = page->mapping->host; |
81 | struct buffer_head *bh = NULL; | 105 | struct buffer_head *bh = NULL; |
82 | unsigned char *symlink; | 106 | unsigned char *symlink; |
83 | int err = -EIO; | 107 | int err; |
84 | unsigned char *p = kmap(page); | 108 | unsigned char *p = kmap(page); |
85 | struct udf_inode_info *iinfo; | 109 | struct udf_inode_info *iinfo; |
86 | uint32_t pos; | 110 | uint32_t pos; |
87 | 111 | ||
112 | /* We don't support symlinks longer than one block */ | ||
113 | if (inode->i_size > inode->i_sb->s_blocksize) { | ||
114 | err = -ENAMETOOLONG; | ||
115 | goto out_unmap; | ||
116 | } | ||
117 | |||
88 | iinfo = UDF_I(inode); | 118 | iinfo = UDF_I(inode); |
89 | pos = udf_block_map(inode, 0); | 119 | pos = udf_block_map(inode, 0); |
90 | 120 | ||
@@ -94,14 +124,18 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
94 | } else { | 124 | } else { |
95 | bh = sb_bread(inode->i_sb, pos); | 125 | bh = sb_bread(inode->i_sb, pos); |
96 | 126 | ||
97 | if (!bh) | 127 | if (!bh) { |
98 | goto out; | 128 | err = -EIO; |
129 | goto out_unlock_inode; | ||
130 | } | ||
99 | 131 | ||
100 | symlink = bh->b_data; | 132 | symlink = bh->b_data; |
101 | } | 133 | } |
102 | 134 | ||
103 | udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); | 135 | err = udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p, PAGE_SIZE); |
104 | brelse(bh); | 136 | brelse(bh); |
137 | if (err) | ||
138 | goto out_unlock_inode; | ||
105 | 139 | ||
106 | up_read(&iinfo->i_data_sem); | 140 | up_read(&iinfo->i_data_sem); |
107 | SetPageUptodate(page); | 141 | SetPageUptodate(page); |
@@ -109,9 +143,10 @@ static int udf_symlink_filler(struct file *file, struct page *page) | |||
109 | unlock_page(page); | 143 | unlock_page(page); |
110 | return 0; | 144 | return 0; |
111 | 145 | ||
112 | out: | 146 | out_unlock_inode: |
113 | up_read(&iinfo->i_data_sem); | 147 | up_read(&iinfo->i_data_sem); |
114 | SetPageError(page); | 148 | SetPageError(page); |
149 | out_unmap: | ||
115 | kunmap(page); | 150 | kunmap(page); |
116 | unlock_page(page); | 151 | unlock_page(page); |
117 | return err; | 152 | return err; |
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h index 1cc3c993ebd0..47bb3f5ca360 100644 --- a/fs/udf/udfdecl.h +++ b/fs/udf/udfdecl.h | |||
@@ -211,7 +211,8 @@ udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc, | |||
211 | } | 211 | } |
212 | 212 | ||
213 | /* unicode.c */ | 213 | /* unicode.c */ |
214 | extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int); | 214 | extern int udf_get_filename(struct super_block *, uint8_t *, int, uint8_t *, |
215 | int); | ||
215 | extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, | 216 | extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *, |
216 | int); | 217 | int); |
217 | extern int udf_build_ustr(struct ustr *, dstring *, int); | 218 | extern int udf_build_ustr(struct ustr *, dstring *, int); |
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c index afd470e588ff..b84fee372734 100644 --- a/fs/udf/unicode.c +++ b/fs/udf/unicode.c | |||
@@ -28,7 +28,8 @@ | |||
28 | 28 | ||
29 | #include "udf_sb.h" | 29 | #include "udf_sb.h" |
30 | 30 | ||
31 | static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int); | 31 | static int udf_translate_to_linux(uint8_t *, int, uint8_t *, int, uint8_t *, |
32 | int); | ||
32 | 33 | ||
33 | static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) | 34 | static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen) |
34 | { | 35 | { |
@@ -333,8 +334,8 @@ try_again: | |||
333 | return u_len + 1; | 334 | return u_len + 1; |
334 | } | 335 | } |
335 | 336 | ||
336 | int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, | 337 | int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen, |
337 | int flen) | 338 | uint8_t *dname, int dlen) |
338 | { | 339 | { |
339 | struct ustr *filename, *unifilename; | 340 | struct ustr *filename, *unifilename; |
340 | int len = 0; | 341 | int len = 0; |
@@ -347,7 +348,7 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, | |||
347 | if (!unifilename) | 348 | if (!unifilename) |
348 | goto out1; | 349 | goto out1; |
349 | 350 | ||
350 | if (udf_build_ustr_exact(unifilename, sname, flen)) | 351 | if (udf_build_ustr_exact(unifilename, sname, slen)) |
351 | goto out2; | 352 | goto out2; |
352 | 353 | ||
353 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { | 354 | if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) { |
@@ -366,7 +367,8 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname, | |||
366 | } else | 367 | } else |
367 | goto out2; | 368 | goto out2; |
368 | 369 | ||
369 | len = udf_translate_to_linux(dname, filename->u_name, filename->u_len, | 370 | len = udf_translate_to_linux(dname, dlen, |
371 | filename->u_name, filename->u_len, | ||
370 | unifilename->u_name, unifilename->u_len); | 372 | unifilename->u_name, unifilename->u_len); |
371 | out2: | 373 | out2: |
372 | kfree(unifilename); | 374 | kfree(unifilename); |
@@ -403,10 +405,12 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname, | |||
403 | #define EXT_MARK '.' | 405 | #define EXT_MARK '.' |
404 | #define CRC_MARK '#' | 406 | #define CRC_MARK '#' |
405 | #define EXT_SIZE 5 | 407 | #define EXT_SIZE 5 |
408 | /* Number of chars we need to store generated CRC to make filename unique */ | ||
409 | #define CRC_LEN 5 | ||
406 | 410 | ||
407 | static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, | 411 | static int udf_translate_to_linux(uint8_t *newName, int newLen, |
408 | int udfLen, uint8_t *fidName, | 412 | uint8_t *udfName, int udfLen, |
409 | int fidNameLen) | 413 | uint8_t *fidName, int fidNameLen) |
410 | { | 414 | { |
411 | int index, newIndex = 0, needsCRC = 0; | 415 | int index, newIndex = 0, needsCRC = 0; |
412 | int extIndex = 0, newExtIndex = 0, hasExt = 0; | 416 | int extIndex = 0, newExtIndex = 0, hasExt = 0; |
@@ -439,7 +443,7 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, | |||
439 | newExtIndex = newIndex; | 443 | newExtIndex = newIndex; |
440 | } | 444 | } |
441 | } | 445 | } |
442 | if (newIndex < 256) | 446 | if (newIndex < newLen) |
443 | newName[newIndex++] = curr; | 447 | newName[newIndex++] = curr; |
444 | else | 448 | else |
445 | needsCRC = 1; | 449 | needsCRC = 1; |
@@ -467,13 +471,13 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName, | |||
467 | } | 471 | } |
468 | ext[localExtIndex++] = curr; | 472 | ext[localExtIndex++] = curr; |
469 | } | 473 | } |
470 | maxFilenameLen = 250 - localExtIndex; | 474 | maxFilenameLen = newLen - CRC_LEN - localExtIndex; |
471 | if (newIndex > maxFilenameLen) | 475 | if (newIndex > maxFilenameLen) |
472 | newIndex = maxFilenameLen; | 476 | newIndex = maxFilenameLen; |
473 | else | 477 | else |
474 | newIndex = newExtIndex; | 478 | newIndex = newExtIndex; |
475 | } else if (newIndex > 250) | 479 | } else if (newIndex > newLen - CRC_LEN) |
476 | newIndex = 250; | 480 | newIndex = newLen - CRC_LEN; |
477 | newName[newIndex++] = CRC_MARK; | 481 | newName[newIndex++] = CRC_MARK; |
478 | valueCRC = crc_itu_t(0, fidName, fidNameLen); | 482 | valueCRC = crc_itu_t(0, fidName, fidNameLen); |
479 | newName[newIndex++] = hex_asc_upper_hi(valueCRC >> 8); | 483 | newName[newIndex++] = hex_asc_upper_hi(valueCRC >> 8); |
diff --git a/fs/xfs/xfs_qm.h b/fs/xfs/xfs_qm.h index 3a07a937e232..41f6c0b9d51c 100644 --- a/fs/xfs/xfs_qm.h +++ b/fs/xfs/xfs_qm.h | |||
@@ -166,9 +166,9 @@ extern void xfs_qm_dqrele_all_inodes(struct xfs_mount *, uint); | |||
166 | /* quota ops */ | 166 | /* quota ops */ |
167 | extern int xfs_qm_scall_trunc_qfiles(struct xfs_mount *, uint); | 167 | extern int xfs_qm_scall_trunc_qfiles(struct xfs_mount *, uint); |
168 | extern int xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t, | 168 | extern int xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t, |
169 | uint, struct fs_disk_quota *); | 169 | uint, struct qc_dqblk *); |
170 | extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint, | 170 | extern int xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint, |
171 | struct fs_disk_quota *); | 171 | struct qc_dqblk *); |
172 | extern int xfs_qm_scall_getqstat(struct xfs_mount *, | 172 | extern int xfs_qm_scall_getqstat(struct xfs_mount *, |
173 | struct fs_quota_stat *); | 173 | struct fs_quota_stat *); |
174 | extern int xfs_qm_scall_getqstatv(struct xfs_mount *, | 174 | extern int xfs_qm_scall_getqstatv(struct xfs_mount *, |
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c index 74fca68e43b6..cb6168ec92c9 100644 --- a/fs/xfs/xfs_qm_syscalls.c +++ b/fs/xfs/xfs_qm_syscalls.c | |||
@@ -39,7 +39,6 @@ STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint); | |||
39 | STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *, | 39 | STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *, |
40 | uint); | 40 | uint); |
41 | STATIC uint xfs_qm_export_flags(uint); | 41 | STATIC uint xfs_qm_export_flags(uint); |
42 | STATIC uint xfs_qm_export_qtype_flags(uint); | ||
43 | 42 | ||
44 | /* | 43 | /* |
45 | * Turn off quota accounting and/or enforcement for all udquots and/or | 44 | * Turn off quota accounting and/or enforcement for all udquots and/or |
@@ -573,8 +572,8 @@ xfs_qm_scall_getqstatv( | |||
573 | return 0; | 572 | return 0; |
574 | } | 573 | } |
575 | 574 | ||
576 | #define XFS_DQ_MASK \ | 575 | #define XFS_QC_MASK \ |
577 | (FS_DQ_LIMIT_MASK | FS_DQ_TIMER_MASK | FS_DQ_WARNS_MASK) | 576 | (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK) |
578 | 577 | ||
579 | /* | 578 | /* |
580 | * Adjust quota limits, and start/stop timers accordingly. | 579 | * Adjust quota limits, and start/stop timers accordingly. |
@@ -584,7 +583,7 @@ xfs_qm_scall_setqlim( | |||
584 | struct xfs_mount *mp, | 583 | struct xfs_mount *mp, |
585 | xfs_dqid_t id, | 584 | xfs_dqid_t id, |
586 | uint type, | 585 | uint type, |
587 | fs_disk_quota_t *newlim) | 586 | struct qc_dqblk *newlim) |
588 | { | 587 | { |
589 | struct xfs_quotainfo *q = mp->m_quotainfo; | 588 | struct xfs_quotainfo *q = mp->m_quotainfo; |
590 | struct xfs_disk_dquot *ddq; | 589 | struct xfs_disk_dquot *ddq; |
@@ -593,9 +592,9 @@ xfs_qm_scall_setqlim( | |||
593 | int error; | 592 | int error; |
594 | xfs_qcnt_t hard, soft; | 593 | xfs_qcnt_t hard, soft; |
595 | 594 | ||
596 | if (newlim->d_fieldmask & ~XFS_DQ_MASK) | 595 | if (newlim->d_fieldmask & ~XFS_QC_MASK) |
597 | return -EINVAL; | 596 | return -EINVAL; |
598 | if ((newlim->d_fieldmask & XFS_DQ_MASK) == 0) | 597 | if ((newlim->d_fieldmask & XFS_QC_MASK) == 0) |
599 | return 0; | 598 | return 0; |
600 | 599 | ||
601 | /* | 600 | /* |
@@ -633,11 +632,11 @@ xfs_qm_scall_setqlim( | |||
633 | /* | 632 | /* |
634 | * Make sure that hardlimits are >= soft limits before changing. | 633 | * Make sure that hardlimits are >= soft limits before changing. |
635 | */ | 634 | */ |
636 | hard = (newlim->d_fieldmask & FS_DQ_BHARD) ? | 635 | hard = (newlim->d_fieldmask & QC_SPC_HARD) ? |
637 | (xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_blk_hardlimit) : | 636 | (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : |
638 | be64_to_cpu(ddq->d_blk_hardlimit); | 637 | be64_to_cpu(ddq->d_blk_hardlimit); |
639 | soft = (newlim->d_fieldmask & FS_DQ_BSOFT) ? | 638 | soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? |
640 | (xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_blk_softlimit) : | 639 | (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : |
641 | be64_to_cpu(ddq->d_blk_softlimit); | 640 | be64_to_cpu(ddq->d_blk_softlimit); |
642 | if (hard == 0 || hard >= soft) { | 641 | if (hard == 0 || hard >= soft) { |
643 | ddq->d_blk_hardlimit = cpu_to_be64(hard); | 642 | ddq->d_blk_hardlimit = cpu_to_be64(hard); |
@@ -650,11 +649,11 @@ xfs_qm_scall_setqlim( | |||
650 | } else { | 649 | } else { |
651 | xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft); | 650 | xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft); |
652 | } | 651 | } |
653 | hard = (newlim->d_fieldmask & FS_DQ_RTBHARD) ? | 652 | hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? |
654 | (xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_rtb_hardlimit) : | 653 | (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : |
655 | be64_to_cpu(ddq->d_rtb_hardlimit); | 654 | be64_to_cpu(ddq->d_rtb_hardlimit); |
656 | soft = (newlim->d_fieldmask & FS_DQ_RTBSOFT) ? | 655 | soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? |
657 | (xfs_qcnt_t) XFS_BB_TO_FSB(mp, newlim->d_rtb_softlimit) : | 656 | (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : |
658 | be64_to_cpu(ddq->d_rtb_softlimit); | 657 | be64_to_cpu(ddq->d_rtb_softlimit); |
659 | if (hard == 0 || hard >= soft) { | 658 | if (hard == 0 || hard >= soft) { |
660 | ddq->d_rtb_hardlimit = cpu_to_be64(hard); | 659 | ddq->d_rtb_hardlimit = cpu_to_be64(hard); |
@@ -667,10 +666,10 @@ xfs_qm_scall_setqlim( | |||
667 | xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft); | 666 | xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft); |
668 | } | 667 | } |
669 | 668 | ||
670 | hard = (newlim->d_fieldmask & FS_DQ_IHARD) ? | 669 | hard = (newlim->d_fieldmask & QC_INO_HARD) ? |
671 | (xfs_qcnt_t) newlim->d_ino_hardlimit : | 670 | (xfs_qcnt_t) newlim->d_ino_hardlimit : |
672 | be64_to_cpu(ddq->d_ino_hardlimit); | 671 | be64_to_cpu(ddq->d_ino_hardlimit); |
673 | soft = (newlim->d_fieldmask & FS_DQ_ISOFT) ? | 672 | soft = (newlim->d_fieldmask & QC_INO_SOFT) ? |
674 | (xfs_qcnt_t) newlim->d_ino_softlimit : | 673 | (xfs_qcnt_t) newlim->d_ino_softlimit : |
675 | be64_to_cpu(ddq->d_ino_softlimit); | 674 | be64_to_cpu(ddq->d_ino_softlimit); |
676 | if (hard == 0 || hard >= soft) { | 675 | if (hard == 0 || hard >= soft) { |
@@ -687,12 +686,12 @@ xfs_qm_scall_setqlim( | |||
687 | /* | 686 | /* |
688 | * Update warnings counter(s) if requested | 687 | * Update warnings counter(s) if requested |
689 | */ | 688 | */ |
690 | if (newlim->d_fieldmask & FS_DQ_BWARNS) | 689 | if (newlim->d_fieldmask & QC_SPC_WARNS) |
691 | ddq->d_bwarns = cpu_to_be16(newlim->d_bwarns); | 690 | ddq->d_bwarns = cpu_to_be16(newlim->d_spc_warns); |
692 | if (newlim->d_fieldmask & FS_DQ_IWARNS) | 691 | if (newlim->d_fieldmask & QC_INO_WARNS) |
693 | ddq->d_iwarns = cpu_to_be16(newlim->d_iwarns); | 692 | ddq->d_iwarns = cpu_to_be16(newlim->d_ino_warns); |
694 | if (newlim->d_fieldmask & FS_DQ_RTBWARNS) | 693 | if (newlim->d_fieldmask & QC_RT_SPC_WARNS) |
695 | ddq->d_rtbwarns = cpu_to_be16(newlim->d_rtbwarns); | 694 | ddq->d_rtbwarns = cpu_to_be16(newlim->d_rt_spc_warns); |
696 | 695 | ||
697 | if (id == 0) { | 696 | if (id == 0) { |
698 | /* | 697 | /* |
@@ -702,24 +701,24 @@ xfs_qm_scall_setqlim( | |||
702 | * soft and hard limit values (already done, above), and | 701 | * soft and hard limit values (already done, above), and |
703 | * for warnings. | 702 | * for warnings. |
704 | */ | 703 | */ |
705 | if (newlim->d_fieldmask & FS_DQ_BTIMER) { | 704 | if (newlim->d_fieldmask & QC_SPC_TIMER) { |
706 | q->qi_btimelimit = newlim->d_btimer; | 705 | q->qi_btimelimit = newlim->d_spc_timer; |
707 | ddq->d_btimer = cpu_to_be32(newlim->d_btimer); | 706 | ddq->d_btimer = cpu_to_be32(newlim->d_spc_timer); |
708 | } | 707 | } |
709 | if (newlim->d_fieldmask & FS_DQ_ITIMER) { | 708 | if (newlim->d_fieldmask & QC_INO_TIMER) { |
710 | q->qi_itimelimit = newlim->d_itimer; | 709 | q->qi_itimelimit = newlim->d_ino_timer; |
711 | ddq->d_itimer = cpu_to_be32(newlim->d_itimer); | 710 | ddq->d_itimer = cpu_to_be32(newlim->d_ino_timer); |
712 | } | 711 | } |
713 | if (newlim->d_fieldmask & FS_DQ_RTBTIMER) { | 712 | if (newlim->d_fieldmask & QC_RT_SPC_TIMER) { |
714 | q->qi_rtbtimelimit = newlim->d_rtbtimer; | 713 | q->qi_rtbtimelimit = newlim->d_rt_spc_timer; |
715 | ddq->d_rtbtimer = cpu_to_be32(newlim->d_rtbtimer); | 714 | ddq->d_rtbtimer = cpu_to_be32(newlim->d_rt_spc_timer); |
716 | } | 715 | } |
717 | if (newlim->d_fieldmask & FS_DQ_BWARNS) | 716 | if (newlim->d_fieldmask & QC_SPC_WARNS) |
718 | q->qi_bwarnlimit = newlim->d_bwarns; | 717 | q->qi_bwarnlimit = newlim->d_spc_warns; |
719 | if (newlim->d_fieldmask & FS_DQ_IWARNS) | 718 | if (newlim->d_fieldmask & QC_INO_WARNS) |
720 | q->qi_iwarnlimit = newlim->d_iwarns; | 719 | q->qi_iwarnlimit = newlim->d_ino_warns; |
721 | if (newlim->d_fieldmask & FS_DQ_RTBWARNS) | 720 | if (newlim->d_fieldmask & QC_RT_SPC_WARNS) |
722 | q->qi_rtbwarnlimit = newlim->d_rtbwarns; | 721 | q->qi_rtbwarnlimit = newlim->d_rt_spc_warns; |
723 | } else { | 722 | } else { |
724 | /* | 723 | /* |
725 | * If the user is now over quota, start the timelimit. | 724 | * If the user is now over quota, start the timelimit. |
@@ -824,7 +823,7 @@ xfs_qm_scall_getquota( | |||
824 | struct xfs_mount *mp, | 823 | struct xfs_mount *mp, |
825 | xfs_dqid_t id, | 824 | xfs_dqid_t id, |
826 | uint type, | 825 | uint type, |
827 | struct fs_disk_quota *dst) | 826 | struct qc_dqblk *dst) |
828 | { | 827 | { |
829 | struct xfs_dquot *dqp; | 828 | struct xfs_dquot *dqp; |
830 | int error; | 829 | int error; |
@@ -848,28 +847,25 @@ xfs_qm_scall_getquota( | |||
848 | } | 847 | } |
849 | 848 | ||
850 | memset(dst, 0, sizeof(*dst)); | 849 | memset(dst, 0, sizeof(*dst)); |
851 | dst->d_version = FS_DQUOT_VERSION; | 850 | dst->d_spc_hardlimit = |
852 | dst->d_flags = xfs_qm_export_qtype_flags(dqp->q_core.d_flags); | 851 | XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit)); |
853 | dst->d_id = be32_to_cpu(dqp->q_core.d_id); | 852 | dst->d_spc_softlimit = |
854 | dst->d_blk_hardlimit = | 853 | XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit)); |
855 | XFS_FSB_TO_BB(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit)); | ||
856 | dst->d_blk_softlimit = | ||
857 | XFS_FSB_TO_BB(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit)); | ||
858 | dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); | 854 | dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); |
859 | dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); | 855 | dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); |
860 | dst->d_bcount = XFS_FSB_TO_BB(mp, dqp->q_res_bcount); | 856 | dst->d_space = XFS_FSB_TO_B(mp, dqp->q_res_bcount); |
861 | dst->d_icount = dqp->q_res_icount; | 857 | dst->d_ino_count = dqp->q_res_icount; |
862 | dst->d_btimer = be32_to_cpu(dqp->q_core.d_btimer); | 858 | dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); |
863 | dst->d_itimer = be32_to_cpu(dqp->q_core.d_itimer); | 859 | dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); |
864 | dst->d_iwarns = be16_to_cpu(dqp->q_core.d_iwarns); | 860 | dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); |
865 | dst->d_bwarns = be16_to_cpu(dqp->q_core.d_bwarns); | 861 | dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns); |
866 | dst->d_rtb_hardlimit = | 862 | dst->d_rt_spc_hardlimit = |
867 | XFS_FSB_TO_BB(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit)); | 863 | XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit)); |
868 | dst->d_rtb_softlimit = | 864 | dst->d_rt_spc_softlimit = |
869 | XFS_FSB_TO_BB(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit)); | 865 | XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit)); |
870 | dst->d_rtbcount = XFS_FSB_TO_BB(mp, dqp->q_res_rtbcount); | 866 | dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_res_rtbcount); |
871 | dst->d_rtbtimer = be32_to_cpu(dqp->q_core.d_rtbtimer); | 867 | dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); |
872 | dst->d_rtbwarns = be16_to_cpu(dqp->q_core.d_rtbwarns); | 868 | dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); |
873 | 869 | ||
874 | /* | 870 | /* |
875 | * Internally, we don't reset all the timers when quota enforcement | 871 | * Internally, we don't reset all the timers when quota enforcement |
@@ -882,23 +878,23 @@ xfs_qm_scall_getquota( | |||
882 | dqp->q_core.d_flags == XFS_DQ_GROUP) || | 878 | dqp->q_core.d_flags == XFS_DQ_GROUP) || |
883 | (!XFS_IS_PQUOTA_ENFORCED(mp) && | 879 | (!XFS_IS_PQUOTA_ENFORCED(mp) && |
884 | dqp->q_core.d_flags == XFS_DQ_PROJ)) { | 880 | dqp->q_core.d_flags == XFS_DQ_PROJ)) { |
885 | dst->d_btimer = 0; | 881 | dst->d_spc_timer = 0; |
886 | dst->d_itimer = 0; | 882 | dst->d_ino_timer = 0; |
887 | dst->d_rtbtimer = 0; | 883 | dst->d_rt_spc_timer = 0; |
888 | } | 884 | } |
889 | 885 | ||
890 | #ifdef DEBUG | 886 | #ifdef DEBUG |
891 | if (((XFS_IS_UQUOTA_ENFORCED(mp) && dst->d_flags == FS_USER_QUOTA) || | 887 | if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) || |
892 | (XFS_IS_GQUOTA_ENFORCED(mp) && dst->d_flags == FS_GROUP_QUOTA) || | 888 | (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) || |
893 | (XFS_IS_PQUOTA_ENFORCED(mp) && dst->d_flags == FS_PROJ_QUOTA)) && | 889 | (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) && |
894 | dst->d_id != 0) { | 890 | id != 0) { |
895 | if ((dst->d_bcount > dst->d_blk_softlimit) && | 891 | if ((dst->d_space > dst->d_spc_softlimit) && |
896 | (dst->d_blk_softlimit > 0)) { | 892 | (dst->d_spc_softlimit > 0)) { |
897 | ASSERT(dst->d_btimer != 0); | 893 | ASSERT(dst->d_spc_timer != 0); |
898 | } | 894 | } |
899 | if ((dst->d_icount > dst->d_ino_softlimit) && | 895 | if ((dst->d_ino_count > dst->d_ino_softlimit) && |
900 | (dst->d_ino_softlimit > 0)) { | 896 | (dst->d_ino_softlimit > 0)) { |
901 | ASSERT(dst->d_itimer != 0); | 897 | ASSERT(dst->d_ino_timer != 0); |
902 | } | 898 | } |
903 | } | 899 | } |
904 | #endif | 900 | #endif |
@@ -908,26 +904,6 @@ out_put: | |||
908 | } | 904 | } |
909 | 905 | ||
910 | STATIC uint | 906 | STATIC uint |
911 | xfs_qm_export_qtype_flags( | ||
912 | uint flags) | ||
913 | { | ||
914 | /* | ||
915 | * Can't be more than one, or none. | ||
916 | */ | ||
917 | ASSERT((flags & (FS_PROJ_QUOTA | FS_USER_QUOTA)) != | ||
918 | (FS_PROJ_QUOTA | FS_USER_QUOTA)); | ||
919 | ASSERT((flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)) != | ||
920 | (FS_PROJ_QUOTA | FS_GROUP_QUOTA)); | ||
921 | ASSERT((flags & (FS_USER_QUOTA | FS_GROUP_QUOTA)) != | ||
922 | (FS_USER_QUOTA | FS_GROUP_QUOTA)); | ||
923 | ASSERT((flags & (FS_PROJ_QUOTA|FS_USER_QUOTA|FS_GROUP_QUOTA)) != 0); | ||
924 | |||
925 | return (flags & XFS_DQ_USER) ? | ||
926 | FS_USER_QUOTA : (flags & XFS_DQ_PROJ) ? | ||
927 | FS_PROJ_QUOTA : FS_GROUP_QUOTA; | ||
928 | } | ||
929 | |||
930 | STATIC uint | ||
931 | xfs_qm_export_flags( | 907 | xfs_qm_export_flags( |
932 | uint flags) | 908 | uint flags) |
933 | { | 909 | { |
diff --git a/fs/xfs/xfs_quotaops.c b/fs/xfs/xfs_quotaops.c index 7542bbeca6a1..801a84c1cdc3 100644 --- a/fs/xfs/xfs_quotaops.c +++ b/fs/xfs/xfs_quotaops.c | |||
@@ -131,7 +131,7 @@ STATIC int | |||
131 | xfs_fs_get_dqblk( | 131 | xfs_fs_get_dqblk( |
132 | struct super_block *sb, | 132 | struct super_block *sb, |
133 | struct kqid qid, | 133 | struct kqid qid, |
134 | struct fs_disk_quota *fdq) | 134 | struct qc_dqblk *qdq) |
135 | { | 135 | { |
136 | struct xfs_mount *mp = XFS_M(sb); | 136 | struct xfs_mount *mp = XFS_M(sb); |
137 | 137 | ||
@@ -141,14 +141,14 @@ xfs_fs_get_dqblk( | |||
141 | return -ESRCH; | 141 | return -ESRCH; |
142 | 142 | ||
143 | return xfs_qm_scall_getquota(mp, from_kqid(&init_user_ns, qid), | 143 | return xfs_qm_scall_getquota(mp, from_kqid(&init_user_ns, qid), |
144 | xfs_quota_type(qid.type), fdq); | 144 | xfs_quota_type(qid.type), qdq); |
145 | } | 145 | } |
146 | 146 | ||
147 | STATIC int | 147 | STATIC int |
148 | xfs_fs_set_dqblk( | 148 | xfs_fs_set_dqblk( |
149 | struct super_block *sb, | 149 | struct super_block *sb, |
150 | struct kqid qid, | 150 | struct kqid qid, |
151 | struct fs_disk_quota *fdq) | 151 | struct qc_dqblk *qdq) |
152 | { | 152 | { |
153 | struct xfs_mount *mp = XFS_M(sb); | 153 | struct xfs_mount *mp = XFS_M(sb); |
154 | 154 | ||
@@ -160,7 +160,7 @@ xfs_fs_set_dqblk( | |||
160 | return -ESRCH; | 160 | return -ESRCH; |
161 | 161 | ||
162 | return xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid), | 162 | return xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid), |
163 | xfs_quota_type(qid.type), fdq); | 163 | xfs_quota_type(qid.type), qdq); |
164 | } | 164 | } |
165 | 165 | ||
166 | const struct quotactl_ops xfs_quotactl_operations = { | 166 | const struct quotactl_ops xfs_quotactl_operations = { |