root/fs/minix/symlink.c

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

DEFINITIONS

This source file includes following definitions.
  1. minix_follow_link
  2. minix_readlink

   1 /*
   2  *  linux/fs/minix/symlink.c
   3  *
   4  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  *
   6  *  minix symlink handling code
   7  */
   8 
   9 #include <linux/errno.h>
  10 #include <linux/sched.h>
  11 #include <linux/fs.h>
  12 #include <linux/minix_fs.h>
  13 #include <linux/stat.h>
  14 
  15 #include <asm/segment.h>
  16 
  17 static int minix_readlink(struct inode *, char *, int);
  18 static int minix_follow_link(struct inode *, struct inode *, int, int, struct inode **);
  19 
  20 /*
  21  * symlinks can't do much...
  22  */
  23 struct inode_operations minix_symlink_inode_operations = {
  24         NULL,                   /* no file-operations */
  25         NULL,                   /* create */
  26         NULL,                   /* lookup */
  27         NULL,                   /* link */
  28         NULL,                   /* unlink */
  29         NULL,                   /* symlink */
  30         NULL,                   /* mkdir */
  31         NULL,                   /* rmdir */
  32         NULL,                   /* mknod */
  33         NULL,                   /* rename */
  34         minix_readlink,         /* readlink */
  35         minix_follow_link,      /* follow_link */
  36         NULL,                   /* readpage */
  37         NULL,                   /* writepage */
  38         NULL,                   /* bmap */
  39         NULL,                   /* truncate */
  40         NULL                    /* permission */
  41 };
  42 
  43 static int minix_follow_link(struct inode * dir, struct inode * inode,
     /* [previous][next][first][last][top][bottom][index][help] */
  44         int flag, int mode, struct inode ** res_inode)
  45 {
  46         int error;
  47         struct buffer_head * bh;
  48 
  49         *res_inode = NULL;
  50         if (!dir) {
  51                 dir = current->fs->root;
  52                 dir->i_count++;
  53         }
  54         if (!inode) {
  55                 iput(dir);
  56                 return -ENOENT;
  57         }
  58         if (!S_ISLNK(inode->i_mode)) {
  59                 iput(dir);
  60                 *res_inode = inode;
  61                 return 0;
  62         }
  63         if (current->link_count > 5) {
  64                 iput(inode);
  65                 iput(dir);
  66                 return -ELOOP;
  67         }
  68         if (!(bh = minix_bread(inode, 0, 0))) {
  69                 iput(inode);
  70                 iput(dir);
  71                 return -EIO;
  72         }
  73         iput(inode);
  74         current->link_count++;
  75         error = open_namei(bh->b_data,flag,mode,res_inode,dir);
  76         current->link_count--;
  77         brelse(bh);
  78         return error;
  79 }
  80 
  81 static int minix_readlink(struct inode * inode, char * buffer, int buflen)
     /* [previous][next][first][last][top][bottom][index][help] */
  82 {
  83         struct buffer_head * bh;
  84         int i;
  85         char c;
  86 
  87         if (!S_ISLNK(inode->i_mode)) {
  88                 iput(inode);
  89                 return -EINVAL;
  90         }
  91         if (buflen > 1023)
  92                 buflen = 1023;
  93         bh = minix_bread(inode, 0, 0);
  94         iput(inode);
  95         if (!bh)
  96                 return 0;
  97         i = 0;
  98         while (i<buflen && (c = bh->b_data[i])) {
  99                 i++;
 100                 put_user(c,buffer++);
 101         }
 102         brelse(bh);
 103         return i;
 104 }

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