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 *file, struct dir_context *ctx)
 434{
 435        loff_t pos = ctx->pos;
 436        struct inode *inode = file_inode(file);
 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 = file->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                        ctx->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                                ctx->pos = (n<<PAGE_CACHE_SHIFT) + offset;
 468                        }
 469                        file->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                                unsigned char d_type = DT_UNKNOWN;
 483
 484                                UFSD("filldir(%s,%u)\n", de->d_name,
 485                                      fs32_to_cpu(sb, de->d_ino));
 486                                UFSD("namlen %u\n", ufs_get_de_namlen(sb, de));
 487
 488                                if ((flags & UFS_DE_MASK) == UFS_DE_44BSD)
 489                                        d_type = de->d_u.d_44.d_type;
 490
 491                                if (!dir_emit(ctx, de->d_name,
 492                                               ufs_get_de_namlen(sb, de),
 493                                               fs32_to_cpu(sb, de->d_ino),
 494                                               d_type)) {
 495                                        ufs_put_page(page);
 496                                        return 0;
 497                                }
 498                        }
 499                        ctx->pos += fs16_to_cpu(sb, de->d_reclen);
 500                }
 501                ufs_put_page(page);
 502        }
 503        return 0;
 504}
 505
 506
 507/*
 508 * ufs_delete_entry deletes a directory entry by merging it with the
 509 * previous entry.
 510 */
 511int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
 512                     struct page * page)
 513{
 514        struct super_block *sb = inode->i_sb;
 515        char *kaddr = page_address(page);
 516        unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
 517        unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen);
 518        loff_t pos;
 519        struct ufs_dir_entry *pde = NULL;
 520        struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from);
 521        int err;
 522
 523        UFSD("ENTER\n");
 524
 525        UFSD("ino %u, reclen %u, namlen %u, name %s\n",
 526              fs32_to_cpu(sb, de->d_ino),
 527              fs16_to_cpu(sb, de->d_reclen),
 528              ufs_get_de_namlen(sb, de), de->d_name);
 529
 530        while ((char*)de < (char*)dir) {
 531                if (de->d_reclen == 0) {
 532                        ufs_error(inode->i_sb, __func__,
 533                                  "zero-length directory entry");
 534                        err = -EIO;
 535                        goto out;
 536                }
 537                pde = de;
 538                de = ufs_next_entry(sb, de);
 539        }
 540        if (pde)
 541                from = (char*)pde - (char*)page_address(page);
 542
 543        pos = page_offset(page) + from;
 544        lock_page(page);
 545        err = ufs_prepare_chunk(page, pos, to - from);
 546        BUG_ON(err);
 547        if (pde)
 548                pde->d_reclen = cpu_to_fs16(sb, to - from);
 549        dir->d_ino = 0;
 550        err = ufs_commit_chunk(page, pos, to - from);
 551        inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 552        mark_inode_dirty(inode);
 553out:
 554        ufs_put_page(page);
 555        UFSD("EXIT\n");
 556        return err;
 557}
 558
 559int ufs_make_empty(struct inode * inode, struct inode *dir)
 560{
 561        struct super_block * sb = dir->i_sb;
 562        struct address_space *mapping = inode->i_mapping;
 563        struct page *page = grab_cache_page(mapping, 0);
 564        const unsigned int chunk_size = UFS_SB(sb)->s_uspi->s_dirblksize;
 565        struct ufs_dir_entry * de;
 566        char *base;
 567        int err;
 568
 569        if (!page)
 570                return -ENOMEM;
 571
 572        err = ufs_prepare_chunk(page, 0, chunk_size);
 573        if (err) {
 574                unlock_page(page);
 575                goto fail;
 576        }
 577
 578        kmap(page);
 579        base = (char*)page_address(page);
 580        memset(base, 0, PAGE_CACHE_SIZE);
 581
 582        de = (struct ufs_dir_entry *) base;
 583
 584        de->d_ino = cpu_to_fs32(sb, inode->i_ino);
 585        ufs_set_de_type(sb, de, inode->i_mode);
 586        ufs_set_de_namlen(sb, de, 1);
 587        de->d_reclen = cpu_to_fs16(sb, UFS_DIR_REC_LEN(1));
 588        strcpy (de->d_name, ".");
 589        de = (struct ufs_dir_entry *)
 590                ((char *)de + fs16_to_cpu(sb, de->d_reclen));
 591        de->d_ino = cpu_to_fs32(sb, dir->i_ino);
 592        ufs_set_de_type(sb, de, dir->i_mode);
 593        de->d_reclen = cpu_to_fs16(sb, chunk_size - UFS_DIR_REC_LEN(1));
 594        ufs_set_de_namlen(sb, de, 2);
 595        strcpy (de->d_name, "..");
 596        kunmap(page);
 597
 598        err = ufs_commit_chunk(page, 0, chunk_size);
 599fail:
 600        page_cache_release(page);
 601        return err;
 602}
 603
 604/*
 605 * routine to check that the specified directory is empty (for rmdir)
 606 */
 607int ufs_empty_dir(struct inode * inode)
 608{
 609        struct super_block *sb = inode->i_sb;
 610        struct page *page = NULL;
 611        unsigned long i, npages = ufs_dir_pages(inode);
 612
 613        for (i = 0; i < npages; i++) {
 614                char *kaddr;
 615                struct ufs_dir_entry *de;
 616                page = ufs_get_page(inode, i);
 617
 618                if (IS_ERR(page))
 619                        continue;
 620
 621                kaddr = page_address(page);
 622                de = (struct ufs_dir_entry *)kaddr;
 623                kaddr += ufs_last_byte(inode, i) - UFS_DIR_REC_LEN(1);
 624
 625                while ((char *)de <= kaddr) {
 626                        if (de->d_reclen == 0) {
 627                                ufs_error(inode->i_sb, __func__,
 628                                        "zero-length directory entry: "
 629                                        "kaddr=%p, de=%p\n", kaddr, de);
 630                                goto not_empty;
 631                        }
 632                        if (de->d_ino) {
 633                                u16 namelen=ufs_get_de_namlen(sb, de);
 634                                /* check for . and .. */
 635                                if (de->d_name[0] != '.')
 636                                        goto not_empty;
 637                                if (namelen > 2)
 638                                        goto not_empty;
 639                                if (namelen < 2) {
 640                                        if (inode->i_ino !=
 641                                            fs32_to_cpu(sb, de->d_ino))
 642                                                goto not_empty;
 643                                } else if (de->d_name[1] != '.')
 644                                        goto not_empty;
 645                        }
 646                        de = ufs_next_entry(sb, de);
 647                }
 648                ufs_put_page(page);
 649        }
 650        return 1;
 651
 652not_empty:
 653        ufs_put_page(page);
 654        return 0;
 655}
 656
 657const struct file_operations ufs_dir_operations = {
 658        .read           = generic_read_dir,
 659        .iterate        = ufs_readdir,
 660        .fsync          = generic_file_fsync,
 661        .llseek         = generic_file_llseek,
 662};
 663
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.