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

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