Commit 04236d39 authored by Steve French's avatar Steve French Committed by Steve French

[CIFS] Check right mid state on hung network responses. Fix remote

dnotify to be disabled by default. Fix dnotify endianness.

Signed-off-by: Steve French (sfrench@us.ibm.com)
parent 0bdd8631
......@@ -571,14 +571,18 @@ struct file_operations cifs_file_ops = {
.flush = cifs_flush,
.mmap = cifs_file_mmap,
.sendfile = generic_file_sendfile,
#ifdef CONFIG_CIFS_EXPERIMENTAL
.dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
};
struct file_operations cifs_dir_ops = {
.readdir = cifs_readdir,
.release = cifs_closedir,
.read = generic_read_dir,
#ifdef CONFIG_CIFS_EXPERIMENTAL
.dir_notify = cifs_dir_notify,
#endif /* CONFIG_CIFS_EXPERIMENTAL */
};
static void
......
......@@ -975,10 +975,10 @@ typedef struct smb_com_transaction_change_notify_rsp {
/* response contains array of the following structures */
struct file_notify_information {
__u32 NextEntryOffset;
__u32 Action;
__u32 FileNameLength;
__u8 FileName[1];
__le32 NextEntryOffset;
__le32 Action;
__le32 FileNameLength;
__u8 FileName[0];
};
struct reparse_data {
......@@ -1077,6 +1077,7 @@ struct smb_t2_rsp {
#define SMB_QUERY_FILE_UNIX_BASIC 0x200
#define SMB_QUERY_FILE_UNIX_LINK 0x201
#define SMB_QUERY_POSIX_ACL 0x204
#define SMB_QUERY_XATTR 0x205
#define SMB_QUERY_FILE_INTERNAL_INFO 0x3ee
#define SMB_QUERY_FILE_ACCESS_INFO 0x3f0
#define SMB_QUERY_FILE_NAME_INFO2 0x3f1 /* 0x30 bytes */
......@@ -1091,8 +1092,9 @@ struct smb_t2_rsp {
#define SMB_SET_FILE_END_OF_FILE_INFO 0x104
#define SMB_SET_FILE_UNIX_BASIC 0x200
#define SMB_SET_FILE_UNIX_LINK 0x201
#define SMB_SET_POSIX_ACL 0x204
#define SMB_SET_FILE_UNIX_HLINK 0x203
#define SMB_SET_POSIX_ACL 0x204
#define SMB_SET_XATTR 0x205
#define SMB_SET_FILE_BASIC_INFO2 0x3ec
#define SMB_SET_FILE_RENAME_INFORMATION 0x3f2 /* BB check if qpathinfo level too */
#define SMB_FILE_ALL_INFO2 0x3fa
......@@ -1501,6 +1503,7 @@ typedef struct {
/* Linux/Unix extensions capability flags */
#define CIFS_UNIX_FCNTL_CAP 0x00000001 /* support for fcntl locks */
#define CIFS_UNIX_POSIX_ACL_CAP 0x00000002
#define CIFS_UNIX_XATTR_CAP 0x00000004 /*support for new namespace*/
/* DeviceType Flags */
#define FILE_DEVICE_CD_ROM 0x00000002
......@@ -1909,6 +1912,15 @@ struct xsymlink {
char path[1024];
};
typedef struct {
/* BB do we need another field for flags? BB */
__u32 xattr_name_len;
__u32 xattr_value_len;
char xattr_name[0];
/* followed by xattr_value[xattr_value_len], no pad */
} FILE_XATTR_INFO; /* extended attribute, info level 205 */
#endif
#pragma pack() /* resume default structure packing */
......
......@@ -28,6 +28,44 @@
#include "cifs_unicode.h"
#include "cifs_debug.h"
__u32 convert_to_cifs_notify_flags(unsigned long fcntl_notify_flags)
{
__u32 cifs_ntfy_flags = 0;
/* No way on Linux VFS to ask to monitor xattr
changes (and no stream support either */
if(fcntl_notify_flags & DN_ACCESS) {
cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_ACCESS;
}
if(fcntl_notify_flags & DN_MODIFY) {
/* What does this mean on directories? */
cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_SIZE;
}
if(fcntl_notify_flags & DN_CREATE) {
cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_CREATION |
FILE_NOTIFY_CHANGE_LAST_WRITE;
}
if(fcntl_notify_flags & DN_DELETE) {
cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_LAST_WRITE;
}
if(fcntl_notify_flags & DN_RENAME) {
/* BB review this - checking various server behaviors */
cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_FILE_NAME;
}
if(fcntl_notify_flags & DN_ATTRIB) {
cifs_ntfy_flags |= FILE_NOTIFY_CHANGE_SECURITY |
FILE_NOTIFY_CHANGE_ATTRIBUTES;
}
/* if(fcntl_notify_flags & DN_MULTISHOT) {
cifs_ntfy_flags |= ;
} */ /* BB fixme - not sure how to handle this with CIFS yet */
return cifs_ntfy_flags;
}
int cifs_dir_notify(struct file * file, unsigned long arg)
{
int xid;
......@@ -50,20 +88,26 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
if(full_path == NULL) {
rc = -ENOMEM;
} else {
cFYI(1,("cifs dir notify on file %s",full_path));
cERROR(1,("cifs dir notify on file %s with arg 0x%lx",full_path,arg)); /* BB removeme BB */
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
GENERIC_READ | SYNCHRONIZE, 0 /* create options */,
&netfid, &oplock,NULL, cifs_sb->local_nls);
/* BB fixme - add this handle to a notify handle list */
if(rc) {
cFYI(1,("Could not open directory for notify"));
cERROR(1,("Could not open directory for notify")); /* BB remove BB */
} else {
rc = CIFSSMBNotify(xid, pTcon, 1 /* subdirs */, netfid,
filter, cifs_sb->local_nls);
filter = convert_to_cifs_notify_flags(arg);
if(filter != 0) {
rc = CIFSSMBNotify(xid, pTcon, 0 /* no subdirs */, netfid,
filter, cifs_sb->local_nls);
} else {
rc = -EINVAL;
}
/* BB add code to close file eventually (at unmount
it would close automatically but may be a way
to do it easily when inode freed or when
notify info is cleared/changed */
cERROR(1,("notify rc %d",rc));
}
}
......
......@@ -450,13 +450,13 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
if(timeout != MAX_SCHEDULE_TIMEOUT) {
timeout += jiffies;
wait_event(ses->server->response_q,
(midQ->midState & MID_RESPONSE_RECEIVED) ||
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
time_after(jiffies, timeout) ||
((ses->server->tcpStatus != CifsGood) &&
(ses->server->tcpStatus != CifsNew)));
} else {
wait_event(ses->server->response_q,
(midQ->midState & MID_RESPONSE_RECEIVED) ||
(!(midQ->midState & MID_REQUEST_SUBMITTED)) ||
((ses->server->tcpStatus != CifsGood) &&
(ses->server->tcpStatus != CifsNew)));
}
......
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