diff options
Diffstat (limited to 'fs/umsdos/symlink.c')
-rw-r--r-- | fs/umsdos/symlink.c | 139 |
1 files changed, 7 insertions, 132 deletions
diff --git a/fs/umsdos/symlink.c b/fs/umsdos/symlink.c index 8f94230e3..7bcd09e44 100644 --- a/fs/umsdos/symlink.c +++ b/fs/umsdos/symlink.c @@ -5,143 +5,18 @@ * inspired from linux/fs/msdos/file.c Werner Almesberger * * Extended MS-DOS regular file handling primitives + * + * Wow. It looks like we could support them on FAT with little (if any) + * problems. Oh, well... */ -#include <linux/sched.h> #include <linux/fs.h> #include <linux/msdos_fs.h> -#include <linux/errno.h> -#include <linux/fcntl.h> -#include <linux/stat.h> -#include <linux/umsdos_fs.h> -#include <linux/malloc.h> - -#include <asm/uaccess.h> -#include <asm/system.h> - -static struct file_operations umsdos_symlink_operations; - - -/* - * Read the data associate with the symlink. - * Return length read in buffer or a negative error code. - * - */ - -int umsdos_readlink_x ( struct dentry *dentry, - char *buffer, - int bufsiz) -{ - size_t size = dentry->d_inode->i_size; - loff_t loffs = 0; - ssize_t ret; - struct file filp; - -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; - - if (size > bufsiz) - size = bufsiz; - - ret = fat_file_read (&filp, buffer, size, &loffs); - if (ret != size) { - ret = -EIO; - } - return ret; -} - - - -static int UMSDOS_readlink (struct dentry *dentry, char *buffer, int buflen) -{ - return umsdos_readlink_x (dentry, buffer, buflen); -} - -/* this one mostly stolen from romfs :) */ -static struct dentry *UMSDOS_followlink (struct dentry *dentry, - struct dentry *base, - unsigned int follow) -{ - struct inode *inode = dentry->d_inode; - char *symname; - int len, cnt; - mm_segment_t old_fs = get_fs (); - -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 (-ENOMEM); - goto outnobuf; - } - - set_fs (KERNEL_DS); /* we read into kernel space this time */ - cnt = umsdos_readlink_x (dentry, symname, len); - set_fs (old_fs); - - if (len != cnt) { - dentry = ERR_PTR (-EIO); - goto out; - } - - symname[len] = 0; - dentry = lookup_dentry (symname, base, follow); - kfree (symname); - - if (0) { - out: - kfree (symname); - outnobuf: - dput (base); - } - return dentry; -} - -/* needed to patch the file structure */ -static struct file_operations umsdos_symlink_operations = -{ - NULL, /* lseek - default */ - NULL, /* read */ - NULL, /* write */ - NULL, /* readdir - bad */ - NULL, /* poll - default */ - NULL, /* ioctl - default */ - NULL, /* mmap */ - NULL, /* no special open is needed */ - NULL, /* no flush code */ - NULL, /* release */ - NULL /* fsync */ -}; - struct inode_operations umsdos_symlink_inode_operations = { - NULL, /* default file operations (none) */ - NULL, /* create */ - NULL, /* lookup */ - NULL, /* link */ - NULL, /* unlink */ - NULL, /* symlink */ - NULL, /* mkdir */ - NULL, /* rmdir */ - NULL, /* mknod */ - NULL, /* rename */ - UMSDOS_readlink, /* readlink */ - UMSDOS_followlink, /* followlink */ - fat_get_block, /* get_block */ - block_read_full_page, /* readpage */ - NULL, /* writepage */ - NULL, /* flushpage */ - NULL, /* truncate */ - NULL, /* permission */ - NULL, /* smap */ - NULL /* revalidate */ + readlink: page_readlink, + follow_link: page_follow_link, + get_block: fat_get_block, + readpage: block_read_full_page }; - |