/* -*- linux-c -*- --------------------------------------------------------- *
|
/* -*- linux-c -*- --------------------------------------------------------- *
|
*
|
*
|
* linux/fs/autofs/symlink.c
|
* linux/fs/autofs/symlink.c
|
*
|
*
|
* Copyright 1997 Transmeta Corporation -- All Rights Reserved
|
* Copyright 1997 Transmeta Corporation -- All Rights Reserved
|
*
|
*
|
* This file is part of the Linux kernel and is made available under
|
* This file is part of the Linux kernel and is made available under
|
* the terms of the GNU General Public License, version 2, or at your
|
* the terms of the GNU General Public License, version 2, or at your
|
* option, any later version, incorporated herein by reference.
|
* option, any later version, incorporated herein by reference.
|
*
|
*
|
* ------------------------------------------------------------------------- */
|
* ------------------------------------------------------------------------- */
|
|
|
#include <linux/string.h>
|
#include <linux/string.h>
|
#include <linux/sched.h>
|
#include <linux/sched.h>
|
#include "autofs_i.h"
|
#include "autofs_i.h"
|
|
|
static int autofs_follow_link(struct inode *dir, struct inode *inode,
|
static int autofs_follow_link(struct inode *dir, struct inode *inode,
|
int flag, int mode, struct inode **res_inode)
|
int flag, int mode, struct inode **res_inode)
|
{
|
{
|
int error;
|
int error;
|
char *link;
|
char *link;
|
|
|
*res_inode = NULL;
|
*res_inode = NULL;
|
if (!dir) {
|
if (!dir) {
|
dir = current->fs->root;
|
dir = current->fs->root;
|
dir->i_count++;
|
dir->i_count++;
|
}
|
}
|
if (!inode) {
|
if (!inode) {
|
iput(dir);
|
iput(dir);
|
return -ENOENT;
|
return -ENOENT;
|
}
|
}
|
if (!S_ISLNK(inode->i_mode)) {
|
if (!S_ISLNK(inode->i_mode)) {
|
iput(dir);
|
iput(dir);
|
*res_inode = inode;
|
*res_inode = inode;
|
return 0;
|
return 0;
|
}
|
}
|
if (current->link_count > 5) {
|
if (current->link_count > 5) {
|
iput(dir);
|
iput(dir);
|
iput(inode);
|
iput(inode);
|
return -ELOOP;
|
return -ELOOP;
|
}
|
}
|
link = ((struct autofs_symlink *)inode->u.generic_ip)->data;
|
link = ((struct autofs_symlink *)inode->u.generic_ip)->data;
|
current->link_count++;
|
current->link_count++;
|
error = open_namei(link,flag,mode,res_inode,dir);
|
error = open_namei(link,flag,mode,res_inode,dir);
|
current->link_count--;
|
current->link_count--;
|
iput(inode);
|
iput(inode);
|
return error;
|
return error;
|
}
|
}
|
|
|
static int autofs_readlink(struct inode *inode, char *buffer, int buflen)
|
static int autofs_readlink(struct inode *inode, char *buffer, int buflen)
|
{
|
{
|
struct autofs_symlink *sl;
|
struct autofs_symlink *sl;
|
int len;
|
int len;
|
|
|
if (!S_ISLNK(inode->i_mode)) {
|
if (!S_ISLNK(inode->i_mode)) {
|
iput(inode);
|
iput(inode);
|
return -EINVAL;
|
return -EINVAL;
|
}
|
}
|
sl = (struct autofs_symlink *)inode->u.generic_ip;
|
sl = (struct autofs_symlink *)inode->u.generic_ip;
|
len = sl->len;
|
len = sl->len;
|
if (len > buflen) len = buflen;
|
if (len > buflen) len = buflen;
|
copy_to_user(buffer,sl->data,len);
|
copy_to_user(buffer,sl->data,len);
|
iput(inode);
|
iput(inode);
|
return len;
|
return len;
|
}
|
}
|
|
|
struct inode_operations autofs_symlink_inode_operations = {
|
struct inode_operations autofs_symlink_inode_operations = {
|
NULL, /* file operations */
|
NULL, /* file operations */
|
NULL, /* create */
|
NULL, /* create */
|
NULL, /* lookup */
|
NULL, /* lookup */
|
NULL, /* link */
|
NULL, /* link */
|
NULL, /* unlink */
|
NULL, /* unlink */
|
NULL, /* symlink */
|
NULL, /* symlink */
|
NULL, /* mkdir */
|
NULL, /* mkdir */
|
NULL, /* rmdir */
|
NULL, /* rmdir */
|
NULL, /* mknod */
|
NULL, /* mknod */
|
NULL, /* rename */
|
NULL, /* rename */
|
autofs_readlink, /* readlink */
|
autofs_readlink, /* readlink */
|
autofs_follow_link, /* follow_link */
|
autofs_follow_link, /* follow_link */
|
NULL, /* readpage */
|
NULL, /* readpage */
|
NULL, /* writepage */
|
NULL, /* writepage */
|
NULL, /* bmap */
|
NULL, /* bmap */
|
NULL, /* truncate */
|
NULL, /* truncate */
|
NULL /* permission */
|
NULL /* permission */
|
};
|
};
|
|
|