linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / fs / cifs / link.c
index 244d441..0f99aae 100644 (file)
@@ -59,10 +59,14 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
 
        if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX)
                rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,
-                                           cifs_sb_target->local_nls);
+                                           cifs_sb_target->local_nls, 
+                                           cifs_sb_target->mnt_cifs_flags &
+                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
        else {
                rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,
-                                       cifs_sb_target->local_nls);
+                                       cifs_sb_target->local_nls, 
+                                       cifs_sb_target->mnt_cifs_flags &
+                                               CIFS_MOUNT_MAP_SPECIAL_CHR);
                if(rc == -EIO)
                        rc = -EOPNOTSUPP;  
        }
@@ -80,15 +84,13 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
        cifsInode->time = 0;    /* will force revalidate to go get info when needed */
 
 cifs_hl_exit:
-       if (fromName)
-               kfree(fromName);
-       if (toName)
-               kfree(toName);
+       kfree(fromName);
+       kfree(toName);
        FreeXid(xid);
        return rc;
 }
 
-int
+void *
 cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
 {
        struct inode *inode = direntry->d_inode;
@@ -106,7 +108,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
        up(&direntry->d_sb->s_vfs_rename_sem);
 
        if (!full_path)
-               goto out;
+               goto out_no_free;
 
        cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode));
        cifs_sb = CIFS_SB(inode->i_sb);
@@ -126,9 +128,8 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
        else {
                /* rc = CIFSSMBQueryReparseLinkInfo */
                /* BB Add code to Query ReparsePoint info */
+               /* BB Add MAC style xsymlink check here if enabled */
        }
-       /* BB Anything else to do to handle recursive links? */
-       /* BB Should we be using page symlink ops here? */
 
        if (rc == 0) {
 
@@ -142,9 +143,10 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
 
 out:
        kfree(full_path);
+out_no_free:
        FreeXid(xid);
        nd_set_link(nd, target_path);
-       return 0;
+       return NULL;    /* No cookie */
 }
 
 int
@@ -194,13 +196,15 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
                             ("Create symlink worked but get_inode_info failed with rc = %d ",
                              rc));
                } else {
-                       direntry->d_op = &cifs_dentry_ops;
+                       if (pTcon->nocase)
+                               direntry->d_op = &cifs_ci_dentry_ops;
+                       else
+                               direntry->d_op = &cifs_dentry_ops;
                        d_instantiate(direntry, newinode);
                }
        }
 
-       if (full_path)
-               kfree(full_path);
+       kfree(full_path);
        FreeXid(xid);
        return rc;
 }
@@ -246,8 +250,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
                len = buflen;
        tmpbuffer = kmalloc(len,GFP_KERNEL);   
        if(tmpbuffer == NULL) {
-               if (full_path)
-                       kfree(full_path);
+               kfree(full_path);
                FreeXid(xid);
                return -ENOMEM;
        }
@@ -260,7 +263,10 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
                                cifs_sb->local_nls);
        else {
                rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
-                               OPEN_REPARSE_POINT,&fid, &oplock, NULL, cifs_sb->local_nls);
+                               OPEN_REPARSE_POINT,&fid, &oplock, NULL, 
+                               cifs_sb->local_nls, 
+                               cifs_sb->mnt_cifs_flags & 
+                                       CIFS_MOUNT_MAP_SPECIAL_CHR);
                if(!rc) {
                        rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path,
                                tmpbuffer,
@@ -279,7 +285,10 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
                                        strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
                                        strncat(tmp_path, full_path, MAX_PATHCONF);
                                        rc = get_dfs_path(xid, pTcon->ses, tmp_path,
-                                               cifs_sb->local_nls, &num_referrals, &referrals);
+                                               cifs_sb->local_nls,
+                                               &num_referrals, &referrals,
+                                               cifs_sb->mnt_cifs_flags &
+                                                   CIFS_MOUNT_MAP_SPECIAL_CHR);
                                        cFYI(1,("Get DFS for %s rc = %d ",tmp_path, rc));
                                        if((num_referrals == 0) && (rc == 0))
                                                rc = -EACCES;
@@ -290,13 +299,9 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
                                                        strncpy(tmpbuffer, referrals, len-1);                            
                                                }
                                        }
-                                       if(referrals)
-                                               kfree(referrals);
+                                       kfree(referrals);
                                        kfree(tmp_path);
-                                       if(referrals) {
-                                               kfree(referrals);
-                                       }
-                               }
+}
                                /* BB add code like else decode referrals then memcpy to
                                  tmpbuffer and free referrals string array BB */
                        }
@@ -313,17 +318,13 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen)
                      rc));
        }
 
-       if (tmpbuffer) {
-               kfree(tmpbuffer);
-       }
-       if (full_path) {
-               kfree(full_path);
-       }
+       kfree(tmpbuffer);
+       kfree(full_path);
        FreeXid(xid);
        return rc;
 }
 
-void cifs_put_link(struct dentry *direntry, struct nameidata *nd)
+void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)
 {
        char *p = nd_get_link(nd);
        if (!IS_ERR(p))