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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [parisc/] [hpux/] [fs.c] - Blame information for rev 1275

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

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * linux/arch/parisc/kernel/sys_hpux.c
3
 *
4
 * implements HPUX syscalls.
5
 */
6
 
7
#include <linux/mm.h>
8
#include <linux/sched.h>
9
#include <linux/file.h>
10
#include <linux/smp_lock.h>
11
#include <linux/slab.h>
12
#include <asm/errno.h>
13
#include <asm/uaccess.h>
14
 
15
int hpux_execve(struct pt_regs *regs)
16
{
17
        int error;
18
        char *filename;
19
 
20
        filename = getname((char *) regs->gr[26]);
21
        error = PTR_ERR(filename);
22
        if (IS_ERR(filename))
23
                goto out;
24
 
25
        error = do_execve(filename, (char **) regs->gr[25],
26
                (char **)regs->gr[24], regs);
27
 
28
        if (error == 0)
29
                current->ptrace &= ~PT_DTRACE;
30
        putname(filename);
31
 
32
out:
33
        return error;
34
}
35
 
36
struct hpux_dirent {
37
        long    d_off_pad; /* we only have a 32-bit off_t */
38
        long    d_off;
39
        ino_t   d_ino;
40
        short   d_reclen;
41
        short   d_namlen;
42
        char    d_name[1];
43
};
44
 
45
struct getdents_callback {
46
        struct hpux_dirent *current_dir;
47
        struct hpux_dirent *previous;
48
        int count;
49
        int error;
50
};
51
 
52
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
53
#define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1))
54
 
55
static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
56
                ino_t ino, unsigned int d_type)
57
{
58
        struct hpux_dirent * dirent;
59
        struct getdents_callback * buf = (struct getdents_callback *) __buf;
60
        int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
61
 
62
        buf->error = -EINVAL;   /* only used if we fail.. */
63
        if (reclen > buf->count)
64
                return -EINVAL;
65
        dirent = buf->previous;
66
        if (dirent)
67
                put_user(offset, &dirent->d_off);
68
        dirent = buf->current_dir;
69
        buf->previous = dirent;
70
        put_user(ino, &dirent->d_ino);
71
        put_user(reclen, &dirent->d_reclen);
72
        put_user(namlen, &dirent->d_namlen);
73
        copy_to_user(dirent->d_name, name, namlen);
74
        put_user(0, dirent->d_name + namlen);
75
        ((char *) dirent) += reclen;
76
        buf->current_dir = dirent;
77
        buf->count -= reclen;
78
        return 0;
79
}
80
 
81
#undef NAME_OFFSET
82
#undef ROUND_UP
83
 
84
int hpux_getdents(unsigned int fd, struct hpux_dirent *dirent, unsigned int count)
85
{
86
        struct file * file;
87
        struct hpux_dirent * lastdirent;
88
        struct getdents_callback buf;
89
        int error;
90
 
91
        error = -EBADF;
92
        file = fget(fd);
93
        if (!file)
94
                goto out;
95
 
96
        buf.current_dir = dirent;
97
        buf.previous = NULL;
98
        buf.count = count;
99
        buf.error = 0;
100
 
101
        error = vfs_readdir(file, filldir, &buf);
102
        if (error < 0)
103
                goto out_putf;
104
        error = buf.error;
105
        lastdirent = buf.previous;
106
        if (lastdirent) {
107
                put_user(file->f_pos, &lastdirent->d_off);
108
                error = count - buf.count;
109
        }
110
 
111
out_putf:
112
        fput(file);
113
out:
114
        return error;
115
}
116
 
117
int hpux_mount(const char *fs, const char *path, int mflag,
118
                const char *fstype, const char *dataptr, int datalen)
119
{
120
        return -ENOSYS;
121
}
122
 
123
static int cp_hpux_stat(struct inode * inode, struct hpux_stat64 * statbuf)
124
{
125
        struct hpux_stat64 tmp;
126
        unsigned int blocks, indirect;
127
 
128
        memset(&tmp, 0, sizeof(tmp));
129
        tmp.st_dev = kdev_t_to_nr(inode->i_dev);
130
        tmp.st_ino = inode->i_ino;
131
        tmp.st_mode = inode->i_mode;
132
        tmp.st_nlink = inode->i_nlink;
133
        tmp.st_uid = inode->i_uid;
134
        tmp.st_gid = inode->i_gid;
135
        tmp.st_rdev = kdev_t_to_nr(inode->i_rdev);
136
        tmp.st_size = inode->i_size;
137
        tmp.st_atime = inode->i_atime;
138
        tmp.st_mtime = inode->i_mtime;
139
        tmp.st_ctime = inode->i_ctime;
140
 
141
#define D_B   7
142
#define I_B   (BLOCK_SIZE / sizeof(unsigned short))
143
 
144
        if (!inode->i_blksize) {
145
                blocks = (tmp.st_size + BLOCK_SIZE - 1) / BLOCK_SIZE;
146
                if (blocks > D_B) {
147
                        indirect = (blocks - D_B + I_B - 1) / I_B;
148
                        blocks += indirect;
149
                        if (indirect > 1) {
150
                                indirect = (indirect - 1 + I_B - 1) / I_B;
151
                                blocks += indirect;
152
                                if (indirect > 1)
153
                                        blocks++;
154
                        }
155
                }
156
                tmp.st_blocks = (BLOCK_SIZE / 512) * blocks;
157
                tmp.st_blksize = BLOCK_SIZE;
158
        } else {
159
                tmp.st_blocks = inode->i_blocks;
160
                tmp.st_blksize = inode->i_blksize;
161
        }
162
        return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
163
}
164
 
165
/*
166
 * Revalidate the inode. This is required for proper NFS attribute caching.
167
 * Blatently copied wholesale from fs/stat.c
168
 */
169
static __inline__ int
170
do_revalidate(struct dentry *dentry)
171
{
172
        struct inode * inode = dentry->d_inode;
173
        if (inode->i_op && inode->i_op->revalidate)
174
                return inode->i_op->revalidate(dentry);
175
        return 0;
176
}
177
 
178
long hpux_stat64(const char *path, struct hpux_stat64 *buf)
179
{
180
        struct nameidata nd;
181
        int error;
182
 
183
        lock_kernel();
184
        error = user_path_walk(path, &nd);
185
        if (!error) {
186
                error = do_revalidate(nd.dentry);
187
                if (!error)
188
                        error = cp_hpux_stat(nd.dentry->d_inode, buf);
189
                path_release(&nd);
190
        }
191
        unlock_kernel();
192
        return error;
193
}
194
 
195
long hpux_fstat64(unsigned int fd, struct hpux_stat64 *statbuf)
196
{
197
        struct file * f;
198
        int err = -EBADF;
199
 
200
        lock_kernel();
201
        f = fget(fd);
202
        if (f) {
203
                struct dentry * dentry = f->f_dentry;
204
 
205
                err = do_revalidate(dentry);
206
                if (!err)
207
                        err = cp_hpux_stat(dentry->d_inode, statbuf);
208
                fput(f);
209
        }
210
        unlock_kernel();
211
        return err;
212
}
213
 
214
long hpux_lstat64(char *filename, struct hpux_stat64 *statbuf)
215
{
216
        struct nameidata nd;
217
        int error;
218
 
219
        lock_kernel();
220
        error = user_path_walk_link(filename, &nd);
221
        if (!error) {
222
                error = do_revalidate(nd.dentry);
223
                if (!error)
224
                        error = cp_hpux_stat(nd.dentry->d_inode, statbuf);
225
                path_release(&nd);
226
        }
227
        unlock_kernel();
228
        return error;
229
}

powered by: WebSVN 2.1.0

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