root/fs/isofs/symlink.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. isofs_follow_link
  2. isofs_readlink

   1 /*
   2  *  linux/fs/isofs/symlink.c
   3  *
   4  *  (C) 1992  Eric Youngdale Modified for ISO9660 filesystem.
   5  *
   6  *  Copyright (C) 1991, 1992  Linus Torvalds
   7  *
   8  *  isofs symlink handling code.  This is only used with the Rock Ridge
   9  *  extensions to iso9660
  10  */
  11 
  12 #include <asm/segment.h>
  13 
  14 #include <linux/errno.h>
  15 #include <linux/sched.h>
  16 #include <linux/fs.h>
  17 #include <linux/iso_fs.h>
  18 #include <linux/stat.h>
  19 
  20 static int isofs_readlink(struct inode *, char *, int);
  21 static int isofs_follow_link(struct inode *, struct inode *, int, int, struct inode **);
  22 
  23 /*
  24  * symlinks can't do much...
  25  */
  26 struct inode_operations isofs_symlink_inode_operations = {
  27         NULL,                   /* no file-operations */
  28         NULL,                   /* create */
  29         NULL,                   /* lookup */
  30         NULL,                   /* link */
  31         NULL,                   /* unlink */
  32         NULL,                   /* symlink */
  33         NULL,                   /* mkdir */
  34         NULL,                   /* rmdir */
  35         NULL,                   /* mknod */
  36         NULL,                   /* rename */
  37         isofs_readlink,         /* readlink */
  38         isofs_follow_link,      /* follow_link */
  39         NULL,                   /* bmap */
  40         NULL,                   /* truncate */
  41         NULL                    /* permission */
  42 };
  43 
  44 static int isofs_follow_link(struct inode * dir, struct inode * inode,
     /* [previous][next][first][last][top][bottom][index][help] */
  45         int flag, int mode, struct inode ** res_inode)
  46 {
  47         int error;
  48         unsigned short fs;
  49         char * pnt;
  50 
  51         if (!dir) {
  52                 dir = current->root;
  53                 dir->i_count++;
  54         }
  55         if (!inode) {
  56                 iput(dir);
  57                 *res_inode = NULL;
  58                 return -ENOENT;
  59         }
  60         if (!S_ISLNK(inode->i_mode)) {
  61                 iput(dir);
  62                 *res_inode = inode;
  63                 return 0;
  64         }
  65         __asm__("mov %%fs,%0":"=r" (fs));
  66         if ((current->link_count > 5) ||
  67            !(pnt = get_rock_ridge_symlink(inode))) {
  68                 iput(dir);
  69                 iput(inode);
  70                 *res_inode = NULL;
  71                 return -ELOOP;
  72         }
  73         iput(inode);
  74         __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
  75         current->link_count++;
  76         error = open_namei(pnt,flag,mode,res_inode,dir);
  77         current->link_count--;
  78         __asm__("mov %0,%%fs"::"r" (fs));
  79         kfree(pnt);
  80         return error;
  81 }
  82 
  83 static int isofs_readlink(struct inode * inode, char * buffer, int buflen)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85         char * pnt;
  86         int i;
  87         char c;
  88 
  89         if (!S_ISLNK(inode->i_mode)) {
  90                 iput(inode);
  91                 return -EINVAL;
  92         }
  93 
  94         if (buflen > 1023)
  95                 buflen = 1023;
  96         pnt = get_rock_ridge_symlink(inode);
  97 
  98         iput(inode);
  99         if (!pnt)
 100                 return 0;
 101         i = 0;
 102 
 103         while (i<buflen && (c = pnt[i])) {
 104                 i++;
 105                 put_fs_byte(c,buffer++);
 106         }
 107         kfree(pnt);
 108         return i;
 109 }

/* [previous][next][first][last][top][bottom][index][help] */