root/fs/affs/symlink.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. affs_symlink_readpage

   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 
  14 static 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;
  63 fail:
  64         SetPageError(page);
  65         unlock_page(page);
  66         return -EIO;
  67 }
  68 
  69 const struct address_space_operations affs_symlink_aops = {
  70         .readpage       = affs_symlink_readpage,
  71 };
  72 
  73 const struct inode_operations affs_symlink_inode_operations = {
  74         .get_link       = page_get_link,
  75         .setattr        = affs_notify_change,
  76 };

/* [<][>][^][v][top][bottom][index][help] */