Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at 77b2555b52a894a2e39a42e43d993df875c46a6a 123 lines 2.6 kB view raw
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@hpesjro.fc.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-2001 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/time.h> 33#include <linux/mm.h> 34#include <linux/stat.h> 35#include <linux/slab.h> 36#include <linux/pagemap.h> 37#include <linux/smp_lock.h> 38#include <linux/buffer_head.h> 39#include "udf_i.h" 40 41static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen, char *to) 42{ 43 struct pathComponent *pc; 44 int elen = 0; 45 char *p = to; 46 47 while (elen < fromlen) 48 { 49 pc = (struct pathComponent *)(from + elen); 50 switch (pc->componentType) 51 { 52 case 1: 53 if (pc->lengthComponentIdent == 0) 54 { 55 p = to; 56 *p++ = '/'; 57 } 58 break; 59 case 3: 60 memcpy(p, "../", 3); 61 p += 3; 62 break; 63 case 4: 64 memcpy(p, "./", 2); 65 p += 2; 66 /* that would be . - just ignore */ 67 break; 68 case 5: 69 p += udf_get_filename(sb, pc->componentIdent, p, pc->lengthComponentIdent); 70 *p++ = '/'; 71 break; 72 } 73 elen += sizeof(struct pathComponent) + pc->lengthComponentIdent; 74 } 75 if (p > to+1) 76 p[-1] = '\0'; 77 else 78 p[0] = '\0'; 79} 80 81static int udf_symlink_filler(struct file *file, struct page *page) 82{ 83 struct inode *inode = page->mapping->host; 84 struct buffer_head *bh = NULL; 85 char *symlink; 86 int err = -EIO; 87 char *p = kmap(page); 88 89 lock_kernel(); 90 if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) 91 symlink = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode); 92 else 93 { 94 bh = sb_bread(inode->i_sb, udf_block_map(inode, 0)); 95 96 if (!bh) 97 goto out; 98 99 symlink = bh->b_data; 100 } 101 102 udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p); 103 udf_release_data(bh); 104 105 unlock_kernel(); 106 SetPageUptodate(page); 107 kunmap(page); 108 unlock_page(page); 109 return 0; 110out: 111 unlock_kernel(); 112 SetPageError(page); 113 kunmap(page); 114 unlock_page(page); 115 return err; 116} 117 118/* 119 * symlinks can't do much... 120 */ 121struct address_space_operations udf_symlink_aops = { 122 .readpage = udf_symlink_filler, 123};