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 = page_address(page);
  18        struct slink_front *lf;
  19        int                      i, j;
  20        char                     c;
  21        char                     lc;
  22
  23        pr_debug("get_link(ino=%lu)\n", inode->i_ino);
  24
  25        bh = affs_bread(inode->i_sb, inode->i_ino);
  26        if (!bh)
  27                goto fail;
  28        i  = 0;
  29        j  = 0;
  30        lf = (struct slink_front *)bh->b_data;
  31        lc = 0;
  32
  33        if (strchr(lf->symname,':')) {  /* Handle assign or volume name */
  34                struct affs_sb_info *sbi = AFFS_SB(inode->i_sb);
  35                char *pf;
  36                spin_lock(&sbi->symlink_lock);
  37                pf = sbi->s_prefix ? sbi->s_prefix : "/";
  38                while (i < 1023 && (c = pf[i]))
  39                        link[i++] = c;
  40                spin_unlock(&sbi->symlink_lock);
  41                while (i < 1023 && lf->symname[j] != ':')
  42                        link[i++] = lf->symname[j++];
  43                if (i < 1023)
  44                        link[i++] = '/';
  45                j++;
  46                lc = '/';
  47        }
  48        while (i < 1023 && (c = lf->symname[j])) {
  49                if (c == '/' && lc == '/' && i < 1020) {        /* parent dir */
  50                        link[i++] = '.';
  51                        link[i++] = '.';
  52                }
  53                link[i++] = c;
  54                lc = c;
  55                j++;
  56        }
  57        link[i] = '\0';
  58        affs_brelse(bh);
  59        SetPageUptodate(page);
  60        unlock_page(page);
  61        return 0;
  62fail:
  63        SetPageError(page);
  64        unlock_page(page);
  65        return -EIO;
  66}
  67
  68const struct address_space_operations affs_symlink_aops = {
  69        .readpage       = affs_symlink_readpage,
  70};
  71
  72const struct inode_operations affs_symlink_inode_operations = {
  73        .get_link       = page_get_link,
  74        .setattr        = affs_notify_change,
  75};
  76