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  *  nfs symlink handling code
   7  */
   8 
   9 #include <asm/segment.h>
  10 
  11 #include <linux/sched.h>
  12 #include <linux/errno.h>
  13 #include <linux/nfs_fs.h>
  14 #include <linux/stat.h>
  15 #include <linux/mm.h>
  16 
  17 static int nfs_readlink(struct inode *, char *, int);
  18 static int nfs_follow_link(struct inode *, struct inode *, int, int,
  19                            struct inode **);
  20 
  21 /*
  22  * symlinks can't do much...
  23  */
  24 struct inode_operations nfs_symlink_inode_operations = {
  25         NULL,                   /* no file-operations */
  26         NULL,                   /* create */
  27         NULL,                   /* lookup */
  28         NULL,                   /* link */
  29         NULL,                   /* unlink */
  30         NULL,                   /* symlink */
  31         NULL,                   /* mkdir */
  32         NULL,                   /* rmdir */
  33         NULL,                   /* mknod */
  34         NULL,                   /* rename */
  35         nfs_readlink,           /* readlink */
  36         nfs_follow_link,        /* follow_link */
  37         NULL,                   /* bmap */
  38         NULL,                   /* truncate */
  39         NULL                    /* permission */
  40 };
  41 
  42 static int nfs_follow_link(struct inode *dir, struct inode *inode,
     /* [previous][next][first][last][top][bottom][index][help] */
  43                            int flag, int mode, struct inode **res_inode)
  44 {
  45         int error;
  46         char *res;
  47 
  48         *res_inode = NULL;
  49         if (!dir) {
  50                 dir = current->root;
  51                 dir->i_count++;
  52         }
  53         if (!inode) {
  54                 iput(dir);
  55                 return -ENOENT;
  56         }
  57         if (!S_ISLNK(inode->i_mode)) {
  58                 iput(dir);
  59                 *res_inode = inode;
  60                 return 0;
  61         }
  62         if (current->link_count > 5) {
  63                 iput(inode);
  64                 iput(dir);
  65                 return -ELOOP;
  66         }
  67         res = (char *) kmalloc(NFS_MAXPATHLEN + 1, GFP_KERNEL);
  68         error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), res);
  69         if (error) {
  70                 iput(inode);
  71                 iput(dir);
  72                 kfree_s(res, NFS_MAXPATHLEN + 1);
  73                 return error;
  74         }
  75         iput(inode);
  76         current->link_count++;
  77         error = open_namei(res, flag, mode, res_inode, dir);
  78         current->link_count--;
  79         kfree_s(res, NFS_MAXPATHLEN + 1);
  80         return error;
  81 }
  82 
  83 static int nfs_readlink(struct inode *inode, char *buffer, int buflen)
     /* [previous][next][first][last][top][bottom][index][help] */
  84 {
  85         int i;
  86         char c;
  87         int error;
  88         char *res;
  89 
  90         if (!S_ISLNK(inode->i_mode)) {
  91                 iput(inode);
  92                 return -EINVAL;
  93         }
  94         if (buflen > NFS_MAXPATHLEN)
  95                 buflen = NFS_MAXPATHLEN;
  96         res = (char *) kmalloc(buflen + 1, GFP_KERNEL);
  97         error = nfs_proc_readlink(NFS_SERVER(inode), NFS_FH(inode), res);
  98         iput(inode);
  99         if (error) {
 100                 kfree_s(res, buflen + 1);
 101                 return error;
 102         }
 103         for (i = 0; i < buflen && (c = res[i]); i++)
 104                 put_fs_byte(c,buffer++);
 105         kfree_s(res, buflen + 1);
 106         return i;
 107 }

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