13 cifs/smb3 patches most from testing at the SMB3 plugfest this week
-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE6fsu8pdIjtWE/DpLiiy9cAdyT1EFAl49bNsACgkQiiy9cAdy T1EGlQwArDJiHUV7W/WaoDZnusPPQqUT3ayqAHL0P8cDsjxLu3uNMkUISr0HdbxC kqYahSTb+/BKQzoZhVe5wK3S8W6R8+wyaPJExRCL3brlIHVP/eC9uUjSgkT6QVDl /vZCwxj7KmTK/S+ofji/XTl2f8f8BCw2biGVxwR2Jj5pwKI4wFIMFm7mDetTQRD4 bK0UR2Owiw4DpPXdwHlXPf9N06z0ETa1UdMXklIBgeK9B1eT1STD9q/iHJh3bLpO klhbiq5eGRCcs9cBVTQcn6U+zGYBOcdJuhPGbAObEU+R2vNX06clydKlKy1oz1VL 4jbVVn9xuGZ9evFBC3h7Na1X7C3V28WcpfeRfFxZ157hNuQSNo5wiq0rF66EQ14U hbmlx2S2ooyNKcnrj46SUw9zVLZ0xcx1Mw7kmoyHgI/vznW9fvV0Y2JXawJMPei5 VuQTgDLFsvnIIrUnrGBu2UXMzXghxLZ3SXJVKXuW3luvNRk82RAGHmIdty3OTgPp DN9lhGvv =F1qf -----END PGP SIGNATURE----- Merge tag '5.6-rc-smb3-plugfest-patches' of git://git.samba.org/sfrench/cifs-2.6 Pull cifs fixes from Steve French: "13 cifs/smb3 patches, most from testing at the SMB3 plugfest this week: - Important fix for multichannel and for modefromsid mounts. - Two reconnect fixes - Addition of SMB3 change notify support - Backup tools fix - A few additional minor debug improvements (tracepoints and additional logging found useful during testing this week)" * tag '5.6-rc-smb3-plugfest-patches' of git://git.samba.org/sfrench/cifs-2.6: smb3: Add defines for new information level, FileIdInformation smb3: print warning once if posix context returned on open smb3: add one more dynamic tracepoint missing from strict fsync path cifs: fix mode bits from dir listing when mounted with modefromsid cifs: fix channel signing cifs: add SMB3 change notification support cifs: make multichannel warning more visible cifs: fix soft mounts hanging in the reconnect code cifs: Add tracepoints for errors on flush or fsync cifs: log warning message (once) if out of disk space cifs: fail i/o on soft mounts if sessionsetup errors out smb3: fix problem with null cifs super block with previous patch SMB3: Backup intent flag missing from some more ops
This commit is contained in:
commit
d1ea35f4cd
|
@ -65,6 +65,11 @@ struct smb3_key_debug_info {
|
|||
__u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE];
|
||||
} __packed;
|
||||
|
||||
struct smb3_notify {
|
||||
__u32 completion_filter;
|
||||
bool watch_tree;
|
||||
} __packed;
|
||||
|
||||
#define CIFS_IOCTL_MAGIC 0xCF
|
||||
#define CIFS_IOC_COPYCHUNK_FILE _IOW(CIFS_IOCTL_MAGIC, 3, int)
|
||||
#define CIFS_IOC_SET_INTEGRITY _IO(CIFS_IOCTL_MAGIC, 4)
|
||||
|
@ -72,3 +77,4 @@ struct smb3_key_debug_info {
|
|||
#define CIFS_ENUMERATE_SNAPSHOTS _IOR(CIFS_IOCTL_MAGIC, 6, struct smb_snapshot_array)
|
||||
#define CIFS_QUERY_INFO _IOWR(CIFS_IOCTL_MAGIC, 7, struct smb_query_info)
|
||||
#define CIFS_DUMP_KEY _IOWR(CIFS_IOCTL_MAGIC, 8, struct smb3_key_debug_info)
|
||||
#define CIFS_IOC_NOTIFY _IOW(CIFS_IOCTL_MAGIC, 9, struct smb3_notify)
|
||||
|
|
|
@ -1084,7 +1084,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
|
|||
struct cifs_ntsd *pntsd = NULL;
|
||||
int oplock = 0;
|
||||
unsigned int xid;
|
||||
int rc, create_options = 0;
|
||||
int rc;
|
||||
struct cifs_tcon *tcon;
|
||||
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
|
||||
struct cifs_fid fid;
|
||||
|
@ -1096,13 +1096,10 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
|
|||
tcon = tlink_tcon(tlink);
|
||||
xid = get_xid();
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
|
||||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = READ_CONTROL;
|
||||
oparms.create_options = create_options;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.path = path;
|
||||
oparms.fid = &fid;
|
||||
|
@ -1147,7 +1144,7 @@ int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
|
|||
{
|
||||
int oplock = 0;
|
||||
unsigned int xid;
|
||||
int rc, access_flags, create_options = 0;
|
||||
int rc, access_flags;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
|
||||
|
@ -1160,9 +1157,6 @@ int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
|
|||
tcon = tlink_tcon(tlink);
|
||||
xid = get_xid();
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
|
||||
if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
|
||||
access_flags = WRITE_OWNER;
|
||||
else
|
||||
|
@ -1171,7 +1165,7 @@ int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
|
|||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = access_flags;
|
||||
oparms.create_options = create_options;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.path = path;
|
||||
oparms.fid = &fid;
|
||||
|
|
|
@ -275,7 +275,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
|
|||
buf->f_ffree = 0; /* unlimited */
|
||||
|
||||
if (server->ops->queryfs)
|
||||
rc = server->ops->queryfs(xid, tcon, buf);
|
||||
rc = server->ops->queryfs(xid, tcon, cifs_sb, buf);
|
||||
|
||||
free_xid(xid);
|
||||
return 0;
|
||||
|
|
|
@ -298,7 +298,8 @@ struct smb_version_operations {
|
|||
const char *, struct dfs_info3_param **,
|
||||
unsigned int *, const struct nls_table *, int);
|
||||
/* informational QFS call */
|
||||
void (*qfs_tcon)(const unsigned int, struct cifs_tcon *);
|
||||
void (*qfs_tcon)(const unsigned int, struct cifs_tcon *,
|
||||
struct cifs_sb_info *);
|
||||
/* check if a path is accessible or not */
|
||||
int (*is_path_accessible)(const unsigned int, struct cifs_tcon *,
|
||||
struct cifs_sb_info *, const char *);
|
||||
|
@ -409,7 +410,7 @@ struct smb_version_operations {
|
|||
struct cifsInodeInfo *);
|
||||
/* query remote filesystem */
|
||||
int (*queryfs)(const unsigned int, struct cifs_tcon *,
|
||||
struct kstatfs *);
|
||||
struct cifs_sb_info *, struct kstatfs *);
|
||||
/* send mandatory brlock to the server */
|
||||
int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64,
|
||||
__u64, __u32, int, int, bool);
|
||||
|
@ -430,6 +431,8 @@ struct smb_version_operations {
|
|||
struct cifsFileInfo *src_file);
|
||||
int (*enum_snapshots)(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifsFileInfo *src_file, void __user *);
|
||||
int (*notify)(const unsigned int xid, struct file *pfile,
|
||||
void __user *pbuf);
|
||||
int (*query_mf_symlink)(unsigned int, struct cifs_tcon *,
|
||||
struct cifs_sb_info *, const unsigned char *,
|
||||
char *, unsigned int *);
|
||||
|
@ -490,6 +493,7 @@ struct smb_version_operations {
|
|||
/* ioctl passthrough for query_info */
|
||||
int (*ioctl_query_info)(const unsigned int xid,
|
||||
struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb,
|
||||
__le16 *path, int is_dir,
|
||||
unsigned long p);
|
||||
/* make unix special files (block, char, fifo, socket) */
|
||||
|
|
|
@ -612,4 +612,12 @@ static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
|
|||
}
|
||||
#endif
|
||||
|
||||
static inline int cifs_create_options(struct cifs_sb_info *cifs_sb, int options)
|
||||
{
|
||||
if (cifs_sb && (backup_cred(cifs_sb)))
|
||||
return options | CREATE_OPEN_BACKUP_INTENT;
|
||||
else
|
||||
return options;
|
||||
}
|
||||
|
||||
#endif /* _CIFSPROTO_H */
|
||||
|
|
|
@ -260,7 +260,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
|
|||
if (server->tcpStatus != CifsNeedReconnect)
|
||||
break;
|
||||
|
||||
if (--retries)
|
||||
if (retries && --retries)
|
||||
continue;
|
||||
|
||||
/*
|
||||
|
|
|
@ -4365,7 +4365,7 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
|
|||
|
||||
/* do not care if a following call succeed - informational */
|
||||
if (!tcon->pipe && server->ops->qfs_tcon) {
|
||||
server->ops->qfs_tcon(*xid, tcon);
|
||||
server->ops->qfs_tcon(*xid, tcon, cifs_sb);
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) {
|
||||
if (tcon->fsDevInfo.DeviceCharacteristics &
|
||||
cpu_to_le32(FILE_READ_ONLY_DEVICE))
|
||||
|
|
|
@ -355,13 +355,10 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
|
|||
if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
|
||||
create_options |= CREATE_OPTION_READONLY;
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
|
||||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = desired_access;
|
||||
oparms.create_options = create_options;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, create_options);
|
||||
oparms.disposition = disposition;
|
||||
oparms.path = full_path;
|
||||
oparms.fid = fid;
|
||||
|
|
|
@ -222,9 +222,6 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
|
|||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
|
||||
/* O_SYNC also has bit for O_DSYNC so following check picks up either */
|
||||
if (f_flags & O_SYNC)
|
||||
create_options |= CREATE_WRITE_THROUGH;
|
||||
|
@ -235,7 +232,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
|
|||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = desired_access;
|
||||
oparms.create_options = create_options;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, create_options);
|
||||
oparms.disposition = disposition;
|
||||
oparms.path = full_path;
|
||||
oparms.fid = fid;
|
||||
|
@ -752,9 +749,6 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
|
|||
|
||||
desired_access = cifs_convert_flags(cfile->f_flags);
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
|
||||
/* O_SYNC also has bit for O_DSYNC so following check picks up either */
|
||||
if (cfile->f_flags & O_SYNC)
|
||||
create_options |= CREATE_WRITE_THROUGH;
|
||||
|
@ -768,7 +762,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
|
|||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = desired_access;
|
||||
oparms.create_options = create_options;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, create_options);
|
||||
oparms.disposition = disposition;
|
||||
oparms.path = full_path;
|
||||
oparms.fid = &cfile->fid;
|
||||
|
@ -2599,8 +2593,10 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
|
|||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
|
||||
rc = file_write_and_wait_range(file, start, end);
|
||||
if (rc)
|
||||
if (rc) {
|
||||
trace_cifs_fsync_err(inode->i_ino, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
xid = get_xid();
|
||||
|
||||
|
@ -2638,8 +2634,10 @@ int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
|
|||
struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
|
||||
|
||||
rc = file_write_and_wait_range(file, start, end);
|
||||
if (rc)
|
||||
if (rc) {
|
||||
trace_cifs_fsync_err(file_inode(file)->i_ino, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
xid = get_xid();
|
||||
|
||||
|
@ -2672,7 +2670,8 @@ int cifs_flush(struct file *file, fl_owner_t id)
|
|||
rc = filemap_write_and_wait(inode->i_mapping);
|
||||
|
||||
cifs_dbg(FYI, "Flush inode %p file %p rc %d\n", inode, file, rc);
|
||||
|
||||
if (rc)
|
||||
trace_cifs_flush_err(inode->i_ino, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -475,9 +475,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const char *path,
|
|||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = GENERIC_READ;
|
||||
oparms.create_options = CREATE_NOT_DIR;
|
||||
if (backup_cred(cifs_sb))
|
||||
oparms.create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.path = path;
|
||||
oparms.fid = &fid;
|
||||
|
@ -1285,7 +1283,7 @@ cifs_rename_pending_delete(const char *full_path, struct dentry *dentry,
|
|||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = DELETE | FILE_WRITE_ATTRIBUTES;
|
||||
oparms.create_options = CREATE_NOT_DIR;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.path = full_path;
|
||||
oparms.fid = &fid;
|
||||
|
@ -1823,7 +1821,7 @@ cifs_do_rename(const unsigned int xid, struct dentry *from_dentry,
|
|||
oparms.cifs_sb = cifs_sb;
|
||||
/* open the file to be renamed -- we need DELETE perms */
|
||||
oparms.desired_access = DELETE;
|
||||
oparms.create_options = CREATE_NOT_DIR;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.path = from_path;
|
||||
oparms.fid = &fid;
|
||||
|
|
|
@ -65,7 +65,7 @@ static long cifs_ioctl_query_info(unsigned int xid, struct file *filep,
|
|||
|
||||
if (tcon->ses->server->ops->ioctl_query_info)
|
||||
rc = tcon->ses->server->ops->ioctl_query_info(
|
||||
xid, tcon, utf16_path,
|
||||
xid, tcon, cifs_sb, utf16_path,
|
||||
filep->private_data ? 0 : 1, p);
|
||||
else
|
||||
rc = -EOPNOTSUPP;
|
||||
|
@ -169,6 +169,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
|
|||
unsigned int xid;
|
||||
struct cifsFileInfo *pSMBFile = filep->private_data;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
__u64 ExtAttrBits = 0;
|
||||
__u64 caps;
|
||||
|
||||
|
@ -299,6 +300,21 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
|
|||
else
|
||||
rc = 0;
|
||||
break;
|
||||
case CIFS_IOC_NOTIFY:
|
||||
if (!S_ISDIR(inode->i_mode)) {
|
||||
/* Notify can only be done on directories */
|
||||
rc = -EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
cifs_sb = CIFS_SB(inode->i_sb);
|
||||
tcon = tlink_tcon(cifs_sb_tlink(cifs_sb));
|
||||
if (tcon && tcon->ses->server->ops->notify) {
|
||||
rc = tcon->ses->server->ops->notify(xid,
|
||||
filep, (void __user *)arg);
|
||||
cifs_dbg(FYI, "ioctl notify rc %d\n", rc);
|
||||
} else
|
||||
rc = -EOPNOTSUPP;
|
||||
break;
|
||||
default:
|
||||
cifs_dbg(FYI, "unsupported ioctl\n");
|
||||
break;
|
||||
|
|
|
@ -315,7 +315,7 @@ cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = GENERIC_READ;
|
||||
oparms.create_options = CREATE_NOT_DIR;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.path = path;
|
||||
oparms.fid = &fid;
|
||||
|
@ -353,15 +353,11 @@ cifs_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
|||
struct cifs_fid fid;
|
||||
struct cifs_open_parms oparms;
|
||||
struct cifs_io_parms io_parms;
|
||||
int create_options = CREATE_NOT_DIR;
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
|
||||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = GENERIC_WRITE;
|
||||
oparms.create_options = create_options;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
|
||||
oparms.disposition = FILE_CREATE;
|
||||
oparms.path = path;
|
||||
oparms.fid = &fid;
|
||||
|
@ -402,9 +398,7 @@ smb3_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = GENERIC_READ;
|
||||
oparms.create_options = CREATE_NOT_DIR;
|
||||
if (backup_cred(cifs_sb))
|
||||
oparms.create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
@ -457,14 +451,10 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
|||
struct cifs_fid fid;
|
||||
struct cifs_open_parms oparms;
|
||||
struct cifs_io_parms io_parms;
|
||||
int create_options = CREATE_NOT_DIR;
|
||||
__le16 *utf16_path;
|
||||
__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
|
||||
struct kvec iov[2];
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
|
||||
cifs_dbg(FYI, "%s: path: %s\n", __func__, path);
|
||||
|
||||
utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
|
||||
|
@ -474,7 +464,7 @@ smb3_create_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = GENERIC_WRITE;
|
||||
oparms.create_options = create_options;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
|
||||
oparms.disposition = FILE_CREATE;
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
|
|
@ -196,7 +196,8 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
|
|||
* may look wrong since the inodes may not have timed out by the time
|
||||
* "ls" does a stat() call on them.
|
||||
*/
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
|
||||
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) ||
|
||||
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID))
|
||||
fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;
|
||||
|
||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL &&
|
||||
|
|
|
@ -101,7 +101,7 @@ int cifs_try_adding_channels(struct cifs_ses *ses)
|
|||
iface_count = ses->iface_count;
|
||||
if (iface_count <= 0) {
|
||||
spin_unlock(&ses->iface_lock);
|
||||
cifs_dbg(FYI, "no iface list available to open channels\n");
|
||||
cifs_dbg(VFS, "no iface list available to open channels\n");
|
||||
return 0;
|
||||
}
|
||||
ifaces = kmemdup(ses->iface_list, iface_count*sizeof(*ifaces),
|
||||
|
|
|
@ -504,7 +504,8 @@ cifs_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
|
|||
}
|
||||
|
||||
static void
|
||||
cifs_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
|
||||
cifs_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
CIFSSMBQFSDeviceInfo(xid, tcon);
|
||||
CIFSSMBQFSAttributeInfo(xid, tcon);
|
||||
|
@ -565,7 +566,7 @@ cifs_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
||||
oparms.create_options = 0;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.path = full_path;
|
||||
oparms.fid = &fid;
|
||||
|
@ -793,7 +794,7 @@ smb_set_file_info(struct inode *inode, const char *full_path,
|
|||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = SYNCHRONIZE | FILE_WRITE_ATTRIBUTES;
|
||||
oparms.create_options = CREATE_NOT_DIR;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR);
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.path = full_path;
|
||||
oparms.fid = &fid;
|
||||
|
@ -872,7 +873,7 @@ cifs_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
|
|||
|
||||
static int
|
||||
cifs_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct kstatfs *buf)
|
||||
struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
|
||||
{
|
||||
int rc = -EOPNOTSUPP;
|
||||
|
||||
|
@ -970,7 +971,8 @@ cifs_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
||||
oparms.create_options = OPEN_REPARSE_POINT;
|
||||
oparms.create_options = cifs_create_options(cifs_sb,
|
||||
OPEN_REPARSE_POINT);
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.path = full_path;
|
||||
oparms.fid = &fid;
|
||||
|
@ -1029,7 +1031,6 @@ cifs_make_node(unsigned int xid, struct inode *inode,
|
|||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct inode *newinode = NULL;
|
||||
int rc = -EPERM;
|
||||
int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
|
||||
FILE_ALL_INFO *buf = NULL;
|
||||
struct cifs_io_parms io_parms;
|
||||
__u32 oplock = 0;
|
||||
|
@ -1090,13 +1091,11 @@ cifs_make_node(unsigned int xid, struct inode *inode,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
|
||||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = GENERIC_WRITE;
|
||||
oparms.create_options = create_options;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR |
|
||||
CREATE_OPTION_SPECIAL);
|
||||
oparms.disposition = FILE_CREATE;
|
||||
oparms.path = full_path;
|
||||
oparms.fid = &fid;
|
||||
|
|
|
@ -99,9 +99,7 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.tcon = tcon;
|
||||
oparms.desired_access = desired_access;
|
||||
oparms.disposition = create_disposition;
|
||||
oparms.create_options = create_options;
|
||||
if (backup_cred(cifs_sb))
|
||||
oparms.create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, create_options);
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
oparms.mode = mode;
|
||||
|
@ -457,7 +455,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
|
||||
/* If it is a root and its handle is cached then use it */
|
||||
if (!strlen(full_path) && !no_cached_open) {
|
||||
rc = open_shroot(xid, tcon, &fid);
|
||||
rc = open_shroot(xid, tcon, cifs_sb, &fid);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
|
@ -474,9 +472,6 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
|
||||
cifs_get_readable_path(tcon, full_path, &cfile);
|
||||
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
|
||||
FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
|
||||
|
|
|
@ -655,7 +655,8 @@ smb2_cached_lease_break(struct work_struct *work)
|
|||
/*
|
||||
* Open the directory at the root of a share
|
||||
*/
|
||||
int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
|
||||
int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb, struct cifs_fid *pfid)
|
||||
{
|
||||
struct cifs_ses *ses = tcon->ses;
|
||||
struct TCP_Server_Info *server = ses->server;
|
||||
|
@ -702,7 +703,7 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
|
|||
rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
|
||||
|
||||
oparms.tcon = tcon;
|
||||
oparms.create_options = 0;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.fid = pfid;
|
||||
|
@ -818,7 +819,8 @@ oshr_free:
|
|||
}
|
||||
|
||||
static void
|
||||
smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
|
||||
smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
int rc;
|
||||
__le16 srch_path = 0; /* Null - open root of share */
|
||||
|
@ -830,7 +832,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
|
|||
oparms.tcon = tcon;
|
||||
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.create_options = 0;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
|
@ -838,7 +840,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
|
|||
rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL,
|
||||
NULL);
|
||||
else
|
||||
rc = open_shroot(xid, tcon, &fid);
|
||||
rc = open_shroot(xid, tcon, cifs_sb, &fid);
|
||||
|
||||
if (rc)
|
||||
return;
|
||||
|
@ -860,7 +862,8 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
|
|||
}
|
||||
|
||||
static void
|
||||
smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
|
||||
smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb)
|
||||
{
|
||||
int rc;
|
||||
__le16 srch_path = 0; /* Null - open root of share */
|
||||
|
@ -871,7 +874,7 @@ smb2_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
|
|||
oparms.tcon = tcon;
|
||||
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.create_options = 0;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
|
@ -906,10 +909,7 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.tcon = tcon;
|
||||
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
if (backup_cred(cifs_sb))
|
||||
oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
|
||||
else
|
||||
oparms.create_options = 0;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
|
@ -1151,10 +1151,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.tcon = tcon;
|
||||
oparms.desired_access = FILE_WRITE_EA;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
if (backup_cred(cifs_sb))
|
||||
oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
|
||||
else
|
||||
oparms.create_options = 0;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
|
@ -1422,6 +1419,7 @@ req_res_key_exit:
|
|||
static int
|
||||
smb2_ioctl_query_info(const unsigned int xid,
|
||||
struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb,
|
||||
__le16 *path, int is_dir,
|
||||
unsigned long p)
|
||||
{
|
||||
|
@ -1447,6 +1445,7 @@ smb2_ioctl_query_info(const unsigned int xid,
|
|||
struct kvec close_iov[1];
|
||||
unsigned int size[2];
|
||||
void *data[2];
|
||||
int create_options = is_dir ? CREATE_NOT_FILE : CREATE_NOT_DIR;
|
||||
|
||||
memset(rqst, 0, sizeof(rqst));
|
||||
resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
|
||||
|
@ -1477,10 +1476,7 @@ smb2_ioctl_query_info(const unsigned int xid,
|
|||
memset(&oparms, 0, sizeof(oparms));
|
||||
oparms.tcon = tcon;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
if (is_dir)
|
||||
oparms.create_options = CREATE_NOT_FILE;
|
||||
else
|
||||
oparms.create_options = CREATE_NOT_DIR;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, create_options);
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
|
@ -2049,6 +2045,66 @@ smb3_enum_snapshots(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
smb3_notify(const unsigned int xid, struct file *pfile,
|
||||
void __user *ioc_buf)
|
||||
{
|
||||
struct smb3_notify notify;
|
||||
struct dentry *dentry = pfile->f_path.dentry;
|
||||
struct inode *inode = file_inode(pfile);
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct cifs_open_parms oparms;
|
||||
struct cifs_fid fid;
|
||||
struct cifs_tcon *tcon;
|
||||
unsigned char *path = NULL;
|
||||
__le16 *utf16_path = NULL;
|
||||
u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
|
||||
int rc = 0;
|
||||
|
||||
path = build_path_from_dentry(dentry);
|
||||
if (path == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
cifs_sb = CIFS_SB(inode->i_sb);
|
||||
|
||||
utf16_path = cifs_convert_path_to_utf16(path + 1, cifs_sb);
|
||||
if (utf16_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto notify_exit;
|
||||
}
|
||||
|
||||
if (copy_from_user(¬ify, ioc_buf, sizeof(struct smb3_notify))) {
|
||||
rc = -EFAULT;
|
||||
goto notify_exit;
|
||||
}
|
||||
|
||||
tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
oparms.tcon = tcon;
|
||||
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL, NULL);
|
||||
if (rc)
|
||||
goto notify_exit;
|
||||
|
||||
rc = SMB2_change_notify(xid, tcon, fid.persistent_fid, fid.volatile_fid,
|
||||
notify.watch_tree, notify.completion_filter);
|
||||
|
||||
SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
|
||||
|
||||
cifs_dbg(FYI, "change notify for path %s rc %d\n", path, rc);
|
||||
|
||||
notify_exit:
|
||||
kfree(path);
|
||||
kfree(utf16_path);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
const char *path, struct cifs_sb_info *cifs_sb,
|
||||
|
@ -2086,10 +2142,7 @@ smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.tcon = tcon;
|
||||
oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
if (backup_cred(cifs_sb))
|
||||
oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
|
||||
else
|
||||
oparms.create_options = 0;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.fid = fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
|
@ -2343,10 +2396,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.tcon = tcon;
|
||||
oparms.desired_access = desired_access;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
if (cifs_sb && backup_cred(cifs_sb))
|
||||
oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
|
||||
else
|
||||
oparms.create_options = 0;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
|
@ -2402,7 +2452,7 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
|
||||
static int
|
||||
smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct kstatfs *buf)
|
||||
struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
|
||||
{
|
||||
struct smb2_query_info_rsp *rsp;
|
||||
struct smb2_fs_full_size_info *info = NULL;
|
||||
|
@ -2417,7 +2467,7 @@ smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
FS_FULL_SIZE_INFORMATION,
|
||||
SMB2_O_INFO_FILESYSTEM,
|
||||
sizeof(struct smb2_fs_full_size_info),
|
||||
&rsp_iov, &buftype, NULL);
|
||||
&rsp_iov, &buftype, cifs_sb);
|
||||
if (rc)
|
||||
goto qfs_exit;
|
||||
|
||||
|
@ -2439,7 +2489,7 @@ qfs_exit:
|
|||
|
||||
static int
|
||||
smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct kstatfs *buf)
|
||||
struct cifs_sb_info *cifs_sb, struct kstatfs *buf)
|
||||
{
|
||||
int rc;
|
||||
__le16 srch_path = 0; /* Null - open root of share */
|
||||
|
@ -2448,12 +2498,12 @@ smb311_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
struct cifs_fid fid;
|
||||
|
||||
if (!tcon->posix_extensions)
|
||||
return smb2_queryfs(xid, tcon, buf);
|
||||
return smb2_queryfs(xid, tcon, cifs_sb, buf);
|
||||
|
||||
oparms.tcon = tcon;
|
||||
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.create_options = 0;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
|
@ -2722,6 +2772,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
struct smb2_create_rsp *create_rsp;
|
||||
struct smb2_ioctl_rsp *ioctl_rsp;
|
||||
struct reparse_data_buffer *reparse_buf;
|
||||
int create_options = is_reparse_point ? OPEN_REPARSE_POINT : 0;
|
||||
u32 plen;
|
||||
|
||||
cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
|
||||
|
@ -2748,14 +2799,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
oparms.tcon = tcon;
|
||||
oparms.desired_access = FILE_READ_ATTRIBUTES;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
|
||||
else
|
||||
oparms.create_options = 0;
|
||||
if (is_reparse_point)
|
||||
oparms.create_options = OPEN_REPARSE_POINT;
|
||||
|
||||
oparms.create_options = cifs_create_options(cifs_sb, create_options);
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
|
@ -2934,11 +2978,6 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb,
|
|||
tcon = tlink_tcon(tlink);
|
||||
xid = get_xid();
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
|
||||
else
|
||||
oparms.create_options = 0;
|
||||
|
||||
utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
|
||||
if (!utf16_path) {
|
||||
rc = -ENOMEM;
|
||||
|
@ -2949,6 +2988,7 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb,
|
|||
oparms.tcon = tcon;
|
||||
oparms.desired_access = READ_CONTROL;
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.fid = &fid;
|
||||
oparms.reconnect = false;
|
||||
|
||||
|
@ -2990,11 +3030,6 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
|
|||
tcon = tlink_tcon(tlink);
|
||||
xid = get_xid();
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
oparms.create_options = CREATE_OPEN_BACKUP_INTENT;
|
||||
else
|
||||
oparms.create_options = 0;
|
||||
|
||||
if (aclflag == CIFS_ACL_OWNER || aclflag == CIFS_ACL_GROUP)
|
||||
access_flags = WRITE_OWNER;
|
||||
else
|
||||
|
@ -3009,6 +3044,7 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
|
|||
|
||||
oparms.tcon = tcon;
|
||||
oparms.desired_access = access_flags;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, 0);
|
||||
oparms.disposition = FILE_OPEN;
|
||||
oparms.path = path;
|
||||
oparms.fid = &fid;
|
||||
|
@ -4491,7 +4527,6 @@ smb2_make_node(unsigned int xid, struct inode *inode,
|
|||
{
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
int rc = -EPERM;
|
||||
int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
|
||||
FILE_ALL_INFO *buf = NULL;
|
||||
struct cifs_io_parms io_parms;
|
||||
__u32 oplock = 0;
|
||||
|
@ -4527,13 +4562,11 @@ smb2_make_node(unsigned int xid, struct inode *inode,
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (backup_cred(cifs_sb))
|
||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||
|
||||
oparms.tcon = tcon;
|
||||
oparms.cifs_sb = cifs_sb;
|
||||
oparms.desired_access = GENERIC_WRITE;
|
||||
oparms.create_options = create_options;
|
||||
oparms.create_options = cifs_create_options(cifs_sb, CREATE_NOT_DIR |
|
||||
CREATE_OPTION_SPECIAL);
|
||||
oparms.disposition = FILE_CREATE;
|
||||
oparms.path = full_path;
|
||||
oparms.fid = &fid;
|
||||
|
@ -4868,6 +4901,7 @@ struct smb_version_operations smb30_operations = {
|
|||
.dir_needs_close = smb2_dir_needs_close,
|
||||
.fallocate = smb3_fallocate,
|
||||
.enum_snapshots = smb3_enum_snapshots,
|
||||
.notify = smb3_notify,
|
||||
.init_transform_rq = smb3_init_transform_rq,
|
||||
.is_transform_hdr = smb3_is_transform_hdr,
|
||||
.receive_transform = smb3_receive_transform,
|
||||
|
@ -4978,6 +5012,7 @@ struct smb_version_operations smb311_operations = {
|
|||
.dir_needs_close = smb2_dir_needs_close,
|
||||
.fallocate = smb3_fallocate,
|
||||
.enum_snapshots = smb3_enum_snapshots,
|
||||
.notify = smb3_notify,
|
||||
.init_transform_rq = smb3_init_transform_rq,
|
||||
.is_transform_hdr = smb3_is_transform_hdr,
|
||||
.receive_transform = smb3_receive_transform,
|
||||
|
|
|
@ -350,9 +350,14 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon)
|
|||
}
|
||||
|
||||
rc = cifs_negotiate_protocol(0, tcon->ses);
|
||||
if (!rc && tcon->ses->need_reconnect)
|
||||
if (!rc && tcon->ses->need_reconnect) {
|
||||
rc = cifs_setup_session(0, tcon->ses, nls_codepage);
|
||||
|
||||
if ((rc == -EACCES) && !tcon->retry) {
|
||||
rc = -EHOSTDOWN;
|
||||
mutex_unlock(&tcon->ses->session_mutex);
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
if (rc || !tcon->need_reconnect) {
|
||||
mutex_unlock(&tcon->ses->session_mutex);
|
||||
goto out;
|
||||
|
@ -397,6 +402,7 @@ out:
|
|||
case SMB2_SET_INFO:
|
||||
rc = -EAGAIN;
|
||||
}
|
||||
failed:
|
||||
unload_nls(nls_codepage);
|
||||
return rc;
|
||||
}
|
||||
|
@ -1933,6 +1939,16 @@ parse_query_id_ctxt(struct create_context *cc, struct smb2_file_all_info *buf)
|
|||
buf->IndexNumber = pdisk_id->DiskFileId;
|
||||
}
|
||||
|
||||
static void
|
||||
parse_posix_ctxt(struct create_context *cc, struct smb_posix_info *pposix_inf)
|
||||
{
|
||||
/* struct smb_posix_info *ppinf = (struct smb_posix_info *)cc; */
|
||||
|
||||
/* TODO: Need to add parsing for the context and return */
|
||||
printk_once(KERN_WARNING
|
||||
"SMB3 3.11 POSIX response context not completed yet\n");
|
||||
}
|
||||
|
||||
void
|
||||
smb2_parse_contexts(struct TCP_Server_Info *server,
|
||||
struct smb2_create_rsp *rsp,
|
||||
|
@ -1944,6 +1960,9 @@ smb2_parse_contexts(struct TCP_Server_Info *server,
|
|||
unsigned int next;
|
||||
unsigned int remaining;
|
||||
char *name;
|
||||
const char smb3_create_tag_posix[] = {0x93, 0xAD, 0x25, 0x50, 0x9C,
|
||||
0xB4, 0x11, 0xE7, 0xB4, 0x23, 0x83,
|
||||
0xDE, 0x96, 0x8B, 0xCD, 0x7C};
|
||||
|
||||
*oplock = 0;
|
||||
data_offset = (char *)rsp + le32_to_cpu(rsp->CreateContextsOffset);
|
||||
|
@ -1963,6 +1982,15 @@ smb2_parse_contexts(struct TCP_Server_Info *server,
|
|||
else if (buf && (le16_to_cpu(cc->NameLength) == 4) &&
|
||||
strncmp(name, SMB2_CREATE_QUERY_ON_DISK_ID, 4) == 0)
|
||||
parse_query_id_ctxt(cc, buf);
|
||||
else if ((le16_to_cpu(cc->NameLength) == 16)) {
|
||||
if (memcmp(name, smb3_create_tag_posix, 16) == 0)
|
||||
parse_posix_ctxt(cc, NULL);
|
||||
}
|
||||
/* else {
|
||||
cifs_dbg(FYI, "Context not matched with len %d\n",
|
||||
le16_to_cpu(cc->NameLength));
|
||||
cifs_dump_mem("Cctxt name: ", name, 4);
|
||||
} */
|
||||
|
||||
next = le32_to_cpu(cc->Next);
|
||||
if (!next)
|
||||
|
@ -3357,6 +3385,7 @@ SMB2_notify_init(const unsigned int xid, struct smb_rqst *rqst,
|
|||
|
||||
req->PersistentFileId = persistent_fid;
|
||||
req->VolatileFileId = volatile_fid;
|
||||
/* See note 354 of MS-SMB2, 64K max */
|
||||
req->OutputBufferLength =
|
||||
cpu_to_le32(SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE);
|
||||
req->CompletionFilter = cpu_to_le32(completion_filter);
|
||||
|
@ -4023,6 +4052,9 @@ smb2_writev_callback(struct mid_q_entry *mid)
|
|||
wdata->cfile->fid.persistent_fid,
|
||||
tcon->tid, tcon->ses->Suid, wdata->offset,
|
||||
wdata->bytes, wdata->result);
|
||||
if (wdata->result == -ENOSPC)
|
||||
printk_once(KERN_WARNING "Out of space writing to %s\n",
|
||||
tcon->treeName);
|
||||
} else
|
||||
trace_smb3_write_done(0 /* no xid */,
|
||||
wdata->cfile->fid.persistent_fid,
|
||||
|
|
|
@ -1519,6 +1519,7 @@ struct smb3_fs_vol_info {
|
|||
#define FILE_NORMALIZED_NAME_INFORMATION 48
|
||||
#define FILEID_GLOBAL_TX_DIRECTORY_INFORMATION 50
|
||||
#define FILE_STANDARD_LINK_INFORMATION 54
|
||||
#define FILE_ID_INFORMATION 59
|
||||
|
||||
struct smb2_file_internal_info {
|
||||
__le64 IndexNumber;
|
||||
|
@ -1593,6 +1594,21 @@ struct smb2_file_network_open_info {
|
|||
__le32 Reserved;
|
||||
} __packed; /* level 34 Query also similar returned in close rsp and open rsp */
|
||||
|
||||
/* See MS-FSCC 2.4.43 */
|
||||
struct smb2_file_id_information {
|
||||
__le64 VolumeSerialNumber;
|
||||
__u64 PersistentFileId; /* opaque endianness */
|
||||
__u64 VolatileFileId; /* opaque endianness */
|
||||
} __packed; /* level 59 */
|
||||
|
||||
extern char smb2_padding[7];
|
||||
|
||||
/* equivalent of the contents of SMB3.1.1 POSIX open context response */
|
||||
struct smb_posix_info {
|
||||
__le32 nlink;
|
||||
__le32 reparse_tag;
|
||||
__le32 mode;
|
||||
kuid_t uid;
|
||||
kuid_t gid;
|
||||
};
|
||||
#endif /* _SMB2PDU_H */
|
||||
|
|
|
@ -68,7 +68,7 @@ extern int smb3_handle_read_data(struct TCP_Server_Info *server,
|
|||
struct mid_q_entry *mid);
|
||||
|
||||
extern int open_shroot(unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_fid *pfid);
|
||||
struct cifs_sb_info *cifs_sb, struct cifs_fid *pfid);
|
||||
extern void close_shroot(struct cached_fid *cfid);
|
||||
extern void close_shroot_lease(struct cached_fid *cfid);
|
||||
extern void close_shroot_lease_locked(struct cached_fid *cfid);
|
||||
|
|
|
@ -104,13 +104,14 @@ int smb2_get_sign_key(__u64 ses_id, struct TCP_Server_Info *server, u8 *key)
|
|||
{
|
||||
struct cifs_chan *chan;
|
||||
struct cifs_ses *ses = NULL;
|
||||
struct TCP_Server_Info *it = NULL;
|
||||
int i;
|
||||
int rc = 0;
|
||||
|
||||
spin_lock(&cifs_tcp_ses_lock);
|
||||
|
||||
list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
|
||||
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
|
||||
list_for_each_entry(it, &cifs_tcp_ses_list, tcp_ses_list) {
|
||||
list_for_each_entry(ses, &it->smb_ses_list, smb_ses_list) {
|
||||
if (ses->Suid == ses_id)
|
||||
goto found;
|
||||
}
|
||||
|
|
|
@ -547,6 +547,33 @@ DEFINE_EVENT(smb3_exit_err_class, smb3_##name, \
|
|||
|
||||
DEFINE_SMB3_EXIT_ERR_EVENT(exit_err);
|
||||
|
||||
|
||||
DECLARE_EVENT_CLASS(smb3_sync_err_class,
|
||||
TP_PROTO(unsigned long ino,
|
||||
int rc),
|
||||
TP_ARGS(ino, rc),
|
||||
TP_STRUCT__entry(
|
||||
__field(unsigned long, ino)
|
||||
__field(int, rc)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__entry->ino = ino;
|
||||
__entry->rc = rc;
|
||||
),
|
||||
TP_printk("\tino=%lu rc=%d",
|
||||
__entry->ino, __entry->rc)
|
||||
)
|
||||
|
||||
#define DEFINE_SMB3_SYNC_ERR_EVENT(name) \
|
||||
DEFINE_EVENT(smb3_sync_err_class, cifs_##name, \
|
||||
TP_PROTO(unsigned long ino, \
|
||||
int rc), \
|
||||
TP_ARGS(ino, rc))
|
||||
|
||||
DEFINE_SMB3_SYNC_ERR_EVENT(fsync_err);
|
||||
DEFINE_SMB3_SYNC_ERR_EVENT(flush_err);
|
||||
|
||||
|
||||
DECLARE_EVENT_CLASS(smb3_enter_exit_class,
|
||||
TP_PROTO(unsigned int xid,
|
||||
const char *func_name),
|
||||
|
|
Loading…
Reference in New Issue