Subversion Repositories shark

Rev

Rev 2 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
 
2
#include <fs/types.h>
3
#include <fs/errno.h>
4
#include <fs/task.h>
5
#include <fs/maccess.h>
6
#include <fs/stat.h>
7
#include <fs/fcntl.h>
8
#include <fs/mount.h>
9
 
10
#include "fsconst.h"
11
#include "file.h"
12
#include "dentry.h"
13
#include "inode.h"
14
#include "fileop.h"
15
#include "inodeop.h"
16
#include "super.h"
17
#include "fs.h"
18
 
19
#include "debug.h"
20
 
21
 
22
/*
23
  Example of how the code is expanded in system with/without
24
  memory protection.
25
 
26
  If DUMMY_MACCESS is defined:
27
 
28
  char *pathname;
29
  int len;
30
 
31
  len=1;
32
  if ((!len)||len>MAXSIZE) return -EVERIFY;
33
  pathname=userpathname;
34
  ...
35
 
36
 
37
  if DUMMY_MACCESS is NOT defined:
38
 
39
  char pathname[MAXSIZE];
40
  int len;
41
 
42
  len=verifyreadnolen(userpathanme);
43
  if ((!len)||len>MAXSIZE) return -EVERIFY;
44
  memcpyfromuser(pathname,userpathname);
45
  ...
46
 
47
*/
48
 
49
/* PS: open() e opendir() potrebbero condividere codice! */
50
 
51
int k_open(char *upathname, int oflag, int mode)
52
{
53
  declare_buffer(char,pathname,MAXPATHNAME);
54
  int len;
55
  struct file   *f;
56
  struct dentry *d;
57
  int           ret,res,createflag;
58
  __pid_t       pid;
59
 
60
  call_to_fs();
61
 
62
  printk0("k_open: START");
63
  pid=__get_pid();
64
 
65
  len=__verify_read_nolen((char*)upathname);
66
  if ((!len)||(len>MAXPATHNAMELEN)) return_from_fs(-EVERIFY);
67
  __copy_from_user(pathname,upathname,len+1);
68
 
69
  printk0("k_open: verifing memory... done");
70
 
71
  /* flags not supported */
72
  /* O_NOCTTY is ignored */
73
  if (oflag&O_DSYNC||
74
      oflag&O_NOCTTY||
75
      oflag&O_NONBLOCK||
76
      oflag&O_RSYNC||
77
      oflag&O_SYNC) {
78
    return_from_fs(-EACCES);
79
  }
80
 
81
  /* O_TRUNC wiht O_RDONLY not permitted! */
82
  if ((oflag&O_RDONLY)&&(oflag&O_TRUNC)) return_from_fs(-EACCES);
83
 
84
  printk0("k_open: checking flags... done");
85
 
86
  if (oflag&O_CREAT) {
87
    if (oflag&O_EXCL) createflag=DENTRY_MUSTCREATE;
88
    else createflag=DENTRY_CANCREATE;
89
  } else createflag=DENTRY_NOCREATE;
90
 
91
 
92
  d=find_dentry_from_ext(cwden_ptr(pid),(char *)pathname,&createflag);
93
  if (d==NULL) {
94
    printk0("k_open: can't find/create directory entry");
95
    if (createflag&DENTRY_EXIST) return_from_fs(-EEXIST);
96
    return_from_fs(-ENOENT);
97
  }
98
 
99
  if (__S_ISDIR(d->d_inode->i_st.st_mode)) {
100
    if (oflag&O_WRONLY||oflag&O_RDWR)
101
      /* can't write on a directory */
102
      return_from_fs(-EISDIR);
103
  }
104
 
105
  /* check for read-only filesystem */
106
  if (!(d->d_sb->sb_mopts.flags&MOUNT_FLAG_RW)) {
107
    if (oflag&O_WRONLY||oflag&O_RDWR||oflag&O_TRUNC) {
108
      /* NB: O_CREAT va testata prima della find_dentry() */
109
      unlock_dentry(d);      
110
      return_from_fs(-EROFS);
111
    }
112
  }
113
 
114
  printk0("k_open: find dir entry... done");
115
 
116
  f=get_file(d->d_inode);
117
  if (f==NULL) {
118
    unlock_dentry(d);
119
    return_from_fs(-ENFILE);
120
  }
121
 
122
  printk0("k_open: getting system file entry... done");
123
 
124
  if (createflag&DENTRY_CREATED)
125
    d->d_inode->i_st.st_mode=(mode&__ALLPERMS)|__S_IFREG;
126
 
127
  f->f_dentry=d;
128
  f->f_op=d->d_inode->i_op->default_file_ops;
129
  f->f_pos=0;
130
  f->f_flag_isdir=__S_ISDIR(d->d_inode->i_st.st_mode);
131
 
132
  ret=get_fd(pid,f);
133
  if (ret==-1) {
134
    free_file(f);
135
    unlock_dentry(d);
136
    return_from_fs(-EMFILE);
137
  }
138
  *fildesfflags_ptr(pid,ret)=oflag;
139
 
140
  printk0("k_open: getting file descriptor... done");
141
 
142
  if (oflag&O_TRUNC&&!(createflag&DENTRY_CREATED)) {
143
    struct inode *in=file_ptr(pid,ret)->f_dentry->d_inode;
144
    /* acquire write lock on inode's file */
145
    __rwlock_wrlock(&in->i_lock);
146
    /* truncate the file */
147
    in->i_op->truncate(in,0);      
148
    /* release write lock on inode's file */
149
    __rwlock_wrunlock(&in->i_lock);
150
    printk0("k_open: file truncation... done");
151
  }
152
 
153
  res=f->f_op->open(f->f_dentry->d_inode,f);
154
  if (res!=0) {
155
    free_fd(pid,ret);
156
    free_file(f);
157
    unlock_dentry(d);
158
    return_from_fs(res);
159
  }
160
 
161
  printk0("k_open: called proper filesystem open... done");
162
 
163
  printk0("k_open: END");
164
  return_from_fs(ret);
165
}
166