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

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