linux/fs/exofs/dir.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2005, 2006
   3 * Avishay Traeger (avishay@gmail.com)
   4 * Copyright (C) 2008, 2009
   5 * Boaz Harrosh <ooo@electrozaur.com>
   6 *
   7 * Copyrights for code taken from ext2:
   8 *     Copyright (C) 1992, 1993, 1994, 1995
   9 *     Remy Card (card@masi.ibp.fr)
  10 *     Laboratoire MASI - Institut Blaise Pascal
  11 *     Universite Pierre et Marie Curie (Paris VI)
  12 *     from
  13 *     linux/fs/minix/inode.c
  14 *     Copyright (C) 1991, 1992  Linus Torvalds
  15 *
  16 * This file is part of exofs.
  17 *
  18 * exofs is free software; you can redistribute it and/or modify
  19 * it under the terms of the GNU General Public License as published by
  20 * the Free Software Foundation.  Since it is based on ext2, and the only
  21 * valid version of GPL for the Linux kernel is version 2, the only valid
  22 * version of GPL for exofs is version 2.
  23 *
  24 * exofs is distributed in the hope that it will be useful,
  25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27 * GNU General Public License for more details.
  28 *
  29 * You should have received a copy of the GNU General Public License
  30 * along with exofs; if not, write to the Free Software
  31 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  32 */
  33
  34#include <linux/iversion.h>
  35#include "exofs.h"
  36
  37static inline unsigned exofs_chunk_size(struct inode *inode)
  38{
  39        return inode->i_sb->s_blocksize;
  40}
  41
  42static inline void exofs_put_page(struct page *page)
  43{
  44        kunmap(page);
  45        put_page(page);
  46}
  47
  48static unsigned exofs_last_byte(struct inode *inode, unsigned long page_nr)
  49{
  50        loff_t last_byte = inode->i_size;
  51
  52        last_byte -= page_nr << PAGE_SHIFT;
  53        if (last_byte > PAGE_SIZE)
  54                last_byte = PAGE_SIZE;
  55        return last_byte;
  56}
  57
  58static int exofs_commit_chunk(struct page *page, loff_t pos, unsigned len)
  59{
  60        struct address_space *mapping = page->mapping;
  61        struct inode *dir = mapping->host;
  62        int err = 0;
  63
  64        inode_inc_iversion(dir);
  65
  66        if (!PageUptodate(page))
  67                SetPageUptodate(page);
  68
  69        if (pos+len > dir->i_size) {
  70                i_size_write(dir, pos+len);
  71                mark_inode_dirty(dir);
  72        }
  73        set_page_dirty(page);
  74
  75        if (IS_DIRSYNC(dir))
  76                err = write_one_page(page);
  77        else
  78                unlock_page(page);
  79
  80        return err;
  81}
  82
  83static bool exofs_check_page(struct page *page)
  84{
  85        struct inode *dir = page->mapping->host;
  86        unsigned chunk_size = exofs_chunk_size(dir);
  87        char *kaddr = page_address(page);
  88        unsigned offs, rec_len;
  89        unsigned limit = PAGE_SIZE;
  90        struct exofs_dir_entry *p;
  91        char *error;
  92
  93        /* if the page is the last one in the directory */
  94        if ((dir->i_size >> PAGE_SHIFT) == page->index) {
  95                limit = dir->i_size & ~PAGE_MASK;
  96                if (limit & (chunk_size - 1))
  97                        goto Ebadsize;
  98                if (!limit)
  99                        goto out;
 100        }
 101        for (offs = 0; offs <= limit - EXOFS_DIR_REC_LEN(1); offs += rec_len) {
 102                p = (struct exofs_dir_entry *)(kaddr + offs);
 103                rec_len = le16_to_cpu(p->rec_len);
 104
 105                if (rec_len < EXOFS_DIR_REC_LEN(1))
 106                        goto Eshort;
 107                if (rec_len & 3)
 108                        goto Ealign;
 109                if (rec_len < EXOFS_DIR_REC_LEN(p->name_len))
 110                        goto Enamelen;
 111                if (((offs + rec_len - 1) ^ offs) & ~(chunk_size-1))
 112                        goto Espan;
 113        }
 114        if (offs != limit)
 115                goto Eend;
 116out:
 117        SetPageChecked(page);
 118        return true;
 119
 120Ebadsize:
 121        EXOFS_ERR("ERROR [exofs_check_page]: "
 122                "size of directory(0x%lx) is not a multiple of chunk size\n",
 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;
 138bad_entry:
 139        EXOFS_ERR(
 140                "ERROR [exofs_check_page]: bad entry in directory(0x%lx): %s - "
 141                "offset=%lu, inode=0x%llx, rec_len=%d, name_len=%d\n",
 142                dir->i_ino, error, (page->index<<PAGE_SHIFT)+offs,
 143                _LLU(le64_to_cpu(p->inode_no)),
 144                rec_len, p->name_len);
 145        goto fail;
 146Eend:
 147        p = (struct exofs_dir_entry *)(kaddr + offs);
 148        EXOFS_ERR("ERROR [exofs_check_page]: "
 149                "entry in directory(0x%lx) spans the page boundary"
 150                "offset=%lu, inode=0x%llx\n",
 151                dir->i_ino, (page->index<<PAGE_SHIFT)+offs,
 152                _LLU(le64_to_cpu(p->inode_no)));
 153fail:
 154        SetPageError(page);
 155        return false;
 156}
 157
 158static struct page *exofs_get_page(struct inode *dir, unsigned long n)
 159{
 160        struct address_space *mapping = dir->i_mapping;
 161        struct page *page = read_mapping_page(mapping, n, NULL);
 162
 163        if (!IS_ERR(page)) {
 164                kmap(page);
 165                if (unlikely(!PageChecked(page))) {
 166                        if (PageError(page) || !exofs_check_page(page))
 167                                goto fail;
 168                }
 169        }
 170        return page;
 171
 172fail:
 173        exofs_put_page(page);
 174        return ERR_PTR(-EIO);
 175}
 176
 177static inline int exofs_match(int len, const unsigned char *name,
 178                                        struct exofs_dir_entry *de)
 179{
 180        if (len != de->name_len)
 181                return 0;
 182        if (!de->inode_no)
 183                return 0;
 184        return !memcmp(name, de->name, len);
 185}
 186
 187static inline
 188struct exofs_dir_entry *exofs_next_entry(struct exofs_dir_entry *p)
 189{
 190        return (struct exofs_dir_entry *)((char *)p + le16_to_cpu(p->rec_len));
 191}
 192
 193static inline unsigned
 194exofs_validate_entry(char *base, unsigned offset, unsigned mask)
 195{
 196        struct exofs_dir_entry *de = (struct exofs_dir_entry *)(base + offset);
 197        struct exofs_dir_entry *p =
 198                        (struct exofs_dir_entry *)(base + (offset&mask));
 199        while ((char *)p < (char *)de) {
 200                if (p->rec_len == 0)
 201                        break;
 202                p = exofs_next_entry(p);
 203        }
 204        return (char *)p - base;
 205}
 206
 207static unsigned char exofs_filetype_table[EXOFS_FT_MAX] = {
 208        [EXOFS_FT_UNKNOWN]      = DT_UNKNOWN,
 209        [EXOFS_FT_REG_FILE]     = DT_REG,
 210        [EXOFS_FT_DIR]          = DT_DIR,
 211        [EXOFS_FT_CHRDEV]       = DT_CHR,
 212        [EXOFS_FT_BLKDEV]       = DT_BLK,
 213        [EXOFS_FT_FIFO]         = DT_FIFO,
 214        [EXOFS_FT_SOCK]         = DT_SOCK,
 215        [EXOFS_FT_SYMLINK]      = DT_LNK,
 216};
 217
 218#define S_SHIFT 12
 219static unsigned char exofs_type_by_mode[S_IFMT >> S_SHIFT] = {
 220        [S_IFREG >> S_SHIFT]    = EXOFS_FT_REG_FILE,
 221        [S_IFDIR >> S_SHIFT]    = EXOFS_FT_DIR,
 222        [S_IFCHR >> S_SHIFT]    = EXOFS_FT_CHRDEV,
 223        [S_IFBLK >> S_SHIFT]    = EXOFS_FT_BLKDEV,
 224        [S_IFIFO >> S_SHIFT]    = EXOFS_FT_FIFO,
 225        [S_IFSOCK >> S_SHIFT]   = EXOFS_FT_SOCK,
 226        [S_IFLNK >> S_SHIFT]    = EXOFS_FT_SYMLINK,
 227};
 228
 229static inline
 230void exofs_set_de_type(struct exofs_dir_entry *de, struct inode *inode)
 231{
 232        umode_t mode = inode->i_mode;
 233        de->file_type = exofs_type_by_mode[(mode & S_IFMT) >> S_SHIFT];
 234}
 235
 236static int
 237exofs_readdir(struct file *file, struct dir_context *ctx)
 238{
 239        loff_t pos = ctx->pos;
 240        struct inode *inode = file_inode(file);
 241        unsigned int offset = pos & ~PAGE_MASK;
 242        unsigned long n = pos >> PAGE_SHIFT;
 243        unsigned long npages = dir_pages(inode);
 244        unsigned chunk_mask = ~(exofs_chunk_size(inode)-1);
 245        bool need_revalidate = !inode_eq_iversion(inode, file->f_version);
 246
 247        if (pos > inode->i_size - EXOFS_DIR_REC_LEN(1))
 248                return 0;
 249
 250        for ( ; n < npages; n++, offset = 0) {
 251                char *kaddr, *limit;
 252                struct exofs_dir_entry *de;
 253                struct page *page = exofs_get_page(inode, n);
 254
 255                if (IS_ERR(page)) {
 256                        EXOFS_ERR("ERROR: bad page in directory(0x%lx)\n",
 257                                  inode->i_ino);
 258                        ctx->pos += PAGE_SIZE - offset;
 259                        return PTR_ERR(page);
 260                }
 261                kaddr = page_address(page);
 262                if (unlikely(need_revalidate)) {
 263                        if (offset) {
 264                                offset = exofs_validate_entry(kaddr, offset,
 265                                                                chunk_mask);
 266                                ctx->pos = (n<<PAGE_SHIFT) + offset;
 267                        }
 268                        file->f_version = inode_query_iversion(inode);
 269                        need_revalidate = false;
 270                }
 271                de = (struct exofs_dir_entry *)(kaddr + offset);
 272                limit = kaddr + exofs_last_byte(inode, n) -
 273                                                        EXOFS_DIR_REC_LEN(1);
 274                for (; (char *)de <= limit; de = exofs_next_entry(de)) {
 275                        if (de->rec_len == 0) {
 276                                EXOFS_ERR("ERROR: "
 277                                     "zero-length entry in directory(0x%lx)\n",
 278                                     inode->i_ino);
 279                                exofs_put_page(page);
 280                                return -EIO;
 281                        }
 282                        if (de->inode_no) {
 283                                unsigned char t;
 284
 285                                if (de->file_type < EXOFS_FT_MAX)
 286                                        t = exofs_filetype_table[de->file_type];
 287                                else
 288                                        t = DT_UNKNOWN;
 289
 290                                if (!dir_emit(ctx, de->name, de->name_len,
 291                                                le64_to_cpu(de->inode_no),
 292                                                t)) {
 293                                        exofs_put_page(page);
 294                                        return 0;
 295                                }
 296                        }
 297                        ctx->pos += le16_to_cpu(de->rec_len);
 298                }
 299                exofs_put_page(page);
 300        }
 301        return 0;
 302}
 303
 304struct exofs_dir_entry *exofs_find_entry(struct inode *dir,
 305                        struct dentry *dentry, struct page **res_page)
 306{
 307        const unsigned char *name = dentry->d_name.name;
 308        int namelen = dentry->d_name.len;
 309        unsigned reclen = EXOFS_DIR_REC_LEN(namelen);
 310        unsigned long start, n;
 311        unsigned long npages = dir_pages(dir);
 312        struct page *page = NULL;
 313        struct exofs_i_info *oi = exofs_i(dir);
 314        struct exofs_dir_entry *de;
 315
 316        if (npages == 0)
 317                goto out;
 318
 319        *res_page = NULL;
 320
 321        start = oi->i_dir_start_lookup;
 322        if (start >= npages)
 323                start = 0;
 324        n = start;
 325        do {
 326                char *kaddr;
 327                page = exofs_get_page(dir, n);
 328                if (!IS_ERR(page)) {
 329                        kaddr = page_address(page);
 330                        de = (struct exofs_dir_entry *) kaddr;
 331                        kaddr += exofs_last_byte(dir, n) - reclen;
 332                        while ((char *) de <= kaddr) {
 333                                if (de->rec_len == 0) {
 334                                        EXOFS_ERR("ERROR: zero-length entry in "
 335                                                  "directory(0x%lx)\n",
 336                                                  dir->i_ino);
 337                                        exofs_put_page(page);
 338                                        goto out;
 339                                }
 340                                if (exofs_match(namelen, name, de))
 341                                        goto found;
 342                                de = exofs_next_entry(de);
 343                        }
 344                        exofs_put_page(page);
 345                }
 346                if (++n >= npages)
 347                        n = 0;
 348        } while (n != start);
 349out:
 350        return NULL;
 351
 352found:
 353        *res_page = page;
 354        oi->i_dir_start_lookup = n;
 355        return de;
 356}
 357
 358struct exofs_dir_entry *exofs_dotdot(struct inode *dir, struct page **p)
 359{
 360        struct page *page = exofs_get_page(dir, 0);
 361        struct exofs_dir_entry *de = NULL;
 362
 363        if (!IS_ERR(page)) {
 364                de = exofs_next_entry(
 365                                (struct exofs_dir_entry *)page_address(page));
 366                *p = page;
 367        }
 368        return de;
 369}
 370
 371ino_t exofs_parent_ino(struct dentry *child)
 372{
 373        struct page *page;
 374        struct exofs_dir_entry *de;
 375        ino_t ino;
 376
 377        de = exofs_dotdot(d_inode(child), &page);
 378        if (!de)
 379                return 0;
 380
 381        ino = le64_to_cpu(de->inode_no);
 382        exofs_put_page(page);
 383        return ino;
 384}
 385
 386ino_t exofs_inode_by_name(struct inode *dir, struct dentry *dentry)
 387{
 388        ino_t res = 0;
 389        struct exofs_dir_entry *de;
 390        struct page *page;
 391
 392        de = exofs_find_entry(dir, dentry, &page);
 393        if (de) {
 394                res = le64_to_cpu(de->inode_no);
 395                exofs_put_page(page);
 396        }
 397        return res;
 398}
 399
 400int exofs_set_link(struct inode *dir, struct exofs_dir_entry *de,
 401                        struct page *page, struct inode *inode)
 402{
 403        loff_t pos = page_offset(page) +
 404                        (char *) de - (char *) page_address(page);
 405        unsigned len = le16_to_cpu(de->rec_len);
 406        int err;
 407
 408        lock_page(page);
 409        err = exofs_write_begin(NULL, page->mapping, pos, len, 0, &page, NULL);
 410        if (err)
 411                EXOFS_ERR("exofs_set_link: exofs_write_begin FAILED => %d\n",
 412                          err);
 413
 414        de->inode_no = cpu_to_le64(inode->i_ino);
 415        exofs_set_de_type(de, inode);
 416        if (likely(!err))
 417                err = exofs_commit_chunk(page, pos, len);
 418        exofs_put_page(page);
 419        dir->i_mtime = dir->i_ctime = current_time(dir);
 420        mark_inode_dirty(dir);
 421        return err;
 422}
 423
 424int exofs_add_link(struct dentry *dentry, struct inode *inode)
 425{
 426        struct inode *dir = d_inode(dentry->d_parent);
 427        const unsigned char *name = dentry->d_name.name;
 428        int namelen = dentry->d_name.len;
 429        unsigned chunk_size = exofs_chunk_size(dir);
 430        unsigned reclen = EXOFS_DIR_REC_LEN(namelen);
 431        unsigned short rec_len, name_len;
 432        struct page *page = NULL;
 433        struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
 434        struct exofs_dir_entry *de;
 435        unsigned long npages = dir_pages(dir);
 436        unsigned long n;
 437        char *kaddr;
 438        loff_t pos;
 439        int err;
 440
 441        for (n = 0; n <= npages; n++) {
 442                char *dir_end;
 443
 444                page = exofs_get_page(dir, n);
 445                err = PTR_ERR(page);
 446                if (IS_ERR(page))
 447                        goto out;
 448                lock_page(page);
 449                kaddr = page_address(page);
 450                dir_end = kaddr + exofs_last_byte(dir, n);
 451                de = (struct exofs_dir_entry *)kaddr;
 452                kaddr += PAGE_SIZE - reclen;
 453                while ((char *)de <= kaddr) {
 454                        if ((char *)de == dir_end) {
 455                                name_len = 0;
 456                                rec_len = chunk_size;
 457                                de->rec_len = cpu_to_le16(chunk_size);
 458                                de->inode_no = 0;
 459                                goto got_it;
 460                        }
 461                        if (de->rec_len == 0) {
 462                                EXOFS_ERR("ERROR: exofs_add_link: "
 463                                      "zero-length entry in directory(0x%lx)\n",
 464                                      inode->i_ino);
 465                                err = -EIO;
 466                                goto out_unlock;
 467                        }
 468                        err = -EEXIST;
 469                        if (exofs_match(namelen, name, de))
 470                                goto out_unlock;
 471                        name_len = EXOFS_DIR_REC_LEN(de->name_len);
 472                        rec_len = le16_to_cpu(de->rec_len);
 473                        if (!de->inode_no && rec_len >= reclen)
 474                                goto got_it;
 475                        if (rec_len >= name_len + reclen)
 476                                goto got_it;
 477                        de = (struct exofs_dir_entry *) ((char *) de + rec_len);
 478                }
 479                unlock_page(page);
 480                exofs_put_page(page);
 481        }
 482
 483        EXOFS_ERR("exofs_add_link: BAD dentry=%p or inode=0x%lx\n",
 484                  dentry, inode->i_ino);
 485        return -EINVAL;
 486
 487got_it:
 488        pos = page_offset(page) +
 489                (char *)de - (char *)page_address(page);
 490        err = exofs_write_begin(NULL, page->mapping, pos, rec_len, 0,
 491                                                        &page, NULL);
 492        if (err)
 493                goto out_unlock;
 494        if (de->inode_no) {
 495                struct exofs_dir_entry *de1 =
 496                        (struct exofs_dir_entry *)((char *)de + name_len);
 497                de1->rec_len = cpu_to_le16(rec_len - name_len);
 498                de->rec_len = cpu_to_le16(name_len);
 499                de = de1;
 500        }
 501        de->name_len = namelen;
 502        memcpy(de->name, name, namelen);
 503        de->inode_no = cpu_to_le64(inode->i_ino);
 504        exofs_set_de_type(de, inode);
 505        err = exofs_commit_chunk(page, pos, rec_len);
 506        dir->i_mtime = dir->i_ctime = current_time(dir);
 507        mark_inode_dirty(dir);
 508        sbi->s_numfiles++;
 509
 510out_put:
 511        exofs_put_page(page);
 512out:
 513        return err;
 514out_unlock:
 515        unlock_page(page);
 516        goto out_put;
 517}
 518
 519int exofs_delete_entry(struct exofs_dir_entry *dir, struct page *page)
 520{
 521        struct address_space *mapping = page->mapping;
 522        struct inode *inode = mapping->host;
 523        struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
 524        char *kaddr = page_address(page);
 525        unsigned from = ((char *)dir - kaddr) & ~(exofs_chunk_size(inode)-1);
 526        unsigned to = ((char *)dir - kaddr) + le16_to_cpu(dir->rec_len);
 527        loff_t pos;
 528        struct exofs_dir_entry *pde = NULL;
 529        struct exofs_dir_entry *de = (struct exofs_dir_entry *) (kaddr + from);
 530        int err;
 531
 532        while (de < dir) {
 533                if (de->rec_len == 0) {
 534                        EXOFS_ERR("ERROR: exofs_delete_entry:"
 535                                  "zero-length entry in directory(0x%lx)\n",
 536                                  inode->i_ino);
 537                        err = -EIO;
 538                        goto out;
 539                }
 540                pde = de;
 541                de = exofs_next_entry(de);
 542        }
 543        if (pde)
 544                from = (char *)pde - (char *)page_address(page);
 545        pos = page_offset(page) + from;
 546        lock_page(page);
 547        err = exofs_write_begin(NULL, page->mapping, pos, to - from, 0,
 548                                                        &page, NULL);
 549        if (err)
 550                EXOFS_ERR("exofs_delete_entry: exofs_write_begin FAILED => %d\n",
 551                          err);
 552        if (pde)
 553                pde->rec_len = cpu_to_le16(to - from);
 554        dir->inode_no = 0;
 555        if (likely(!err))
 556                err = exofs_commit_chunk(page, pos, to - from);
 557        inode->i_ctime = inode->i_mtime = current_time(inode);
 558        mark_inode_dirty(inode);
 559        sbi->s_numfiles--;
 560out:
 561        exofs_put_page(page);
 562        return err;
 563}
 564
 565/* kept aligned on 4 bytes */
 566#define THIS_DIR ".\0\0"
 567#define PARENT_DIR "..\0"
 568
 569int exofs_make_empty(struct inode *inode, struct inode *parent)
 570{
 571        struct address_space *mapping = inode->i_mapping;
 572        struct page *page = grab_cache_page(mapping, 0);
 573        unsigned chunk_size = exofs_chunk_size(inode);
 574        struct exofs_dir_entry *de;
 575        int err;
 576        void *kaddr;
 577
 578        if (!page)
 579                return -ENOMEM;
 580
 581        err = exofs_write_begin(NULL, page->mapping, 0, chunk_size, 0,
 582                                                        &page, NULL);
 583        if (err) {
 584                unlock_page(page);
 585                goto fail;
 586        }
 587
 588        kaddr = kmap_atomic(page);
 589        de = (struct exofs_dir_entry *)kaddr;
 590        de->name_len = 1;
 591        de->rec_len = cpu_to_le16(EXOFS_DIR_REC_LEN(1));
 592        memcpy(de->name, THIS_DIR, sizeof(THIS_DIR));
 593        de->inode_no = cpu_to_le64(inode->i_ino);
 594        exofs_set_de_type(de, inode);
 595
 596        de = (struct exofs_dir_entry *)(kaddr + EXOFS_DIR_REC_LEN(1));
 597        de->name_len = 2;
 598        de->rec_len = cpu_to_le16(chunk_size - EXOFS_DIR_REC_LEN(1));
 599        de->inode_no = cpu_to_le64(parent->i_ino);
 600        memcpy(de->name, PARENT_DIR, sizeof(PARENT_DIR));
 601        exofs_set_de_type(de, inode);
 602        kunmap_atomic(kaddr);
 603        err = exofs_commit_chunk(page, 0, chunk_size);
 604fail:
 605        put_page(page);
 606        return err;
 607}
 608
 609int exofs_empty_dir(struct inode *inode)
 610{
 611        struct page *page = NULL;
 612        unsigned long i, npages = dir_pages(inode);
 613
 614        for (i = 0; i < npages; i++) {
 615                char *kaddr;
 616                struct exofs_dir_entry *de;
 617                page = exofs_get_page(inode, i);
 618
 619                if (IS_ERR(page))
 620                        continue;
 621
 622                kaddr = page_address(page);
 623                de = (struct exofs_dir_entry *)kaddr;
 624                kaddr += exofs_last_byte(inode, i) - EXOFS_DIR_REC_LEN(1);
 625
 626                while ((char *)de <= kaddr) {
 627                        if (de->rec_len == 0) {
 628                                EXOFS_ERR("ERROR: exofs_empty_dir: "
 629                                          "zero-length directory entry"
 630                                          "kaddr=%p, de=%p\n", kaddr, de);
 631                                goto not_empty;
 632                        }
 633                        if (de->inode_no != 0) {
 634                                /* check for . and .. */
 635                                if (de->name[0] != '.')
 636                                        goto not_empty;
 637                                if (de->name_len > 2)
 638                                        goto not_empty;
 639                                if (de->name_len < 2) {
 640                                        if (le64_to_cpu(de->inode_no) !=
 641                                            inode->i_ino)
 642                                                goto not_empty;
 643                                } else if (de->name[1] != '.')
 644                                        goto not_empty;
 645                        }
 646                        de = exofs_next_entry(de);
 647                }
 648                exofs_put_page(page);
 649        }
 650        return 1;
 651
 652not_empty:
 653        exofs_put_page(page);
 654        return 0;
 655}
 656
 657const struct file_operations exofs_dir_operations = {
 658        .llseek         = generic_file_llseek,
 659        .read           = generic_read_dir,
 660        .iterate_shared = exofs_readdir,
 661};
 662