home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / KERNEL-S / V1.0 / LINUX-1.0 / LINUX-1 / linux / fs / nfs / symlink.c < prev   
Encoding:
C/C++ Source or Header  |  1993-12-01  |  2.2 KB  |  109 lines

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