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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [smbfs/] [file.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1628 jcastillo
/*
2
 *  file.c
3
 *
4
 *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
5
 *
6
 */
7
 
8
#include <asm/segment.h>
9
#include <asm/system.h>
10
 
11
#include <linux/sched.h>
12
#include <linux/kernel.h>
13
#include <linux/errno.h>
14
#include <linux/fcntl.h>
15
#include <linux/stat.h>
16
#include <linux/mm.h>
17
#include <linux/smb_fs.h>
18
#include <linux/malloc.h>
19
 
20
static inline int
21
min(int a, int b)
22
{
23
        return a < b ? a : b;
24
}
25
 
26
static int
27
smb_fsync(struct inode *inode, struct file *file)
28
{
29
        return 0;
30
}
31
 
32
int
33
smb_make_open(struct inode *i, int right)
34
{
35
        struct smb_dirent *dirent;
36
 
37
        if (i == NULL)
38
        {
39
                printk("smb_make_open: got NULL inode\n");
40
                return -EINVAL;
41
        }
42
        dirent = &(SMB_INOP(i)->finfo);
43
 
44
        DDPRINTK("smb_make_open: dirent->opened = %d\n", dirent->opened);
45
 
46
        if ((dirent->opened) == 0)
47
        {
48
                /* tries max. rights */
49
                int open_result = smb_proc_open(SMB_SERVER(i),
50
                                                SMB_INOP(i)->dir,
51
                                                dirent->name, dirent->len,
52
                                                dirent);
53
                if (open_result)
54
                {
55
                        return open_result;
56
                }
57
        }
58
        if (((right == O_RDONLY) && ((dirent->access == O_RDONLY)
59
                                     || (dirent->access == O_RDWR)))
60
            || ((right == O_WRONLY) && ((dirent->access == O_WRONLY)
61
                                        || (dirent->access == O_RDWR)))
62
            || ((right == O_RDWR) && (dirent->access == O_RDWR)))
63
                return 0;
64
 
65
        return -EACCES;
66
}
67
 
68
static int
69
smb_file_read(struct inode *inode, struct file *file, char *buf, int count)
70
{
71
        int result, bufsize, to_read, already_read;
72
        off_t pos;
73
        int errno;
74
 
75
        DPRINTK("smb_file_read: enter %s\n", SMB_FINFO(inode)->name);
76
 
77
        if (!inode)
78
        {
79
                DPRINTK("smb_file_read: inode = NULL\n");
80
                return -EINVAL;
81
        }
82
        if (!S_ISREG(inode->i_mode))
83
        {
84
                DPRINTK("smb_file_read: read from non-file, mode %07o\n",
85
                        inode->i_mode);
86
                return -EINVAL;
87
        }
88
        if ((errno = smb_make_open(inode, O_RDONLY)) != 0)
89
                return errno;
90
 
91
        pos = file->f_pos;
92
 
93
        if (pos + count > inode->i_size)
94
        {
95
                count = inode->i_size - pos;
96
        }
97
        if (count <= 0)
98
        {
99
                return 0;
100
        }
101
        bufsize = SMB_SERVER(inode)->max_xmit - SMB_HEADER_LEN - 5 * 2 - 5;
102
 
103
        already_read = 0;
104
 
105
        /* First read in as much as possible for each bufsize. */
106
        while (already_read < count)
107
        {
108
                to_read = min(bufsize, count - already_read);
109
                result = smb_proc_read(SMB_SERVER(inode), SMB_FINFO(inode),
110
                                       pos, to_read, buf, 1);
111
                if (result < 0)
112
                {
113
                        return result;
114
                }
115
                pos += result;
116
                buf += result;
117
                already_read += result;
118
 
119
                if (result < to_read)
120
                {
121
                        break;
122
                }
123
        }
124
 
125
        file->f_pos = pos;
126
 
127
        if (!IS_RDONLY(inode))
128
                inode->i_atime = CURRENT_TIME;
129
        inode->i_dirt = 1;
130
 
131
        DPRINTK("smb_file_read: exit %s\n", SMB_FINFO(inode)->name);
132
 
133
        return already_read;
134
}
135
 
136
static int
137
smb_file_write(struct inode *inode, struct file *file, const char *buf,
138
               int count)
139
{
140
        int result, bufsize, to_write, already_written;
141
        off_t pos;
142
        int errno;
143
 
144
        if (!inode)
145
        {
146
                DPRINTK("smb_file_write: inode = NULL\n");
147
                return -EINVAL;
148
        }
149
        if (!S_ISREG(inode->i_mode))
150
        {
151
                DPRINTK("smb_file_write: write to non-file, mode %07o\n",
152
                        inode->i_mode);
153
                return -EINVAL;
154
        }
155
        DPRINTK("smb_file_write: enter %s\n", SMB_FINFO(inode)->name);
156
 
157
        if (count <= 0)
158
        {
159
                return 0;
160
        }
161
        if ((errno = smb_make_open(inode, O_RDWR)) != 0)
162
        {
163
                return errno;
164
        }
165
        pos = file->f_pos;
166
 
167
        if (file->f_flags & O_APPEND)
168
                pos = inode->i_size;
169
 
170
        bufsize = SMB_SERVER(inode)->max_xmit - SMB_HEADER_LEN - 5 * 2 - 5;
171
 
172
        already_written = 0;
173
 
174
        DPRINTK("smb_write_file: blkmode = %d, blkmode & 2 = %d\n",
175
                SMB_SERVER(inode)->blkmode,
176
                SMB_SERVER(inode)->blkmode & 2);
177
 
178
        while (already_written < count)
179
        {
180
                to_write = min(bufsize, count - already_written);
181
                result = smb_proc_write(SMB_SERVER(inode), SMB_FINFO(inode),
182
                                        pos, to_write, buf);
183
 
184
                if (result < 0)
185
                {
186
                        return result;
187
                }
188
                pos += result;
189
                buf += result;
190
                already_written += result;
191
 
192
                if (result < to_write)
193
                {
194
                        break;
195
                }
196
        }
197
 
198
        inode->i_mtime = inode->i_ctime = CURRENT_TIME;
199
        inode->i_dirt = 1;
200
 
201
        file->f_pos = pos;
202
 
203
        if (pos > inode->i_size)
204
        {
205
                inode->i_size = pos;
206
        }
207
        DPRINTK("smb_file_write: exit %s\n", SMB_FINFO(inode)->name);
208
 
209
        return already_written;
210
}
211
 
212
static struct file_operations smb_file_operations =
213
{
214
        NULL,                   /* lseek - default */
215
        smb_file_read,          /* read */
216
        smb_file_write,         /* write */
217
        NULL,                   /* readdir - bad */
218
        NULL,                   /* select - default */
219
        smb_ioctl,              /* ioctl */
220
        smb_mmap,               /* mmap */
221
        NULL,                   /* open */
222
        NULL,                   /* release */
223
        smb_fsync,              /* fsync */
224
};
225
 
226
struct inode_operations smb_file_inode_operations =
227
{
228
        &smb_file_operations,   /* default file operations */
229
        NULL,                   /* create */
230
        NULL,                   /* lookup */
231
        NULL,                   /* link */
232
        NULL,                   /* unlink */
233
        NULL,                   /* symlink */
234
        NULL,                   /* mkdir */
235
        NULL,                   /* rmdir */
236
        NULL,                   /* mknod */
237
        NULL,                   /* rename */
238
        NULL,                   /* readlink */
239
        NULL,                   /* follow_link */
240
        NULL,                   /* readpage */
241
        NULL,                   /* writepage */
242
        NULL,                   /* bmap */
243
        NULL                    /* truncate */
244
};

powered by: WebSVN 2.1.0

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