linux/fs/affs/symlink.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/affs/symlink.c
   3 *
   4 *  1995  Hans-Joachim Widmaier - Modified for affs.
   5 *
   6 *  Copyright (C) 1991, 1992  Linus Torvalds
   7 *
   8 *  affs symlink handling code
   9 */
  10
  11#include "affs.h"
  12
  13static int affs_symlink_readpage(struct file *file, struct page *page)
  14{
  15        struct buffer_head *bh;
  16        struct inode *inode = page->mapping->host;
  17        char *link = kmap(page);
  18        struct slink_front *lf;
  19        int err;
  20        int                      i, j;
  21        char                     c;
  22        char                     lc;
  23        char                    *pf;
  24
  25        pr_debug("AFFS: follow_link(ino=%lu)\n",inode->i_ino);
  26
  27        err = -EIO;
  28        bh = affs_bread(inode->i_sb, inode->i_ino);
  29        if (!bh)
  30                goto fail;
  31        i  = 0;
  32        j  = 0;
  33        lf = (struct slink_front *)bh->b_data;
  34        lc = 0;
  35        pf = AFFS_SB(inode->i_sb)->s_prefix ? AFFS_SB(inode->i_sb)->s_prefix : "/";
  36
  37        if (strchr(lf->symname,':')) {  /* Handle assign or volume name */
  38                while (i < 1023 && (c = pf[i]))
  39                        link[i++] = c;
  40                while (i < 1023 && lf->symname[j] != ':')
  41                        link[i++] = lf->symname[j++];
  42                if (i < 1023)
  43                        link[i++] = '/';
  44                j++;
  45                lc = '/';
  46        }
  47        while (i < 1023 && (c = lf->symname[j])) {
  48                if (c == '/' && lc == '/' && i < 1020) {        /* parent dir */
  49                        link[i++] = '.';
  50                        link[i++] = '.';
  51                }
  52                link[i++] = c;
  53                lc = c;
  54                j++;
  55        }
  56        link[i] = '\0';
  57        affs_brelse(bh);
  58        SetPageUptodate(page);
  59        kunmap(page);
  60        unlock_page(page);
  61        return 0;
  62fail:
  63        SetPageError(page);
  64        kunmap(page);
  65        unlock_page(page);
  66        return err;
  67}
  68
  69const struct address_space_operations affs_symlink_aops = {
  70        .readpage       = affs_symlink_readpage,
  71};
  72
  73const struct inode_operations affs_symlink_inode_operations = {
  74        .readlink       = generic_readlink,
  75        .follow_link    = page_follow_link_light,
  76        .put_link       = page_put_link,
  77        .setattr        = affs_notify_change,
  78};
  79