root/fs/umsdos/symlink.c

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

DEFINITIONS

This source file includes following definitions.
  1. umsdos_readlink_x
  2. UMSDOS_follow_link
  3. UMSDOS_readlink

   1 /*
   2  *  linux/fs/umsdos/file.c
   3  *
   4  *  Written 1992 by Jacques Gelinas
   5  *      inspired from linux/fs/msdos/file.c Werner Almesberger
   6  *
   7  *  Extended MS-DOS regular file handling primitives
   8  */
   9 
  10 #include <asm/segment.h>
  11 #include <asm/system.h>
  12 
  13 #include <linux/sched.h>
  14 #include <linux/fs.h>
  15 #include <linux/msdos_fs.h>
  16 #include <linux/errno.h>
  17 #include <linux/fcntl.h>
  18 #include <linux/stat.h>
  19 #include <linux/umsdos_fs.h>
  20 #include <linux/malloc.h>
  21 
  22 #define PRINTK(x)
  23 #define Printk(x)       printk x
  24 /*
  25         Read the data associate with the symlink.
  26         Return length read in buffer or  a negative error code.
  27 */
  28 static int umsdos_readlink_x (
     /* [previous][next][first][last][top][bottom][index][help] */
  29         struct inode *inode,
  30         char *buffer,
  31         int (*msdos_read)(struct inode *, struct file *, char *, int),
  32         int bufsiz)
  33 {
  34         int ret = inode->i_size;
  35         struct file filp;
  36         filp.f_pos = 0;
  37         filp.f_reada = 0;
  38         if (ret > bufsiz) ret = bufsiz;
  39         if ((*msdos_read) (inode, &filp, buffer,ret) != ret){
  40                 ret = -EIO;
  41         }
  42         return ret;
  43 }
  44 /*
  45         Follow a symbolic link chain by calling open_namei recursively
  46         until an inode is found.
  47 
  48         Return 0 if ok, or a negative error code if not.
  49 */
  50 static int UMSDOS_follow_link(
     /* [previous][next][first][last][top][bottom][index][help] */
  51         struct inode * dir,
  52         struct inode * inode,
  53         int flag,
  54         int mode,
  55         struct inode ** res_inode)
  56 {
  57         int ret = -ELOOP;
  58         *res_inode = NULL;
  59         if (current->link_count < 5) {
  60                 char *path = (char*)kmalloc(PATH_MAX,GFP_KERNEL);
  61                 if (path == NULL){
  62                         ret = -ENOMEM;
  63                 }else{
  64                         if (!dir) {
  65                                 dir = current->fs[1].root;
  66                                 dir->i_count++;
  67                         }
  68                         if (!inode){
  69                                 PRINTK (("symlink: inode = NULL\n"));
  70                                 ret = -ENOENT;
  71                         }else if (!S_ISLNK(inode->i_mode)){
  72                                 PRINTK (("symlink: Not ISLNK\n"));
  73                                 *res_inode = inode;
  74                                 inode = NULL;
  75                                 ret = 0;
  76                         }else{
  77                                 ret = umsdos_readlink_x (inode,path
  78                                         ,umsdos_file_read_kmem,PATH_MAX-1);
  79                                 if (ret > 0){
  80                                         path[ret] = '\0';
  81                                         PRINTK (("follow :%s: %d ",path,ret));
  82                                         iput(inode);
  83                                         inode = NULL;
  84                                         current->link_count++;
  85                                         ret = open_namei(path,flag,mode,res_inode,dir);
  86                                         current->link_count--;
  87                                         dir = NULL;
  88                                 }else{
  89                                         ret = -EIO;
  90                                 }
  91                         }
  92                         kfree (path);
  93                 }
  94         }       
  95         iput(inode);
  96         iput(dir);
  97         PRINTK (("follow_link ret %d\n",ret));
  98         return ret;
  99 }
 100 
 101 static int UMSDOS_readlink(struct inode * inode, char * buffer, int buflen)
     /* [previous][next][first][last][top][bottom][index][help] */
 102 {
 103         int ret = -EINVAL;
 104         if (S_ISLNK(inode->i_mode)) {
 105                 ret = umsdos_readlink_x (inode,buffer,msdos_file_read,buflen);
 106         }
 107         PRINTK (("readlink %d %x bufsiz %d\n",ret,inode->i_mode,buflen));
 108         iput(inode);
 109         return ret;
 110         
 111 }
 112 
 113 static struct file_operations umsdos_symlink_operations = {
 114         NULL,                           /* lseek - default */
 115         NULL,                           /* read */
 116         NULL,                           /* write */
 117         NULL,                           /* readdir - bad */
 118         NULL,                           /* select - default */
 119         NULL,                           /* ioctl - default */
 120         NULL,                           /* mmap */
 121         NULL,                           /* no special open is needed */
 122         NULL,                           /* release */
 123         NULL                            /* fsync */
 124 };
 125 
 126 struct inode_operations umsdos_symlink_inode_operations = {
 127         &umsdos_symlink_operations,     /* default file operations */
 128         NULL,                   /* create */
 129         NULL,                   /* lookup */
 130         NULL,                   /* link */
 131         NULL,                   /* unlink */
 132         NULL,                   /* symlink */
 133         NULL,                   /* mkdir */
 134         NULL,                   /* rmdir */
 135         NULL,                   /* mknod */
 136         NULL,                   /* rename */
 137         UMSDOS_readlink,        /* readlink */
 138         UMSDOS_follow_link,     /* follow_link */
 139         NULL,                   /* bmap */
 140         NULL,                   /* truncate */
 141         NULL                    /* permission */
 142 };
 143 
 144 
 145 

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