Skip to content

Commit

Permalink
Merge tag '5.1-rc-smb3' of git://git.samba.org/sfrench/cifs-2.6
Browse files Browse the repository at this point in the history
Pull more smb3 updates from Steve French:
 "Various tracing and debugging improvements, crediting fixes, some
  cleanup, and important fallocate fix (fixes three xfstests) and lock
  fix.

  Summary:

   - Various additional dynamic tracing tracepoints

   - Debugging improvements (including ability to query the server via
     SMB3 fsctl from userspace tools which can help with stats and
     debugging)

   - One minor performance improvement (root directory inode caching)

   - Crediting (SMB3 flow control) fixes

   - Some cleanup (docs and to mknod)

   - Important fixes: one to smb3 implementation of fallocate zero range
     (which fixes three xfstests) and a POSIX lock fix"

* tag '5.1-rc-smb3' of git://git.samba.org/sfrench/cifs-2.6: (22 commits)
  CIFS: fix POSIX lock leak and invalid ptr deref
  SMB3: Allow SMB3 FSCTL queries to be sent to server from tools
  cifs: fix incorrect handling of smb2_set_sparse() return in smb3_simple_falloc
  smb2: fix typo in definition of a few error flags
  CIFS: make mknod() an smb_version_op
  cifs: minor documentation updates
  cifs: remove unused value pointed out by Coverity
  SMB3: passthru query info doesn't check for SMB3 FSCTL passthru
  smb3: add dynamic tracepoints for simple fallocate and zero range
  cifs: fix smb3_zero_range so it can expand the file-size when required
  cifs: add SMB2_ioctl_init/free helpers to be used with compounding
  smb3: Add dynamic trace points for various compounded smb3 ops
  cifs: cache FILE_ALL_INFO for the shared root handle
  smb3: display volume serial number for shares in /proc/fs/cifs/DebugData
  cifs: simplify how we handle credits in compound_send_recv()
  smb3: add dynamic tracepoint for timeout waiting for credits
  smb3: display security information in /proc/fs/cifs/DebugData more accurately
  cifs: add a timeout argument to wait_for_free_credits
  cifs: prevent starvation in wait_for_free_credits for multi-credit requests
  cifs: wait_for_free_credits() make it possible to wait for >=1 credits
  ...
  • Loading branch information
torvalds committed Mar 16, 2019
2 parents 6c83d0d + bc31d0c commit 9c7dc82
Show file tree
Hide file tree
Showing 17 changed files with 981 additions and 362 deletions.
3 changes: 2 additions & 1 deletion Documentation/filesystems/cifs/TODO
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ negotiated size) and send larger write sizes to modern servers.

5) Continue to extend the smb3 "buildbot" which does automated xfstesting
against Windows, Samba and Azure currently - to add additional tests and
to allow the buildbot to execute the tests faster.
to allow the buildbot to execute the tests faster. The URL for the
buildbot is: http://smb3-test-rhel-75.southcentralus.cloudapp.azure.com

6) Address various coverity warnings (most are not bugs per-se, but
the more warnings are addressed, the easier it is to spot real
Expand Down
34 changes: 22 additions & 12 deletions Documentation/filesystems/cifs/cifs.txt
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
This is the client VFS module for the SMB3 NAS protocol as well
older dialects such as the Common Internet File System (CIFS)
as for older dialects such as the Common Internet File System (CIFS)
protocol which was the successor to the Server Message Block
(SMB) protocol, the native file sharing mechanism for most early
PC operating systems. New and improved versions of CIFS are now
called SMB2 and SMB3. These dialects are also supported by the
CIFS VFS module. CIFS is fully supported by network
file servers such as Windows 2000, 2003, 2008, 2012 and 2016
as well by Samba (which provides excellent CIFS
server support for Linux and many other operating systems), Apple
systems, as well as most Network Attached Storage vendors, so
this network filesystem client can mount to a wide variety of
servers.
called SMB2 and SMB3. Use of SMB3 (and later, including SMB3.1.1)
is strongly preferred over using older dialects like CIFS due to
security reaasons. All modern dialects, including the most recent,
SMB3.1.1 are supported by the CIFS VFS module. The SMB3 protocol
is implemented and supported by all major file servers
such as all modern versions of Windows (including Windows 2016
Server), as well as by Samba (which provides excellent
CIFS/SMB2/SMB3 server support and tools for Linux and many other
operating systems). Apple systems also support SMB3 well, as
do most Network Attached Storage vendors, so this network
filesystem client can mount to a wide variety of systems.
It also supports mounting to the cloud (for example
Microsoft Azure), including the necessary security features.

The intent of this module is to provide the most advanced network
file system function for SMB3 compliant servers, including advanced
Expand All @@ -24,12 +29,17 @@
cluster file systems for fileserving in some Linux to Linux environments,
not just in Linux to Windows (or Linux to Mac) environments.

This filesystem has an mount utility (mount.cifs) that can be obtained from
This filesystem has a mount utility (mount.cifs) and various user space
tools (including smbinfo and setcifsacl) that can be obtained from

https://ftp.samba.org/pub/linux-cifs/cifs-utils/
https://git.samba.org/?p=cifs-utils.git
or
git://git.samba.org/cifs-utils.git

It must be installed in the directory with the other mount helpers.
mount.cifs should be installed in the directory with the other mount helpers.

For more information on the module see the project wiki page at

https://wiki.samba.org/index.php/LinuxCIFS
and
https://wiki.samba.org/index.php/LinuxCIFS_utils
11 changes: 10 additions & 1 deletion fs/cifs/cifs_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,12 @@ static void cifs_debug_tcon(struct seq_file *m, struct cifs_tcon *tcon)
seq_puts(m, " type: CDROM ");
else
seq_printf(m, " type: %d ", dev_type);
if (tcon->seal)

seq_printf(m, "Serial Number: 0x%x", tcon->vol_serial_number);

if ((tcon->seal) ||
(tcon->ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA) ||
(tcon->share_flags & SHI1005_FLAGS_ENCRYPT_DATA))
seq_printf(m, " Encrypted");
if (tcon->nocase)
seq_printf(m, " nocase");
Expand Down Expand Up @@ -371,6 +376,10 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
atomic_read(&server->in_send),
atomic_read(&server->num_waiters));
#endif
if (ses->session_flags & SMB2_SESSION_FLAG_ENCRYPT_DATA)
seq_puts(m, " encrypted");
if (ses->sign)
seq_puts(m, " signed");

seq_puts(m, "\n\tShares:");
j = 0;
Expand Down
3 changes: 3 additions & 0 deletions fs/cifs/cifs_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ struct smb_snapshot_array {
/* snapshots[]; */
} __packed;

/* query_info flags */
#define PASSTHRU_QUERY_INFO 0x00000000
#define PASSTHRU_FSCTL 0x00000001
struct smb_query_info {
__u32 info_type;
__u32 file_info_class;
Expand Down
16 changes: 14 additions & 2 deletions fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,14 @@ struct smb_version_operations {
struct cifs_tcon *tcon,
__le16 *path, int is_dir,
unsigned long p);
/* make unix special files (block, char, fifo, socket) */
int (*make_node)(unsigned int xid,
struct inode *inode,
struct dentry *dentry,
struct cifs_tcon *tcon,
char *full_path,
umode_t mode,
dev_t device_number);
};

struct smb_version_values {
Expand Down Expand Up @@ -735,13 +743,13 @@ in_flight(struct TCP_Server_Info *server)
}

static inline bool
has_credits(struct TCP_Server_Info *server, int *credits)
has_credits(struct TCP_Server_Info *server, int *credits, int num_credits)
{
int num;
spin_lock(&server->req_lock);
num = *credits;
spin_unlock(&server->req_lock);
return num > 0;
return num >= num_credits;
}

static inline void
Expand Down Expand Up @@ -962,11 +970,14 @@ cap_unix(struct cifs_ses *ses)

struct cached_fid {
bool is_valid:1; /* Do we have a useable root fid */
bool file_all_info_is_valid:1;

struct kref refcount;
struct cifs_fid *fid;
struct mutex fid_mutex;
struct cifs_tcon *tcon;
struct work_struct lease_break;
struct smb2_file_all_info file_all_info;
};

/*
Expand Down Expand Up @@ -1735,6 +1746,7 @@ require use of the stronger protocol */
* GlobalMid_Lock protects:
* list operations on pending_mid_q and oplockQ
* updates to XID counters, multiplex id and SMB sequence numbers
* list operations on global DnotifyReqList
* tcp_ses_lock protects:
* list operations on tcp and SMB session lists
* tcon->open_file_lock protects the list of open files hanging off the tcon
Expand Down
4 changes: 0 additions & 4 deletions fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -1191,10 +1191,6 @@ cifs_demultiplex_thread(void *p)
continue;
}

if (server->large_buf)
buf = server->bigbuf;


server->lstrp = jiffies;

for (i = 0; i < num_mids; i++) {
Expand Down
107 changes: 3 additions & 104 deletions fs/cifs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,20 +621,10 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
{
int rc = -EPERM;
unsigned int xid;
int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifs_tcon *tcon;
struct cifs_io_parms io_parms;
char *full_path = NULL;
struct inode *newinode = NULL;
__u32 oplock = 0;
struct cifs_fid fid;
struct cifs_open_parms oparms;
FILE_ALL_INFO *buf = NULL;
unsigned int bytes_written;
struct win_dev *pdev;
struct kvec iov[2];

if (!old_valid_dev(device_number))
return -EINVAL;
Expand All @@ -654,103 +644,12 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
goto mknod_out;
}

if (tcon->unix_ext) {
struct cifs_unix_set_info_args args = {
.mode = mode & ~current_umask(),
.ctime = NO_CHANGE_64,
.atime = NO_CHANGE_64,
.mtime = NO_CHANGE_64,
.device = device_number,
};
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
args.uid = current_fsuid();
args.gid = current_fsgid();
} else {
args.uid = INVALID_UID; /* no change */
args.gid = INVALID_GID; /* no change */
}
rc = CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
cifs_sb->local_nls,
cifs_remap(cifs_sb));
if (rc)
goto mknod_out;

rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb, xid);

if (rc == 0)
d_instantiate(direntry, newinode);
goto mknod_out;
}

if (!S_ISCHR(mode) && !S_ISBLK(mode))
goto mknod_out;

if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
goto mknod_out;


cifs_dbg(FYI, "sfu compat create special file\n");

buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
if (buf == NULL) {
rc = -ENOMEM;
goto mknod_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.disposition = FILE_CREATE;
oparms.path = full_path;
oparms.fid = &fid;
oparms.reconnect = false;

if (tcon->ses->server->oplocks)
oplock = REQ_OPLOCK;
else
oplock = 0;
rc = tcon->ses->server->ops->open(xid, &oparms, &oplock, buf);
if (rc)
goto mknod_out;

/*
* BB Do not bother to decode buf since no local inode yet to put
* timestamps in, but we can reuse it safely.
*/

pdev = (struct win_dev *)buf;
io_parms.pid = current->tgid;
io_parms.tcon = tcon;
io_parms.offset = 0;
io_parms.length = sizeof(struct win_dev);
iov[1].iov_base = buf;
iov[1].iov_len = sizeof(struct win_dev);
if (S_ISCHR(mode)) {
memcpy(pdev->type, "IntxCHR", 8);
pdev->major = cpu_to_le64(MAJOR(device_number));
pdev->minor = cpu_to_le64(MINOR(device_number));
rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
&bytes_written, iov, 1);
} else if (S_ISBLK(mode)) {
memcpy(pdev->type, "IntxBLK", 8);
pdev->major = cpu_to_le64(MAJOR(device_number));
pdev->minor = cpu_to_le64(MINOR(device_number));
rc = tcon->ses->server->ops->sync_write(xid, &fid, &io_parms,
&bytes_written, iov, 1);
}
tcon->ses->server->ops->close(xid, tcon, &fid);
d_drop(direntry);

/* FIXME: add code here to set EAs */
rc = tcon->ses->server->ops->make_node(xid, inode, direntry, tcon,
full_path, mode,
device_number);

mknod_out:
kfree(full_path);
kfree(buf);
free_xid(xid);
cifs_put_tlink(tlink);
return rc;
Expand Down
14 changes: 13 additions & 1 deletion fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1645,8 +1645,20 @@ cifs_setlk(struct file *file, struct file_lock *flock, __u32 type,
rc = server->ops->mand_unlock_range(cfile, flock, xid);

out:
if (flock->fl_flags & FL_POSIX && !rc)
if (flock->fl_flags & FL_POSIX) {
/*
* If this is a request to remove all locks because we
* are closing the file, it doesn't matter if the
* unlocking failed as both cifs.ko and the SMB server
* remove the lock on file close
*/
if (rc) {
cifs_dbg(VFS, "%s failed rc=%d\n", __func__, rc);
if (!(flock->fl_flags & FL_CLOSE))
return rc;
}
rc = locks_lock_file_wait(file, flock);
}
return rc;
}

Expand Down
Loading

0 comments on commit 9c7dc82

Please sign in to comment.