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