linux/fs/affs/symlink.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 *  linux/fs/affs/symlink.c
   4 *
   5 *  1995  Hans-Joachim Widmaier - Modified for affs.
   6 *
   7 *  Copyright (C) 1991, 1992  Linus Torvalds
   8 *
   9 *  affs symlink handling code
  10 */
  11
  12#include "affs.h"
  13
  14static int affs_symlink_readpage(struct file *file, struct page *page)
  15{
  16        struct buffer_head *bh;
  17        struct inode *inode = page->mapping->host;
  18        char *link = page_address(page);
  19        struct slink_front *lf;
  20        int                      i, j;
  21        char                     c;
  22        char                     lc;
  23
  24        pr_debug("get_link(ino=%lu)\n", inode->i_ino);
  25
  26        bh = affs_bread(inode->i_sb, inode->i_ino);
  27        if (!bh)
  28                goto fail;
  29        i  = 0;
  30        j  = 0;
  31        lf = (struct slink_front *)bh->b_data;
  32        lc = 0;
  33
  34        if (strchr(lf->symname,':')) {  /* Handle assign or volume name */
  35                struct affs_sb_info *sbi = AFFS_SB(inode->i_sb);
  36                char *pf;
  37                spin_lock(&sbi->symlink_lock);
  38                pf = sbi->s_prefix ? sbi->s_prefix : "/";
  39                while (i < 1023 && (c = pf[i]))
  40                        link[i++] = c;
  41                spin_unlock(&sbi->symlink_lock);
  42                while (i < 1023 && lf->symname[j] != ':')
  43                        link[i++] = lf->symname[j++];
  44                if (i < 1023)
  45                        link[i++] = '/';
  46                j++;
  47                lc = '/';
  48        }
  49        while (i < 1023 && (c = lf->symname[j])) {
  50                if (c == '/' && lc == '/' && i < 1020) {        /* parent dir */
  51                        link[i++] = '.';
  52                        link[i++] = '.';
  53                }
  54                link[i++] = c;
  55                lc = c;
  56                j++;
  57        }
  58        link[i] = '\0';
  59        affs_brelse(bh);
  60        SetPageUptodate(page);
  61        unlock_page(page);
  62        return 0;
  63fail:
  64        SetPageError(page);
  65        unlock_page(page);
  66        return -EIO;
  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        .get_link       = page_get_link,
  75        .setattr        = affs_notify_change,
  76};
  77