Commit 6e40cfce authored by Pavel Shilovsky's avatar Pavel Shilovsky

Fixes in 2.6.33

- oplock handling - update from longterm tree
parent 0244d374
......@@ -623,49 +623,6 @@ cifs_get_sb(struct file_system_type *fs_type,
return 0;
}
static ssize_t cifs_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
{
int retval, read, posix_locking = 0;
struct file_lock pfLock;
struct cifsInodeInfo *cifsInode;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *tcon;
cifs_sb = CIFS_SB(filp->f_path.dentry->d_sb);
tcon = cifs_sb->tcon;
if ((tcon->ses->capabilities & CAP_UNIX) &&
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
posix_locking = 1;
retval = cifs_revalidate(filp->f_path.dentry);
if (retval < 0)
return (ssize_t)retval;
memset(&pfLock, 0, sizeof(pfLock));
pfLock.fl_type = F_RDLCK;
pfLock.fl_start = *ppos;
pfLock.fl_end = *ppos+len;
cifsInode = CIFS_I(filp->f_path.dentry->d_inode);
if (cifsInode == NULL)
return -ENOENT;
if (!CIFS_I(filp->f_path.dentry->d_inode)->clientCanCacheRead && !posix_locking) {
retval = cifs_lock(filp, F_GETLK | CIFS_NOPOSIXBRL_READ, &pfLock);
if (retval < 0)
return (ssize_t)retval;
if (pfLock.fl_type == F_UNLCK)
read = do_sync_read(filp, buf, len, ppos);
else
return -EACCES;
} else
read = do_sync_read(filp, buf, len, ppos);
if (read == -EACCES && !posix_locking)
read = cifs_user_read(filp, buf, len, ppos);
return read;
}
static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
......@@ -787,7 +744,7 @@ const struct inode_operations cifs_symlink_inode_ops = {
};
const struct file_operations cifs_file_ops = {
.read = cifs_sync_read,
.read = do_sync_read,
.write = do_sync_write,
.aio_read = generic_file_aio_read,
.aio_write = cifs_file_aio_write,
......@@ -1086,7 +1043,7 @@ init_cifs(void)
goto out_unregister_filesystem;
#endif
#ifdef CONFIG_CIFS_DFS_UPCALL
rc = register_key_type(&key_type_dns_resolver);
rc = cifs_init_dns_resolver();
if (rc)
goto out_unregister_key_type;
#endif
......@@ -1098,7 +1055,7 @@ init_cifs(void)
out_unregister_resolver_key:
#ifdef CONFIG_CIFS_DFS_UPCALL
unregister_key_type(&key_type_dns_resolver);
cifs_exit_dns_resolver();
out_unregister_key_type:
#endif
#ifdef CONFIG_CIFS_UPCALL
......@@ -1124,7 +1081,7 @@ exit_cifs(void)
cifs_proc_clean();
#ifdef CONFIG_CIFS_DFS_UPCALL
cifs_dfs_release_automount_timer();
unregister_key_type(&key_type_dns_resolver);
cifs_exit_dns_resolver();
#endif
#ifdef CONFIG_CIFS_UPCALL
unregister_key_type(&cifs_spnego_key_type);
......
......@@ -319,8 +319,6 @@ struct cifsLockInfo {
__u8 type;
};
#define CIFS_NOPOSIXBRL_READ 64
/*
* One of these for each open instance of a file
*/
......@@ -469,7 +467,6 @@ struct oplock_q_entry {
struct inode *pinode;
struct cifsTconInfo *tcon;
__u16 netfid;
__u32 netpid;
};
/* for pending dnotify requests */
......@@ -503,6 +500,7 @@ struct dfs_info3_param {
#define CIFS_FATTR_DFS_REFERRAL 0x1
#define CIFS_FATTR_DELETE_PENDING 0x2
#define CIFS_FATTR_NEED_REVAL 0x4
#define CIFS_FATTR_INO_COLLISION 0x8
struct cifs_fattr {
u32 cf_flags;
......
......@@ -95,8 +95,10 @@ extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode,
__u16 fileHandle, struct file *file,
struct vfsmount *mnt, unsigned int oflags);
extern int cifs_posix_open(char *full_path, struct inode **pinode,
struct vfsmount *mnt, int mode, int oflags,
__u32 *poplock, __u16 *pnetfid, int xid);
struct vfsmount *mnt,
struct super_block *sb,
int mode, int oflags,
__u32 *poplock, __u16 *pnetfid, int xid);
extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
FILE_UNIX_BASIC_INFO *info,
struct cifs_sb_info *cifs_sb);
......@@ -318,12 +320,12 @@ extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
const struct nls_table *cp, int mapChars);
extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
const __u16 netfid, const __u32 netpid, const __u64 len,
const __u16 netfid, const __u64 len,
const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType,
const bool waitFlag);
const bool waitFlag, const __u8 oplock_level);
extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
const __u16 smb_file_id, const __u32 netpid, const int get_flag,
const __u16 smb_file_id, const int get_flag,
const __u64 len, struct file_lock *,
const __u16 lock_type, const bool waitFlag);
extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
......
......@@ -1440,6 +1440,8 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
__u32 bytes_sent;
__u16 byte_count;
*nbytes = 0;
/* cFYI(1, ("write at %lld %d bytes", offset, count));*/
if (tcon->ses == NULL)
return -ECONNABORTED;
......@@ -1526,11 +1528,18 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
cifs_stats_inc(&tcon->num_writes);
if (rc) {
cFYI(1, ("Send error in write = %d", rc));
*nbytes = 0;
} else {
*nbytes = le16_to_cpu(pSMBr->CountHigh);
*nbytes = (*nbytes) << 16;
*nbytes += le16_to_cpu(pSMBr->Count);
/*
* Mask off high 16 bits when bytes written as returned by the
* server is greater than bytes requested by the client. Some
* OS/2 servers are known to set incorrect CountHigh values.
*/
if (*nbytes > count)
*nbytes &= 0xFFFF;
}
cifs_buf_release(pSMB);
......@@ -1623,6 +1632,14 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
*nbytes = le16_to_cpu(pSMBr->CountHigh);
*nbytes = (*nbytes) << 16;
*nbytes += le16_to_cpu(pSMBr->Count);
/*
* Mask off high 16 bits when bytes written as returned by the
* server is greater than bytes requested by the client. OS/2
* servers are known to set incorrect CountHigh values.
*/
if (*nbytes > count)
*nbytes &= 0xFFFF;
}
/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
......@@ -1640,9 +1657,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
int
CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
const __u16 smb_file_id, const __u32 net_pid, const __u64 len,
const __u16 smb_file_id, const __u64 len,
const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType, const bool waitFlag)
const __u32 numLock, const __u8 lockType,
const bool waitFlag, const __u8 oplock_level)
{
int rc = 0;
LOCK_REQ *pSMB = NULL;
......@@ -1670,11 +1688,12 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
pSMB->NumberOfLocks = cpu_to_le16(numLock);
pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
pSMB->LockType = lockType;
pSMB->OplockLevel = oplock_level;
pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = smb_file_id; /* netfid stays le */
if ((numLock != 0) || (numUnlock != 0)) {
pSMB->Locks[0].Pid = cpu_to_le16(net_pid);
pSMB->Locks[0].Pid = cpu_to_le16(current->tgid);
/* BB where to store pid high? */
pSMB->Locks[0].LengthLow = cpu_to_le32((u32)len);
pSMB->Locks[0].LengthHigh = cpu_to_le32((u32)(len>>32));
......@@ -1708,7 +1727,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
int
CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
const __u16 smb_file_id, const __u32 net_pid, const int get_flag, const __u64 len,
const __u16 smb_file_id, const int get_flag, const __u64 len,
struct file_lock *pLockData, const __u16 lock_type,
const bool waitFlag)
{
......@@ -1768,7 +1787,7 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
} else
pSMB->Timeout = 0;
parm_data->pid = cpu_to_le32(net_pid);
parm_data->pid = cpu_to_le32(current->tgid);
parm_data->start = cpu_to_le64(pLockData->fl_start);
parm_data->length = cpu_to_le64(len); /* normalize negative numbers */
......
......@@ -183,13 +183,14 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
}
int cifs_posix_open(char *full_path, struct inode **pinode,
struct vfsmount *mnt, int mode, int oflags,
__u32 *poplock, __u16 *pnetfid, int xid)
struct vfsmount *mnt, struct super_block *sb,
int mode, int oflags,
__u32 *poplock, __u16 *pnetfid, int xid)
{
int rc;
FILE_UNIX_BASIC_INFO *presp_data;
__u32 posix_flags = 0;
struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifs_fattr fattr;
cFYI(1, ("posix open %s", full_path));
......@@ -242,7 +243,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
/* get new inode and set it up */
if (*pinode == NULL) {
*pinode = cifs_iget(mnt->mnt_sb, &fattr);
*pinode = cifs_iget(sb, &fattr);
if (!*pinode) {
rc = -ENOMEM;
goto posix_open_ret;
......@@ -251,7 +252,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
cifs_fattr_to_inode(*pinode, &fattr);
}
cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, oflags);
if (mnt)
cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, oflags);
posix_open_ret:
kfree(presp_data);
......@@ -315,14 +317,15 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
if (nd && (nd->flags & LOOKUP_OPEN))
oflags = nd->intent.open.flags;
else
oflags = FMODE_READ;
oflags = FMODE_READ | SMB_O_CREAT;
if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0) &&
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
rc = cifs_posix_open(full_path, &newinode, nd->path.mnt,
mode, oflags, &oplock, &fileHandle, xid);
rc = cifs_posix_open(full_path, &newinode,
nd ? nd->path.mnt : NULL,
inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
/* EIO could indicate that (posix open) operation is not
supported, despite what server claimed in capability
negotation. EREMOTE indicates DFS junction, which is not
......@@ -681,6 +684,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
(nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
(nd->intent.open.flags & O_CREAT)) {
rc = cifs_posix_open(full_path, &newInode, nd->path.mnt,
parent_dir_inode->i_sb,
nd->intent.open.create_mode,
nd->intent.open.flags, &oplock,
&fileHandle, xid);
......
......@@ -23,12 +23,16 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/keyctl.h>
#include <linux/key-type.h>
#include <keys/user-type.h>
#include "dns_resolve.h"
#include "cifsglob.h"
#include "cifsproto.h"
#include "cifs_debug.h"
static const struct cred *dns_resolver_cache;
/* Checks if supplied name is IP address
* returns:
* 1 - name is IP
......@@ -93,6 +97,7 @@ struct key_type key_type_dns_resolver = {
int
dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
{
const struct cred *saved_cred;
int rc = -EAGAIN;
struct key *rkey = ERR_PTR(-EAGAIN);
char *name;
......@@ -132,8 +137,15 @@ dns_resolve_server_name_to_ip(const char *unc, char **ip_addr)
goto skip_upcall;
}
saved_cred = override_creds(dns_resolver_cache);
rkey = request_key(&key_type_dns_resolver, name, "");
revert_creds(saved_cred);
if (!IS_ERR(rkey)) {
if (!(rkey->perm & KEY_USR_VIEW)) {
down_read(&rkey->sem);
rkey->perm |= KEY_USR_VIEW;
up_read(&rkey->sem);
}
len = rkey->type_data.x[0];
data = rkey->payload.data;
} else {
......@@ -164,4 +176,61 @@ out:
return rc;
}
int __init cifs_init_dns_resolver(void)
{
struct cred *cred;
struct key *keyring;
int ret;
printk(KERN_NOTICE "Registering the %s key type\n",
key_type_dns_resolver.name);
/* create an override credential set with a special thread keyring in
* which DNS requests are cached
*
* this is used to prevent malicious redirections from being installed
* with add_key().
*/
cred = prepare_kernel_cred(NULL);
if (!cred)
return -ENOMEM;
keyring = key_alloc(&key_type_keyring, ".dns_resolver", 0, 0, cred,
(KEY_POS_ALL & ~KEY_POS_SETATTR) |
KEY_USR_VIEW | KEY_USR_READ,
KEY_ALLOC_NOT_IN_QUOTA);
if (IS_ERR(keyring)) {
ret = PTR_ERR(keyring);
goto failed_put_cred;
}
ret = key_instantiate_and_link(keyring, NULL, 0, NULL, NULL);
if (ret < 0)
goto failed_put_key;
ret = register_key_type(&key_type_dns_resolver);
if (ret < 0)
goto failed_put_key;
/* instruct request_key() to use this special keyring as a cache for
* the results it looks up */
cred->thread_keyring = keyring;
cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
dns_resolver_cache = cred;
return 0;
failed_put_key:
key_put(keyring);
failed_put_cred:
put_cred(cred);
return ret;
}
void __exit cifs_exit_dns_resolver(void)
{
key_revoke(dns_resolver_cache->thread_keyring);
unregister_key_type(&key_type_dns_resolver);
put_cred(dns_resolver_cache);
printk(KERN_NOTICE "Unregistered %s key type\n",
key_type_dns_resolver.name);
}
......@@ -24,8 +24,8 @@
#define _DNS_RESOLVE_H
#ifdef __KERNEL__
#include <linux/key-type.h>
extern struct key_type key_type_dns_resolver;
extern int __init cifs_init_dns_resolver(void);
extern void __exit cifs_exit_dns_resolver(void);
extern int dns_resolve_server_name_to_ip(const char *unc, char **ip_addr);
#endif /* KERNEL */
......
......@@ -304,10 +304,12 @@ int cifs_open(struct inode *inode, struct file *file)
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
int oflags = (int) cifs_posix_convert_flags(file->f_flags);
oflags |= SMB_O_CREAT;
/* can not refresh inode info since size could be stale */
rc = cifs_posix_open(full_path, &inode, file->f_path.mnt,
cifs_sb->mnt_file_mode /* ignored */,
oflags, &oplock, &netfid, xid);
inode->i_sb,
cifs_sb->mnt_file_mode /* ignored */,
oflags, &oplock, &netfid, xid);
if (rc == 0) {
cFYI(1, ("posix open succeeded"));
/* no need for special case handling of setting mode
......@@ -523,8 +525,9 @@ reopen_error_exit:
int oflags = (int) cifs_posix_convert_flags(file->f_flags);
/* can not refresh inode info since size could be stale */
rc = cifs_posix_open(full_path, NULL, file->f_path.mnt,
cifs_sb->mnt_file_mode /* ignored */,
oflags, &oplock, &netfid, xid);
inode->i_sb,
cifs_sb->mnt_file_mode /* ignored */,
oflags, &oplock, &netfid, xid);
if (rc == 0) {
cFYI(1, ("posix reopen succeeded"));
goto reopen_success;
......@@ -750,7 +753,6 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
bool wait_flag = false;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *tcon;
__u32 netpid;
__u16 netfid;
__u8 lockType = LOCKING_ANDX_LARGE_FILES;
bool posix_locking = 0;
......@@ -813,14 +815,6 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
}
netfid = ((struct cifsFileInfo *)file->private_data)->netfid;
if ((cmd & CIFS_NOPOSIXBRL_READ) &&
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_WINE_MODE))
netpid = ((struct cifsFileInfo *)file->private_data)->pid;
else
netpid = current->tgid;
cmd &= ~CIFS_NOPOSIXBRL_READ;
if ((tcon->ses->capabilities & CAP_UNIX) &&
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
......@@ -835,7 +829,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
posix_lock_type = CIFS_RDLCK;
else
posix_lock_type = CIFS_WRLCK;
rc = CIFSSMBPosixLock(xid, tcon, netfid, netpid, 1 /* get */,
rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */,
length, pfLock,
posix_lock_type, wait_flag);
FreeXid(xid);
......@@ -843,13 +837,13 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
}
/* BB we could chain these into one lock request BB */
rc = CIFSSMBLock(xid, tcon, netfid, netpid, length, pfLock->fl_start,
0, 1, lockType, 0 /* wait flag */ );
rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start,
0, 1, lockType, 0 /* wait flag */, 0);
if (rc == 0) {
rc = CIFSSMBLock(xid, tcon, netfid, netpid, length,
rc = CIFSSMBLock(xid, tcon, netfid, length,
pfLock->fl_start, 1 /* numUnlock */ ,
0 /* numLock */ , lockType,
0 /* wait flag */ );
0 /* wait flag */, 0);
pfLock->fl_type = F_UNLCK;
if (rc != 0)
cERROR(1, ("Error unlocking previously locked "
......@@ -863,17 +857,16 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
if (lockType & LOCKING_ANDX_SHARED_LOCK) {
pfLock->fl_type = F_WRLCK;
} else {
rc = CIFSSMBLock(xid, tcon, netfid, netpid,
rc = CIFSSMBLock(xid, tcon, netfid,
length, pfLock->fl_start, 0, 1,
lockType | LOCKING_ANDX_SHARED_LOCK,
0 /* wait flag */ );
0 /* wait flag */, 0);
if (rc == 0) {
rc = CIFSSMBLock(xid, tcon, netfid,
netpid, length,
pfLock->fl_start, 1, 0,
length, pfLock->fl_start, 1, 0,
lockType |
LOCKING_ANDX_SHARED_LOCK,
0 /* wait flag */ );
0 /* wait flag */, 0);
pfLock->fl_type = F_RDLCK;
if (rc != 0)
cERROR(1, ("Error unlocking "
......@@ -908,7 +901,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
if (numUnlock == 1)
posix_lock_type = CIFS_UNLCK;
rc = CIFSSMBPosixLock(xid, tcon, netfid, netpid, 0 /* set */,
rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */,
length, pfLock,
posix_lock_type, wait_flag);
} else {
......@@ -916,9 +909,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
(struct cifsFileInfo *)file->private_data;
if (numLock) {
rc = CIFSSMBLock(xid, tcon, netfid, netpid, length,
pfLock->fl_start,
0, numLock, lockType, wait_flag);
rc = CIFSSMBLock(xid, tcon, netfid, length,
pfLock->fl_start, 0, numLock, lockType,
wait_flag, 0);
if (rc == 0) {
/* For Windows locks we must store them. */
......@@ -938,9 +931,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
(pfLock->fl_start + length) >=
(li->offset + li->length)) {
stored_rc = CIFSSMBLock(xid, tcon,
netfid, netpid,
li->length, li->offset,
1, 0, li->type, false);
netfid, li->length,
li->offset, 1, 0,
li->type, false, 0);
if (stored_rc)
rc = stored_rc;
else {
......@@ -2394,9 +2387,9 @@ cifs_oplock_break(struct slow_work *work)
* disconnected since oplock already released by the server
*/
if (!cfile->closePend && !cfile->oplock_break_cancelled) {
rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, cfile->pid,
0, 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE,
false);
rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0,
LOCKING_ANDX_OPLOCK_RELEASE, false,
cinode->clientCanCacheRead ? 1 : 0);
cFYI(1, ("Oplock release rc = %d", rc));
}
}
......
......@@ -610,6 +610,16 @@ cifs_find_inode(struct inode *inode, void *opaque)
if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
return 0;
/*
* uh oh -- it's a directory. We can't use it since hardlinked dirs are
* verboten. Disable serverino and return it as if it were found, the
* caller can discard it, generate a uniqueid and retry the find
*/
if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) {
fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
cifs_autodisable_serverino(CIFS_SB(inode->i_sb));
}
return 1;
}
......@@ -629,15 +639,22 @@ cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
unsigned long hash;
struct inode *inode;
retry_iget5_locked:
cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid));
/* hash down to 32-bits on 32-bit arch */
hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
/* we have fattrs in hand, update the inode */
if (inode) {
/* was there a problematic inode number collision? */
if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {
iput(inode);
fattr->cf_uniqueid = iunique(sb, ROOT_I);
fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;
goto retry_iget5_locked;
}
cifs_fattr_to_inode(inode, fattr);
if (sb->s_flags & MS_NOATIME)
inode->i_flags |= S_NOATIME | S_NOCMTIME;
......@@ -1267,6 +1284,10 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
if (rc == 0 || rc != -ETXTBSY)
return rc;
/* open-file renames don't work across directories */
if (to_dentry->d_parent != from_dentry->d_parent)
return rc;
/* open the file to be renamed -- we need DELETE perms */
rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, FILE_SHARE_ALL,
CREATE_NOT_DIR, &srcfid, &oplock, NULL,
......@@ -1507,9 +1528,13 @@ int cifs_revalidate(struct dentry *direntry)
if (wbrc)
CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
}
cFYI(1, ("Invalidating read ahead data on "
"closed file"));
invalidate_remote_inode(direntry->d_inode);
/* may eventually have to do this for open files too */
if (list_empty(&(cifsInode->openFileList))) {
/* changed on server - flush read ahead pages */
cFYI(1, ("Invalidating read ahead data on "
"closed file"));
invalidate_remote_inode(direntry->d_inode);
}
}
}
/* mutex_unlock(&direntry->d_inode->i_mutex); */
......
......@@ -722,15 +722,7 @@ ssetup_ntlmssp_authenticate:
/* calculate session key */
setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
if (first_time) /* should this be moved into common code
with similar ntlmv2 path? */
/* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
response BB FIXME, v2_sess_key); */
/* copy session key */
/* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
bcc_ptr += LM2_SESS_KEY_SIZE; */
/* FIXME: calculate MAC key */
memcpy(bcc_ptr, (char *)v2_sess_key,
sizeof(struct ntlmv2_resp));
bcc_ptr += sizeof(struct ntlmv2_resp);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment