diff options
Diffstat (limited to 'fs/f2fs/namei.c')
-rw-r--r-- | fs/f2fs/namei.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 1e2ae21bd6b6..8055e30eb14d 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c | |||
@@ -187,6 +187,44 @@ struct dentry *f2fs_get_parent(struct dentry *child) | |||
187 | return d_obtain_alias(f2fs_iget(child->d_inode->i_sb, ino)); | 187 | return d_obtain_alias(f2fs_iget(child->d_inode->i_sb, ino)); |
188 | } | 188 | } |
189 | 189 | ||
190 | static int __recover_dot_dentries(struct inode *dir, nid_t pino) | ||
191 | { | ||
192 | struct f2fs_sb_info *sbi = F2FS_I_SB(dir); | ||
193 | struct qstr dot = QSTR_INIT(".", 1); | ||
194 | struct qstr dotdot = QSTR_INIT("..", 2); | ||
195 | struct f2fs_dir_entry *de; | ||
196 | struct page *page; | ||
197 | int err = 0; | ||
198 | |||
199 | f2fs_lock_op(sbi); | ||
200 | |||
201 | de = f2fs_find_entry(dir, &dot, &page); | ||
202 | if (de) { | ||
203 | f2fs_dentry_kunmap(dir, page); | ||
204 | f2fs_put_page(page, 0); | ||
205 | } else { | ||
206 | err = __f2fs_add_link(dir, &dot, NULL, dir->i_ino, S_IFDIR); | ||
207 | if (err) | ||
208 | goto out; | ||
209 | } | ||
210 | |||
211 | de = f2fs_find_entry(dir, &dotdot, &page); | ||
212 | if (de) { | ||
213 | f2fs_dentry_kunmap(dir, page); | ||
214 | f2fs_put_page(page, 0); | ||
215 | } else { | ||
216 | err = __f2fs_add_link(dir, &dotdot, NULL, pino, S_IFDIR); | ||
217 | } | ||
218 | out: | ||
219 | if (!err) { | ||
220 | clear_inode_flag(F2FS_I(dir), FI_INLINE_DOTS); | ||
221 | mark_inode_dirty(dir); | ||
222 | } | ||
223 | |||
224 | f2fs_unlock_op(sbi); | ||
225 | return err; | ||
226 | } | ||
227 | |||
190 | static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, | 228 | static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, |
191 | unsigned int flags) | 229 | unsigned int flags) |
192 | { | 230 | { |
@@ -206,6 +244,16 @@ static struct dentry *f2fs_lookup(struct inode *dir, struct dentry *dentry, | |||
206 | inode = f2fs_iget(dir->i_sb, ino); | 244 | inode = f2fs_iget(dir->i_sb, ino); |
207 | if (IS_ERR(inode)) | 245 | if (IS_ERR(inode)) |
208 | return ERR_CAST(inode); | 246 | return ERR_CAST(inode); |
247 | |||
248 | if (f2fs_has_inline_dots(inode)) { | ||
249 | int err; | ||
250 | |||
251 | err = __recover_dot_dentries(inode, dir->i_ino); | ||
252 | if (err) { | ||
253 | iget_failed(inode); | ||
254 | return ERR_PTR(err); | ||
255 | } | ||
256 | } | ||
209 | } | 257 | } |
210 | 258 | ||
211 | return d_splice_alias(inode, dentry); | 259 | return d_splice_alias(inode, dentry); |