linux/fs/ufs/dir.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/ufs/ufs_dir.c
   3 *
   4 * Copyright (C) 1996
   5 * Adrian Rodriguez (adrian@franklins-tower.rutgers.edu)
   6 * Laboratory for Computer Science Research Computing Facility
   7 * Rutgers, The State University of New Jersey
   8 *
   9 * swab support by Francois-Rene Rideau <fare@tunes.org> 19970406
  10 *
  11 * 4.4BSD (FreeBSD) support added on February 1st 1998 by
  12 * Niels Kristian Bech Jensen <nkbj@image.dk> partially based
  13 * on code by Martin von Loewis <martin@mira.isdn.cs.tu-berlin.de>.
  14 *
  15 * Migration to usage of "page cache" on May 2006 by
  16 * Evgeniy Dushistov <dushistov@mail.ru> based on ext2 code base.
  17 */
  18
  19#include <linux/time.h>
  20#include <linux/fs.h>
  21#include <linux/swap.h>
  22
  23#include "ufs_fs.h"
  24#include "ufs.h"
  25#include "swab.h"
  26#include "util.h"
  27
  28/*
  29 * NOTE! unlike strncmp, ufs_match returns 1 for success, 0 for failure.
  30 *
  31 * len <= UFS_MAXNAMLEN and de != NULL are guaranteed by caller.
  32 */
  33static inline int ufs_match(struct super_block *sb, int len,
  34                const unsigned char *name, struct ufs_dir_entry *de)
  35{
  36        if (len != ufs_get_de_namlen(sb, de))
  37                return 0;
  38        if (!de->d_ino)
  39                return 0;
  40        return !memcmp(name, de->d_name, len);
  41}
  42
  43static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
  44{
  45        struct address_space *mapping = page->mapping;
  46        struct inode *dir = mapping->host;
  47        int err = 0;
  48
  49        dir->i_version++;
  50        block_write_end(NULL, mapping, pos, len, len, page, NULL);
  51        if (pos+len > dir->i_size) {
  52                i_size_write(dir, pos+len);
  53                mark_inode_dirty(dir);
  54        }
  55        if (IS_DIRSYNC(dir))
  56                err = write_one_page(page, 1);
  57        else
  58                unlock_page(page);
  59        return err;
  60}
  61
  62static inline void ufs_put_page(struct page *page)
  63{
  64        kunmap(page);
  65        page_cache_release(page);
  66}
  67
  68static inline unsigned long ufs_dir_pages(struct inode *inode)
  69{
  70        return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
  71}
  72
  73ino_t ufs_inode_by_name(struct inode *dir, const struct qstr *qstr)
  74{
  75        ino_t res = 0;
  76        struct ufs_dir_entry *de;
  77        struct page *page;
  78        
  79        de = ufs_find_entry(dir, qstr, &page);
  80        if (de) {
  81                res = fs32_to_cpu(dir->i_sb, de->d_ino);
  82                ufs_put_page(page);
  83        }
  84        return res;
  85}
  86
  87
  88/* Releases the page */
  89void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
  90                  struct page *page, struct inode *inode)
  91{
  92        loff_t pos = page_offset(page) +
  93                        (char *) de - (char *) page_address(page);
  94        unsigned len = fs16_to_cpu(dir->i_sb, de->d_reclen);
  95        int err;
  96
  97        lock_page(page);
  98        err = ufs_prepare_chunk(page, pos, len);
  99        BUG_ON(err);
 100
 101        de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
 102        ufs_set_de_type(dir->i_sb, de, inode->i_mode);
 103
 104        err = ufs_commit_chunk(page, pos, len);
 105        ufs_put_page(page);
 106        dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 107        mark_inode_dirty(dir);
 108}
 109
 110
 111static void ufs_check_page(struct page *page)
 112{
 113        struct inode *dir = page->mapping->host;
 114        struct super_block *sb = dir->i_sb;
 115        char *kaddr = page_address(page);
 116        unsigned offs, rec_len;
 117        unsigned limit = PAGE_CACHE_SIZE;
 118        const unsigned chunk_mask = UFS_SB(sb)->s_uspi->s_dirblksize - 1;
 119        struct ufs_dir_entry *p;
 120        char *error;
 121
 122        if ((dir->i_size >> PAGE_CACHE_SHIFT) == page->index) {
 123                limit = dir->i_size & ~PAGE_CACHE_MASK;
 124                if (limit & chunk_mask)
 125                        goto Ebadsize;
 126                if (!limit)
 127                        goto out;
 128        }
 129        for (offs = 0; offs <= limit - UFS_DIR_REC_LEN(1); offs += rec_len) {
 130                p = (struct ufs_dir_entry *)(kaddr + offs);
 131                rec_len = fs16_to_cpu(sb, p->d_reclen);
 132
 133                if (rec_len < UFS_DIR_REC_LEN(1))
 134                        goto Eshort;
 135                if (rec_len & 3)
 136                        goto Ealign;
 137                if (rec_len < UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, p)))
 138                        goto Enamelen;
 139                if (((offs + rec_len - 1) ^ offs) & ~chunk_mask)
 140                        goto Espan;
 141                if (fs32_to_cpu(sb, p->d_ino) > (UFS_SB(sb)->s_uspi->s_ipg *
 142                                                  UFS_SB(sb)->s_uspi->s_ncg))
 143                        goto Einumber;
 144        }
 145        if (offs != limit)
 146                goto Eend;
 147out:
 148        SetPageChecked(page);
 149        return;
 150
 151        /* Too bad, we had an error */
 152
 153Ebadsize:
 154        ufs_error(sb, "ufs_check_page",
 155                  "size of directory #%lu is not a multiple of chunk size",
 156                  dir->i_ino
 157        );
 158        goto fail;
 159Eshort:
 160        error = "rec_len is smaller than minimal";
 161        goto bad_entry;
 162Ealign:
 163        error = "unaligned directory entry";
 164        goto bad_entry;
 165Enamelen:
 166        error = "rec_len is too small for name_len";
 167        goto bad_entry;
 168Espan:
 169        error = "directory entry across blocks";
 170        goto bad_entry;
 171Einumber:
 172        error = "inode out of bounds";
 173bad_entry:
 174        ufs_error (sb, "ufs_check_page", "bad entry in directory #%lu: %s - "
 175                   "offset=%lu, rec_len=%d, name_len=%d",
 176                   dir->i_ino, error, (page->index<<PAGE_CACHE_SHIFT)+offs,
 177                   rec_len, ufs_get_de_namlen(sb, p));
 178        goto fail;
 179Eend:
 180        p = (struct ufs_dir_entry *)(kaddr + offs);
 181        ufs_error(sb, __func__,
 182                   "entry in directory #%lu spans the page boundary"
 183                   "offset=%lu",
 184                   dir->i_ino, (page->index<<PAGE_CACHE_SHIFT)+offs);
 185fail:
 186        SetPageChecked(page);
 187        SetPageError(page);
 188}
 189
 190static struct page *ufs_get_page(struct inode *dir, unsigned long n)
 191{
 192        struct address_space *mapping = dir->i_mapping;
 193        struct page *page = read_mapping_page(mapping, n, NULL);
 194        if (!IS_ERR(page)) {
 195                kmap(page);
 196                if (!PageChecked(page))
 197                        ufs_check_page(page);
 198                if (PageError(page))
 199                        goto fail;
 200        }
 201        return page;
 202
 203fail:
 204        ufs_put_page(page);
 205        return ERR_PTR(-EIO);
 206}
 207
 208/*
 209 * Return the offset into page `page_nr' of the last valid
 210 * byte in that page, plus one.
 211 */
 212static unsigned
 213ufs_last_byte(struct inode *inode, unsigned long page_nr)
 214{
 215        unsigned last_byte = inode->i_size;
 216
 217        last_byte -= page_nr << PAGE_CACHE_SHIFT;
 218        if (last_byte > PAGE_CACHE_SIZE)
 219                last_byte = PAGE_CACHE_SIZE;
 220        return last_byte;
 221}
 222
 223static inline struct ufs_dir_entry *
 224ufs_next_entry(struct super_block *sb, struct ufs_dir_entry *p)
 225{
 226        return (struct ufs_dir_entry *)((char *)p +
 227                                        fs16_to_cpu(sb, p->d_reclen));
 228}
 229
 230struct ufs_dir_entry *ufs_dotdot(struct inode *dir, struct page **p)
 231{
 232        struct page *page = ufs_get_page(dir, 0);
 233        struct ufs_dir_entry *de = NULL;
 234
 235        if (!IS_ERR(page)) {
 236                de = ufs_next_entry(dir->i_sb,
 237                                    (struct ufs_dir_entry *)page_address(page));
 238                *p = page;
 239        }
 240        return de;
 241}
 242
 243/*
 244 *      ufs_find_entry()
 245 *
 246 * finds an entry in the specified directory with the wanted name. It
 247 * returns the page in which the entry was found, and the entry itself
 248 * (as a parameter - res_dir). Page is returned mapped and unlocked.
 249 * Entry is guaranteed to be valid.
 250 */
 251struct ufs_dir_entry *ufs_find_entry(struct inode *dir, const struct qstr *qstr,
 252                                     struct page **res_page)
 253{
 254        struct super_block *sb = dir->i_sb;
 255        const unsigned char *name = qstr->name;
 256        int namelen = qstr->len;
 257        unsigned reclen = UFS_DIR_REC_LEN(namelen);
 258        unsigned long start, n;
 259        unsigned long npages = ufs_dir_pages(dir);
 260        struct page *page = NULL;
 261        struct ufs_inode_info *ui = UFS_I(dir);
 262        struct ufs_dir_entry *de;
 263
 264        UFSD("ENTER, dir_ino %lu, name %s, namlen %u\n", dir->i_ino, name, namelen);
 265
 266        if (npages == 0 || namelen > UFS_MAXNAMLEN)
 267                goto out;
 268
 269        /* OFFSET_CACHE */
 270        *res_page = NULL;
 271
 272        start = ui->i_dir_start_lookup;
 273
 274        if (start >= npages)
 275                start = 0;
 276        n = start;
 277        do {
 278                char *kaddr;
 279                page = ufs_get_page(dir, n);
 280                if (!IS_ERR(page)) {
 281                        kaddr = page_address(page);
 282                        de = (struct ufs_dir_entry *) kaddr;
 283                        kaddr += ufs_last_byte(dir, n) - reclen;
 284                        while ((char *) de <= kaddr) {
 285                                if (de->d_reclen == 0) {
 286                                        ufs_error(dir->i_sb, __func__,
 287                                                  "zero-length directory entry");
 288                                        ufs_put_page(page);
 289                                        goto out;
 290                                }
 291                                if (ufs_match(sb, namelen, name, de))
 292                                        goto found;
 293                                de = ufs_next_entry(sb, de);
 294                        }
 295                        ufs_put_page(page);
 296                }
 297                if (++n >= npages)
 298                        n = 0;
 299        } while (n != start);
 300out:
 301        return NULL;
 302
 303found:
 304        *res_page = page;
 305        ui->i_dir_start_lookup = n;
 306        return de;
 307}
 308
 309/*
 310 *      Parent is locked.
 311 */
 312int ufs_add_link(struct dentry *dentry, struct inode *inode)
 313{
 314        struct inode *dir = dentry->d_parent->d_inode;
 315        const unsigned char *name = dentry->d_name.name;
 316        int namelen = dentry->d_name.len;
 317        struct super_block *sb = dir->i_sb;
 318        unsigned reclen = UFS_DIR_REC_LEN(namelen);
 319        const unsigned int chunk_size = UFS_SB(sb)->s_uspi->s_dirblksize;
 320        unsigned short rec_len, name_len;
 321        struct page *page = NULL;
 322        struct ufs_dir_entry *de;
 323        unsigned long npages = ufs_dir_pages(dir);
 324        unsigned long n;
 325        char *kaddr;
 326        loff_t pos;
 327        int err;
 328
 329        UFSD("ENTER, name %s, namelen %u\n", name, namelen);
 330
 331        /*
 332         * We take care of directory expansion in the same loop.
 333         * This code plays outside i_size, so it locks the page
 334         * to protect that region.
 335         */
 336        for (n = 0; n <= npages; n++) {
 337                char *dir_end;
 338
 339                page = ufs_get_page(dir, n);
 340                err = PTR_ERR(page);
 341                if (IS_ERR(page))
 342                        goto out;
 343                lock_page(page);
 344                kaddr = page_address(page);
 345                dir_end = kaddr + ufs_last_byte(dir, n);
 346                de = (struct ufs_dir_entry *)kaddr;
 347                kaddr += PAGE_CACHE_SIZE - reclen;
 348                while ((char *)de <= kaddr) {
 349                        if ((char *)de == dir_end) {
 350                                /* We hit i_size */
 351                                name_len = 0;
 352                                rec_len = chunk_size;
 353                                de->d_reclen = cpu_to_fs16(sb, chunk_size);
 354                                de->d_ino = 0;
 355                                goto got_it;
 356                        }
 357                        if (de->d_reclen == 0) {
 358                                ufs_error(dir->i_sb, __func__,
 359                                          "zero-length directory entry");
 360                                err = -EIO;
 361                                goto out_unlock;
 362                        }
 363                        err = -EEXIST;
 364                        if (ufs_match(sb, namelen, name, de))
 365                                goto out_unlock;
 366                        name_len = UFS_DIR_REC_LEN(ufs_get_de_namlen(sb, de));
 367                        rec_len = fs16_to_cpu(sb, de->d_reclen);
 368                        if (!de->d_ino && rec_len >= reclen)
 369                                goto got_it;
 370                        if (rec_len >= name_len + reclen)
 371                                goto got_it;
 372                        de = (struct ufs_dir_entry *) ((char *) de + rec_len);
 373                }
 374                unlock_page(page);
 375                ufs_put_page(page);
 376        }
 377        BUG();
 378        return -EINVAL;
 379
 380got_it:
 381        pos = page_offset(page) +
 382                        (char*)de - (char*)page_address(page);
 383        err = ufs_prepare_chunk(page, pos, rec_len);
 384        if (err)
 385                goto out_unlock;
 386        if (de->d_ino) {
 387                struct ufs_dir_entry *de1 =
 388                        (struct ufs_dir_entry *) ((char *) de + name_len);
 389                de1->d_reclen = cpu_to_fs16(sb, rec_len - name_len);
 390                de->d_reclen = cpu_to_fs16(sb, name_len);
 391
 392                de = de1;
 393        }
 394
 395        ufs_set_de_namlen(sb, de, namelen);
 396        memcpy(de->d_name, name, namelen + 1);
 397        de->d_ino = cpu_to_fs32(sb, inode->i_ino);
 398        ufs_set_de_type(sb, de, inode->i_mode);
 399
 400        err = ufs_commit_chunk(page, pos, rec_len);
 401        dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 402
 403        mark_inode_dirty(dir);
 404        /* OFFSET_CACHE */
 405out_put:
 406        ufs_put_page(page);
 407out:
 408        return err;
 409out_unlock:
 410        unlock_page(page);
 411        goto out_put;
 412}
 413
 414static inline unsigned
 415ufs_validate_entry(struct super_block *sb, char *base,
 416                   unsigned offset, unsigned mask)
 417{
 418        struct ufs_dir_entry *de = (struct ufs_dir_entry*)(base + offset);
 419        struct ufs_dir_entry *p = (struct ufs_dir_entry*)(base + (offset&mask));
 420        while ((char*)p < (char*)de) {
 421                if (p->d_reclen == 0)
 422                        break;
 423                p = ufs_next_entry(sb, p);
 424        }
 425        return (char *)p - base;
 426}
 427
 428
 429/*
 430 * This is blatantly stolen from ext2fs
 431 */
 432static int
 433ufs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 434{
 435        loff_t pos = filp->f_pos;
 436        struct inode *inode = filp->f_path.dentry->d_inode;
 437        struct super_block *sb = inode->i_sb;
 438        unsigned int offset = pos & ~PAGE_CACHE_MASK;
 439        unsigned long n = pos >> PAGE_CACHE_SHIFT;
 440        unsigned long npages = ufs_dir_pages(inode);
 441        unsigned chunk_mask = ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
 442        int need_revalidate = filp->f_version != inode->i_version;
 443        unsigned flags = UFS_SB(sb)->s_flags;
 444
 445        UFSD("BEGIN\n");
 446
 447        if (pos > inode->i_size - UFS_DIR_REC_LEN(1))
 448                return 0;
 449
 450        for ( ; n < npages; n++, offset = 0) {
 451                char *kaddr, *limit;
 452                struct ufs_dir_entry *de;
 453
 454                struct page *page = ufs_get_page(inode, n);
 455
 456                if (IS_ERR(page)) {
 457                        ufs_error(sb, __func__,
 458                                  "bad page in #%lu",
 459                                  inode->i_ino);
 460                        filp->f_pos += PAGE_CACHE_SIZE - offset;
 461                        return -EIO;
 462                }
 463                kaddr = page_address(page);
 464                if (unlikely(need_revalidate)) {
 465                        if (offset) {
 466                                offset = ufs_validate_entry(sb, kaddr, offset, chunk_mask);
 467                                filp->f_pos = (n<<PAGE_CACHE_SHIFT) + offset;
 468                        }
 469                        filp->f_version = inode->i_version;
 470                        need_revalidate = 0;
 471                }
 472                de = (struct ufs_dir_entry *)(kaddr+offset);
 473                limit = kaddr + ufs_last_byte(inode, n) - UFS_DIR_REC_LEN(1);
 474                for ( ;(char*)de <= limit; de = ufs_next_entry(sb, de)) {
 475                        if (de->d_reclen == 0) {
 476                                ufs_error(sb, __func__,
 477                                        "zero-length directory entry");
 478                                ufs_put_page(page);
 479                                return -EIO;
 480                        }
 481                        if (de->d_ino) {
 482                                int over;
 483                                unsigned char d_type = DT_UNKNOWN;
 484
 485                                offset = (char *)de - kaddr;
 486
 487                                UFSD("filldir(%s,%u)\n", de->d_name,
 488                                      fs32_to_cpu(sb, de->d_ino));
 489                                UFSD("namlen %u\n", ufs_get_de_namlen(sb, de));
 490
 491                                if ((flags & UFS_DE_MASK) == UFS_DE_44BSD)
 492                                        d_type = de->d_u.d_44.d_type;
 493
 494                                over = filldir(dirent, de->d_name,
 495                                               ufs_get_de_namlen(sb, de),
 496                                                (n<<PAGE_CACHE_SHIFT) | offset,
 497                                               fs32_to_cpu(sb, de->d_ino), d_type);
 498                                if (over) {
 499                                        ufs_put_page(page);
 500                                        return 0;
 501                                }
 502                        }
 503                        filp->f_pos += fs16_to_cpu(sb, de->d_reclen);
 504                }
 505                ufs_put_page(page);
 506        }
 507        return 0;
 508}
 509
 510
 511/*
 512 * ufs_delete_entry deletes a directory entry by merging it with the
 513 * previous entry.
 514 */
 515int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
 516                     struct page * page)
 517{
 518        struct super_block *sb = inode->i_sb;
 519        char *kaddr = page_address(page);
 520        unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
 521        unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen);
 522        loff_t pos;
 523        struct ufs_dir_entry *pde = NULL;
 524        struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from);
 525        int err;
 526
 527        UFSD("ENTER\n");
 528
 529        UFSD("ino %u, reclen %u, namlen %u, name %s\n",
 530              fs32_to_cpu(sb, de->d_ino),
 531              fs16_to_cpu(sb, de->d_reclen),
 532              ufs_get_de_namlen(sb, de), de->d_name);
 533
 534        while ((char*)de < (char*)dir) {
 535                if (de->d_reclen == 0) {
 536                        ufs_error(inode->i_sb, __func__,
 537                                  "zero-length directory entry");
 538                        err = -EIO;
 539                        goto out;
 540                }
 541                pde = de;
 542                de = ufs_next_entry(sb, de);
 543        }
 544        if (pde)
 545                from = (char*)pde - (char*)page_address(page);
 546
 547        pos = page_offset(page) + from;
 548        lock_page(page);
 549        err = ufs_prepare_chunk(page, pos, to - from);
 550        BUG_ON(err);
 551        if (pde)
 552                pde->d_reclen = cpu_to_fs16(sb, to - from);
 553        dir->d_ino = 0;
 554        err = ufs_commit_chunk(page, pos, to - from);
 555        inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 556        mark_inode_dirty(inode);
 557out:
 558        ufs_put_page(page);
 559        UFSD("EXIT\n");
 560        return err;
 561}
 562
 563int ufs_make_empty(struct inode * inode, struct inode *dir)
 564{
 565        struct super_block * sb = dir->i_sb;
 566        struct address_space *mapping = inode->i_mapping;
 567        struct page *page = grab_cache_page(mapping, 0);
 568        const unsigned int chunk_size = UFS_SB(sb)->s_uspi->s_dirblksize;
 569        struct ufs_dir_entry * de;
 570        char *base;
 571        int err;
 572
 573        if (!page)
 574                return -ENOMEM;
 575
 576        err = ufs_prepare_chunk(page, 0, chunk_size);
 577        if (err) {
 578                unlock_page(page);
 579                goto fail;
 580        }
 581
 582        kmap(page);
 583        base = (char*)page_address(page);
 584        memset(base, 0, PAGE_CACHE_SIZE);
 585
 586        de = (struct ufs_dir_entry *) base;
 587
 588        de->d_ino = cpu_to_fs32(sb, inode->i_ino);
 589        ufs_set_de_type(sb, de, inode->i_mode);
 590        ufs_set_de_namlen(sb, de, 1);
 591        de->d_reclen = cpu_to_fs16(sb, UFS_DIR_REC_LEN(1));
 592        strcpy (de->d_name, ".");
 593        de = (struct ufs_dir_entry *)
 594                ((char *)de + fs16_to_cpu(sb, de->d_reclen));
 595        de->d_ino = cpu_to_fs32(sb, dir->i_ino);
 596        ufs_set_de_type(sb, de, dir->i_mode);
 597        de->d_reclen = cpu_to_fs16(sb, chunk_size - UFS_DIR_REC_LEN(1));
 598        ufs_set_de_namlen(sb, de, 2);
 599        strcpy (de->d_name, "..");
 600        kunmap(page);
 601
 602        err = ufs_commit_chunk(page, 0, chunk_size);
 603fail:
 604        page_cache_release(page);
 605        return err;
 606}
 607
 608/*
 609 * routine to check that the specified directory is empty (for rmdir)
 610 */
 611int ufs_empty_dir(struct inode * inode)
 612{
 613        struct super_block *sb = inode->i_sb;
 614        struct page *page = NULL;
 615        unsigned long i, npages = ufs_dir_pages(inode);
 616
 617        for (i = 0; i < npages; i++) {
 618                char *kaddr;
 619                struct ufs_dir_entry *de;
 620                page = ufs_get_page(inode, i);
 621
 622                if (IS_ERR(page))
 623                        continue;
 624
 625                kaddr = page_address(page);
 626                de = (struct ufs_dir_entry *)kaddr;
 627                kaddr += ufs_last_byte(inode, i) - UFS_DIR_REC_LEN(1);
 628
 629                while ((char *)de <= kaddr) {
 630                        if (de->d_reclen == 0) {
 631                                ufs_error(inode->i_sb, __func__,
 632                                        "zero-length directory entry: "
 633                                        "kaddr=%p, de=%p\n", kaddr, de);
 634                                goto not_empty;
 635                        }
 636                        if (de->d_ino) {
 637                                u16 namelen=ufs_get_de_namlen(sb, de);
 638                                /* check for . and .. */
 639                                if (de->d_name[0] != '.')
 640                                        goto not_empty;
 641                                if (namelen > 2)
 642                                        goto not_empty;
 643                                if (namelen < 2) {
 644                                        if (inode->i_ino !=
 645                                            fs32_to_cpu(sb, de->d_ino))
 646                                                goto not_empty;
 647                                } else if (de->d_name[1] != '.')
 648                                        goto not_empty;
 649                        }
 650                        de = ufs_next_entry(sb, de);
 651                }
 652                ufs_put_page(page);
 653        }
 654        return 1;
 655
 656not_empty:
 657        ufs_put_page(page);
 658        return 0;
 659}
 660
 661const struct file_operations ufs_dir_operations = {
 662        .read           = generic_read_dir,
 663        .readdir        = ufs_readdir,
 664        .fsync          = generic_file_fsync,
 665        .llseek         = generic_file_llseek,
 666};
 667
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.