diff options
Diffstat (limited to 'fs/reiserfs')
-rw-r--r-- | fs/reiserfs/dir.c | 36 | ||||
-rw-r--r-- | fs/reiserfs/inode.c | 12 | ||||
-rw-r--r-- | fs/reiserfs/procfs.c | 99 | ||||
-rw-r--r-- | fs/reiserfs/reiserfs.h | 2 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 3 | ||||
-rw-r--r-- | fs/reiserfs/xattr.c | 33 |
6 files changed, 61 insertions, 124 deletions
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 6c2d136561cb..03e4ca5624d6 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c | |||
@@ -13,14 +13,14 @@ | |||
13 | 13 | ||
14 | extern const struct reiserfs_key MIN_KEY; | 14 | extern const struct reiserfs_key MIN_KEY; |
15 | 15 | ||
16 | static int reiserfs_readdir(struct file *, void *, filldir_t); | 16 | static int reiserfs_readdir(struct file *, struct dir_context *); |
17 | static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end, | 17 | static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end, |
18 | int datasync); | 18 | int datasync); |
19 | 19 | ||
20 | const struct file_operations reiserfs_dir_operations = { | 20 | const struct file_operations reiserfs_dir_operations = { |
21 | .llseek = generic_file_llseek, | 21 | .llseek = generic_file_llseek, |
22 | .read = generic_read_dir, | 22 | .read = generic_read_dir, |
23 | .readdir = reiserfs_readdir, | 23 | .iterate = reiserfs_readdir, |
24 | .fsync = reiserfs_dir_fsync, | 24 | .fsync = reiserfs_dir_fsync, |
25 | .unlocked_ioctl = reiserfs_ioctl, | 25 | .unlocked_ioctl = reiserfs_ioctl, |
26 | #ifdef CONFIG_COMPAT | 26 | #ifdef CONFIG_COMPAT |
@@ -50,18 +50,15 @@ static int reiserfs_dir_fsync(struct file *filp, loff_t start, loff_t end, | |||
50 | 50 | ||
51 | #define store_ih(where,what) copy_item_head (where, what) | 51 | #define store_ih(where,what) copy_item_head (where, what) |
52 | 52 | ||
53 | static inline bool is_privroot_deh(struct dentry *dir, | 53 | static inline bool is_privroot_deh(struct inode *dir, struct reiserfs_de_head *deh) |
54 | struct reiserfs_de_head *deh) | ||
55 | { | 54 | { |
56 | struct dentry *privroot = REISERFS_SB(dir->d_sb)->priv_root; | 55 | struct dentry *privroot = REISERFS_SB(dir->i_sb)->priv_root; |
57 | return (dir == dir->d_parent && privroot->d_inode && | 56 | return (privroot->d_inode && |
58 | deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid); | 57 | deh->deh_objectid == INODE_PKEY(privroot->d_inode)->k_objectid); |
59 | } | 58 | } |
60 | 59 | ||
61 | int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | 60 | int reiserfs_readdir_inode(struct inode *inode, struct dir_context *ctx) |
62 | filldir_t filldir, loff_t *pos) | ||
63 | { | 61 | { |
64 | struct inode *inode = dentry->d_inode; | ||
65 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ | 62 | struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */ |
66 | INITIALIZE_PATH(path_to_entry); | 63 | INITIALIZE_PATH(path_to_entry); |
67 | struct buffer_head *bh; | 64 | struct buffer_head *bh; |
@@ -81,7 +78,7 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | |||
81 | 78 | ||
82 | /* form key for search the next directory entry using f_pos field of | 79 | /* form key for search the next directory entry using f_pos field of |
83 | file structure */ | 80 | file structure */ |
84 | make_cpu_key(&pos_key, inode, *pos ?: DOT_OFFSET, TYPE_DIRENTRY, 3); | 81 | make_cpu_key(&pos_key, inode, ctx->pos ?: DOT_OFFSET, TYPE_DIRENTRY, 3); |
85 | next_pos = cpu_key_k_offset(&pos_key); | 82 | next_pos = cpu_key_k_offset(&pos_key); |
86 | 83 | ||
87 | path_to_entry.reada = PATH_READA; | 84 | path_to_entry.reada = PATH_READA; |
@@ -126,7 +123,6 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | |||
126 | entry_num++, deh++) { | 123 | entry_num++, deh++) { |
127 | int d_reclen; | 124 | int d_reclen; |
128 | char *d_name; | 125 | char *d_name; |
129 | off_t d_off; | ||
130 | ino_t d_ino; | 126 | ino_t d_ino; |
131 | 127 | ||
132 | if (!de_visible(deh)) | 128 | if (!de_visible(deh)) |
@@ -155,11 +151,10 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | |||
155 | } | 151 | } |
156 | 152 | ||
157 | /* Ignore the .reiserfs_priv entry */ | 153 | /* Ignore the .reiserfs_priv entry */ |
158 | if (is_privroot_deh(dentry, deh)) | 154 | if (is_privroot_deh(inode, deh)) |
159 | continue; | 155 | continue; |
160 | 156 | ||
161 | d_off = deh_offset(deh); | 157 | ctx->pos = deh_offset(deh); |
162 | *pos = d_off; | ||
163 | d_ino = deh_objectid(deh); | 158 | d_ino = deh_objectid(deh); |
164 | if (d_reclen <= 32) { | 159 | if (d_reclen <= 32) { |
165 | local_buf = small_buf; | 160 | local_buf = small_buf; |
@@ -187,9 +182,9 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | |||
187 | * the write lock here for other waiters | 182 | * the write lock here for other waiters |
188 | */ | 183 | */ |
189 | reiserfs_write_unlock(inode->i_sb); | 184 | reiserfs_write_unlock(inode->i_sb); |
190 | if (filldir | 185 | if (!dir_emit |
191 | (dirent, local_buf, d_reclen, d_off, d_ino, | 186 | (ctx, local_buf, d_reclen, d_ino, |
192 | DT_UNKNOWN) < 0) { | 187 | DT_UNKNOWN)) { |
193 | reiserfs_write_lock(inode->i_sb); | 188 | reiserfs_write_lock(inode->i_sb); |
194 | if (local_buf != small_buf) { | 189 | if (local_buf != small_buf) { |
195 | kfree(local_buf); | 190 | kfree(local_buf); |
@@ -237,7 +232,7 @@ int reiserfs_readdir_dentry(struct dentry *dentry, void *dirent, | |||
237 | } /* while */ | 232 | } /* while */ |
238 | 233 | ||
239 | end: | 234 | end: |
240 | *pos = next_pos; | 235 | ctx->pos = next_pos; |
241 | pathrelse(&path_to_entry); | 236 | pathrelse(&path_to_entry); |
242 | reiserfs_check_path(&path_to_entry); | 237 | reiserfs_check_path(&path_to_entry); |
243 | out: | 238 | out: |
@@ -245,10 +240,9 @@ out: | |||
245 | return ret; | 240 | return ret; |
246 | } | 241 | } |
247 | 242 | ||
248 | static int reiserfs_readdir(struct file *file, void *dirent, filldir_t filldir) | 243 | static int reiserfs_readdir(struct file *file, struct dir_context *ctx) |
249 | { | 244 | { |
250 | struct dentry *dentry = file->f_path.dentry; | 245 | return reiserfs_readdir_inode(file_inode(file), ctx); |
251 | return reiserfs_readdir_dentry(dentry, dirent, filldir, &file->f_pos); | ||
252 | } | 246 | } |
253 | 247 | ||
254 | /* compose directory item containing "." and ".." entries (entries are | 248 | /* compose directory item containing "." and ".." entries (entries are |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index f844533792ee..0048cc16a6a8 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -2975,16 +2975,19 @@ static int invalidatepage_can_drop(struct inode *inode, struct buffer_head *bh) | |||
2975 | } | 2975 | } |
2976 | 2976 | ||
2977 | /* clm -- taken from fs/buffer.c:block_invalidate_page */ | 2977 | /* clm -- taken from fs/buffer.c:block_invalidate_page */ |
2978 | static void reiserfs_invalidatepage(struct page *page, unsigned long offset) | 2978 | static void reiserfs_invalidatepage(struct page *page, unsigned int offset, |
2979 | unsigned int length) | ||
2979 | { | 2980 | { |
2980 | struct buffer_head *head, *bh, *next; | 2981 | struct buffer_head *head, *bh, *next; |
2981 | struct inode *inode = page->mapping->host; | 2982 | struct inode *inode = page->mapping->host; |
2982 | unsigned int curr_off = 0; | 2983 | unsigned int curr_off = 0; |
2984 | unsigned int stop = offset + length; | ||
2985 | int partial_page = (offset || length < PAGE_CACHE_SIZE); | ||
2983 | int ret = 1; | 2986 | int ret = 1; |
2984 | 2987 | ||
2985 | BUG_ON(!PageLocked(page)); | 2988 | BUG_ON(!PageLocked(page)); |
2986 | 2989 | ||
2987 | if (offset == 0) | 2990 | if (!partial_page) |
2988 | ClearPageChecked(page); | 2991 | ClearPageChecked(page); |
2989 | 2992 | ||
2990 | if (!page_has_buffers(page)) | 2993 | if (!page_has_buffers(page)) |
@@ -2996,6 +2999,9 @@ static void reiserfs_invalidatepage(struct page *page, unsigned long offset) | |||
2996 | unsigned int next_off = curr_off + bh->b_size; | 2999 | unsigned int next_off = curr_off + bh->b_size; |
2997 | next = bh->b_this_page; | 3000 | next = bh->b_this_page; |
2998 | 3001 | ||
3002 | if (next_off > stop) | ||
3003 | goto out; | ||
3004 | |||
2999 | /* | 3005 | /* |
3000 | * is this block fully invalidated? | 3006 | * is this block fully invalidated? |
3001 | */ | 3007 | */ |
@@ -3014,7 +3020,7 @@ static void reiserfs_invalidatepage(struct page *page, unsigned long offset) | |||
3014 | * The get_block cached value has been unconditionally invalidated, | 3020 | * The get_block cached value has been unconditionally invalidated, |
3015 | * so real IO is not possible anymore. | 3021 | * so real IO is not possible anymore. |
3016 | */ | 3022 | */ |
3017 | if (!offset && ret) { | 3023 | if (!partial_page && ret) { |
3018 | ret = try_to_release_page(page, 0); | 3024 | ret = try_to_release_page(page, 0); |
3019 | /* maybe should BUG_ON(!ret); - neilb */ | 3025 | /* maybe should BUG_ON(!ret); - neilb */ |
3020 | } | 3026 | } |
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c index 33532f79b4f7..a958444a75fc 100644 --- a/fs/reiserfs/procfs.c +++ b/fs/reiserfs/procfs.c | |||
@@ -19,12 +19,13 @@ | |||
19 | /* | 19 | /* |
20 | * LOCKING: | 20 | * LOCKING: |
21 | * | 21 | * |
22 | * We rely on new Alexander Viro's super-block locking. | 22 | * These guys are evicted from procfs as the very first step in ->kill_sb(). |
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | 25 | ||
26 | static int show_version(struct seq_file *m, struct super_block *sb) | 26 | static int show_version(struct seq_file *m, void *unused) |
27 | { | 27 | { |
28 | struct super_block *sb = m->private; | ||
28 | char *format; | 29 | char *format; |
29 | 30 | ||
30 | if (REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6)) { | 31 | if (REISERFS_SB(sb)->s_properties & (1 << REISERFS_3_6)) { |
@@ -66,8 +67,9 @@ static int show_version(struct seq_file *m, struct super_block *sb) | |||
66 | #define DJP( x ) le32_to_cpu( jp -> x ) | 67 | #define DJP( x ) le32_to_cpu( jp -> x ) |
67 | #define JF( x ) ( r -> s_journal -> x ) | 68 | #define JF( x ) ( r -> s_journal -> x ) |
68 | 69 | ||
69 | static int show_super(struct seq_file *m, struct super_block *sb) | 70 | static int show_super(struct seq_file *m, void *unused) |
70 | { | 71 | { |
72 | struct super_block *sb = m->private; | ||
71 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 73 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
72 | 74 | ||
73 | seq_printf(m, "state: \t%s\n" | 75 | seq_printf(m, "state: \t%s\n" |
@@ -128,8 +130,9 @@ static int show_super(struct seq_file *m, struct super_block *sb) | |||
128 | return 0; | 130 | return 0; |
129 | } | 131 | } |
130 | 132 | ||
131 | static int show_per_level(struct seq_file *m, struct super_block *sb) | 133 | static int show_per_level(struct seq_file *m, void *unused) |
132 | { | 134 | { |
135 | struct super_block *sb = m->private; | ||
133 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 136 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
134 | int level; | 137 | int level; |
135 | 138 | ||
@@ -186,8 +189,9 @@ static int show_per_level(struct seq_file *m, struct super_block *sb) | |||
186 | return 0; | 189 | return 0; |
187 | } | 190 | } |
188 | 191 | ||
189 | static int show_bitmap(struct seq_file *m, struct super_block *sb) | 192 | static int show_bitmap(struct seq_file *m, void *unused) |
190 | { | 193 | { |
194 | struct super_block *sb = m->private; | ||
191 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 195 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
192 | 196 | ||
193 | seq_printf(m, "free_block: %lu\n" | 197 | seq_printf(m, "free_block: %lu\n" |
@@ -218,8 +222,9 @@ static int show_bitmap(struct seq_file *m, struct super_block *sb) | |||
218 | return 0; | 222 | return 0; |
219 | } | 223 | } |
220 | 224 | ||
221 | static int show_on_disk_super(struct seq_file *m, struct super_block *sb) | 225 | static int show_on_disk_super(struct seq_file *m, void *unused) |
222 | { | 226 | { |
227 | struct super_block *sb = m->private; | ||
223 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); | 228 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); |
224 | struct reiserfs_super_block *rs = sb_info->s_rs; | 229 | struct reiserfs_super_block *rs = sb_info->s_rs; |
225 | int hash_code = DFL(s_hash_function_code); | 230 | int hash_code = DFL(s_hash_function_code); |
@@ -261,8 +266,9 @@ static int show_on_disk_super(struct seq_file *m, struct super_block *sb) | |||
261 | return 0; | 266 | return 0; |
262 | } | 267 | } |
263 | 268 | ||
264 | static int show_oidmap(struct seq_file *m, struct super_block *sb) | 269 | static int show_oidmap(struct seq_file *m, void *unused) |
265 | { | 270 | { |
271 | struct super_block *sb = m->private; | ||
266 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); | 272 | struct reiserfs_sb_info *sb_info = REISERFS_SB(sb); |
267 | struct reiserfs_super_block *rs = sb_info->s_rs; | 273 | struct reiserfs_super_block *rs = sb_info->s_rs; |
268 | unsigned int mapsize = le16_to_cpu(rs->s_v1.s_oid_cursize); | 274 | unsigned int mapsize = le16_to_cpu(rs->s_v1.s_oid_cursize); |
@@ -291,8 +297,9 @@ static int show_oidmap(struct seq_file *m, struct super_block *sb) | |||
291 | return 0; | 297 | return 0; |
292 | } | 298 | } |
293 | 299 | ||
294 | static int show_journal(struct seq_file *m, struct super_block *sb) | 300 | static int show_journal(struct seq_file *m, void *unused) |
295 | { | 301 | { |
302 | struct super_block *sb = m->private; | ||
296 | struct reiserfs_sb_info *r = REISERFS_SB(sb); | 303 | struct reiserfs_sb_info *r = REISERFS_SB(sb); |
297 | struct reiserfs_super_block *rs = r->s_rs; | 304 | struct reiserfs_super_block *rs = r->s_rs; |
298 | struct journal_params *jp = &rs->s_v1.s_journal; | 305 | struct journal_params *jp = &rs->s_v1.s_journal; |
@@ -383,92 +390,24 @@ static int show_journal(struct seq_file *m, struct super_block *sb) | |||
383 | return 0; | 390 | return 0; |
384 | } | 391 | } |
385 | 392 | ||
386 | /* iterator */ | ||
387 | static int test_sb(struct super_block *sb, void *data) | ||
388 | { | ||
389 | return data == sb; | ||
390 | } | ||
391 | |||
392 | static int set_sb(struct super_block *sb, void *data) | ||
393 | { | ||
394 | return -ENOENT; | ||
395 | } | ||
396 | |||
397 | struct reiserfs_seq_private { | ||
398 | struct super_block *sb; | ||
399 | int (*show) (struct seq_file *, struct super_block *); | ||
400 | }; | ||
401 | |||
402 | static void *r_start(struct seq_file *m, loff_t * pos) | ||
403 | { | ||
404 | struct reiserfs_seq_private *priv = m->private; | ||
405 | loff_t l = *pos; | ||
406 | |||
407 | if (l) | ||
408 | return NULL; | ||
409 | |||
410 | if (IS_ERR(sget(&reiserfs_fs_type, test_sb, set_sb, 0, priv->sb))) | ||
411 | return NULL; | ||
412 | |||
413 | up_write(&priv->sb->s_umount); | ||
414 | return priv->sb; | ||
415 | } | ||
416 | |||
417 | static void *r_next(struct seq_file *m, void *v, loff_t * pos) | ||
418 | { | ||
419 | ++*pos; | ||
420 | if (v) | ||
421 | deactivate_super(v); | ||
422 | return NULL; | ||
423 | } | ||
424 | |||
425 | static void r_stop(struct seq_file *m, void *v) | ||
426 | { | ||
427 | if (v) | ||
428 | deactivate_super(v); | ||
429 | } | ||
430 | |||
431 | static int r_show(struct seq_file *m, void *v) | ||
432 | { | ||
433 | struct reiserfs_seq_private *priv = m->private; | ||
434 | return priv->show(m, v); | ||
435 | } | ||
436 | |||
437 | static const struct seq_operations r_ops = { | ||
438 | .start = r_start, | ||
439 | .next = r_next, | ||
440 | .stop = r_stop, | ||
441 | .show = r_show, | ||
442 | }; | ||
443 | |||
444 | static int r_open(struct inode *inode, struct file *file) | 393 | static int r_open(struct inode *inode, struct file *file) |
445 | { | 394 | { |
446 | struct reiserfs_seq_private *priv; | 395 | return single_open(file, PDE_DATA(inode), |
447 | int ret = seq_open_private(file, &r_ops, | 396 | proc_get_parent_data(inode)); |
448 | sizeof(struct reiserfs_seq_private)); | ||
449 | |||
450 | if (!ret) { | ||
451 | struct seq_file *m = file->private_data; | ||
452 | priv = m->private; | ||
453 | priv->sb = proc_get_parent_data(inode); | ||
454 | priv->show = PDE_DATA(inode); | ||
455 | } | ||
456 | return ret; | ||
457 | } | 397 | } |
458 | 398 | ||
459 | static const struct file_operations r_file_operations = { | 399 | static const struct file_operations r_file_operations = { |
460 | .open = r_open, | 400 | .open = r_open, |
461 | .read = seq_read, | 401 | .read = seq_read, |
462 | .llseek = seq_lseek, | 402 | .llseek = seq_lseek, |
463 | .release = seq_release_private, | 403 | .release = single_release, |
464 | .owner = THIS_MODULE, | ||
465 | }; | 404 | }; |
466 | 405 | ||
467 | static struct proc_dir_entry *proc_info_root = NULL; | 406 | static struct proc_dir_entry *proc_info_root = NULL; |
468 | static const char proc_info_root_name[] = "fs/reiserfs"; | 407 | static const char proc_info_root_name[] = "fs/reiserfs"; |
469 | 408 | ||
470 | static void add_file(struct super_block *sb, char *name, | 409 | static void add_file(struct super_block *sb, char *name, |
471 | int (*func) (struct seq_file *, struct super_block *)) | 410 | int (*func) (struct seq_file *, void *)) |
472 | { | 411 | { |
473 | proc_create_data(name, 0, REISERFS_SB(sb)->procdir, | 412 | proc_create_data(name, 0, REISERFS_SB(sb)->procdir, |
474 | &r_file_operations, func); | 413 | &r_file_operations, func); |
diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h index 157e474ab303..3df5ce6c724d 100644 --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h | |||
@@ -2709,7 +2709,7 @@ extern const struct inode_operations reiserfs_dir_inode_operations; | |||
2709 | extern const struct inode_operations reiserfs_symlink_inode_operations; | 2709 | extern const struct inode_operations reiserfs_symlink_inode_operations; |
2710 | extern const struct inode_operations reiserfs_special_inode_operations; | 2710 | extern const struct inode_operations reiserfs_special_inode_operations; |
2711 | extern const struct file_operations reiserfs_dir_operations; | 2711 | extern const struct file_operations reiserfs_dir_operations; |
2712 | int reiserfs_readdir_dentry(struct dentry *, void *, filldir_t, loff_t *); | 2712 | int reiserfs_readdir_inode(struct inode *, struct dir_context *); |
2713 | 2713 | ||
2714 | /* tail_conversion.c */ | 2714 | /* tail_conversion.c */ |
2715 | int direct2indirect(struct reiserfs_transaction_handle *, struct inode *, | 2715 | int direct2indirect(struct reiserfs_transaction_handle *, struct inode *, |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index f8a23c3078f8..e2e202a07b31 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -499,6 +499,7 @@ int remove_save_link(struct inode *inode, int truncate) | |||
499 | static void reiserfs_kill_sb(struct super_block *s) | 499 | static void reiserfs_kill_sb(struct super_block *s) |
500 | { | 500 | { |
501 | if (REISERFS_SB(s)) { | 501 | if (REISERFS_SB(s)) { |
502 | reiserfs_proc_info_done(s); | ||
502 | /* | 503 | /* |
503 | * Force any pending inode evictions to occur now. Any | 504 | * Force any pending inode evictions to occur now. Any |
504 | * inodes to be removed that have extended attributes | 505 | * inodes to be removed that have extended attributes |
@@ -554,8 +555,6 @@ static void reiserfs_put_super(struct super_block *s) | |||
554 | REISERFS_SB(s)->reserved_blocks); | 555 | REISERFS_SB(s)->reserved_blocks); |
555 | } | 556 | } |
556 | 557 | ||
557 | reiserfs_proc_info_done(s); | ||
558 | |||
559 | reiserfs_write_unlock(s); | 558 | reiserfs_write_unlock(s); |
560 | mutex_destroy(&REISERFS_SB(s)->lock); | 559 | mutex_destroy(&REISERFS_SB(s)->lock); |
561 | kfree(s->s_fs_info); | 560 | kfree(s->s_fs_info); |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 821bcf70e467..c69cdd749f09 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -171,6 +171,7 @@ static struct dentry *open_xa_dir(const struct inode *inode, int flags) | |||
171 | * modifying extended attributes. This includes operations such as permissions | 171 | * modifying extended attributes. This includes operations such as permissions |
172 | * or ownership changes, object deletions, etc. */ | 172 | * or ownership changes, object deletions, etc. */ |
173 | struct reiserfs_dentry_buf { | 173 | struct reiserfs_dentry_buf { |
174 | struct dir_context ctx; | ||
174 | struct dentry *xadir; | 175 | struct dentry *xadir; |
175 | int count; | 176 | int count; |
176 | struct dentry *dentries[8]; | 177 | struct dentry *dentries[8]; |
@@ -223,9 +224,8 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
223 | { | 224 | { |
224 | struct dentry *dir; | 225 | struct dentry *dir; |
225 | int i, err = 0; | 226 | int i, err = 0; |
226 | loff_t pos = 0; | ||
227 | struct reiserfs_dentry_buf buf = { | 227 | struct reiserfs_dentry_buf buf = { |
228 | .count = 0, | 228 | .ctx.actor = fill_with_dentries, |
229 | }; | 229 | }; |
230 | 230 | ||
231 | /* Skip out, an xattr has no xattrs associated with it */ | 231 | /* Skip out, an xattr has no xattrs associated with it */ |
@@ -249,29 +249,27 @@ static int reiserfs_for_each_xattr(struct inode *inode, | |||
249 | reiserfs_write_lock(inode->i_sb); | 249 | reiserfs_write_lock(inode->i_sb); |
250 | 250 | ||
251 | buf.xadir = dir; | 251 | buf.xadir = dir; |
252 | err = reiserfs_readdir_dentry(dir, &buf, fill_with_dentries, &pos); | 252 | while (1) { |
253 | while ((err == 0 || err == -ENOSPC) && buf.count) { | 253 | err = reiserfs_readdir_inode(dir->d_inode, &buf.ctx); |
254 | err = 0; | 254 | if (err) |
255 | 255 | break; | |
256 | for (i = 0; i < buf.count && buf.dentries[i]; i++) { | 256 | if (!buf.count) |
257 | int lerr = 0; | 257 | break; |
258 | for (i = 0; !err && i < buf.count && buf.dentries[i]; i++) { | ||
258 | struct dentry *dentry = buf.dentries[i]; | 259 | struct dentry *dentry = buf.dentries[i]; |
259 | 260 | ||
260 | if (err == 0 && !S_ISDIR(dentry->d_inode->i_mode)) | 261 | if (!S_ISDIR(dentry->d_inode->i_mode)) |
261 | lerr = action(dentry, data); | 262 | err = action(dentry, data); |
262 | 263 | ||
263 | dput(dentry); | 264 | dput(dentry); |
264 | buf.dentries[i] = NULL; | 265 | buf.dentries[i] = NULL; |
265 | err = lerr ?: err; | ||
266 | } | 266 | } |
267 | if (err) | ||
268 | break; | ||
267 | buf.count = 0; | 269 | buf.count = 0; |
268 | if (!err) | ||
269 | err = reiserfs_readdir_dentry(dir, &buf, | ||
270 | fill_with_dentries, &pos); | ||
271 | } | 270 | } |
272 | mutex_unlock(&dir->d_inode->i_mutex); | 271 | mutex_unlock(&dir->d_inode->i_mutex); |
273 | 272 | ||
274 | /* Clean up after a failed readdir */ | ||
275 | cleanup_dentry_buf(&buf); | 273 | cleanup_dentry_buf(&buf); |
276 | 274 | ||
277 | if (!err) { | 275 | if (!err) { |
@@ -800,6 +798,7 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name) | |||
800 | } | 798 | } |
801 | 799 | ||
802 | struct listxattr_buf { | 800 | struct listxattr_buf { |
801 | struct dir_context ctx; | ||
803 | size_t size; | 802 | size_t size; |
804 | size_t pos; | 803 | size_t pos; |
805 | char *buf; | 804 | char *buf; |
@@ -845,8 +844,8 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | |||
845 | { | 844 | { |
846 | struct dentry *dir; | 845 | struct dentry *dir; |
847 | int err = 0; | 846 | int err = 0; |
848 | loff_t pos = 0; | ||
849 | struct listxattr_buf buf = { | 847 | struct listxattr_buf buf = { |
848 | .ctx.actor = listxattr_filler, | ||
850 | .dentry = dentry, | 849 | .dentry = dentry, |
851 | .buf = buffer, | 850 | .buf = buffer, |
852 | .size = buffer ? size : 0, | 851 | .size = buffer ? size : 0, |
@@ -868,7 +867,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | |||
868 | } | 867 | } |
869 | 868 | ||
870 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); | 869 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); |
871 | err = reiserfs_readdir_dentry(dir, &buf, listxattr_filler, &pos); | 870 | err = reiserfs_readdir_inode(dir->d_inode, &buf.ctx); |
872 | mutex_unlock(&dir->d_inode->i_mutex); | 871 | mutex_unlock(&dir->d_inode->i_mutex); |
873 | 872 | ||
874 | if (!err) | 873 | if (!err) |