summaryrefslogtreecommitdiffstats
path: root/fs/umsdos/symlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/umsdos/symlink.c')
-rw-r--r--fs/umsdos/symlink.c89
1 files changed, 27 insertions, 62 deletions
diff --git a/fs/umsdos/symlink.c b/fs/umsdos/symlink.c
index dc639a7a4..4b3678a22 100644
--- a/fs/umsdos/symlink.c
+++ b/fs/umsdos/symlink.c
@@ -32,52 +32,26 @@ int umsdos_readlink_x ( struct dentry *dentry,
char *buffer,
int bufsiz)
{
- int ret;
+ size_t size = dentry->d_inode->i_size;
loff_t loffs = 0;
+ ssize_t ret;
struct file filp;
- ret = dentry->d_inode->i_size;
-
- if (!(dentry->d_inode)) {
- return -EBADF;
- }
+Printk((KERN_DEBUG "UMSDOS_read: %s/%s, size=%u\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, size));
fill_new_filp (&filp, dentry);
-
filp.f_reada = 0;
filp.f_flags = O_RDONLY;
- filp.f_op = &umsdos_symlink_operations; /* /mn/ - we have to fill it with dummy values so we won't segfault */
-
- if (ret > bufsiz)
- ret = bufsiz;
-
- PRINTK ((KERN_DEBUG "umsdos_readlink_x /mn/: Checkin: filp=%p, buffer=%p, size=%d, offs=%Lu\n", &filp, buffer, ret, loffs));
- PRINTK ((KERN_DEBUG " f_op=%p\n", filp.f_op));
- PRINTK ((KERN_DEBUG " inode=%lu, i_size=%lu\n", filp.f_dentry->d_inode->i_ino, filp.f_dentry->d_inode->i_size));
- PRINTK ((KERN_DEBUG " f_pos=%Lu\n", filp.f_pos));
- PRINTK ((KERN_DEBUG " name=%.*s\n", (int) filp.f_dentry->d_name.len, filp.f_dentry->d_name.name));
- PRINTK ((KERN_DEBUG " i_binary(sb)=%d\n", MSDOS_I (filp.f_dentry->d_inode)->i_binary));
- PRINTK ((KERN_DEBUG " f_count=%d, f_flags=%d\n", filp.f_count, filp.f_flags));
- PRINTK ((KERN_DEBUG " f_owner=%d\n", filp.f_owner.uid));
- PRINTK ((KERN_DEBUG " f_version=%ld\n", filp.f_version));
- 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));
+ filp.f_op = &umsdos_symlink_operations;
+ if (size > bufsiz)
+ size = bufsiz;
- PRINTK ((KERN_DEBUG "umsdos_readlink_x: FIXME /mn/: running fat_file_read (%p, %p, %d, %Lu)\n", &filp, buffer, ret, loffs));
- if (fat_file_read (&filp, buffer, (size_t) ret, &loffs) != ret) {
+ ret = fat_file_read (&filp, buffer, size, &loffs);
+ if (ret != size) {
ret = -EIO;
}
-#if 0
- {
- struct umsdos_dirent *mydirent = buffer;
-
- PRINTK ((KERN_DEBUG " (DDD) uid=%d\n", mydirent->uid));
- PRINTK ((KERN_DEBUG " (DDD) gid=%d\n", mydirent->gid));
- PRINTK ((KERN_DEBUG " (DDD) name=>%.20s<\n", mydirent->name));
- }
-#endif
-
- PRINTK ((KERN_DEBUG "umsdos_readlink_x: FIXME /mn/: fat_file_read returned offs=%Lu ret=%d\n", loffs, ret));
return ret;
}
@@ -85,49 +59,40 @@ int umsdos_readlink_x ( struct dentry *dentry,
static int UMSDOS_readlink (struct dentry *dentry, char *buffer, int buflen)
{
- int ret;
-
- PRINTK ((KERN_DEBUG "UMSDOS_readlink: calling umsdos_readlink_x for %.*s\n", (int) dentry->d_name.len, dentry->d_name.name));
-
- ret = umsdos_readlink_x (dentry, buffer, buflen);
- PRINTK ((KERN_DEBUG "readlink %d bufsiz %d\n", ret, buflen));
- /* dput(dentry); / * FIXME /mn/? It seems it is unneeded. d_count is not changed by umsdos_readlink_x */
-
- Printk ((KERN_WARNING "UMSDOS_readlink /mn/: FIXME! skipped dput(dentry). returning %d\n", ret));
- return ret;
-
+ return umsdos_readlink_x (dentry, buffer, buflen);
}
/* this one mostly stolen from romfs :) */
-static struct dentry *UMSDOS_followlink (struct dentry *dentry, struct dentry *base)
+static struct dentry *UMSDOS_followlink (struct dentry *dentry,
+ struct dentry *base,
+ unsigned int follow)
{
struct inode *inode = dentry->d_inode;
- char *symname = NULL;
+ char *symname;
int len, cnt;
mm_segment_t old_fs = get_fs ();
- 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));
+Printk((KERN_DEBUG "UMSDOS_followlink /mn/: (%s/%s)\n",
+dentry->d_parent->d_name.name, dentry->d_name.name));
len = inode->i_size;
if (!(symname = kmalloc (len + 1, GFP_KERNEL))) {
- dentry = ERR_PTR (-EAGAIN); /* correct? */
+ dentry = ERR_PTR (-ENOMEM);
goto outnobuf;
}
+
set_fs (KERNEL_DS); /* we read into kernel space this time */
- PRINTK ((KERN_DEBUG "UMSDOS_followlink /mn/: Here goes umsdos_readlink_x %p, %p, %d\n", dentry, symname, len));
cnt = umsdos_readlink_x (dentry, symname, len);
- PRINTK ((KERN_DEBUG "UMSDOS_followlink /mn/: back from umsdos_readlink_x %p, %p, %d!\n", dentry, symname, len));
set_fs (old_fs);
- Printk ((KERN_DEBUG "UMSDOS_followlink /mn/: link name is %.*s with len %d\n", cnt, symname, cnt));
if (len != cnt) {
dentry = ERR_PTR (-EIO);
goto out;
- } else
- symname[len] = 0;
+ }
- dentry = lookup_dentry (symname, base, 1);
+ symname[len] = 0;
+ dentry = lookup_dentry (symname, base, follow);
kfree (symname);
if (0) {
@@ -139,7 +104,7 @@ static struct dentry *UMSDOS_followlink (struct dentry *dentry, struct dentry *b
return dentry;
}
-
+/* needed to patch the file structure */
static struct file_operations umsdos_symlink_operations =
{
NULL, /* lseek - default */
@@ -158,7 +123,7 @@ static struct file_operations umsdos_symlink_operations =
struct inode_operations umsdos_symlink_inode_operations =
{
- NULL, /* default file operations */
+ NULL, /* default file operations (none) */
NULL, /* create */
NULL, /* lookup */
NULL, /* link */
@@ -169,14 +134,14 @@ struct inode_operations umsdos_symlink_inode_operations =
NULL, /* mknod */
NULL, /* rename */
UMSDOS_readlink, /* readlink */
- UMSDOS_followlink, /* followlink *//* /mn/ is this REALLY needed ? I recall seeing it working w/o it... */
- generic_readpage, /* readpage *//* in original NULL. changed to generic_readpage. FIXME? /mn/ */
+ UMSDOS_followlink, /* followlink */
+ generic_readpage, /* readpage */
NULL, /* writepage */
- fat_bmap, /* bmap *//* in original NULL. changed to fat_bmap. FIXME? /mn/ */
+ fat_bmap, /* bmap */
NULL, /* truncate */
NULL, /* permission */
NULL, /* smap */
NULL, /* updatepage */
NULL /* revalidate */
-
};
+