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

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)