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         if (ret > bufsiz) ret = bufsiz;
  38         if ((*msdos_read) (inode, &filp, buffer,ret) != ret){
  39                 ret = -EIO;
  40         }
  41         return ret;
  42 }
  43 /*
  44         Follow a symbolic link chain by calling open_namei recursively
  45         until an inode is found.
  46 
  47         Return 0 if ok, or a negative error code if not.
  48 */
  49 static int UMSDOS_follow_link(
     /* [previous][next][first][last][top][bottom][index][help] */
  50         struct inode * dir,
  51         struct inode * inode,
  52         int flag,
  53         int mode,
  54         struct inode ** res_inode)
  55 {
  56         int ret = -ELOOP;
  57         *res_inode = NULL;
  58         if (current->link_count < 5) {
  59                 char *path = (char*)kmalloc(PATH_MAX,GFP_KERNEL);
  60                 if (path == NULL){
  61                         ret = -ENOMEM;
  62                 }else{
  63                         if (!dir) {
  64                                 dir = current->fs[1].root;
  65                                 dir->i_count++;
  66                         }
  67                         if (!inode){
  68                                 PRINTK (("symlink: inode = NULL\n"));
  69                                 ret = -ENOENT;
  70                         }else if (!S_ISLNK(inode->i_mode)){
  71                                 PRINTK (("symlink: Not ISLNK\n"));
  72                                 *res_inode = inode;
  73                                 inode = NULL;
  74                                 ret = 0;
  75                         }else{
  76                                 ret = umsdos_readlink_x (inode,path
  77                                         ,umsdos_file_read_kmem,PATH_MAX-1);
  78                                 if (ret > 0){
  79                                         path[ret] = '\0';
  80                                         PRINTK (("follow :%s: %d ",path,ret));
  81                                         iput(inode);
  82                                         inode = NULL;
  83                                         current->link_count++;
  84                                         ret = open_namei(path,flag,mode,res_inode,dir);
  85                                         current->link_count--;
  86                                         dir = NULL;
  87                                 }else{
  88                                         ret = -EIO;
  89                                 }
  90                         }
  91                         kfree (path);
  92                 }
  93         }       
  94         iput(inode);
  95         iput(dir);
  96         PRINTK (("follow_link ret %d\n",ret));
  97         return ret;
  98 }
  99 
 100 static int UMSDOS_readlink(struct inode * inode, char * buffer, int buflen)
     /* [previous][next][first][last][top][bottom][index][help] */
 101 {
 102         int ret = -EINVAL;
 103         if (S_ISLNK(inode->i_mode)) {
 104                 ret = umsdos_readlink_x (inode,buffer,msdos_file_read,buflen);
 105         }
 106         PRINTK (("readlink %d %x bufsiz %d\n",ret,inode->i_mode,buflen));
 107         iput(inode);
 108         return ret;
 109         
 110 }
 111 
 112 static struct file_operations umsdos_symlink_operations = {
 113         NULL,                           /* lseek - default */
 114         NULL,                           /* read */
 115         NULL,                           /* write */
 116         NULL,                           /* readdir - bad */
 117         NULL,                           /* select - default */
 118         NULL,                           /* ioctl - default */
 119         NULL,                           /* mmap */
 120         NULL,                           /* no special open is needed */
 121         NULL,                           /* release */
 122         NULL                            /* fsync */
 123 };
 124 
 125 struct inode_operations umsdos_symlink_inode_operations = {
 126         &umsdos_symlink_operations,     /* default file operations */
 127         NULL,                   /* create */
 128         NULL,                   /* lookup */
 129         NULL,                   /* link */
 130         NULL,                   /* unlink */
 131         NULL,                   /* symlink */
 132         NULL,                   /* mkdir */
 133         NULL,                   /* rmdir */
 134         NULL,                   /* mknod */
 135         NULL,                   /* rename */
 136         UMSDOS_readlink,        /* readlink */
 137         UMSDOS_follow_link,     /* follow_link */
 138         NULL,                   /* bmap */
 139         NULL,                   /* truncate */
 140         NULL                    /* permission */
 141 };
 142 
 143 
 144 

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