diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/affs/dir.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/fs/affs/dir.c b/fs/affs/dir.c index f1eba8c3644e..cbbda476a805 100644 --- a/fs/affs/dir.c +++ b/fs/affs/dir.c | |||
@@ -52,8 +52,10 @@ affs_readdir(struct file *file, struct dir_context *ctx) | |||
52 | int hash_pos; | 52 | int hash_pos; |
53 | int chain_pos; | 53 | int chain_pos; |
54 | u32 ino; | 54 | u32 ino; |
55 | int error = 0; | ||
55 | 56 | ||
56 | pr_debug("AFFS: readdir(ino=%lu,f_pos=%lx)\n",inode->i_ino,(unsigned long)ctx->pos); | 57 | pr_debug("AFFS: readdir(ino=%lu,f_pos=%lx)\n", |
58 | inode->i_ino, (unsigned long)ctx->pos); | ||
57 | 59 | ||
58 | if (ctx->pos < 2) { | 60 | if (ctx->pos < 2) { |
59 | file->private_data = (void *)0; | 61 | file->private_data = (void *)0; |
@@ -72,7 +74,7 @@ affs_readdir(struct file *file, struct dir_context *ctx) | |||
72 | } | 74 | } |
73 | dir_bh = affs_bread(sb, inode->i_ino); | 75 | dir_bh = affs_bread(sb, inode->i_ino); |
74 | if (!dir_bh) | 76 | if (!dir_bh) |
75 | goto readdir_out; | 77 | goto out_unlock_dir; |
76 | 78 | ||
77 | /* If the directory hasn't changed since the last call to readdir(), | 79 | /* If the directory hasn't changed since the last call to readdir(), |
78 | * we can jump directly to where we left off. | 80 | * we can jump directly to where we left off. |
@@ -88,7 +90,8 @@ affs_readdir(struct file *file, struct dir_context *ctx) | |||
88 | fh_bh = affs_bread(sb, ino); | 90 | fh_bh = affs_bread(sb, ino); |
89 | if (!fh_bh) { | 91 | if (!fh_bh) { |
90 | affs_error(sb, "readdir","Cannot read block %d", i); | 92 | affs_error(sb, "readdir","Cannot read block %d", i); |
91 | return -EIO; | 93 | error = -EIO; |
94 | goto out_brelse_dir; | ||
92 | } | 95 | } |
93 | ino = be32_to_cpu(AFFS_TAIL(sb, fh_bh)->hash_chain); | 96 | ino = be32_to_cpu(AFFS_TAIL(sb, fh_bh)->hash_chain); |
94 | affs_brelse(fh_bh); | 97 | affs_brelse(fh_bh); |
@@ -107,29 +110,34 @@ inside: | |||
107 | do { | 110 | do { |
108 | fh_bh = affs_bread(sb, ino); | 111 | fh_bh = affs_bread(sb, ino); |
109 | if (!fh_bh) { | 112 | if (!fh_bh) { |
110 | affs_error(sb, "readdir","Cannot read block %d", ino); | 113 | affs_error(sb, "readdir", |
114 | "Cannot read block %d", ino); | ||
111 | break; | 115 | break; |
112 | } | 116 | } |
113 | 117 | ||
114 | namelen = min(AFFS_TAIL(sb, fh_bh)->name[0], (u8)30); | 118 | namelen = min(AFFS_TAIL(sb, fh_bh)->name[0], (u8)30); |
115 | name = AFFS_TAIL(sb, fh_bh)->name + 1; | 119 | name = AFFS_TAIL(sb, fh_bh)->name + 1; |
116 | pr_debug("AFFS: readdir(): filldir(\"%.*s\", ino=%u), hash=%d, f_pos=%x\n", | 120 | pr_debug("AFFS: readdir(): dir_emit(\"%.*s\", " |
121 | "ino=%u), hash=%d, f_pos=%x\n", | ||
117 | namelen, name, ino, hash_pos, (u32)ctx->pos); | 122 | namelen, name, ino, hash_pos, (u32)ctx->pos); |
123 | |||
118 | if (!dir_emit(ctx, name, namelen, ino, DT_UNKNOWN)) | 124 | if (!dir_emit(ctx, name, namelen, ino, DT_UNKNOWN)) |
119 | goto readdir_done; | 125 | goto done; |
120 | ctx->pos++; | 126 | ctx->pos++; |
121 | ino = be32_to_cpu(AFFS_TAIL(sb, fh_bh)->hash_chain); | 127 | ino = be32_to_cpu(AFFS_TAIL(sb, fh_bh)->hash_chain); |
122 | affs_brelse(fh_bh); | 128 | affs_brelse(fh_bh); |
123 | fh_bh = NULL; | 129 | fh_bh = NULL; |
124 | } while (ino); | 130 | } while (ino); |
125 | } | 131 | } |
126 | readdir_done: | 132 | done: |
127 | file->f_version = inode->i_version; | 133 | file->f_version = inode->i_version; |
128 | file->private_data = (void *)(long)ino; | 134 | file->private_data = (void *)(long)ino; |
135 | affs_brelse(fh_bh); | ||
129 | 136 | ||
130 | readdir_out: | 137 | out_brelse_dir: |
131 | affs_brelse(dir_bh); | 138 | affs_brelse(dir_bh); |
132 | affs_brelse(fh_bh); | 139 | |
140 | out_unlock_dir: | ||
133 | affs_unlock_dir(inode); | 141 | affs_unlock_dir(inode); |
134 | return 0; | 142 | return error; |
135 | } | 143 | } |