OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [umsdos/] [symlink.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1628 jcastillo
/*
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 (
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(
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)
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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.