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 #ifdef MODULE
  13 #include <linux/module.h>
  14 #endif
  15 
  16 #include <asm/segment.h>
  17 
  18 #include <linux/errno.h>
  19 #include <linux/sched.h>
  20 #include <linux/fs.h>
  21 #include <linux/iso_fs.h>
  22 #include <linux/stat.h>
  23 #include <linux/malloc.h>
  24 
  25 static int isofs_readlink(struct inode *, char *, int);
  26 static int isofs_follow_link(struct inode *, struct inode *, int, int, struct inode **);
  27 
  28 /*
  29  * symlinks can't do much...
  30  */
  31 struct inode_operations isofs_symlink_inode_operations = {
  32         NULL,                   /* no file-operations */
  33         NULL,                   /* create */
  34         NULL,                   /* lookup */
  35         NULL,                   /* link */
  36         NULL,                   /* unlink */
  37         NULL,                   /* symlink */
  38         NULL,                   /* mkdir */
  39         NULL,                   /* rmdir */
  40         NULL,                   /* mknod */
  41         NULL,                   /* rename */
  42         isofs_readlink,         /* readlink */
  43         isofs_follow_link,      /* follow_link */
  44         NULL,                   /* bmap */
  45         NULL,                   /* truncate */
  46         NULL                    /* permission */
  47 };
  48 
  49 static int isofs_follow_link(struct inode * dir, struct inode * inode,
     /* [previous][next][first][last][top][bottom][index][help] */
  50         int flag, int mode, struct inode ** res_inode)
  51 {
  52         int error;
  53         char * pnt;
  54 
  55         if (!dir) {
  56                 dir = current->fs->root;
  57                 dir->i_count++;
  58         }
  59         if (!inode) {
  60                 iput(dir);
  61                 *res_inode = NULL;
  62                 return -ENOENT;
  63         }
  64         if (!S_ISLNK(inode->i_mode)) {
  65                 iput(dir);
  66                 *res_inode = inode;
  67                 return 0;
  68         }
  69         if ((current->link_count > 5) ||
  70            !(pnt = get_rock_ridge_symlink(inode))) {
  71                 iput(dir);
  72                 iput(inode);
  73                 *res_inode = NULL;
  74                 return -ELOOP;
  75         }
  76         iput(inode);
  77         current->link_count++;
  78         error = open_namei(pnt,flag,mode,res_inode,dir);
  79         current->link_count--;
  80         kfree(pnt);
  81         return error;
  82 }
  83 
  84 static int isofs_readlink(struct inode * inode, char * buffer, int buflen)
     /* [previous][next][first][last][top][bottom][index][help] */
  85 {
  86         char * pnt;
  87         int i;
  88         char c;
  89 
  90         if (!S_ISLNK(inode->i_mode)) {
  91                 iput(inode);
  92                 return -EINVAL;
  93         }
  94 
  95         if (buflen > 1023)
  96                 buflen = 1023;
  97         pnt = get_rock_ridge_symlink(inode);
  98 
  99         iput(inode);
 100         if (!pnt)
 101                 return 0;
 102         i = 0;
 103 
 104         while (i<buflen && (c = pnt[i])) {
 105                 i++;
 106                 put_user(c,buffer++);
 107         }
 108         kfree(pnt);
 109         return i;
 110 }

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