f2fs: change type for 'sbi->readdir_ra'
[linux-block.git] / fs / f2fs / dir.c
index d5bd7932fb642c7e5fa74ac0d77dc0d80c0206f8..8e025157f35c9550885b5d9c7eb8506871f560bb 100644 (file)
@@ -340,6 +340,7 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir,
        unsigned int bidx, end_block;
        struct page *dentry_page;
        struct f2fs_dir_entry *de = NULL;
+       pgoff_t next_pgofs;
        bool room = false;
        int max_slots;
 
@@ -350,12 +351,13 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir,
                               le32_to_cpu(fname->hash) % nbucket);
        end_block = bidx + nblock;
 
-       for (; bidx < end_block; bidx++) {
+       while (bidx < end_block) {
                /* no need to allocate new dentry pages to all the indices */
-               dentry_page = f2fs_find_data_page(dir, bidx);
+               dentry_page = f2fs_find_data_page(dir, bidx, &next_pgofs);
                if (IS_ERR(dentry_page)) {
                        if (PTR_ERR(dentry_page) == -ENOENT) {
                                room = true;
+                               bidx = next_pgofs;
                                continue;
                        } else {
                                *res_page = dentry_page;
@@ -376,6 +378,8 @@ static struct f2fs_dir_entry *find_in_level(struct inode *dir,
                if (max_slots >= s)
                        room = true;
                f2fs_put_page(dentry_page, 0);
+
+               bidx++;
        }
 
        if (!de && room && F2FS_I(dir)->chash != fname->hash) {
@@ -956,7 +960,7 @@ void f2fs_delete_entry(struct f2fs_dir_entry *dentry, struct page *page,
 
 bool f2fs_empty_dir(struct inode *dir)
 {
-       unsigned long bidx;
+       unsigned long bidx = 0;
        struct page *dentry_page;
        unsigned int bit_pos;
        struct f2fs_dentry_block *dentry_blk;
@@ -965,13 +969,17 @@ bool f2fs_empty_dir(struct inode *dir)
        if (f2fs_has_inline_dentry(dir))
                return f2fs_empty_inline_dir(dir);
 
-       for (bidx = 0; bidx < nblock; bidx++) {
-               dentry_page = f2fs_get_lock_data_page(dir, bidx, false);
+       while (bidx < nblock) {
+               pgoff_t next_pgofs;
+
+               dentry_page = f2fs_find_data_page(dir, bidx, &next_pgofs);
                if (IS_ERR(dentry_page)) {
-                       if (PTR_ERR(dentry_page) == -ENOENT)
+                       if (PTR_ERR(dentry_page) == -ENOENT) {
+                               bidx = next_pgofs;
                                continue;
-                       else
+                       } else {
                                return false;
+                       }
                }
 
                dentry_blk = page_address(dentry_page);
@@ -983,10 +991,12 @@ bool f2fs_empty_dir(struct inode *dir)
                                                NR_DENTRY_IN_BLOCK,
                                                bit_pos);
 
-               f2fs_put_page(dentry_page, 1);
+               f2fs_put_page(dentry_page, 0);
 
                if (bit_pos < NR_DENTRY_IN_BLOCK)
                        return false;
+
+               bidx++;
        }
        return true;
 }
@@ -1000,7 +1010,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
        struct fscrypt_str de_name = FSTR_INIT(NULL, 0);
        struct f2fs_sb_info *sbi = F2FS_I_SB(d->inode);
        struct blk_plug plug;
-       bool readdir_ra = sbi->readdir_ra == 1;
+       bool readdir_ra = sbi->readdir_ra;
        bool found_valid_dirent = false;
        int err = 0;
 
@@ -1041,6 +1051,7 @@ int f2fs_fill_dentries(struct dir_context *ctx, struct f2fs_dentry_ptr *d,
                                  __func__, le16_to_cpu(de->name_len));
                        set_sbi_flag(sbi, SBI_NEED_FSCK);
                        err = -EFSCORRUPTED;
+                       f2fs_handle_error(sbi, ERROR_CORRUPTED_DIRENT);
                        goto out;
                }
 
@@ -1103,7 +1114,8 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
                goto out_free;
        }
 
-       for (; n < npages; n++, ctx->pos = n * NR_DENTRY_IN_BLOCK) {
+       for (; n < npages; ctx->pos = n * NR_DENTRY_IN_BLOCK) {
+               pgoff_t next_pgofs;
 
                /* allow readdir() to be interrupted */
                if (fatal_signal_pending(current)) {
@@ -1117,11 +1129,12 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
                        page_cache_sync_readahead(inode->i_mapping, ra, file, n,
                                min(npages - n, (pgoff_t)MAX_DIR_RA_PAGES));
 
-               dentry_page = f2fs_find_data_page(inode, n);
+               dentry_page = f2fs_find_data_page(inode, n, &next_pgofs);
                if (IS_ERR(dentry_page)) {
                        err = PTR_ERR(dentry_page);
                        if (err == -ENOENT) {
                                err = 0;
+                               n = next_pgofs;
                                continue;
                        } else {
                                goto out_free;
@@ -1140,6 +1153,8 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
                }
 
                f2fs_put_page(dentry_page, 0);
+
+               n++;
        }
 out_free:
        fscrypt_fname_free_buffer(&fstr);