diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-05-16 13:41:48 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2013-06-29 04:56:33 -0400 |
commit | 81b9f66e6b5cd8bc8aa4502dc69a923b3e68f664 (patch) | |
tree | d3ce92b15758d80a93a4c2439bdf3982e7a62f5a /fs/bfs | |
parent | f0c3b5093addc8bfe9fe3a5b01acb7ec7969eafa (diff) |
[readdir] convert bfs
... and get rid of that ridiculous mutex in bfs_readdir()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/bfs')
-rw-r--r-- | fs/bfs/dir.c | 35 |
1 files changed, 14 insertions, 21 deletions
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 3f422f6bb5ca..a399e6d9dc74 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
@@ -26,58 +26,51 @@ static struct buffer_head *bfs_find_entry(struct inode *dir, | |||
26 | const unsigned char *name, int namelen, | 26 | const unsigned char *name, int namelen, |
27 | struct bfs_dirent **res_dir); | 27 | struct bfs_dirent **res_dir); |
28 | 28 | ||
29 | static int bfs_readdir(struct file *f, void *dirent, filldir_t filldir) | 29 | static int bfs_readdir(struct file *f, struct dir_context *ctx) |
30 | { | 30 | { |
31 | struct inode *dir = file_inode(f); | 31 | struct inode *dir = file_inode(f); |
32 | struct buffer_head *bh; | 32 | struct buffer_head *bh; |
33 | struct bfs_dirent *de; | 33 | struct bfs_dirent *de; |
34 | struct bfs_sb_info *info = BFS_SB(dir->i_sb); | ||
35 | unsigned int offset; | 34 | unsigned int offset; |
36 | int block; | 35 | int block; |
37 | 36 | ||
38 | mutex_lock(&info->bfs_lock); | 37 | if (ctx->pos & (BFS_DIRENT_SIZE - 1)) { |
39 | |||
40 | if (f->f_pos & (BFS_DIRENT_SIZE - 1)) { | ||
41 | printf("Bad f_pos=%08lx for %s:%08lx\n", | 38 | printf("Bad f_pos=%08lx for %s:%08lx\n", |
42 | (unsigned long)f->f_pos, | 39 | (unsigned long)ctx->pos, |
43 | dir->i_sb->s_id, dir->i_ino); | 40 | dir->i_sb->s_id, dir->i_ino); |
44 | mutex_unlock(&info->bfs_lock); | 41 | return -EINVAL; |
45 | return -EBADF; | ||
46 | } | 42 | } |
47 | 43 | ||
48 | while (f->f_pos < dir->i_size) { | 44 | while (ctx->pos < dir->i_size) { |
49 | offset = f->f_pos & (BFS_BSIZE - 1); | 45 | offset = ctx->pos & (BFS_BSIZE - 1); |
50 | block = BFS_I(dir)->i_sblock + (f->f_pos >> BFS_BSIZE_BITS); | 46 | block = BFS_I(dir)->i_sblock + (ctx->pos >> BFS_BSIZE_BITS); |
51 | bh = sb_bread(dir->i_sb, block); | 47 | bh = sb_bread(dir->i_sb, block); |
52 | if (!bh) { | 48 | if (!bh) { |
53 | f->f_pos += BFS_BSIZE - offset; | 49 | ctx->pos += BFS_BSIZE - offset; |
54 | continue; | 50 | continue; |
55 | } | 51 | } |
56 | do { | 52 | do { |
57 | de = (struct bfs_dirent *)(bh->b_data + offset); | 53 | de = (struct bfs_dirent *)(bh->b_data + offset); |
58 | if (de->ino) { | 54 | if (de->ino) { |
59 | int size = strnlen(de->name, BFS_NAMELEN); | 55 | int size = strnlen(de->name, BFS_NAMELEN); |
60 | if (filldir(dirent, de->name, size, f->f_pos, | 56 | if (!dir_emit(ctx, de->name, size, |
61 | le16_to_cpu(de->ino), | 57 | le16_to_cpu(de->ino), |
62 | DT_UNKNOWN) < 0) { | 58 | DT_UNKNOWN)) { |
63 | brelse(bh); | 59 | brelse(bh); |
64 | mutex_unlock(&info->bfs_lock); | ||
65 | return 0; | 60 | return 0; |
66 | } | 61 | } |
67 | } | 62 | } |
68 | offset += BFS_DIRENT_SIZE; | 63 | offset += BFS_DIRENT_SIZE; |
69 | f->f_pos += BFS_DIRENT_SIZE; | 64 | ctx->pos += BFS_DIRENT_SIZE; |
70 | } while ((offset < BFS_BSIZE) && (f->f_pos < dir->i_size)); | 65 | } while ((offset < BFS_BSIZE) && (ctx->pos < dir->i_size)); |
71 | brelse(bh); | 66 | brelse(bh); |
72 | } | 67 | } |
73 | 68 | return 0; | |
74 | mutex_unlock(&info->bfs_lock); | ||
75 | return 0; | ||
76 | } | 69 | } |
77 | 70 | ||
78 | const struct file_operations bfs_dir_operations = { | 71 | const struct file_operations bfs_dir_operations = { |
79 | .read = generic_read_dir, | 72 | .read = generic_read_dir, |
80 | .readdir = bfs_readdir, | 73 | .iterate = bfs_readdir, |
81 | .fsync = generic_file_fsync, | 74 | .fsync = generic_file_fsync, |
82 | .llseek = generic_file_llseek, | 75 | .llseek = generic_file_llseek, |
83 | }; | 76 | }; |