diff options
Diffstat (limited to 'fs/btrfs/xattr.c')
| -rw-r--r-- | fs/btrfs/xattr.c | 33 |
1 files changed, 12 insertions, 21 deletions
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index a5303b871b13..cfd660550ded 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c | |||
| @@ -180,11 +180,10 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 180 | struct btrfs_path *path; | 180 | struct btrfs_path *path; |
| 181 | struct extent_buffer *leaf; | 181 | struct extent_buffer *leaf; |
| 182 | struct btrfs_dir_item *di; | 182 | struct btrfs_dir_item *di; |
| 183 | int ret = 0, slot, advance; | 183 | int ret = 0, slot; |
| 184 | size_t total_size = 0, size_left = size; | 184 | size_t total_size = 0, size_left = size; |
| 185 | unsigned long name_ptr; | 185 | unsigned long name_ptr; |
| 186 | size_t name_len; | 186 | size_t name_len; |
| 187 | u32 nritems; | ||
| 188 | 187 | ||
| 189 | /* | 188 | /* |
| 190 | * ok we want all objects associated with this id. | 189 | * ok we want all objects associated with this id. |
| @@ -204,34 +203,24 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 204 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 203 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
| 205 | if (ret < 0) | 204 | if (ret < 0) |
| 206 | goto err; | 205 | goto err; |
| 207 | advance = 0; | 206 | |
| 208 | while (1) { | 207 | while (1) { |
| 209 | leaf = path->nodes[0]; | 208 | leaf = path->nodes[0]; |
| 210 | nritems = btrfs_header_nritems(leaf); | ||
| 211 | slot = path->slots[0]; | 209 | slot = path->slots[0]; |
| 212 | 210 | ||
| 213 | /* this is where we start walking through the path */ | 211 | /* this is where we start walking through the path */ |
| 214 | if (advance || slot >= nritems) { | 212 | if (slot >= btrfs_header_nritems(leaf)) { |
| 215 | /* | 213 | /* |
| 216 | * if we've reached the last slot in this leaf we need | 214 | * if we've reached the last slot in this leaf we need |
| 217 | * to go to the next leaf and reset everything | 215 | * to go to the next leaf and reset everything |
| 218 | */ | 216 | */ |
| 219 | if (slot >= nritems-1) { | 217 | ret = btrfs_next_leaf(root, path); |
| 220 | ret = btrfs_next_leaf(root, path); | 218 | if (ret < 0) |
| 221 | if (ret) | 219 | goto err; |
| 222 | break; | 220 | else if (ret > 0) |
| 223 | leaf = path->nodes[0]; | 221 | break; |
| 224 | nritems = btrfs_header_nritems(leaf); | 222 | continue; |
| 225 | slot = path->slots[0]; | ||
| 226 | } else { | ||
| 227 | /* | ||
| 228 | * just walking through the slots on this leaf | ||
| 229 | */ | ||
| 230 | slot++; | ||
| 231 | path->slots[0]++; | ||
| 232 | } | ||
| 233 | } | 223 | } |
| 234 | advance = 1; | ||
| 235 | 224 | ||
| 236 | btrfs_item_key_to_cpu(leaf, &found_key, slot); | 225 | btrfs_item_key_to_cpu(leaf, &found_key, slot); |
| 237 | 226 | ||
| @@ -250,7 +239,7 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 250 | 239 | ||
| 251 | /* we are just looking for how big our buffer needs to be */ | 240 | /* we are just looking for how big our buffer needs to be */ |
| 252 | if (!size) | 241 | if (!size) |
| 253 | continue; | 242 | goto next; |
| 254 | 243 | ||
| 255 | if (!buffer || (name_len + 1) > size_left) { | 244 | if (!buffer || (name_len + 1) > size_left) { |
| 256 | ret = -ERANGE; | 245 | ret = -ERANGE; |
| @@ -263,6 +252,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size) | |||
| 263 | 252 | ||
| 264 | size_left -= name_len + 1; | 253 | size_left -= name_len + 1; |
| 265 | buffer += name_len + 1; | 254 | buffer += name_len + 1; |
| 255 | next: | ||
| 256 | path->slots[0]++; | ||
| 266 | } | 257 | } |
| 267 | ret = total_size; | 258 | ret = total_size; |
| 268 | 259 | ||
