Skip to content

Commit

Permalink
Merge tag '6.2-rc-smb3-client-fixes-part1' of git://git.samba.org/sfr…
Browse files Browse the repository at this point in the history
…ench/cifs-2.6

Pull cifs client updates from Steve French:

 - SMB3.1.1 POSIX Extensions fixes

 - remove use of generic_writepages() and ->cifs_writepage(), in favor
   of ->cifs_writepages() and ->migrate_folio()

 - memory management fixes

 - mount parm parsing fixes

 - minor cleanup fixes

* tag '6.2-rc-smb3-client-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: Remove duplicated include in cifsglob.h
  cifs: fix oops during encryption
  cifs: print warning when conflicting soft vs. hard mount options specified
  cifs: fix missing display of three mount options
  cifs: fix various whitespace errors in headers
  cifs: minor cleanup of some headers
  cifs: skip alloc when request has no pages
  cifs: remove ->writepage
  cifs: stop using generic_writepages
  cifs: wire up >migrate_folio
  cifs: Parse owner/group for stat in smb311 posix extensions
  cifs: Add "extbuf" and "extbuflen" args to smb2_compound_op()
  Fix path in cifs/usage.rst
  • Loading branch information
Linus Torvalds committed Dec 15, 2022
2 parents ec9187e + d74f4a3 commit 851f657
Show file tree
Hide file tree
Showing 14 changed files with 298 additions and 166 deletions.
2 changes: 1 addition & 1 deletion Documentation/admin-guide/cifs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ CIFS kernel module parameters
These module parameters can be specified or modified either during the time of
module loading or during the runtime by using the interface::

/proc/module/cifs/parameters/<param>
/sys/module/cifs/parameters/<param>

i.e.::

Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/cifs_ioctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ struct smb3_notify_info {
#define CIFS_IOC_NOTIFY _IOW(CIFS_IOCTL_MAGIC, 9, struct smb3_notify)
#define CIFS_DUMP_FULL_KEY _IOWR(CIFS_IOCTL_MAGIC, 10, struct smb3_full_key_debug_info)
#define CIFS_IOC_NOTIFY_INFO _IOWR(CIFS_IOCTL_MAGIC, 11, struct smb3_notify_info)
#define CIFS_IOC_SHUTDOWN _IOR ('X', 125, __u32)
#define CIFS_IOC_SHUTDOWN _IOR('X', 125, __u32)

/*
* Flags for going down operation
Expand Down
8 changes: 7 additions & 1 deletion fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -678,9 +678,15 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
seq_printf(s, ",echo_interval=%lu",
tcon->ses->server->echo_interval / HZ);

/* Only display max_credits if it was overridden on mount */
/* Only display the following if overridden on mount */
if (tcon->ses->server->max_credits != SMB2_MAX_CREDITS_AVAILABLE)
seq_printf(s, ",max_credits=%u", tcon->ses->server->max_credits);
if (tcon->ses->server->tcp_nodelay)
seq_puts(s, ",tcpnodelay");
if (tcon->ses->server->noautotune)
seq_puts(s, ",noautotune");
if (tcon->ses->server->noblocksnd)
seq_puts(s, ",noblocksend");

if (tcon->snapshot_time)
seq_printf(s, ",snapshot=%llu", tcon->snapshot_time);
Expand Down
4 changes: 2 additions & 2 deletions fs/cifs/cifsfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ extern int cifs_lock(struct file *, int, struct file_lock *);
extern int cifs_fsync(struct file *, loff_t, loff_t, int);
extern int cifs_strict_fsync(struct file *, loff_t, loff_t, int);
extern int cifs_flush(struct file *, fl_owner_t id);
extern int cifs_file_mmap(struct file * , struct vm_area_struct *);
extern int cifs_file_strict_mmap(struct file * , struct vm_area_struct *);
extern int cifs_file_mmap(struct file *file, struct vm_area_struct *vma);
extern int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma);
extern const struct file_operations cifs_dir_ops;
extern int cifs_dir_open(struct inode *inode, struct file *file);
extern int cifs_readdir(struct file *file, struct dir_context *ctx);
Expand Down
76 changes: 73 additions & 3 deletions fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include <linux/in6.h>
#include <linux/inet.h>
#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/mm.h>
#include <linux/mempool.h>
#include <linux/workqueue.h>
#include <linux/utsname.h>
Expand All @@ -21,7 +23,6 @@
#include "cifs_fs_sb.h"
#include "cifsacl.h"
#include <crypto/internal/hash.h>
#include <linux/scatterlist.h>
#include <uapi/linux/cifs/cifs_mount.h>
#include "../smbfs_common/smb2pdu.h"
#include "smb2pdu.h"
Expand Down Expand Up @@ -785,6 +786,7 @@ static inline unsigned int
in_flight(struct TCP_Server_Info *server)
{
unsigned int num;

spin_lock(&server->req_lock);
num = server->in_flight;
spin_unlock(&server->req_lock);
Expand All @@ -795,6 +797,7 @@ static inline bool
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);
Expand Down Expand Up @@ -1025,7 +1028,7 @@ struct cifs_ses {
struct TCP_Server_Info *server; /* pointer to server info */
int ses_count; /* reference counter */
enum ses_status_enum ses_status; /* updates protected by cifs_tcp_ses_lock */
unsigned overrideSecFlg; /* if non-zero override global sec flags */
unsigned int overrideSecFlg; /* if non-zero override global sec flags */
char *serverOS; /* name of operating system underlying server */
char *serverNOS; /* name of network operating system of server */
char *serverDomain; /* security realm of server */
Expand Down Expand Up @@ -1381,7 +1384,7 @@ struct cifsFileInfo {
__u32 pid; /* process id who opened file */
struct cifs_fid fid; /* file id from remote */
struct list_head rlist; /* reconnect list */
/* BB add lock scope info here if needed */ ;
/* BB add lock scope info here if needed */
/* lock scope id (0 if none) */
struct dentry *dentry;
struct tcon_link *tlink;
Expand Down Expand Up @@ -1769,6 +1772,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
int number_of_items)
{
int i;

if ((number_of_items == 0) || (param == NULL))
return;
for (i = 0; i < number_of_items; i++) {
Expand Down Expand Up @@ -2137,4 +2141,70 @@ static inline void move_cifs_info_to_smb2(struct smb2_file_all_info *dst, const
dst->FileNameLength = src->FileNameLength;
}

static inline unsigned int cifs_get_num_sgs(const struct smb_rqst *rqst,
int num_rqst,
const u8 *sig)
{
unsigned int len, skip;
unsigned int nents = 0;
unsigned long addr;
int i, j;

/* Assumes the first rqst has a transform header as the first iov.
* I.e.
* rqst[0].rq_iov[0] is transform header
* rqst[0].rq_iov[1+] data to be encrypted/decrypted
* rqst[1+].rq_iov[0+] data to be encrypted/decrypted
*/
for (i = 0; i < num_rqst; i++) {
/*
* The first rqst has a transform header where the
* first 20 bytes are not part of the encrypted blob.
*/
for (j = 0; j < rqst[i].rq_nvec; j++) {
struct kvec *iov = &rqst[i].rq_iov[j];

skip = (i == 0) && (j == 0) ? 20 : 0;
addr = (unsigned long)iov->iov_base + skip;
if (unlikely(is_vmalloc_addr((void *)addr))) {
len = iov->iov_len - skip;
nents += DIV_ROUND_UP(offset_in_page(addr) + len,
PAGE_SIZE);
} else {
nents++;
}
}
nents += rqst[i].rq_npages;
}
nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE);
return nents;
}

/* We can not use the normal sg_set_buf() as we will sometimes pass a
* stack object as buf.
*/
static inline struct scatterlist *cifs_sg_set_buf(struct scatterlist *sg,
const void *buf,
unsigned int buflen)
{
unsigned long addr = (unsigned long)buf;
unsigned int off = offset_in_page(addr);

addr &= PAGE_MASK;
if (unlikely(is_vmalloc_addr((void *)addr))) {
do {
unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);

sg_set_page(sg++, vmalloc_to_page((void *)addr), len, off);

off = 0;
addr += PAGE_SIZE;
buflen -= len;
} while (buflen);
} else {
sg_set_page(sg++, virt_to_page(addr), buflen, off);
}
return sg;
}

#endif /* _CIFS_GLOB_H */
50 changes: 21 additions & 29 deletions fs/cifs/cifspdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1429,7 +1429,7 @@ typedef struct smb_com_transaction_change_notify_req {
__u8 WatchTree; /* 1 = Monitor subdirectories */
__u8 Reserved2;
__le16 ByteCount;
/* __u8 Pad[3];*/
/* __u8 Pad[3];*/
/* __u8 Data[1];*/
} __attribute__((packed)) TRANSACT_CHANGE_NOTIFY_REQ;

Expand Down Expand Up @@ -1752,8 +1752,7 @@ struct smb_com_transaction2_sfi_rsp {
struct smb_hdr hdr; /* wct = 10 + SetupCount */
struct trans2_resp t2;
__u16 ByteCount;
__u16 Reserved2; /* parameter word reserved -
present for infolevels > 100 */
__u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */
} __attribute__((packed));

struct smb_t2_qfi_req {
Expand All @@ -1768,8 +1767,7 @@ struct smb_t2_qfi_rsp {
struct smb_hdr hdr; /* wct = 10 + SetupCount */
struct trans2_resp t2;
__u16 ByteCount;
__u16 Reserved2; /* parameter word reserved -
present for infolevels > 100 */
__u16 Reserved2; /* parameter word reserved - present for infolevels > 100 */
} __attribute__((packed));

/*
Expand Down Expand Up @@ -2146,13 +2144,11 @@ typedef struct {
#define CIFS_UNIX_POSIX_PATH_OPS_CAP 0x00000020 /* Allow new POSIX path based
calls including posix open
and posix unlink */
#define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up
to 0xFFFF00 */
#define CIFS_UNIX_LARGE_READ_CAP 0x00000040 /* support reads >128K (up to 0xFFFF00 */
#define CIFS_UNIX_LARGE_WRITE_CAP 0x00000080
#define CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP 0x00000100 /* can do SPNEGO crypt */
#define CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP 0x00000200 /* must do */
#define CIFS_UNIX_PROXY_CAP 0x00000400 /* Proxy cap: 0xACE ioctl and
QFS PROXY call */
#define CIFS_UNIX_PROXY_CAP 0x00000400 /* Proxy cap: 0xACE ioctl and QFS PROXY call */
#ifdef CONFIG_CIFS_POSIX
/* presumably don't need the 0x20 POSIX_PATH_OPS_CAP since we never send
LockingX instead of posix locking call on unix sess (and we do not expect
Expand Down Expand Up @@ -2368,8 +2364,7 @@ typedef struct {

struct file_allocation_info {
__le64 AllocationSize; /* Note old Samba srvr rounds this up too much */
} __attribute__((packed)); /* size used on disk, for level 0x103 for set,
0x105 for query */
} __packed; /* size used on disk, for level 0x103 for set, 0x105 for query */

struct file_end_of_file_info {
__le64 FileSize; /* offset to end of file */
Expand Down Expand Up @@ -2409,8 +2404,7 @@ struct cifs_posix_acl { /* access conrol list (ACL) */
__le16 access_entry_count; /* access ACL - count of entries */
__le16 default_entry_count; /* default ACL - count of entries */
struct cifs_posix_ace ace_array[];
/* followed by
struct cifs_posix_ace default_ace_arraay[] */
/* followed by struct cifs_posix_ace default_ace_array[] */
} __attribute__((packed)); /* level 0x204 */

/* types of access control entries already defined in posix_acl.h */
Expand All @@ -2429,17 +2423,17 @@ struct cifs_posix_acl { /* access conrol list (ACL) */
/* end of POSIX ACL definitions */

/* POSIX Open Flags */
#define SMB_O_RDONLY 0x1
#define SMB_O_WRONLY 0x2
#define SMB_O_RDWR 0x4
#define SMB_O_CREAT 0x10
#define SMB_O_EXCL 0x20
#define SMB_O_TRUNC 0x40
#define SMB_O_APPEND 0x80
#define SMB_O_SYNC 0x100
#define SMB_O_DIRECTORY 0x200
#define SMB_O_NOFOLLOW 0x400
#define SMB_O_DIRECT 0x800
#define SMB_O_RDONLY 0x1
#define SMB_O_WRONLY 0x2
#define SMB_O_RDWR 0x4
#define SMB_O_CREAT 0x10
#define SMB_O_EXCL 0x20
#define SMB_O_TRUNC 0x40
#define SMB_O_APPEND 0x80
#define SMB_O_SYNC 0x100
#define SMB_O_DIRECTORY 0x200
#define SMB_O_NOFOLLOW 0x400
#define SMB_O_DIRECT 0x800

typedef struct {
__le32 OpenFlags; /* same as NT CreateX */
Expand Down Expand Up @@ -2716,15 +2710,13 @@ typedef struct file_xattr_info {
__u32 xattr_value_len;
char xattr_name[];
/* followed by xattr_value[xattr_value_len], no pad */
} __attribute__((packed)) FILE_XATTR_INFO; /* extended attribute info
level 0x205 */
} __packed FILE_XATTR_INFO; /* extended attribute info level 0x205 */

/* flags for lsattr and chflags commands removed arein uapi/linux/fs.h */

typedef struct file_chattr_info {
__le64 mask; /* list of all possible attribute bits */
__le64 mode; /* list of actual attribute bits on this inode */
} __attribute__((packed)) FILE_CHATTR_INFO; /* ext attributes
(chattr, chflags) level 0x206 */
#endif /* POSIX */
} __packed FILE_CHATTR_INFO; /* ext attributes (chattr, chflags) level 0x206 */
#endif /* POSIX */
#endif /* _CIFSPDU_H */
6 changes: 3 additions & 3 deletions fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
struct kvec * /* resp vec */);
extern int SendReceiveBlockingLock(const unsigned int xid,
struct cifs_tcon *ptcon,
struct smb_hdr *in_buf ,
struct smb_hdr *in_buf,
struct smb_hdr *out_buf,
int *bytes_returned);
void
Expand Down Expand Up @@ -604,8 +604,8 @@ int setup_aio_ctx_iter(struct cifs_aio_ctx *ctx, struct iov_iter *iter, int rw);
int cifs_alloc_hash(const char *name, struct shash_desc **sdesc);
void cifs_free_hash(struct shash_desc **sdesc);

extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
unsigned int *len, unsigned int *offset);
void rqst_page_get_length(const struct smb_rqst *rqst, unsigned int page,
unsigned int *len, unsigned int *offset);
struct cifs_chan *
cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
Expand Down
36 changes: 22 additions & 14 deletions fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2646,6 +2646,21 @@ wdata_send_pages(struct cifs_writedata *wdata, unsigned int nr_pages,
return rc;
}

static int
cifs_writepage_locked(struct page *page, struct writeback_control *wbc);

static int cifs_write_one_page(struct page *page, struct writeback_control *wbc,
void *data)
{
struct address_space *mapping = data;
int ret;

ret = cifs_writepage_locked(page, wbc);
unlock_page(page);
mapping_set_error(mapping, ret);
return ret;
}

static int cifs_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{
Expand All @@ -2662,10 +2677,11 @@ static int cifs_writepages(struct address_space *mapping,

/*
* If wsize is smaller than the page cache size, default to writing
* one page at a time via cifs_writepage
* one page at a time.
*/
if (cifs_sb->ctx->wsize < PAGE_SIZE)
return generic_writepages(mapping, wbc);
return write_cache_pages(mapping, wbc, cifs_write_one_page,
mapping);

xid = get_xid();
if (wbc->range_cyclic) {
Expand Down Expand Up @@ -2852,13 +2868,6 @@ cifs_writepage_locked(struct page *page, struct writeback_control *wbc)
return rc;
}

static int cifs_writepage(struct page *page, struct writeback_control *wbc)
{
int rc = cifs_writepage_locked(page, wbc);
unlock_page(page);
return rc;
}

static int cifs_write_end(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned copied,
struct page *page, void *fsdata)
Expand Down Expand Up @@ -5231,7 +5240,6 @@ static bool cifs_dirty_folio(struct address_space *mapping, struct folio *folio)
const struct address_space_operations cifs_addr_ops = {
.read_folio = cifs_read_folio,
.readahead = cifs_readahead,
.writepage = cifs_writepage,
.writepages = cifs_writepages,
.write_begin = cifs_write_begin,
.write_end = cifs_write_end,
Expand All @@ -5240,10 +5248,10 @@ const struct address_space_operations cifs_addr_ops = {
.direct_IO = cifs_direct_io,
.invalidate_folio = cifs_invalidate_folio,
.launder_folio = cifs_launder_folio,
.migrate_folio = filemap_migrate_folio,
/*
* TODO: investigate and if useful we could add an cifs_migratePage
* helper (under an CONFIG_MIGRATION) in the future, and also
* investigate and add an is_dirty_writeback helper if needed
* TODO: investigate and if useful we could add an is_dirty_writeback
* helper if needed
*/
.swap_activate = cifs_swap_activate,
.swap_deactivate = cifs_swap_deactivate,
Expand All @@ -5256,12 +5264,12 @@ const struct address_space_operations cifs_addr_ops = {
*/
const struct address_space_operations cifs_addr_ops_smallbuf = {
.read_folio = cifs_read_folio,
.writepage = cifs_writepage,
.writepages = cifs_writepages,
.write_begin = cifs_write_begin,
.write_end = cifs_write_end,
.dirty_folio = cifs_dirty_folio,
.release_folio = cifs_release_folio,
.invalidate_folio = cifs_invalidate_folio,
.launder_folio = cifs_launder_folio,
.migrate_folio = filemap_migrate_folio,
};
Loading

0 comments on commit 851f657

Please sign in to comment.