patch-2.3.32 linux/fs/ncpfs/symlink.c
Next file: linux/fs/nfs/dir.c
Previous file: linux/fs/namei.c
Back to the patch index
Back to the overall index
- Lines: 190
- Date:
Mon Dec 13 16:02:45 1999
- Orig file:
v2.3.31/linux/fs/ncpfs/symlink.c
- Orig date:
Wed Dec 8 14:11:27 1999
diff -u --recursive --new-file v2.3.31/linux/fs/ncpfs/symlink.c linux/fs/ncpfs/symlink.c
@@ -38,152 +38,70 @@
#define NCP_SYMLINK_MAGIC0 le32_to_cpu(0x6c6d7973) /* "symlnk->" */
#define NCP_SYMLINK_MAGIC1 le32_to_cpu(0x3e2d6b6e)
-static int ncp_readlink(struct dentry *, char *, int);
-static struct dentry *ncp_follow_link(struct dentry *, struct dentry *, unsigned int);
int ncp_create_new(struct inode *dir, struct dentry *dentry,
int mode,int attributes);
-/*
- * symlinks can't do much...
- */
-struct inode_operations ncp_symlink_inode_operations={
- NULL, /* no file-operations */
- NULL, /* create */
- NULL, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- ncp_readlink, /* readlink */
- ncp_follow_link, /* follow_link */
- NULL, /* get_block */
- NULL, /* readpage */
- NULL, /* writepage */
- NULL, /* truncate */
- NULL, /* permission */
- NULL /* revalidate */
-};
-
-/* ----- follow a symbolic link ------------------------------------------ */
+/* ----- read a symbolic link ------------------------------------------ */
-static struct dentry *ncp_follow_link(struct dentry *dentry,
- struct dentry *base,
- unsigned int follow)
+static int ncp_symlink_readpage(struct dentry *dentry, struct page *page)
{
struct inode *inode=dentry->d_inode;
int error, length, len, cnt;
- char *link, *buf;
+ char *link;
+ char *buf = (char*)kmap(page);
-#ifdef DEBUG
- PRINTK("ncp_follow_link(dentry=%p,base=%p,follow=%u)\n",dentry,base,follow);
-#endif
-
- if(!S_ISLNK(inode->i_mode)) {
- dput(base);
- return ERR_PTR(-EINVAL);
- }
-
- if(ncp_make_open(inode,O_RDONLY)) {
- dput(base);
- return ERR_PTR(-EIO);
- }
+ error = -EIO;
+ if (ncp_make_open(inode,O_RDONLY))
+ goto fail;
+ error = -ENOMEM;
for (cnt = 0; (link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE, GFP_NFS))==NULL; cnt++) {
- if (cnt > 10) {
- dput(base);
- return ERR_PTR(-EAGAIN); /* -ENOMEM? */
- }
+ if (cnt > 10)
+ goto fail;
schedule();
}
error=ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle,
0,NCP_MAX_SYMLINK_SIZE,link,&length);
- if (error!=0 || length<NCP_MIN_SYMLINK_SIZE ||
- ((__u32 *)link)[0]!=NCP_SYMLINK_MAGIC0 || ((__u32 *)link)[1]!=NCP_SYMLINK_MAGIC1) {
- dput(base);
+ if (error) {
kfree(link);
- return ERR_PTR(-EIO);
+ goto fail;
}
-
- len = NCP_MAX_SYMLINK_SIZE;
- buf = (char *) kmalloc(len, GFP_NFS);
- if (!buf) {
- dput(base);
+ if (length<NCP_MIN_SYMLINK_SIZE ||
+ ((__u32 *)link)[0]!=NCP_SYMLINK_MAGIC0 ||
+ ((__u32 *)link)[1]!=NCP_SYMLINK_MAGIC1) {
+ error = -EIO;
kfree(link);
- return ERR_PTR(-EAGAIN);
- }
- error = ncp_vol2io(NCP_SERVER(inode), buf, &len, link+8, length-8, 0);
- kfree(link);
- if (error) {
- dput(base);
- kfree(buf);
- return ERR_PTR(error);
- }
-
- /* UPDATE_ATIME(inode); */
- base = lookup_dentry(buf, base, follow);
- kfree(buf);
-
- return base;
-}
-
-/* ----- read symbolic link ---------------------------------------------- */
-
-static int ncp_readlink(struct dentry * dentry, char * buffer, int buflen)
-{
- struct inode *inode=dentry->d_inode;
- char *link, *buf;
- int length, len, error;
-
-#ifdef DEBUG
- PRINTK("ncp_readlink(dentry=%p,buffer=%p,buflen=%d)\n",dentry,buffer,buflen);
-#endif
-
- if(!S_ISLNK(inode->i_mode))
- return -EINVAL;
-
- if(ncp_make_open(inode,O_RDONLY))
- return -EIO;
-
- if((link=(char *)kmalloc(NCP_MAX_SYMLINK_SIZE,GFP_NFS))==NULL)
- return -ENOMEM;
-
- error = ncp_read_kernel(NCP_SERVER(inode),NCP_FINFO(inode)->file_handle,
- 0,NCP_MAX_SYMLINK_SIZE,link,&length);
-
- if (error!=0 || length < NCP_MIN_SYMLINK_SIZE || buflen < (length-8) ||
- ((__u32 *)link)[0]!=NCP_SYMLINK_MAGIC0 ||((__u32 *)link)[1]!=NCP_SYMLINK_MAGIC1) {
- error = -EIO;
- goto out;
+ goto fail;
}
len = NCP_MAX_SYMLINK_SIZE;
- buf = (char *) kmalloc(len, GFP_NFS);
- if (!buf) {
- error = -ENOMEM;
- goto out;
- }
error = ncp_vol2io(NCP_SERVER(inode), buf, &len, link+8, length-8, 0);
- if (error || buflen < len) {
- error = -EIO;
- kfree(buf);
- goto out;
- }
-
- error = len;
- if(copy_to_user(buffer, buf, error))
- error = -EFAULT;
- kfree(buf);
-
-out:
kfree(link);
+ if (error)
+ goto fail;
+ SetPageUptodate(page);
+ kunmap(page);
+ UnlockPage(page);
+ return 0;
+
+fail:
+ SetPageError(page);
+ kunmap(page);
+ UnlockPage(page);
return error;
}
+/*
+ * symlinks can't do much...
+ */
+struct inode_operations ncp_symlink_inode_operations={
+ readlink: page_readlink,
+ follow_link: page_follow_link,
+ readpage: ncp_symlink_readpage,
+};
+
/* ----- create a new symbolic link -------------------------------------- */
int ncp_symlink(struct inode *dir, struct dentry *dentry, const char *symname) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)