Fork me on GitHub

root/fs/minix/symlink.c

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

DEFINITIONS

This source file includes following definitions.
  1. minix_readlink
  2. minix_followlink

   1 /*
   2  * fiwix/fs/minix/symlink.c
   3  *
   4  * Copyright 2018, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/types.h>
   9 #include <fiwix/errno.h>
  10 #include <fiwix/buffer.h>
  11 #include <fiwix/fs.h>
  12 #include <fiwix/filesystems.h>
  13 #include <fiwix/stat.h>
  14 #include <fiwix/stdio.h>
  15 #include <fiwix/string.h>
  16 
  17 struct fs_operations minix_symlink_fsop = {
  18         0,
  19         0,
  20 
  21         NULL,                   /* open */
  22         NULL,                   /* close */
  23         NULL,                   /* read */
  24         NULL,                   /* write */
  25         NULL,                   /* ioctl */
  26         NULL,                   /* lseek */
  27         NULL,                   /* readdir */
  28         NULL,                   /* mmap */
  29         NULL,                   /* select */
  30 
  31         minix_readlink,
  32         minix_followlink,
  33         NULL,                   /* bmap */
  34         NULL,                   /* lookup */
  35         NULL,                   /* rmdir */
  36         NULL,                   /* link */
  37         NULL,                   /* unlink */
  38         NULL,                   /* symlink */
  39         NULL,                   /* mkdir */
  40         NULL,                   /* mknod */
  41         NULL,                   /* truncate */
  42         NULL,                   /* create */
  43         NULL,                   /* rename */
  44 
  45         NULL,                   /* read_block */
  46         NULL,                   /* write_block */
  47 
  48         NULL,                   /* read_inode */
  49         NULL,                   /* write_inode */
  50         NULL,                   /* ialloc */
  51         NULL,                   /* ifree */
  52         NULL,                   /* statfs */
  53         NULL,                   /* read_superblock */
  54         NULL,                   /* remount_fs */
  55         NULL,                   /* write_superblock */
  56         NULL                    /* release_superblock */
  57 };
  58 
  59 int minix_readlink(struct inode *i, char *buffer, __size_t count)
  60 {
  61         __u32 blksize;
  62         struct buffer *buf;
  63 
  64         if(!S_ISLNK(i->i_mode)) {
  65                 printk("%s(): Oops, inode '%d' is not a symlink (!?).\n", __FUNCTION__, i->inode);
  66                 return 0;
  67         }
  68 
  69         inode_lock(i);
  70         blksize = i->sb->s_blocksize;
  71         count = MIN(count, i->i_size);
  72         if(!count) {
  73                 inode_unlock(i);
  74                 return 0;
  75         }
  76         count = MIN(count, blksize);
  77         if(i->sb->u.minix.version == 1) {
  78                 if(!(buf = bread(i->dev, i->u.minix.u.i1_zone[0], blksize))) {
  79                         inode_unlock(i);
  80                         return -EIO;
  81                 }
  82         } else {
  83                 if(!(buf = bread(i->dev, i->u.minix.u.i2_zone[0], blksize))) {
  84                         inode_unlock(i);
  85                         return -EIO;
  86                 }
  87         }
  88         memcpy_b(buffer, buf->data, count);
  89         brelse(buf);
  90         buffer[count] = NULL;
  91         inode_unlock(i);
  92         return count;
  93 }
  94 
  95 int minix_followlink(struct inode *dir, struct inode *i, struct inode **i_res)
  96 {
  97         struct buffer *buf;
  98         char *name;
  99         __ino_t errno;
 100 
 101         if(!i) {
 102                 return -ENOENT;
 103         }
 104 
 105         if(!S_ISLNK(i->i_mode)) {
 106                 printk("%s(): Oops, inode '%d' is not a symlink (!?).\n", __FUNCTION__, i->inode);
 107                 return 0;
 108         }
 109 
 110         if(current->loopcnt > MAX_SYMLINKS) {
 111                 printk("%s(): too many nested symbolic links!\n", __FUNCTION__);
 112                 return -ELOOP;
 113         }
 114 
 115         inode_lock(i);
 116         if(i->sb->u.minix.version == 1) {
 117                 if(!(buf = bread(i->dev, i->u.minix.u.i1_zone[0], i->sb->s_blocksize))) {
 118                         inode_unlock(i);
 119                         return -EIO;
 120                 }
 121         } else {
 122                 if(!(buf = bread(i->dev, i->u.minix.u.i2_zone[0], i->sb->s_blocksize))) {
 123                         inode_unlock(i);
 124                         return -EIO;
 125                 }
 126         }
 127         name = buf->data;
 128         inode_unlock(i);
 129 
 130         current->loopcnt++;
 131         iput(i);
 132         brelse(buf);
 133         errno = parse_namei(name, dir, i_res, NULL, FOLLOW_LINKS);
 134         current->loopcnt--;
 135         return errno;
 136 }

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