X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=fs%2Fcifs%2Flink.c;h=f257ff0ad8f823af9666684bf66b805ca4157f1e;hb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;hp=8deba2650f393e736a40b68098f57799223417d1;hpb=c449269f45c2cdf53af08c8d0af37472f66539d9;p=linux-2.6.git diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 8deba2650..f257ff0ad 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -44,10 +44,18 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, cifs_sb_target = CIFS_SB(inode->i_sb); pTcon = cifs_sb_target->tcon; -/* No need to check for cross device links since server will do that - BB note DFS case in future though (when we may have to check) */ +/* No need to check for cross device links since server will do that + BB note DFS case in future though (when we may have to check) */ + down(&inode->i_sb->s_vfs_rename_sem); fromName = build_path_from_dentry(old_file); toName = build_path_from_dentry(direntry); + up(&inode->i_sb->s_vfs_rename_sem); + if((fromName == NULL) || (toName == NULL)) { + rc = -ENOMEM; + goto cifs_hl_exit; + } + if (cifs_sb_target->tcon->ses->capabilities & CAP_UNIX) rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName, cifs_sb_target->local_nls); @@ -70,6 +78,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, cifsInode = CIFS_I(old_file->d_inode); cifsInode->time = 0; /* will force revalidate to go get info when needed */ +cifs_hl_exit: if (fromName) kfree(fromName); if (toName) @@ -90,7 +99,15 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) struct cifsTconInfo *pTcon; xid = GetXid(); + + down(&direntry->d_sb->s_vfs_rename_sem); full_path = build_path_from_dentry(direntry); + up(&direntry->d_sb->s_vfs_rename_sem); + + if(full_path == NULL) { + FreeXid(xid); + return -ENOMEM; + } cFYI(1, ("Full path: %s inode = 0x%p", full_path, inode)); cifs_sb = CIFS_SB(inode->i_sb); pTcon = cifs_sb->tcon; @@ -149,7 +166,15 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) cifs_sb = CIFS_SB(inode->i_sb); pTcon = cifs_sb->tcon; + down(&inode->i_sb->s_vfs_rename_sem); full_path = build_path_from_dentry(direntry); + up(&inode->i_sb->s_vfs_rename_sem); + + if(full_path == NULL) { + FreeXid(xid); + return -ENOMEM; + } + cFYI(1, ("Full path: %s ", full_path)); cFYI(1, ("symname is %s", symname)); @@ -185,7 +210,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) } int -cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen) +cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) { struct inode *inode = direntry->d_inode; int rc = -EACCES; @@ -204,7 +229,18 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen) xid = GetXid(); cifs_sb = CIFS_SB(inode->i_sb); pTcon = cifs_sb->tcon; + +/* BB would it be safe against deadlock to grab this sem + even though rename itself grabs the sem and calls lookup? */ +/* down(&inode->i_sb->s_vfs_rename_sem);*/ full_path = build_path_from_dentry(direntry); +/* up(&inode->i_sb->s_vfs_rename_sem);*/ + + if(full_path == NULL) { + FreeXid(xid); + return -ENOMEM; + } + cFYI(1, ("Full path: %s inode = 0x%p pBuffer = 0x%p buflen = %d", full_path, inode, pBuffer, buflen));