Skip to content

Commit

Permalink
Merge tag '5.6-rc-smb3-plugfest-patches' of git://git.samba.org/sfren…
Browse files Browse the repository at this point in the history
…ch/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
  • Loading branch information
torvalds committed Feb 9, 2020
2 parents 5586c3c + 51d92d6 commit d1ea35f
Show file tree
Hide file tree
Showing 22 changed files with 247 additions and 129 deletions.
6 changes: 6 additions & 0 deletions fs/cifs/cifs_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,16 @@ 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)
#define CIFS_IOC_GET_MNT_INFO _IOR(CIFS_IOCTL_MAGIC, 5, struct smb_mnt_fs_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)
14 changes: 4 additions & 10 deletions fs/cifs/cifsacl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 *);
Expand Down Expand Up @@ -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);
Expand All @@ -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 *);
Expand Down Expand Up @@ -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) */
Expand Down
8 changes: 8 additions & 0 deletions fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
2 changes: 1 addition & 1 deletion fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/*
Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
5 changes: 1 addition & 4 deletions fs/cifs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
21 changes: 10 additions & 11 deletions fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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;
}

Expand Down
8 changes: 3 additions & 5 deletions fs/cifs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
18 changes: 17 additions & 1 deletion fs/cifs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
18 changes: 4 additions & 14 deletions fs/cifs/link.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion fs/cifs/readdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 &&
Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/sess.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
Loading

0 comments on commit d1ea35f

Please sign in to comment.