2 * linux/fs/umsdos/file.c
4 * Written 1992 by Jacques Gelinas
5 * inspired from linux/fs/msdos/file.c Werner Almesberger
7 * Extended MS-DOS regular file handling primitives
10 #include <linux/sched.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>
19 #include <asm/uaccess.h>
20 #include <asm/system.h>
23 #define Printk(x) printk x
25 static struct file_operations umsdos_symlink_operations
;
29 * Read the data associate with the symlink.
30 * Return length read in buffer or a negative error code.
34 static int umsdos_readlink_x (
35 struct dentry
*dentry
,
43 ret
= dentry
->d_inode
->i_size
;
45 check_dentry (dentry
);
46 fill_new_filp (&filp
, dentry
);
49 filp
.f_flags
= O_RDONLY
;
50 filp
.f_op
= &umsdos_symlink_operations
; /* /mn/ - we have to fill it with dummy values so we won't segfault */
55 PRINTK ((KERN_DEBUG
"umsdos_readlink_x /mn/: Checkin: filp=%p, buffer=%p, size=%d, offs=%Lu\n", &filp
, buffer
, ret
, loffs
));
56 PRINTK ((KERN_DEBUG
" f_op=%p\n", filp
.f_op
));
57 PRINTK ((KERN_DEBUG
" inode=%lu, i_size=%lu\n", filp
.f_dentry
->d_inode
->i_ino
, filp
.f_dentry
->d_inode
->i_size
));
58 PRINTK ((KERN_DEBUG
" f_pos=%Lu\n", filp
.f_pos
));
59 PRINTK ((KERN_DEBUG
" name=%.*s\n", (int) filp
.f_dentry
->d_name
.len
, filp
.f_dentry
->d_name
.name
));
60 PRINTK ((KERN_DEBUG
" i_binary(sb)=%d\n", MSDOS_I (filp
.f_dentry
->d_inode
)->i_binary
));
61 PRINTK ((KERN_DEBUG
" f_count=%d, f_flags=%d\n", filp
.f_count
, filp
.f_flags
));
62 PRINTK ((KERN_DEBUG
" f_owner=%d\n", filp
.f_owner
.uid
));
63 PRINTK ((KERN_DEBUG
" f_version=%ld\n", filp
.f_version
));
64 PRINTK ((KERN_DEBUG
" f_reada=%ld, f_ramax=%ld, f_raend=%ld, f_ralen=%ld, f_rawin=%ld\n", filp
.f_reada
, filp
.f_ramax
, filp
.f_raend
, filp
.f_ralen
, filp
.f_rawin
));
67 PRINTK ((KERN_DEBUG
"umsdos_readlink_x: FIXME /mn/: running fat_file_read (%p, %p, %d, %Lu)\n", &filp
, buffer
, ret
, loffs
));
68 if (fat_file_read (&filp
, buffer
, (size_t) ret
, &loffs
) != ret
) {
73 struct umsdos_dirent
*mydirent
= buffer
;
75 PRINTK ((KERN_DEBUG
" (DDD) uid=%d\n", mydirent
->uid
));
76 PRINTK ((KERN_DEBUG
" (DDD) gid=%d\n", mydirent
->gid
));
77 PRINTK ((KERN_DEBUG
" (DDD) name=>%.20s<\n", mydirent
->name
));
81 PRINTK ((KERN_DEBUG
"umsdos_readlink_x: FIXME /mn/: fat_file_read returned offs=%Lu ret=%d\n", loffs
, ret
));
87 static int UMSDOS_readlink (struct dentry
*dentry
, char *buffer
, int buflen
)
91 PRINTK ((KERN_DEBUG
"UMSDOS_readlink: calling umsdos_readlink_x for %.*s\n", (int) dentry
->d_name
.len
, dentry
->d_name
.name
));
92 ret
= umsdos_readlink_x (dentry
, buffer
, buflen
);
93 PRINTK ((KERN_DEBUG
"readlink %d bufsiz %d\n", ret
, buflen
));
94 /* dput(dentry); / * FIXME /mn/ */
95 Printk ((KERN_WARNING
"UMSDOS_readlink /mn/: FIXME! skipped dput(dentry). returning %d\n", ret
));
100 /* this one mostly stolen from romfs :) */
101 static struct dentry
*UMSDOS_followlink (struct dentry
*dentry
, struct dentry
*base
)
103 struct inode
*inode
= dentry
->d_inode
;
104 char *symname
= NULL
;
106 mm_segment_t old_fs
= get_fs ();
108 Printk ((KERN_DEBUG
"UMSDOS_followlink /mn/: (%.*s/%.*s)\n", (int) dentry
->d_parent
->d_name
.len
, dentry
->d_parent
->d_name
.name
, (int) dentry
->d_name
.len
, dentry
->d_name
.name
));
112 if (!(symname
= kmalloc (len
+ 1, GFP_KERNEL
))) {
113 dentry
= ERR_PTR (-EAGAIN
); /* correct? */
116 set_fs (KERNEL_DS
); /* we read into kernel space this time */
117 PRINTK ((KERN_DEBUG
"UMSDOS_followlink /mn/: Here goes umsdos_readlink_x %p, %p, %d\n", dentry
, symname
, len
));
118 cnt
= umsdos_readlink_x (dentry
, symname
, len
);
119 PRINTK ((KERN_DEBUG
"UMSDOS_followlink /mn/: back from umsdos_readlink_x %p, %p, %d!\n", dentry
, symname
, len
));
121 Printk ((KERN_DEBUG
"UMSDOS_followlink /mn/: link name is %.*s with len %d\n", cnt
, symname
, cnt
));
124 dentry
= ERR_PTR (-EIO
);
129 dentry
= lookup_dentry (symname
, base
, 1);
142 static struct file_operations umsdos_symlink_operations
=
144 NULL
, /* lseek - default */
147 NULL
, /* readdir - bad */
148 NULL
, /* poll - default */
149 NULL
, /* ioctl - default */
151 NULL
, /* no special open is needed */
152 NULL
, /* no flush code */
158 struct inode_operations umsdos_symlink_inode_operations
=
160 NULL
, /* default file operations */
170 UMSDOS_readlink
, /* readlink */
171 UMSDOS_followlink
, /* followlink *//* /mn/ is this REALLY needed ? I recall seeing it working w/o it... */
172 generic_readpage
, /* readpage *//* in original NULL. changed to generic_readpage. FIXME? /mn/ */
173 NULL
, /* writepage */
174 fat_bmap
, /* bmap *//* in original NULL. changed to fat_bmap. FIXME? /mn/ */
176 NULL
, /* permission */
178 NULL
, /* updatepage */
179 NULL
/* revalidate */