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 <asm/segment.h>
  10 
  11 #include <linux/errno.h>
  12 #include <linux/sched.h>
  13 #include <linux/fs.h>
  14 #include <linux/minix_fs.h>
  15 #include <linux/stat.h>
  16 
  17 static int minix_readlink(struct inode *, char *, int);
  18 static struct inode * minix_follow_link(struct inode *, 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,                   /* bmap */
  37         NULL                    /* truncate */
  38 };
  39 
  40 static struct inode * minix_follow_link(struct inode * dir, struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  41 {
  42         unsigned short fs;
  43         struct buffer_head * bh;
  44 
  45         if (!dir) {
  46                 dir = current->root;
  47                 dir->i_count++;
  48         }
  49         if (!inode) {
  50                 iput(dir);
  51                 return NULL;
  52         }
  53         if (!S_ISLNK(inode->i_mode)) {
  54                 iput(dir);
  55                 return inode;
  56         }
  57         __asm__("mov %%fs,%0":"=r" (fs));
  58         if ((current->link_count > 5) || !inode->i_data[0] ||
  59            !(bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE))) {
  60                 iput(dir);
  61                 iput(inode);
  62                 return NULL;
  63         }
  64         iput(inode);
  65         __asm__("mov %0,%%fs"::"r" ((unsigned short) 0x10));
  66         current->link_count++;
  67         inode = _namei(bh->b_data,dir,1);
  68         current->link_count--;
  69         __asm__("mov %0,%%fs"::"r" (fs));
  70         brelse(bh);
  71         return inode;
  72 }
  73 
  74 static int minix_readlink(struct inode * inode, char * buffer, int buflen)
     /* [previous][next][first][last][top][bottom][index][help] */
  75 {
  76         struct buffer_head * bh;
  77         int i;
  78         char c;
  79 
  80         if (!S_ISLNK(inode->i_mode)) {
  81                 iput(inode);
  82                 return -EINVAL;
  83         }
  84         if (buflen > 1023)
  85                 buflen = 1023;
  86         if (inode->i_data[0])
  87                 bh = bread(inode->i_dev, inode->i_data[0], BLOCK_SIZE);
  88         else
  89                 bh = NULL;
  90         iput(inode);
  91         if (!bh)
  92                 return 0;
  93         i = 0;
  94         while (i<buflen && (c = bh->b_data[i])) {
  95                 i++;
  96                 put_fs_byte(c,buffer++);
  97         }
  98         brelse(bh);
  99         return i;
 100 }

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