Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
This commit is contained in:
123
fs/udf/symlink.c
Normal file
123
fs/udf/symlink.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* symlink.c
|
||||
*
|
||||
* PURPOSE
|
||||
* Symlink handling routines for the OSTA-UDF(tm) filesystem.
|
||||
*
|
||||
* CONTACTS
|
||||
* E-mail regarding any portion of the Linux UDF file system should be
|
||||
* directed to the development team mailing list (run by majordomo):
|
||||
* linux_udf@hpesjro.fc.hp.com
|
||||
*
|
||||
* COPYRIGHT
|
||||
* This file is distributed under the terms of the GNU General Public
|
||||
* License (GPL). Copies of the GPL can be obtained from:
|
||||
* ftp://prep.ai.mit.edu/pub/gnu/GPL
|
||||
* Each contributing author retains all rights to their own work.
|
||||
*
|
||||
* (C) 1998-2001 Ben Fennema
|
||||
* (C) 1999 Stelias Computing Inc
|
||||
*
|
||||
* HISTORY
|
||||
*
|
||||
* 04/16/99 blf Created.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "udfdecl.h"
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/udf_fs.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/buffer_head.h>
|
||||
#include "udf_i.h"
|
||||
|
||||
static void udf_pc_to_char(struct super_block *sb, char *from, int fromlen, char *to)
|
||||
{
|
||||
struct pathComponent *pc;
|
||||
int elen = 0;
|
||||
char *p = to;
|
||||
|
||||
while (elen < fromlen)
|
||||
{
|
||||
pc = (struct pathComponent *)(from + elen);
|
||||
switch (pc->componentType)
|
||||
{
|
||||
case 1:
|
||||
if (pc->lengthComponentIdent == 0)
|
||||
{
|
||||
p = to;
|
||||
*p++ = '/';
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
memcpy(p, "../", 3);
|
||||
p += 3;
|
||||
break;
|
||||
case 4:
|
||||
memcpy(p, "./", 2);
|
||||
p += 2;
|
||||
/* that would be . - just ignore */
|
||||
break;
|
||||
case 5:
|
||||
p += udf_get_filename(sb, pc->componentIdent, p, pc->lengthComponentIdent);
|
||||
*p++ = '/';
|
||||
break;
|
||||
}
|
||||
elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
|
||||
}
|
||||
if (p > to+1)
|
||||
p[-1] = '\0';
|
||||
else
|
||||
p[0] = '\0';
|
||||
}
|
||||
|
||||
static int udf_symlink_filler(struct file *file, struct page *page)
|
||||
{
|
||||
struct inode *inode = page->mapping->host;
|
||||
struct buffer_head *bh = NULL;
|
||||
char *symlink;
|
||||
int err = -EIO;
|
||||
char *p = kmap(page);
|
||||
|
||||
lock_kernel();
|
||||
if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB)
|
||||
symlink = UDF_I_DATA(inode) + UDF_I_LENEATTR(inode);
|
||||
else
|
||||
{
|
||||
bh = sb_bread(inode->i_sb, udf_block_map(inode, 0));
|
||||
|
||||
if (!bh)
|
||||
goto out;
|
||||
|
||||
symlink = bh->b_data;
|
||||
}
|
||||
|
||||
udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
|
||||
udf_release_data(bh);
|
||||
|
||||
unlock_kernel();
|
||||
SetPageUptodate(page);
|
||||
kunmap(page);
|
||||
unlock_page(page);
|
||||
return 0;
|
||||
out:
|
||||
unlock_kernel();
|
||||
SetPageError(page);
|
||||
kunmap(page);
|
||||
unlock_page(page);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* symlinks can't do much...
|
||||
*/
|
||||
struct address_space_operations udf_symlink_aops = {
|
||||
.readpage = udf_symlink_filler,
|
||||
};
|
Reference in New Issue
Block a user