linux/fs/ext2/dir.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 *  linux/fs/ext2/dir.c
   4 *
   5 * Copyright (C) 1992, 1993, 1994, 1995
   6 * Remy Card (card@masi.ibp.fr)
   7 * Laboratoire MASI - Institut Blaise Pascal
   8 * Universite Pierre et Marie Curie (Paris VI)
   9 *
  10 *  from
  11 *
  12 *  linux/fs/minix/dir.c
  13 *
  14 *  Copyright (C) 1991, 1992  Linus Torvalds
  15 *
  16 *  ext2 directory handling functions
  17 *
  18 *  Big-endian to little-endian byte-swapping/bitmaps by
  19 *        David S. Miller (davem@caip.rutgers.edu), 1995
  20 *
  21 * All code that works with directory layout had been switched to pagecache
  22 * and moved here. AV
  23 */
  24
  25#include "ext2.h"
  26#include <linux/buffer_head.h>
  27#include <linux/pagemap.h>
  28#include <linux/swap.h>
  29#include <linux/iversion.h>
  30
  31typedef struct ext2_dir_entry_2 ext2_dirent;
  32
  33/*
  34 * Tests against MAX_REC_LEN etc were put in place for 64k block
  35 * sizes; if that is not possible on this arch, we can skip
  36 * those tests and speed things up.
  37 */
  38static inline unsigned ext2_rec_len_from_disk(__le16 dlen)
  39{
  40        unsigned len = le16_to_cpu(dlen);
  41
  42#if (PAGE_SIZE >= 65536)
  43        if (len == EXT2_MAX_REC_LEN)
  44                return 1 << 16;
  45#endif
  46        return len;
  47}
  48
  49static inline __le16 ext2_rec_len_to_disk(unsigned len)
  50{
  51#if (PAGE_SIZE >= 65536)
  52        if (len == (1 << 16))
  53                return cpu_to_le16(EXT2_MAX_REC_LEN);
  54        else
  55                BUG_ON(len > (1 << 16));
  56#endif
  57        return cpu_to_le16(len);
  58}
  59
  60/*
  61 * ext2 uses block-sized chunks. Arguably, sector-sized ones would be
  62 * more robust, but we have what we have
  63 */
  64static inline unsigned ext2_chunk_size(struct inode *inode)
  65{
  66        return inode->i_sb->s_blocksize;
  67}
  68
  69/*
  70 * Return the offset into page `page_nr' of the last valid
  71 * byte in that page, plus one.
  72 */
  73static unsigned
  74ext2_last_byte(struct inode *inode, unsigned long page_nr)
  75{
  76        unsigned last_byte = inode->i_size;
  77
  78        last_byte -= page_nr << PAGE_SHIFT;
  79        if (last_byte > PAGE_SIZE)
  80                last_byte = PAGE_SIZE;
  81        return last_byte;
  82}
  83
  84static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
  85{
  86        struct address_space *mapping = page->mapping;
  87        struct inode *dir = mapping->host;
  88        int err = 0;
  89
  90        inode_inc_iversion(dir);
  91        block_write_end(NULL, mapping, pos, len, len, page, NULL);
  92
  93        if (pos+len > dir->i_size) {
  94                i_size_write(dir, pos+len);
  95                mark_inode_dirty(dir);
  96        }
  97
  98        if (IS_DIRSYNC(dir)) {
  99                err = write_one_page(page);
 100                if (!err)
 101                        err = sync_inode_metadata(dir, 1);
 102        } else {
 103                unlock_page(page);
 104        }
 105
 106        return err;
 107}
 108
 109static bool ext2_check_page(struct page *page, int quiet)
 110{
 111        struct inode *dir = page->mapping->host;
 112        struct super_block *sb = dir->i_sb;
 113        unsigned chunk_size = ext2_chunk_size(dir);
 114        char *kaddr = page_address(page);
 115        u32 max_inumber = le32_to_cpu(EXT2_SB(sb)->s_es->s_inodes_count);
 116        unsigned offs, rec_len;
 117        unsigned limit = PAGE_SIZE;
 118        ext2_dirent *p;
 119        char *error;
 120
 121        if ((dir->i_size >> PAGE_SHIFT) == page->index) {
 122                limit = dir->i_size & ~PAGE_MASK;
 123                if (limit & (chunk_size - 1))
 124                        goto Ebadsize;
 125                if (!limit)
 126                        goto out;
 127        }
 128        for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
 129                p = (ext2_dirent *)(kaddr + offs);
 130                rec_len = ext2_rec_len_from_disk(p->rec_len);
 131
 132                if (unlikely(rec_len < EXT2_DIR_REC_LEN(1)))
 133                        goto Eshort;
 134                if (unlikely(rec_len & 3))
 135                        goto Ealign;
 136                if (unlikely(rec_len < EXT2_DIR_REC_LEN(p->name_len)))
 137                        goto Enamelen;
 138                if (unlikely(((offs + rec_len - 1) ^ offs) & ~(chunk_size-1)))
 139                        goto Espan;
 140                if (unlikely(le32_to_cpu(p->inode) > max_inumber))
 141                        goto Einumber;
 142        }
 143        if (offs != limit)
 144                goto Eend;
 145out:
 146        SetPageChecked(page);
 147        return true;
 148
 149        /* Too bad, we had an error */
 150
 151Ebadsize:
 152        if (!quiet)
 153                ext2_error(sb, __func__,
 154                        "size of directory #%lu is not a multiple "
 155                        "of chunk size", dir->i_ino);
 156        goto fail;
 157Eshort:
 158        error = "rec_len is smaller than minimal";
 159        goto bad_entry;
 160Ealign:
 161        error = "unaligned directory entry";
 162        goto bad_entry;
 163Enamelen:
 164        error = "rec_len is too small for name_len";
 165        goto bad_entry;
 166Espan:
 167        error = "directory entry across blocks";
 168        goto bad_entry;
 169Einumber:
 170        error = "inode out of bounds";
 171bad_entry:
 172        if (!quiet)
 173                ext2_error(sb, __func__, "bad entry in directory #%lu: : %s - "
 174                        "offset=%lu, inode=%lu, rec_len=%d, name_len=%d",
 175                        dir->i_ino, error, (page->index<<PAGE_SHIFT)+offs,
 176                        (unsigned long) le32_to_cpu(p->inode),
 177                        rec_len, p->name_len);
 178        goto fail;
 179Eend:
 180        if (!quiet) {
 181                p = (ext2_dirent *)(kaddr + offs);
 182                ext2_error(sb, "ext2_check_page",
 183                        "entry in directory #%lu spans the page boundary"
 184                        "offset=%lu, inode=%lu",
 185                        dir->i_ino, (page->index<<PAGE_SHIFT)+offs,
 186                        (unsigned long) le32_to_cpu(p->inode));
 187        }
 188fail:
 189        SetPageError(page);
 190        return false;
 191}
 192
 193static struct page * ext2_get_page(struct inode *dir, unsigned long n,
 194                                   int quiet)
 195{
 196        struct address_space *mapping = dir->i_mapping;
 197        struct page *page = read_mapping_page(mapping, n, NULL);
 198        if (!IS_ERR(page)) {
 199                kmap(page);
 200                if (unlikely(!PageChecked(page))) {
 201                        if (PageError(page) || !ext2_check_page(page, quiet))
 202                                goto fail;
 203                }
 204        }
 205        return page;
 206
 207fail:
 208        ext2_put_page(page);
 209        return ERR_PTR(-EIO);
 210}
 211
 212/*
 213 * NOTE! unlike strncmp, ext2_match returns 1 for success, 0 for failure.
 214 *
 215 * len <= EXT2_NAME_LEN and de != NULL are guaranteed by caller.
 216 */
 217static inline int ext2_match (int len, const char * const name,
 218                                        struct ext2_dir_entry_2 * de)
 219{
 220        if (len != de->name_len)
 221                return 0;
 222        if (!de->inode)
 223                return 0;
 224        return !memcmp(name, de->name, len);
 225}
 226
 227/*
 228 * p is at least 6 bytes before the end of page
 229 */
 230static inline ext2_dirent *ext2_next_entry(ext2_dirent *p)
 231{
 232        return (ext2_dirent *)((char *)p +
 233                        ext2_rec_len_from_disk(p->rec_len));
 234}
 235
 236static inline unsigned 
 237ext2_validate_entry(char *base, unsigned offset, unsigned mask)
 238{
 239        ext2_dirent *de = (ext2_dirent*)(base + offset);
 240        ext2_dirent *p = (ext2_dirent*)(base + (offset&mask));
 241        while ((char*)p < (char*)de) {
 242                if (p->rec_len == 0)
 243                        break;
 244                p = ext2_next_entry(p);
 245        }
 246        return (char *)p - base;
 247}
 248
 249static inline void ext2_set_de_type(ext2_dirent *de, struct inode *inode)
 250{
 251        if (EXT2_HAS_INCOMPAT_FEATURE(inode->i_sb, EXT2_FEATURE_INCOMPAT_FILETYPE))
 252                de->file_type = fs_umode_to_ftype(inode->i_mode);
 253        else
 254                de->file_type = 0;
 255}
 256
 257static int
 258ext2_readdir(struct file *file, struct dir_context *ctx)
 259{
 260        loff_t pos = ctx->pos;
 261        struct inode *inode = file_inode(file);
 262        struct super_block *sb = inode->i_sb;
 263        unsigned int offset = pos & ~PAGE_MASK;
 264        unsigned long n = pos >> PAGE_SHIFT;
 265        unsigned long npages = dir_pages(inode);
 266        unsigned chunk_mask = ~(ext2_chunk_size(inode)-1);
 267        bool need_revalidate = !inode_eq_iversion(inode, file->f_version);
 268        bool has_filetype;
 269
 270        if (pos > inode->i_size - EXT2_DIR_REC_LEN(1))
 271                return 0;
 272
 273        has_filetype =
 274                EXT2_HAS_INCOMPAT_FEATURE(sb, EXT2_FEATURE_INCOMPAT_FILETYPE);
 275
 276        for ( ; n < npages; n++, offset = 0) {
 277                char *kaddr, *limit;
 278                ext2_dirent *de;
 279                struct page *page = ext2_get_page(inode, n, 0);
 280
 281                if (IS_ERR(page)) {
 282                        ext2_error(sb, __func__,
 283                                   "bad page in #%lu",
 284                                   inode->i_ino);
 285                        ctx->pos += PAGE_SIZE - offset;
 286                        return PTR_ERR(page);
 287                }
 288                kaddr = page_address(page);
 289                if (unlikely(need_revalidate)) {
 290                        if (offset) {
 291                                offset = ext2_validate_entry(kaddr, offset, chunk_mask);
 292                                ctx->pos = (n<<PAGE_SHIFT) + offset;
 293                        }
 294                        file->f_version = inode_query_iversion(inode);
 295                        need_revalidate = false;
 296                }
 297                de = (ext2_dirent *)(kaddr+offset);
 298                limit = kaddr + ext2_last_byte(inode, n) - EXT2_DIR_REC_LEN(1);
 299                for ( ;(char*)de <= limit; de = ext2_next_entry(de)) {
 300                        if (de->rec_len == 0) {
 301                                ext2_error(sb, __func__,
 302                                        "zero-length directory entry");
 303                                ext2_put_page(page);
 304                                return -EIO;
 305                        }
 306                        if (de->inode) {
 307                                unsigned char d_type = DT_UNKNOWN;
 308
 309                                if (has_filetype)
 310                                        d_type = fs_ftype_to_dtype(de->file_type);
 311
 312                                if (!dir_emit(ctx, de->name, de->name_len,
 313                                                le32_to_cpu(de->inode),
 314                                                d_type)) {
 315                                        ext2_put_page(page);
 316                                        return 0;
 317                                }
 318                        }
 319                        ctx->pos += ext2_rec_len_from_disk(de->rec_len);
 320                }
 321                ext2_put_page(page);
 322        }
 323        return 0;
 324}
 325
 326/*
 327 *      ext2_find_entry()
 328 *
 329 * finds an entry in the specified directory with the wanted name. It
 330 * returns the page in which the entry was found (as a parameter - res_page),
 331 * and the entry itself. Page is returned mapped and unlocked.
 332 * Entry is guaranteed to be valid.
 333 *
 334 * On Success ext2_put_page() should be called on *res_page.
 335 */
 336struct ext2_dir_entry_2 *ext2_find_entry (struct inode *dir,
 337                        const struct qstr *child, struct page **res_page)
 338{
 339        const char *name = child->name;
 340        int namelen = child->len;
 341        unsigned reclen = EXT2_DIR_REC_LEN(namelen);
 342        unsigned long start, n;
 343        unsigned long npages = dir_pages(dir);
 344        struct page *page = NULL;
 345        struct ext2_inode_info *ei = EXT2_I(dir);
 346        ext2_dirent * de;
 347
 348        if (npages == 0)
 349                goto out;
 350
 351        /* OFFSET_CACHE */
 352        *res_page = NULL;
 353
 354        start = ei->i_dir_start_lookup;
 355        if (start >= npages)
 356                start = 0;
 357        n = start;
 358        do {
 359                char *kaddr;
 360                page = ext2_get_page(dir, n, 0);
 361                if (IS_ERR(page))
 362                        return ERR_CAST(page);
 363
 364                kaddr = page_address(page);
 365                de = (ext2_dirent *) kaddr;
 366                kaddr += ext2_last_byte(dir, n) - reclen;
 367                while ((char *) de <= kaddr) {
 368                        if (de->rec_len == 0) {
 369                                ext2_error(dir->i_sb, __func__,
 370                                        "zero-length directory entry");
 371                                ext2_put_page(page);
 372                                goto out;
 373                        }
 374                        if (ext2_match(namelen, name, de))
 375                                goto found;
 376                        de = ext2_next_entry(de);
 377                }
 378                ext2_put_page(page);
 379
 380                if (++n >= npages)
 381                        n = 0;
 382                /* next page is past the blocks we've got */
 383                if (unlikely(n > (dir->i_blocks >> (PAGE_SHIFT - 9)))) {
 384                        ext2_error(dir->i_sb, __func__,
 385                                "dir %lu size %lld exceeds block count %llu",
 386                                dir->i_ino, dir->i_size,
 387                                (unsigned long long)dir->i_blocks);
 388                        goto out;
 389                }
 390        } while (n != start);
 391out:
 392        return ERR_PTR(-ENOENT);
 393
 394found:
 395        *res_page = page;
 396        ei->i_dir_start_lookup = n;
 397        return de;
 398}
 399
 400/**
 401 * Return the '..' directory entry and the page in which the entry was found
 402 * (as a parameter - p).
 403 *
 404 * On Success ext2_put_page() should be called on *p.
 405 */
 406struct ext2_dir_entry_2 * ext2_dotdot (struct inode *dir, struct page **p)
 407{
 408        struct page *page = ext2_get_page(dir, 0, 0);
 409        ext2_dirent *de = NULL;
 410
 411        if (!IS_ERR(page)) {
 412                de = ext2_next_entry((ext2_dirent *) page_address(page));
 413                *p = page;
 414        }
 415        return de;
 416}
 417
 418int ext2_inode_by_name(struct inode *dir, const struct qstr *child, ino_t *ino)
 419{
 420        struct ext2_dir_entry_2 *de;
 421        struct page *page;
 422        
 423        de = ext2_find_entry(dir, child, &page);
 424        if (IS_ERR(de))
 425                return PTR_ERR(de);
 426
 427        *ino = le32_to_cpu(de->inode);
 428        ext2_put_page(page);
 429        return 0;
 430}
 431
 432static int ext2_prepare_chunk(struct page *page, loff_t pos, unsigned len)
 433{
 434        return __block_write_begin(page, pos, len, ext2_get_block);
 435}
 436
 437/* Releases the page */
 438void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
 439                   struct page *page, struct inode *inode, int update_times)
 440{
 441        loff_t pos = page_offset(page) +
 442                        (char *) de - (char *) page_address(page);
 443        unsigned len = ext2_rec_len_from_disk(de->rec_len);
 444        int err;
 445
 446        lock_page(page);
 447        err = ext2_prepare_chunk(page, pos, len);
 448        BUG_ON(err);
 449        de->inode = cpu_to_le32(inode->i_ino);
 450        ext2_set_de_type(de, inode);
 451        err = ext2_commit_chunk(page, pos, len);
 452        ext2_put_page(page);
 453        if (update_times)
 454                dir->i_mtime = dir->i_ctime = current_time(dir);
 455        EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
 456        mark_inode_dirty(dir);
 457}
 458
 459/*
 460 *      Parent is locked.
 461 */
 462int ext2_add_link (struct dentry *dentry, struct inode *inode)
 463{
 464        struct inode *dir = d_inode(dentry->d_parent);
 465        const char *name = dentry->d_name.name;
 466        int namelen = dentry->d_name.len;
 467        unsigned chunk_size = ext2_chunk_size(dir);
 468        unsigned reclen = EXT2_DIR_REC_LEN(namelen);
 469        unsigned short rec_len, name_len;
 470        struct page *page = NULL;
 471        ext2_dirent * de;
 472        unsigned long npages = dir_pages(dir);
 473        unsigned long n;
 474        char *kaddr;
 475        loff_t pos;
 476        int err;
 477
 478        /*
 479         * We take care of directory expansion in the same loop.
 480         * This code plays outside i_size, so it locks the page
 481         * to protect that region.
 482         */
 483        for (n = 0; n <= npages; n++) {
 484                char *dir_end;
 485
 486                page = ext2_get_page(dir, n, 0);
 487                err = PTR_ERR(page);
 488                if (IS_ERR(page))
 489                        goto out;
 490                lock_page(page);
 491                kaddr = page_address(page);
 492                dir_end = kaddr + ext2_last_byte(dir, n);
 493                de = (ext2_dirent *)kaddr;
 494                kaddr += PAGE_SIZE - reclen;
 495                while ((char *)de <= kaddr) {
 496                        if ((char *)de == dir_end) {
 497                                /* We hit i_size */
 498                                name_len = 0;
 499                                rec_len = chunk_size;
 500                                de->rec_len = ext2_rec_len_to_disk(chunk_size);
 501                                de->inode = 0;
 502                                goto got_it;
 503                        }
 504                        if (de->rec_len == 0) {
 505                                ext2_error(dir->i_sb, __func__,
 506                                        "zero-length directory entry");
 507                                err = -EIO;
 508                                goto out_unlock;
 509                        }
 510                        err = -EEXIST;
 511                        if (ext2_match (namelen, name, de))
 512                                goto out_unlock;
 513                        name_len = EXT2_DIR_REC_LEN(de->name_len);
 514                        rec_len = ext2_rec_len_from_disk(de->rec_len);
 515                        if (!de->inode && rec_len >= reclen)
 516                                goto got_it;
 517                        if (rec_len >= name_len + reclen)
 518                                goto got_it;
 519                        de = (ext2_dirent *) ((char *) de + rec_len);
 520                }
 521                unlock_page(page);
 522                ext2_put_page(page);
 523        }
 524        BUG();
 525        return -EINVAL;
 526
 527got_it:
 528        pos = page_offset(page) +
 529                (char*)de - (char*)page_address(page);
 530        err = ext2_prepare_chunk(page, pos, rec_len);
 531        if (err)
 532                goto out_unlock;
 533        if (de->inode) {
 534                ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
 535                de1->rec_len = ext2_rec_len_to_disk(rec_len - name_len);
 536                de->rec_len = ext2_rec_len_to_disk(name_len);
 537                de = de1;
 538        }
 539        de->name_len = namelen;
 540        memcpy(de->name, name, namelen);
 541        de->inode = cpu_to_le32(inode->i_ino);
 542        ext2_set_de_type (de, inode);
 543        err = ext2_commit_chunk(page, pos, rec_len);
 544        dir->i_mtime = dir->i_ctime = current_time(dir);
 545        EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
 546        mark_inode_dirty(dir);
 547        /* OFFSET_CACHE */
 548out_put:
 549        ext2_put_page(page);
 550out:
 551        return err;
 552out_unlock:
 553        unlock_page(page);
 554        goto out_put;
 555}
 556
 557/*
 558 * ext2_delete_entry deletes a directory entry by merging it with the
 559 * previous entry. Page is up-to-date. Releases the page.
 560 */
 561int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
 562{
 563        struct inode *inode = page->mapping->host;
 564        char *kaddr = page_address(page);
 565        unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
 566        unsigned to = ((char *)dir - kaddr) +
 567                                ext2_rec_len_from_disk(dir->rec_len);
 568        loff_t pos;
 569        ext2_dirent * pde = NULL;
 570        ext2_dirent * de = (ext2_dirent *) (kaddr + from);
 571        int err;
 572
 573        while ((char*)de < (char*)dir) {
 574                if (de->rec_len == 0) {
 575                        ext2_error(inode->i_sb, __func__,
 576                                "zero-length directory entry");
 577                        err = -EIO;
 578                        goto out;
 579                }
 580                pde = de;
 581                de = ext2_next_entry(de);
 582        }
 583        if (pde)
 584                from = (char*)pde - (char*)page_address(page);
 585        pos = page_offset(page) + from;
 586        lock_page(page);
 587        err = ext2_prepare_chunk(page, pos, to - from);
 588        BUG_ON(err);
 589        if (pde)
 590                pde->rec_len = ext2_rec_len_to_disk(to - from);
 591        dir->inode = 0;
 592        err = ext2_commit_chunk(page, pos, to - from);
 593        inode->i_ctime = inode->i_mtime = current_time(inode);
 594        EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
 595        mark_inode_dirty(inode);
 596out:
 597        ext2_put_page(page);
 598        return err;
 599}
 600
 601/*
 602 * Set the first fragment of directory.
 603 */
 604int ext2_make_empty(struct inode *inode, struct inode *parent)
 605{
 606        struct page *page = grab_cache_page(inode->i_mapping, 0);
 607        unsigned chunk_size = ext2_chunk_size(inode);
 608        struct ext2_dir_entry_2 * de;
 609        int err;
 610        void *kaddr;
 611
 612        if (!page)
 613                return -ENOMEM;
 614
 615        err = ext2_prepare_chunk(page, 0, chunk_size);
 616        if (err) {
 617                unlock_page(page);
 618                goto fail;
 619        }
 620        kaddr = kmap_atomic(page);
 621        memset(kaddr, 0, chunk_size);
 622        de = (struct ext2_dir_entry_2 *)kaddr;
 623        de->name_len = 1;
 624        de->rec_len = ext2_rec_len_to_disk(EXT2_DIR_REC_LEN(1));
 625        memcpy (de->name, ".\0\0", 4);
 626        de->inode = cpu_to_le32(inode->i_ino);
 627        ext2_set_de_type (de, inode);
 628
 629        de = (struct ext2_dir_entry_2 *)(kaddr + EXT2_DIR_REC_LEN(1));
 630        de->name_len = 2;
 631        de->rec_len = ext2_rec_len_to_disk(chunk_size - EXT2_DIR_REC_LEN(1));
 632        de->inode = cpu_to_le32(parent->i_ino);
 633        memcpy (de->name, "..\0", 4);
 634        ext2_set_de_type (de, inode);
 635        kunmap_atomic(kaddr);
 636        err = ext2_commit_chunk(page, 0, chunk_size);
 637fail:
 638        put_page(page);
 639        return err;
 640}
 641
 642/*
 643 * routine to check that the specified directory is empty (for rmdir)
 644 */
 645int ext2_empty_dir (struct inode * inode)
 646{
 647        struct page *page = NULL;
 648        unsigned long i, npages = dir_pages(inode);
 649        int dir_has_error = 0;
 650
 651        for (i = 0; i < npages; i++) {
 652                char *kaddr;
 653                ext2_dirent * de;
 654                page = ext2_get_page(inode, i, dir_has_error);
 655
 656                if (IS_ERR(page)) {
 657                        dir_has_error = 1;
 658                        continue;
 659                }
 660
 661                kaddr = page_address(page);
 662                de = (ext2_dirent *)kaddr;
 663                kaddr += ext2_last_byte(inode, i) - EXT2_DIR_REC_LEN(1);
 664
 665                while ((char *)de <= kaddr) {
 666                        if (de->rec_len == 0) {
 667                                ext2_error(inode->i_sb, __func__,
 668                                        "zero-length directory entry");
 669                                printk("kaddr=%p, de=%p\n", kaddr, de);
 670                                goto not_empty;
 671                        }
 672                        if (de->inode != 0) {
 673                                /* check for . and .. */
 674                                if (de->name[0] != '.')
 675                                        goto not_empty;
 676                                if (de->name_len > 2)
 677                                        goto not_empty;
 678                                if (de->name_len < 2) {
 679                                        if (de->inode !=
 680                                            cpu_to_le32(inode->i_ino))
 681                                                goto not_empty;
 682                                } else if (de->name[1] != '.')
 683                                        goto not_empty;
 684                        }
 685                        de = ext2_next_entry(de);
 686                }
 687                ext2_put_page(page);
 688        }
 689        return 1;
 690
 691not_empty:
 692        ext2_put_page(page);
 693        return 0;
 694}
 695
 696const struct file_operations ext2_dir_operations = {
 697        .llseek         = generic_file_llseek,
 698        .read           = generic_read_dir,
 699        .iterate_shared = ext2_readdir,
 700        .unlocked_ioctl = ext2_ioctl,
 701#ifdef CONFIG_COMPAT
 702        .compat_ioctl   = ext2_compat_ioctl,
 703#endif
 704        .fsync          = ext2_fsync,
 705};
 706