root/fs/xiafs/symlink.c

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

DEFINITIONS

This source file includes following definitions.
  1. xiafs_readlink
  2. xiafs_follow_link

   1 /*
   2  *  linux/fs/xiafs/symlink.c
   3  *
   4  *  Copyright (C) Q. Frank Xia, 1993.
   5  *  
   6  *  Based on Linus' minix/symlink.c
   7  *  Copyright (C) Linus Torvalds, 1991, 1992.
   8  *
   9  *  This software may be redistributed per Linux Copyright.
  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/xia_fs.h>
  18 #include <linux/stat.h>
  19 
  20 static int 
  21 xiafs_readlink(struct inode *, char *, int);
  22 
  23 static int 
  24 xiafs_follow_link(struct inode *, struct inode *, int, int, struct inode **);
  25 
  26 /*
  27  * symlinks can't do much...
  28  */
  29 struct inode_operations xiafs_symlink_inode_operations = {
  30         NULL,                   /* no file-operations */
  31         NULL,                   /* create */
  32         NULL,                   /* lookup */
  33         NULL,                   /* link */
  34         NULL,                   /* unlink */
  35         NULL,                   /* symlink */
  36         NULL,                   /* mkdir */
  37         NULL,                   /* rmdir */
  38         NULL,                   /* mknod */
  39         NULL,                   /* rename */
  40         xiafs_readlink,         /* readlink */
  41         xiafs_follow_link,      /* follow_link */
  42         NULL,                   /* bmap */
  43         NULL,                   /* truncate */
  44         NULL                    /* permission */
  45 };
  46 
  47 static int xiafs_readlink(struct inode * inode, char * buffer, int buflen)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49     struct buffer_head * bh;
  50     int i;
  51     char c;
  52 
  53     if (!S_ISLNK(inode->i_mode)) {
  54         iput(inode);
  55         return -EINVAL;
  56     }
  57     if (buflen > BLOCK_SIZE)
  58         buflen = BLOCK_SIZE;
  59     bh = xiafs_bread(inode, 0, 0);
  60     inode->i_atime=CURRENT_TIME;
  61     inode->i_dirt=1;
  62     iput(inode);
  63     if (!bh)
  64         return 0;
  65     for (i=0; i < buflen && (c=bh->b_data[i]); i++)
  66       put_fs_byte(c, buffer++);
  67     if (i < buflen-1)
  68       put_fs_byte((char)0, buffer);
  69     brelse(bh);
  70     return i;
  71 }
  72 
  73 static int xiafs_follow_link(struct inode * dir, struct inode * inode,
     /* [previous][next][first][last][top][bottom][index][help] */
  74         int flag, int mode, struct inode ** res_inode)
  75 {
  76     int error;
  77     struct buffer_head * bh;
  78 
  79     *res_inode = NULL;
  80     if (!dir) {
  81         dir = current->root;
  82         dir->i_count++;
  83     }
  84     if (!inode) {
  85         iput(dir);
  86         return -ENOENT;
  87     }
  88     if (!S_ISLNK(inode->i_mode)) {
  89         iput(dir);
  90         *res_inode = inode;
  91         return 0;
  92     }
  93     inode->i_atime=CURRENT_TIME;
  94     inode->i_dirt=1;
  95     if (current->link_count > 5) {
  96         iput(inode);
  97         iput(dir);
  98         return -ELOOP;
  99     }
 100     if (!(bh = xiafs_bread(inode, 0, 0))) {
 101         iput(inode);
 102         iput(dir);
 103         return -EIO;
 104     }
 105     iput(inode);
 106     current->link_count++;
 107     error = open_namei(bh->b_data,flag,mode,res_inode,dir);
 108     current->link_count--;
 109     brelse(bh);
 110     return error;
 111 }
 112 
 113 
 114 

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