root/fs/nfs/symlink.c

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

DEFINITIONS

This source file includes following definitions.
  1. nfs_follow_link
  2. nfs_readlink

   1 /*
   2  *  linux/fs/nfs/symlink.c
   3  *
   4  *  Copyright (C) 1992  Rick Sladkey
   5  *
   6  *  Optimization changes Copyright (C) 1994 Florian La Roche
   7  *
   8  *  nfs symlink handling code
   9  */
  10 
  11 #include <asm/segment.h>
  12 
  13 #include <linux/sched.h>
  14 #include <linux/errno.h>
  15 #include <linux/nfs_fs.h>
  16 #include <linux/stat.h>
  17 #include <linux/mm.h>
  18 #include <linux/malloc.h>
  19 #include <linux/string.h>
  20 
  21 static int nfs_readlink(struct inode *, char *, int);
  22 static int nfs_follow_link(struct inode *, struct inode *, int, int,
  23                            struct inode **);
  24 
  25 /*
  26  * symlinks can't do much...
  27  */
  28 struct inode_operations nfs_symlink_inode_operations = {
  29         NULL,                   /* no file-operations */
  30         NULL,                   /* create */
  31         NULL,                   /* lookup */
  32         NULL,                   /* link */
  33         NULL,                   /* unlink */
  34         NULL,                   /* symlink */
  35         NULL,                   /* mkdir */
  36         NULL,                   /* rmdir */
  37         NULL,                   /* mknod */
  38         NULL,                   /* rename */
  39         nfs_readlink,           /* readlink */
  40         nfs_follow_link,        /* follow_link */
  41         NULL,                   /* bmap */
  42         NULL,                   /* truncate */
  43         NULL                    /* permission */
  44 };
  45 
  46 static int nfs_follow_link(struct inode *dir, struct inode *inode,
     /* [previous][next][first][last][top][bottom][index][help] */
  47                            int flag, int mode, struct inode **res_inode)
  48 {
  49         int error, *mem;
  50         unsigned int len;
  51         char *res, *res2;
  52 
  53         *res_inode = NULL;
  54         if (!dir) {
  55                 dir = current->fs->root;
  56                 dir->i_count++;
  57         }
  58         if (!inode) {
  59                 iput(dir);
  60                 return -ENOENT;
  61         }
  62         if (!S_ISLNK(inode->i_mode)) {
  63                 iput(dir);
  64                 *res_inode = inode;
  65                 return 0;
  66         }
  67         if (current->link_count > 5) {
  68                 iput(inode);
  69                 iput(dir);
  70                 return -ELOOP;
  71         }
  72         error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), &mem,
  73                 &res, &len, NFS_MAXPATHLEN);
  74 #if 0
  75         if ((res2 = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_KERNEL)) == NULL) {
  76                 printk("NFS: no memory in nfs_follow_link\n");
  77                 error = -EIO;
  78         }
  79 #else
  80         while ((res2 = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_KERNEL)) == NULL) {
  81                 schedule();
  82         }
  83 #endif
  84         if (error) {
  85                 iput(inode);
  86                 iput(dir);
  87                 kfree(mem);
  88                 return error;
  89         }
  90         memcpy(res2, res, len);
  91         res2[len] = '\0';
  92         kfree(mem);
  93         iput(inode);
  94         current->link_count++;
  95         error = open_namei(res2, flag, mode, res_inode, dir);
  96         current->link_count--;
  97         kfree_s(res2, NFS_MAXPATHLEN + 1);
  98         return error;
  99 }
 100 
 101 static int nfs_readlink(struct inode *inode, char *buffer, int buflen)
     /* [previous][next][first][last][top][bottom][index][help] */
 102 {
 103         int error, *mem;
 104         unsigned int len;
 105         char *res;
 106 
 107         if (!S_ISLNK(inode->i_mode)) {
 108                 iput(inode);
 109                 return -EINVAL;
 110         }
 111         if (buflen > NFS_MAXPATHLEN)
 112                 buflen = NFS_MAXPATHLEN;
 113         error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), &mem,
 114                 &res, &len, buflen);
 115         iput(inode);
 116         if (! error) {
 117                 memcpy_tofs(buffer, res, len);
 118                 put_fs_byte('\0', buffer + len);
 119                 error = len;
 120         }
 121         kfree(mem);
 122         return error;
 123 }

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