~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/udf/symlink.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * symlink.c
  3  *
  4  * PURPOSE
  5  *      Symlink handling routines for the OSTA-UDF(tm) filesystem.
  6  *
  7  * CONTACTS
  8  *      E-mail regarding any portion of the Linux UDF file system should be
  9  *      directed to the development team mailing list (run by majordomo):
 10  *              linux_udf@hootie.lvld.hp.com
 11  *
 12  * COPYRIGHT
 13  *      This file is distributed under the terms of the GNU General Public
 14  *      License (GPL). Copies of the GPL can be obtained from:
 15  *              ftp://prep.ai.mit.edu/pub/gnu/GPL
 16  *      Each contributing author retains all rights to their own work.
 17  *
 18  *  (C) 1998-2000 Ben Fennema
 19  *  (C) 1999 Stelias Computing Inc 
 20  *
 21  * HISTORY
 22  *
 23  *  04/16/99 blf  Created.
 24  *
 25  */
 26 
 27 #include "udfdecl.h"
 28 #include <asm/uaccess.h>
 29 #include <linux/errno.h>
 30 #include <linux/fs.h>
 31 #include <linux/udf_fs.h>
 32 #include <linux/sched.h>
 33 #include <linux/mm.h>
 34 #include <linux/stat.h>
 35 #include <linux/malloc.h>
 36 #include <linux/pagemap.h>
 37 #include <linux/smp_lock.h>
 38 #include "udf_i.h"
 39 
 40 static void udf_pc_to_char(char *from, int fromlen, char *to)
 41 {
 42         struct PathComponent *pc;
 43         int elen = 0;
 44         char *p = to;
 45 
 46         while (elen < fromlen)
 47         {
 48                 pc = (struct PathComponent *)(from + elen);
 49                 switch (pc->componentType)
 50                 {
 51                         case 1:
 52                                 if (pc->lengthComponentIdent == 0)
 53                                 {
 54                                         p = to;
 55                                         *p++ = '/';
 56                                 }
 57                                 break;
 58                         case 3:
 59                                 memcpy(p, "../", 3);
 60                                 p += 3;
 61                                 break;
 62                         case 4:
 63                                 memcpy(p, "./", 2);
 64                                 p += 2;
 65                                 /* that would be . - just ignore */
 66                                 break;
 67                         case 5:
 68                                 memcpy(p, pc->componentIdent, pc->lengthComponentIdent);
 69                                 p += pc->lengthComponentIdent;
 70                                 *p++ = '/';
 71                 }
 72                 elen += sizeof(struct PathComponent) + pc->lengthComponentIdent;
 73         }
 74         if (p > to+1)
 75                 p[-1] = '\0';
 76         else
 77                 p[0] = '\0';
 78 }
 79 
 80 static int udf_symlink_filler(struct file *file, struct page *page)
 81 {
 82         struct inode *inode = page->mapping->host;
 83         struct buffer_head *bh = NULL;
 84         char *symlink;
 85         int err = -EIO;
 86         char *p = kmap(page);
 87         
 88         lock_kernel();
 89         if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
 90         {
 91                 bh = udf_tread(inode->i_sb, inode->i_ino, inode->i_sb->s_blocksize);
 92 
 93                 if (!bh)
 94                         goto out;
 95 
 96                 symlink = bh->b_data + udf_file_entry_alloc_offset(inode);
 97         }
 98         else
 99         {
100                 bh = bread(inode->i_dev, udf_block_map(inode, 0),
101                                 inode->i_sb->s_blocksize);
102 
103                 if (!bh)
104                         goto out;
105 
106                 symlink = bh->b_data;
107         }
108 
109         udf_pc_to_char(symlink, inode->i_size, p);
110         udf_release_data(bh);
111 
112         unlock_kernel();
113         SetPageUptodate(page);
114         kunmap(page);
115         UnlockPage(page);
116         return 0;
117 out:
118         unlock_kernel();
119         SetPageError(page);
120         kunmap(page);
121         UnlockPage(page);
122         return err;
123 }
124 
125 /*
126  * symlinks can't do much...
127  */
128 struct address_space_operations udf_symlink_aops = {
129         readpage:                       udf_symlink_filler,
130 };
131 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.