提交 40efeb4d 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  [CIFS] Fix endian error comparing authusers when cifsacl enabled
  [CIFS] Rename three structures to avoid camel case
  Fix extended security auth failure
  CIFS: Add rwpidforward mount option
  CIFS: Migrate to shared superblock model
  [CIFS] Migrate from prefixpath logic
  CIFS: Fix memory leak in cifs_do_mount
  [CIFS] When mandatory encryption on share, fail mount
  CIFS: Use pid saved from cifsFileInfo in writepages and set_file_size
  cifs: add cifs_async_writev
  cifs: clean up wsize negotiation and allow for larger wsize
  cifs: convert cifs_writepages to use async writes
  CIFS: Fix undefined behavior when mount fails
  cifs: don't call mid_q_entry->callback under the Global_MidLock (try #5)
  CIFS: Simplify mount code for further shared sb capability
  CIFS: Simplify connection structure search calls
  cifs: remove unused SMB2 config and mount options
  cifs: add ignore_pend flag to cifs_call_async
  cifs: make cifs_send_async take a kvec array
  cifs: consolidate SendReceive response checks
......@@ -153,26 +153,6 @@ config CIFS_ACL
Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
is handed over to the application/caller.
config CIFS_SMB2
bool "SMB2 network file system support (EXPERIMENTAL)"
depends on EXPERIMENTAL && INET && BROKEN
select NLS
select KEYS
select FSCACHE
select DNS_RESOLVER
help
This enables experimental support for the SMB2 (Server Message Block
version 2) protocol. The SMB2 protocol is the successor to the
popular CIFS and SMB network file sharing protocols. SMB2 is the
native file sharing mechanism for recent versions of Windows
operating systems (since Vista). SMB2 enablement will eventually
allow users better performance, security and features, than would be
possible with cifs. Note that smb2 mount options also are simpler
(compared to cifs) due to protocol improvements.
Unless you are a developer or tester, say N.
config CIFS_NFSD_EXPORT
bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)"
depends on CIFS && EXPERIMENTAL
......
......@@ -457,6 +457,9 @@ A partial list of the supported mount options follows:
otherwise - read from the server. All written data are stored
in the cache, but if the client doesn't have Exclusive Oplock,
it writes the data to the server.
rwpidforward Forward pid of a process who opened a file to any read or write
operation on that file. This prevent applications like WINE
from failing on read and write if we use mandatory brlock style.
acl Allow setfacl and getfacl to manage posix ACLs if server
supports them. (default)
noacl Do not allow setfacl and getfacl calls on this mount
......
......@@ -146,7 +146,7 @@ static char *extract_sharename(const char *treename)
static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer,
uint16_t maxbuf)
{
const struct cifsTconInfo *tcon = cookie_netfs_data;
const struct cifs_tcon *tcon = cookie_netfs_data;
char *sharename;
uint16_t len;
......@@ -173,7 +173,7 @@ cifs_fscache_super_get_aux(const void *cookie_netfs_data, void *buffer,
uint16_t maxbuf)
{
struct cifs_fscache_super_auxdata auxdata;
const struct cifsTconInfo *tcon = cookie_netfs_data;
const struct cifs_tcon *tcon = cookie_netfs_data;
memset(&auxdata, 0, sizeof(auxdata));
auxdata.resource_id = tcon->resource_id;
......@@ -192,7 +192,7 @@ fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
uint16_t datalen)
{
struct cifs_fscache_super_auxdata auxdata;
const struct cifsTconInfo *tcon = cookie_netfs_data;
const struct cifs_tcon *tcon = cookie_netfs_data;
if (datalen != sizeof(auxdata))
return FSCACHE_CHECKAUX_OBSOLETE;
......
......@@ -110,8 +110,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
struct list_head *tmp1, *tmp2, *tmp3;
struct mid_q_entry *mid_entry;
struct TCP_Server_Info *server;
struct cifsSesInfo *ses;
struct cifsTconInfo *tcon;
struct cifs_ses *ses;
struct cifs_tcon *tcon;
int i, j;
__u32 dev_type;
......@@ -152,7 +152,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
tcp_ses_list);
i++;
list_for_each(tmp2, &server->smb_ses_list) {
ses = list_entry(tmp2, struct cifsSesInfo,
ses = list_entry(tmp2, struct cifs_ses,
smb_ses_list);
if ((ses->serverDomain == NULL) ||
(ses->serverOS == NULL) ||
......@@ -171,7 +171,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
seq_printf(m, "TCP status: %d\n\tLocal Users To "
"Server: %d SecMode: 0x%x Req On Wire: %d",
server->tcpStatus, server->srv_count,
server->secMode,
server->sec_mode,
atomic_read(&server->inFlight));
#ifdef CONFIG_CIFS_STATS2
......@@ -183,7 +183,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
seq_puts(m, "\n\tShares:");
j = 0;
list_for_each(tmp3, &ses->tcon_list) {
tcon = list_entry(tmp3, struct cifsTconInfo,
tcon = list_entry(tmp3, struct cifs_tcon,
tcon_list);
++j;
dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
......@@ -256,8 +256,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
int rc;
struct list_head *tmp1, *tmp2, *tmp3;
struct TCP_Server_Info *server;
struct cifsSesInfo *ses;
struct cifsTconInfo *tcon;
struct cifs_ses *ses;
struct cifs_tcon *tcon;
rc = get_user(c, buffer);
if (rc)
......@@ -273,11 +273,11 @@ static ssize_t cifs_stats_proc_write(struct file *file,
server = list_entry(tmp1, struct TCP_Server_Info,
tcp_ses_list);
list_for_each(tmp2, &server->smb_ses_list) {
ses = list_entry(tmp2, struct cifsSesInfo,
ses = list_entry(tmp2, struct cifs_ses,
smb_ses_list);
list_for_each(tmp3, &ses->tcon_list) {
tcon = list_entry(tmp3,
struct cifsTconInfo,
struct cifs_tcon,
tcon_list);
atomic_set(&tcon->num_smbs_sent, 0);
atomic_set(&tcon->num_writes, 0);
......@@ -312,8 +312,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
int i;
struct list_head *tmp1, *tmp2, *tmp3;
struct TCP_Server_Info *server;
struct cifsSesInfo *ses;
struct cifsTconInfo *tcon;
struct cifs_ses *ses;
struct cifs_tcon *tcon;
seq_printf(m,
"Resources in use\nCIFS Session: %d\n",
......@@ -346,11 +346,11 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
server = list_entry(tmp1, struct TCP_Server_Info,
tcp_ses_list);
list_for_each(tmp2, &server->smb_ses_list) {
ses = list_entry(tmp2, struct cifsSesInfo,
ses = list_entry(tmp2, struct cifs_ses,
smb_ses_list);
list_for_each(tmp3, &ses->tcon_list) {
tcon = list_entry(tmp3,
struct cifsTconInfo,
struct cifs_tcon,
tcon_list);
i++;
seq_printf(m, "\n%d) %s", i, tcon->treeName);
......
......@@ -272,7 +272,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
struct dfs_info3_param *referrals = NULL;
unsigned int num_referrals = 0;
struct cifs_sb_info *cifs_sb;
struct cifsSesInfo *ses;
struct cifs_ses *ses;
char *full_path;
int xid, i;
int rc;
......
......@@ -41,6 +41,7 @@
#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */
#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */
#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */
#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */
struct cifs_sb_info {
struct rb_root tlink_tree;
......@@ -56,8 +57,6 @@ struct cifs_sb_info {
mode_t mnt_file_mode;
mode_t mnt_dir_mode;
unsigned int mnt_cifs_flags;
int prepathlen;
char *prepath; /* relative path under the share to mount to */
char *mountdata; /* options received at mount time or via DFS refs */
struct backing_dev_info bdi;
struct delayed_work prune_tlinks;
......
......@@ -95,7 +95,7 @@ struct key_type cifs_spnego_key_type = {
/* get a key struct with a SPNEGO security blob, suitable for session setup */
struct key *
cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
cifs_get_spnego_key(struct cifs_ses *sesInfo)
{
struct TCP_Server_Info *server = sesInfo->server;
struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
......
......@@ -41,7 +41,7 @@ struct cifs_spnego_msg {
#ifdef __KERNEL__
extern struct key_type cifs_spnego_key_type;
extern struct key *cifs_get_spnego_key(struct cifsSesInfo *sesInfo);
extern struct key *cifs_get_spnego_key(struct cifs_ses *sesInfo);
#endif /* KERNEL */
#endif /* _CIFS_SPNEGO_H */
......@@ -38,7 +38,7 @@ static const struct cifs_sid sid_everyone = {
1, 1, {0, 0, 0, 0, 0, 1}, {0} };
/* security id for Authenticated Users system group */
static const struct cifs_sid sid_authusers = {
1, 1, {0, 0, 0, 0, 0, 5}, {11} };
1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11)} };
/* group users */
static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} };
......@@ -458,7 +458,8 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
if (num_subauth) {
for (i = 0; i < num_subauth; ++i) {
if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) {
if (ctsid->sub_auth[i] > cwsid->sub_auth[i])
if (le32_to_cpu(ctsid->sub_auth[i]) >
le32_to_cpu(cwsid->sub_auth[i]))
return 1;
else
return -1;
......@@ -945,7 +946,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
int oplock = 0;
int xid, rc;
__u16 fid;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
......@@ -1013,7 +1014,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
int oplock = 0;
int xid, rc;
__u16 fid;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
......
......@@ -229,7 +229,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
}
/* first calculate 24 bytes ntlm response and then 16 byte session key */
int setup_ntlm_response(struct cifsSesInfo *ses)
int setup_ntlm_response(struct cifs_ses *ses)
{
int rc = 0;
unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
......@@ -312,7 +312,7 @@ int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
* Allocate domain name which gets freed when session struct is deallocated.
*/
static int
build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
{
unsigned int dlen;
unsigned int wlen;
......@@ -400,7 +400,7 @@ build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
* about target string i.e. for some, just user name might suffice.
*/
static int
find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
{
unsigned int attrsize;
unsigned int type;
......@@ -445,7 +445,7 @@ find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
return 0;
}
static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash,
static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
const struct nls_table *nls_cp)
{
int rc = 0;
......@@ -527,7 +527,7 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash,
}
static int
CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash)
CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
{
int rc;
unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
......@@ -563,7 +563,7 @@ CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash)
int
setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
{
int rc;
int baselen;
......@@ -649,7 +649,7 @@ setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
}
int
calc_seckey(struct cifsSesInfo *ses)
calc_seckey(struct cifs_ses *ses)
{
int rc;
struct crypto_blkcipher *tfm_arc4;
......
......@@ -104,46 +104,25 @@ cifs_sb_deactive(struct super_block *sb)
}
static int
cifs_read_super(struct super_block *sb, void *data,
cifs_read_super(struct super_block *sb, struct smb_vol *volume_info,
const char *devname, int silent)
{
struct inode *inode;
struct cifs_sb_info *cifs_sb;
int rc = 0;
/* BB should we make this contingent on mount parm? */
sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
cifs_sb = CIFS_SB(sb);
if (cifs_sb == NULL)
return -ENOMEM;
spin_lock_init(&cifs_sb->tlink_tree_lock);
cifs_sb->tlink_tree = RB_ROOT;
rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
if (rc) {
kfree(cifs_sb);
if (rc)
return rc;
}
cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
/*
* Copy mount params to sb for use in submounts. Better to do
* the copy here and deal with the error before cleanup gets
* complicated post-mount.
*/
if (data) {
cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
if (cifs_sb->mountdata == NULL) {
bdi_destroy(&cifs_sb->bdi);
kfree(sb->s_fs_info);
sb->s_fs_info = NULL;
return -ENOMEM;
}
}
cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages;
rc = cifs_mount(sb, cifs_sb, devname);
rc = cifs_mount(sb, cifs_sb, volume_info, devname);
if (rc) {
if (!silent)
......@@ -194,15 +173,7 @@ cifs_read_super(struct super_block *sb, void *data,
cifs_umount(sb, cifs_sb);
out_mount_failed:
if (cifs_sb) {
if (cifs_sb->mountdata) {
kfree(cifs_sb->mountdata);
cifs_sb->mountdata = NULL;
}
unload_nls(cifs_sb->local_nls);
bdi_destroy(&cifs_sb->bdi);
kfree(cifs_sb);
}
return rc;
}
......@@ -237,7 +208,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
struct super_block *sb = dentry->d_sb;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
int rc = -EOPNOTSUPP;
int xid;
......@@ -390,7 +361,7 @@ static int
cifs_show_options(struct seq_file *s, struct vfsmount *m)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb);
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
struct sockaddr *srcaddr;
srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
......@@ -444,14 +415,20 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
seq_printf(s, ",nocase");
if (tcon->retry)
seq_printf(s, ",hard");
if (cifs_sb->prepath)
seq_printf(s, ",prepath=%s", cifs_sb->prepath);
if (tcon->unix_ext)
seq_printf(s, ",unix");
else
seq_printf(s, ",nounix");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
seq_printf(s, ",posixpaths");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
seq_printf(s, ",setuids");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
seq_printf(s, ",serverino");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
seq_printf(s, ",rwpidforward");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL)
seq_printf(s, ",forcemand");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
seq_printf(s, ",directio");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
......@@ -484,7 +461,7 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
static void cifs_umount_begin(struct super_block *sb)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
if (cifs_sb == NULL)
return;
......@@ -559,29 +536,189 @@ static const struct super_operations cifs_super_ops = {
#endif
};
/*
* Get root dentry from superblock according to prefix path mount option.
* Return dentry with refcount + 1 on success and NULL otherwise.
*/
static struct dentry *
cifs_get_root(struct smb_vol *vol, struct super_block *sb)
{
int xid, rc;
struct inode *inode;
struct qstr name;
struct dentry *dparent = NULL, *dchild = NULL, *alias;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
unsigned int i, full_len, len;
char *full_path = NULL, *pstart;
char sep;
full_path = cifs_build_path_to_root(vol, cifs_sb,
cifs_sb_master_tcon(cifs_sb));
if (full_path == NULL)
return NULL;
cFYI(1, "Get root dentry for %s", full_path);
xid = GetXid();
sep = CIFS_DIR_SEP(cifs_sb);
dparent = dget(sb->s_root);
full_len = strlen(full_path);
full_path[full_len] = sep;
pstart = full_path + 1;
for (i = 1, len = 0; i <= full_len; i++) {
if (full_path[i] != sep || !len) {
len++;
continue;
}
full_path[i] = 0;
cFYI(1, "get dentry for %s", pstart);
name.name = pstart;
name.len = len;
name.hash = full_name_hash(pstart, len);
dchild = d_lookup(dparent, &name);
if (dchild == NULL) {
cFYI(1, "not exists");
dchild = d_alloc(dparent, &name);
if (dchild == NULL) {
dput(dparent);
dparent = NULL;
goto out;
}
}
cFYI(1, "get inode");
if (dchild->d_inode == NULL) {
cFYI(1, "not exists");
inode = NULL;
if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
rc = cifs_get_inode_info_unix(&inode, full_path,
sb, xid);
else
rc = cifs_get_inode_info(&inode, full_path,
NULL, sb, xid, NULL);
if (rc) {
dput(dchild);
dput(dparent);
dparent = NULL;
goto out;
}
alias = d_materialise_unique(dchild, inode);
if (alias != NULL) {
dput(dchild);
if (IS_ERR(alias)) {
dput(dparent);
dparent = NULL;
goto out;
}
dchild = alias;
}
}
cFYI(1, "parent %p, child %p", dparent, dchild);
dput(dparent);
dparent = dchild;
len = 0;
pstart = full_path + i + 1;
full_path[i] = sep;
}
out:
_FreeXid(xid);
kfree(full_path);
return dparent;
}
static struct dentry *
cifs_do_mount(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data)
{
int rc;
struct super_block *sb;
sb = sget(fs_type, NULL, set_anon_super, NULL);
struct cifs_sb_info *cifs_sb;
struct smb_vol *volume_info;
struct cifs_mnt_data mnt_data;
struct dentry *root;
cFYI(1, "Devname: %s flags: %d ", dev_name, flags);
if (IS_ERR(sb))
return ERR_CAST(sb);
rc = cifs_setup_volume_info(&volume_info, (char *)data, dev_name);
if (rc)
return ERR_PTR(rc);
cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
if (cifs_sb == NULL) {
root = ERR_PTR(-ENOMEM);
goto out;
}
cifs_setup_cifs_sb(volume_info, cifs_sb);
mnt_data.vol = volume_info;
mnt_data.cifs_sb = cifs_sb;
mnt_data.flags = flags;
sb = sget(fs_type, cifs_match_super, set_anon_super, &mnt_data);
if (IS_ERR(sb)) {
root = ERR_CAST(sb);
goto out_cifs_sb;
}
if (sb->s_fs_info) {
cFYI(1, "Use existing superblock");
goto out_shared;
}
/*
* Copy mount params for use in submounts. Better to do
* the copy here and deal with the error before cleanup gets
* complicated post-mount.
*/
cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
if (cifs_sb->mountdata == NULL) {
root = ERR_PTR(-ENOMEM);
goto out_super;
}
sb->s_flags = flags;
/* BB should we make this contingent on mount parm? */
sb->s_flags |= MS_NODIRATIME | MS_NOATIME;
sb->s_fs_info = cifs_sb;
rc = cifs_read_super(sb, data, dev_name, flags & MS_SILENT ? 1 : 0);
rc = cifs_read_super(sb, volume_info, dev_name,
flags & MS_SILENT ? 1 : 0);
if (rc) {
deactivate_locked_super(sb);
return ERR_PTR(rc);
root = ERR_PTR(rc);
goto out_super;
}
sb->s_flags |= MS_ACTIVE;
return dget(sb->s_root);
root = cifs_get_root(volume_info, sb);
if (root == NULL)
goto out_super;
cFYI(1, "dentry root is: %p", root);
goto out;
out_shared:
root = cifs_get_root(volume_info, sb);
if (root)
cFYI(1, "dentry root is: %p", root);
goto out;
out_super:
kfree(cifs_sb->mountdata);
deactivate_locked_super(sb);
out_cifs_sb:
unload_nls(cifs_sb->local_nls);
kfree(cifs_sb);
out:
cifs_cleanup_volume_info(&volume_info);
return root;
}
static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
......
......@@ -155,6 +155,81 @@ struct cifs_cred {
*****************************************************************
*/
struct smb_vol {
char *username;
char *password;
char *domainname;
char *UNC;
char *UNCip;
char *iocharset; /* local code page for mapping to and from Unicode */
char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
uid_t cred_uid;
uid_t linux_uid;
gid_t linux_gid;
mode_t file_mode;
mode_t dir_mode;
unsigned secFlg;
bool retry:1;
bool intr:1;
bool setuids:1;
bool override_uid:1;
bool override_gid:1;
bool dynperm:1;
bool noperm:1;
bool no_psx_acl:1; /* set if posix acl support should be disabled */
bool cifs_acl:1;
bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
bool server_ino:1; /* use inode numbers from server ie UniqueId */
bool direct_io:1;
bool strict_io:1; /* strict cache behavior */
bool remap:1; /* set to remap seven reserved chars in filenames */
bool posix_paths:1; /* unset to not ask for posix pathnames. */
bool no_linux_ext:1;
bool sfu_emul:1;
bool nullauth:1; /* attempt to authenticate with null user */
bool nocase:1; /* request case insensitive filenames */
bool nobrl:1; /* disable sending byte range locks to srv */
bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
bool seal:1; /* request transport encryption on share */
bool nodfs:1; /* Do not request DFS, even if available */
bool local_lease:1; /* check leases only on local system, not remote */
bool noblocksnd:1;
bool noautotune:1;
bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
bool fsc:1; /* enable fscache */
bool mfsymlinks:1; /* use Minshall+French Symlinks */
bool multiuser:1;
bool rwpidforward:1; /* pid forward for read/write operations */
unsigned int rsize;
unsigned int wsize;
bool sockopt_tcp_nodelay:1;
unsigned short int port;
unsigned long actimeo; /* attribute cache timeout (jiffies) */
char *prepath;
struct sockaddr_storage srcaddr; /* allow binding to a local IP */
struct nls_table *local_nls;
};
#define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
CIFS_MOUNT_SERVER_INUM | CIFS_MOUNT_DIRECT_IO | \
CIFS_MOUNT_NO_XATTR | CIFS_MOUNT_MAP_SPECIAL_CHR | \
CIFS_MOUNT_UNX_EMUL | CIFS_MOUNT_NO_BRL | \
CIFS_MOUNT_CIFS_ACL | CIFS_MOUNT_OVERR_UID | \
CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO)
#define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
MS_NODEV | MS_SYNCHRONOUS)
struct cifs_mnt_data {
struct cifs_sb_info *cifs_sb;
struct smb_vol *vol;
int flags;
};
struct TCP_Server_Info {
struct list_head tcp_ses_list;
struct list_head smb_ses_list;
......@@ -179,7 +254,7 @@ struct TCP_Server_Info {
struct mutex srv_mutex;
struct task_struct *tsk;
char server_GUID[16];
char secMode;
char sec_mode;
bool session_estab; /* mark when very first sess is established */
u16 dialect; /* dialect index that server chose */
enum securityEnum secType;
......@@ -254,7 +329,7 @@ static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net)
/*
* Session structure. One of these for each uid session with a particular host
*/
struct cifsSesInfo {
struct cifs_ses {
struct list_head smb_ses_list;
struct list_head tcon_list;
struct mutex session_mutex;
......@@ -294,11 +369,11 @@ struct cifsSesInfo {
* there is one of these for each connection to a resource on a particular
* session
*/
struct cifsTconInfo {
struct cifs_tcon {
struct list_head tcon_list;
int tc_count;
struct list_head openFileList;
struct cifsSesInfo *ses; /* pointer to session associated with */
struct cifs_ses *ses; /* pointer to session associated with */
char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
char *nativeFileSystem;
char *password; /* for share-level security */
......@@ -380,12 +455,12 @@ struct tcon_link {
#define TCON_LINK_IN_TREE 2
unsigned long tl_time;
atomic_t tl_count;
struct cifsTconInfo *tl_tcon;
struct cifs_tcon *tl_tcon;
};
extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb);
static inline struct cifsTconInfo *
static inline struct cifs_tcon *
tlink_tcon(struct tcon_link *tlink)
{
return tlink->tl_tcon;
......@@ -402,7 +477,7 @@ cifs_get_tlink(struct tcon_link *tlink)
}
/* This function is always expected to succeed */
extern struct cifsTconInfo *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
extern struct cifs_tcon *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
/*
* This info hangs off the cifsFileInfo structure, pointed to by llist.
......@@ -455,6 +530,14 @@ struct cifsFileInfo {
struct work_struct oplock_break; /* work for oplock breaks */
};
struct cifs_io_parms {
__u16 netfid;
__u32 pid;
__u64 offset;
unsigned int length;
struct cifs_tcon *tcon;
};
/*
* Take a reference on the file private data. Must be called with
* cifs_file_list_lock held.
......@@ -509,10 +592,30 @@ static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
return '\\';
}
static inline void
convert_delimiter(char *path, char delim)
{
int i;
char old_delim;
if (path == NULL)
return;
if (delim == '/')
old_delim = '\\';
else
old_delim = '/';
for (i = 0; path[i] != '\0'; i++) {
if (path[i] == old_delim)
path[i] = delim;
}
}
#ifdef CONFIG_CIFS_STATS
#define cifs_stats_inc atomic_inc
static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon,
static inline void cifs_stats_bytes_written(struct cifs_tcon *tcon,
unsigned int bytes)
{
if (bytes) {
......@@ -522,7 +625,7 @@ static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon,
}
}
static inline void cifs_stats_bytes_read(struct cifsTconInfo *tcon,
static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon,
unsigned int bytes)
{
spin_lock(&tcon->stat_lock);
......@@ -543,9 +646,8 @@ struct mid_q_entry;
* This is the prototype for the mid callback function. When creating one,
* take special care to avoid deadlocks. Things to bear in mind:
*
* - it will be called by cifsd
* - the GlobalMid_Lock will be held
* - the mid will be removed from the pending_mid_q list
* - it will be called by cifsd, with no locks held
* - the mid will be removed from any lists
*/
typedef void (mid_callback_t)(struct mid_q_entry *mid);
......@@ -573,7 +675,7 @@ struct mid_q_entry {
struct oplock_q_entry {
struct list_head qhead;
struct inode *pinode;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
__u16 netfid;
};
......@@ -656,6 +758,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
#define MID_RESPONSE_RECEIVED 4
#define MID_RETRY_NEEDED 8 /* session closed while this request out */
#define MID_RESPONSE_MALFORMED 0x10
#define MID_SHUTDOWN 0x20
/* Types of response buffer returned from SendReceive2 */
#define CIFS_NO_BUFFER 0 /* Response buffer not returned */
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -50,12 +50,11 @@ build_path_from_dentry(struct dentry *direntry)
{
struct dentry *temp;
int namelen;
int pplen;
int dfsplen;
char *full_path;
char dirsep;
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
if (direntry == NULL)
return NULL; /* not much we can do if dentry is freed and
......@@ -63,13 +62,12 @@ build_path_from_dentry(struct dentry *direntry)
when the server crashed */
dirsep = CIFS_DIR_SEP(cifs_sb);
pplen = cifs_sb->prepathlen;
if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
else
dfsplen = 0;
cifs_bp_rename_retry:
namelen = pplen + dfsplen;
namelen = dfsplen;
for (temp = direntry; !IS_ROOT(temp);) {
namelen += (1 + temp->d_name.len);
temp = temp->d_parent;
......@@ -100,7 +98,7 @@ build_path_from_dentry(struct dentry *direntry)
return NULL;
}
}
if (namelen != pplen + dfsplen) {
if (namelen != dfsplen) {
cERROR(1, "did not end path lookup where expected namelen is %d",
namelen);
/* presumably this is only possible if racing with a rename
......@@ -126,7 +124,6 @@ build_path_from_dentry(struct dentry *direntry)
}
}
}
strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen);
return full_path;
}
......@@ -152,7 +149,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
__u16 fileHandle;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
char *full_path = NULL;
FILE_ALL_INFO *buf = NULL;
struct inode *newinode = NULL;
......@@ -356,7 +353,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct cifs_io_parms io_parms;
char *full_path = NULL;
struct inode *newinode = NULL;
int oplock = 0;
......@@ -439,16 +437,19 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
* timestamps in, but we can reuse it safely */
pdev = (struct win_dev *)buf;
io_parms.netfid = fileHandle;
io_parms.pid = current->tgid;
io_parms.tcon = pTcon;
io_parms.offset = 0;
io_parms.length = 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 = CIFSSMBWrite(xid, pTcon,
fileHandle,
sizeof(struct win_dev),
0, &bytes_written, (char *)pdev,
rc = CIFSSMBWrite(xid, &io_parms,
&bytes_written, (char *)pdev,
NULL, 0);
} else if (S_ISBLK(mode)) {
memcpy(pdev->type, "IntxBLK", 8);
......@@ -456,10 +457,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
cpu_to_le64(MAJOR(device_number));
pdev->minor =
cpu_to_le64(MINOR(device_number));
rc = CIFSSMBWrite(xid, pTcon,
fileHandle,
sizeof(struct win_dev),
0, &bytes_written, (char *)pdev,
rc = CIFSSMBWrite(xid, &io_parms,
&bytes_written, (char *)pdev,
NULL, 0);
} /* else if (S_ISFIFO) */
CIFSSMBClose(xid, pTcon, fileHandle);
......@@ -486,7 +485,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
bool posix_open = false;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct cifsFileInfo *cfile;
struct inode *newInode = NULL;
char *full_path = NULL;
......
......@@ -114,7 +114,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifs_fattr fattr;
struct tcon_link *tlink;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
cFYI(1, "posix open %s", full_path);
......@@ -168,7 +168,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
static int
cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
struct cifsTconInfo *tcon, unsigned int f_flags, __u32 *poplock,
struct cifs_tcon *tcon, unsigned int f_flags, __u32 *poplock,
__u16 *pnetfid, int xid)
{
int rc;
......@@ -285,7 +285,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
{
struct inode *inode = cifs_file->dentry->d_inode;
struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink);
struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink);
struct cifsInodeInfo *cifsi = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsLockInfo *li, *tmp;
......@@ -343,7 +343,7 @@ int cifs_open(struct inode *inode, struct file *file)
int xid;
__u32 oplock;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
struct tcon_link *tlink;
struct cifsFileInfo *pCifsFile = NULL;
char *full_path = NULL;
......@@ -457,7 +457,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
int xid;
__u32 oplock;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
struct cifsInodeInfo *pCifsInode;
struct inode *inode;
char *full_path = NULL;
......@@ -596,7 +596,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
xid = GetXid();
if (pCFileStruct) {
struct cifsTconInfo *pTcon = tlink_tcon(pCFileStruct->tlink);
struct cifs_tcon *pTcon = tlink_tcon(pCFileStruct->tlink);
cFYI(1, "Freeing private data in close dir");
spin_lock(&cifs_file_list_lock);
......@@ -653,7 +653,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
__u64 length;
bool wait_flag = false;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
__u16 netfid;
__u8 lockType = LOCKING_ANDX_LARGE_FILES;
bool posix_locking = 0;
......@@ -725,8 +725,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
else
posix_lock_type = CIFS_WRLCK;
rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */,
length, pfLock,
posix_lock_type, wait_flag);
length, pfLock, posix_lock_type,
wait_flag);
FreeXid(xid);
return rc;
}
......@@ -797,8 +797,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
posix_lock_type = CIFS_UNLCK;
rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */,
length, pfLock,
posix_lock_type, wait_flag);
length, pfLock, posix_lock_type,
wait_flag);
} else {
struct cifsFileInfo *fid = file->private_data;
......@@ -857,7 +857,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
cifsi->server_eof = end_of_write;
}
static ssize_t cifs_write(struct cifsFileInfo *open_file,
static ssize_t cifs_write(struct cifsFileInfo *open_file, __u32 pid,
const char *write_data, size_t write_size,
loff_t *poffset)
{
......@@ -865,10 +865,11 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
unsigned int bytes_written = 0;
unsigned int total_written;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
int xid;
struct dentry *dentry = open_file->dentry;
struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode);
struct cifs_io_parms io_parms;
cifs_sb = CIFS_SB(dentry->d_sb);
......@@ -901,8 +902,13 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
/* iov[0] is reserved for smb header */
iov[1].iov_base = (char *)write_data + total_written;
iov[1].iov_len = len;
rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, len,
*poffset, &bytes_written, iov, 1, 0);
io_parms.netfid = open_file->netfid;
io_parms.pid = pid;
io_parms.tcon = pTcon;
io_parms.offset = *poffset;
io_parms.length = len;
rc = CIFSSMBWrite2(xid, &io_parms, &bytes_written, iov,
1, 0);
}
if (rc || (bytes_written == 0)) {
if (total_written)
......@@ -1071,8 +1077,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
open_file = find_writable_file(CIFS_I(mapping->host), false);
if (open_file) {
bytes_written = cifs_write(open_file, write_data,
to - from, &offset);
bytes_written = cifs_write(open_file, open_file->pid,
write_data, to - from, &offset);
cifsFileInfo_put(open_file);
/* Does mm or vfs already set times? */
inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
......@@ -1092,58 +1098,20 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)
static int cifs_writepages(struct address_space *mapping,
struct writeback_control *wbc)
{
unsigned int bytes_to_write;
unsigned int bytes_written;
struct cifs_sb_info *cifs_sb;
int done = 0;
pgoff_t end;
pgoff_t index;
int range_whole = 0;
struct kvec *iov;
int len;
int n_iov = 0;
pgoff_t next;
int nr_pages;
__u64 offset = 0;
struct cifsFileInfo *open_file;
struct cifsTconInfo *tcon;
struct cifsInodeInfo *cifsi = CIFS_I(mapping->host);
struct cifs_sb_info *cifs_sb = CIFS_SB(mapping->host->i_sb);
bool done = false, scanned = false, range_whole = false;
pgoff_t end, index;
struct cifs_writedata *wdata;
struct page *page;
struct pagevec pvec;
int rc = 0;
int scanned = 0;
int xid;
cifs_sb = CIFS_SB(mapping->host->i_sb);
/*
* If wsize is smaller that the page cache size, default to writing
* If wsize is smaller than the page cache size, default to writing
* one page at a time via cifs_writepage
*/
if (cifs_sb->wsize < PAGE_CACHE_SIZE)
return generic_writepages(mapping, wbc);
iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL);
if (iov == NULL)
return generic_writepages(mapping, wbc);
/*
* if there's no open file, then this is likely to fail too,
* but it'll at least handle the return. Maybe it should be
* a BUG() instead?
*/
open_file = find_writable_file(CIFS_I(mapping->host), false);
if (!open_file) {
kfree(iov);
return generic_writepages(mapping, wbc);
}
tcon = tlink_tcon(open_file->tlink);
cifsFileInfo_put(open_file);
xid = GetXid();
pagevec_init(&pvec, 0);
if (wbc->range_cyclic) {
index = mapping->writeback_index; /* Start from prev offset */
end = -1;
......@@ -1151,24 +1119,49 @@ static int cifs_writepages(struct address_space *mapping,
index = wbc->range_start >> PAGE_CACHE_SHIFT;
end = wbc->range_end >> PAGE_CACHE_SHIFT;
if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
range_whole = 1;
scanned = 1;
range_whole = true;
scanned = true;
}
retry:
while (!done && (index <= end) &&
(nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
PAGECACHE_TAG_DIRTY,
min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1))) {
int first;
unsigned int i;
while (!done && index <= end) {
unsigned int i, nr_pages, found_pages;
pgoff_t next = 0, tofind;
struct page **pages;
tofind = min((cifs_sb->wsize / PAGE_CACHE_SIZE) - 1,
end - index) + 1;
wdata = cifs_writedata_alloc((unsigned int)tofind);
if (!wdata) {
rc = -ENOMEM;
break;
}
first = -1;
next = 0;
n_iov = 0;
bytes_to_write = 0;
/*
* find_get_pages_tag seems to return a max of 256 on each
* iteration, so we must call it several times in order to
* fill the array or the wsize is effectively limited to
* 256 * PAGE_CACHE_SIZE.
*/
found_pages = 0;
pages = wdata->pages;
do {
nr_pages = find_get_pages_tag(mapping, &index,
PAGECACHE_TAG_DIRTY,
tofind, pages);
found_pages += nr_pages;
tofind -= nr_pages;
pages += nr_pages;
} while (nr_pages && tofind && index <= end);
if (found_pages == 0) {
kref_put(&wdata->refcount, cifs_writedata_release);
break;
}
for (i = 0; i < nr_pages; i++) {
page = pvec.pages[i];
nr_pages = 0;
for (i = 0; i < found_pages; i++) {
page = wdata->pages[i];
/*
* At this point we hold neither mapping->tree_lock nor
* lock on the page itself: the page may be truncated or
......@@ -1177,7 +1170,7 @@ static int cifs_writepages(struct address_space *mapping,
* mapping
*/
if (first < 0)
if (nr_pages == 0)
lock_page(page);
else if (!trylock_page(page))
break;
......@@ -1188,7 +1181,7 @@ static int cifs_writepages(struct address_space *mapping,
}
if (!wbc->range_cyclic && page->index > end) {
done = 1;
done = true;
unlock_page(page);
break;
}
......@@ -1215,119 +1208,89 @@ static int cifs_writepages(struct address_space *mapping,
set_page_writeback(page);
if (page_offset(page) >= mapping->host->i_size) {
done = 1;
done = true;
unlock_page(page);
end_page_writeback(page);
break;
}
/*
* BB can we get rid of this? pages are held by pvec
*/
page_cache_get(page);
len = min(mapping->host->i_size - page_offset(page),
(loff_t)PAGE_CACHE_SIZE);
wdata->pages[i] = page;
next = page->index + 1;
++nr_pages;
}
/* reserve iov[0] for the smb header */
n_iov++;
iov[n_iov].iov_base = kmap(page);
iov[n_iov].iov_len = len;
bytes_to_write += len;
/* reset index to refind any pages skipped */
if (nr_pages == 0)
index = wdata->pages[0]->index + 1;
if (first < 0) {
first = i;
offset = page_offset(page);
/* put any pages we aren't going to use */
for (i = nr_pages; i < found_pages; i++) {
page_cache_release(wdata->pages[i]);
wdata->pages[i] = NULL;
}
next = page->index + 1;
if (bytes_to_write + PAGE_CACHE_SIZE > cifs_sb->wsize)
break;
/* nothing to write? */
if (nr_pages == 0) {
kref_put(&wdata->refcount, cifs_writedata_release);
continue;
}
if (n_iov) {
retry_write:
open_file = find_writable_file(CIFS_I(mapping->host),
wdata->sync_mode = wbc->sync_mode;
wdata->nr_pages = nr_pages;
wdata->offset = page_offset(wdata->pages[0]);
do {
if (wdata->cfile != NULL)
cifsFileInfo_put(wdata->cfile);
wdata->cfile = find_writable_file(CIFS_I(mapping->host),
false);
if (!open_file) {
if (!wdata->cfile) {
cERROR(1, "No writable handles for inode");
rc = -EBADF;
} else {
rc = CIFSSMBWrite2(xid, tcon, open_file->netfid,
bytes_to_write, offset,
&bytes_written, iov, n_iov,
0);
cifsFileInfo_put(open_file);
}
cFYI(1, "Write2 rc=%d, wrote=%u", rc, bytes_written);
/*
* For now, treat a short write as if nothing got
* written. A zero length write however indicates
* ENOSPC or EFBIG. We have no way to know which
* though, so call it ENOSPC for now. EFBIG would
* get translated to AS_EIO anyway.
*
* FIXME: make it take into account the data that did
* get written
*/
if (rc == 0) {
if (bytes_written == 0)
rc = -ENOSPC;
else if (bytes_written < bytes_to_write)
rc = -EAGAIN;
break;
}
rc = cifs_async_writev(wdata);
} while (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN);
/* retry on data-integrity flush */
if (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN)
goto retry_write;
/* fix the stats and EOF */
if (bytes_written > 0) {
cifs_stats_bytes_written(tcon, bytes_written);
cifs_update_eof(cifsi, offset, bytes_written);
}
for (i = 0; i < nr_pages; ++i)
unlock_page(wdata->pages[i]);
for (i = 0; i < n_iov; i++) {
page = pvec.pages[first + i];
/* on retryable write error, redirty page */
/* send failure -- clean up the mess */
if (rc != 0) {
for (i = 0; i < nr_pages; ++i) {
if (rc == -EAGAIN)
redirty_page_for_writepage(wbc, page);
else if (rc != 0)
SetPageError(page);
kunmap(page);
unlock_page(page);
end_page_writeback(page);
page_cache_release(page);
redirty_page_for_writepage(wbc,
wdata->pages[i]);
else
SetPageError(wdata->pages[i]);
end_page_writeback(wdata->pages[i]);
page_cache_release(wdata->pages[i]);
}
if (rc != -EAGAIN)
mapping_set_error(mapping, rc);
else
rc = 0;
}
kref_put(&wdata->refcount, cifs_writedata_release);
if ((wbc->nr_to_write -= n_iov) <= 0)
done = 1;
index = next;
} else
/* Need to re-find the pages we skipped */
index = pvec.pages[0]->index + 1;
wbc->nr_to_write -= nr_pages;
if (wbc->nr_to_write <= 0)
done = true;
pagevec_release(&pvec);
index = next;
}
if (!scanned && !done) {
/*
* We hit the last page and there is more work to be done: wrap
* back to the start of the file
*/
scanned = 1;
scanned = true;
index = 0;
goto retry;
}
if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
mapping->writeback_index = index;
FreeXid(xid);
kfree(iov);
return rc;
}
......@@ -1383,6 +1346,14 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
{
int rc;
struct inode *inode = mapping->host;
struct cifsFileInfo *cfile = file->private_data;
struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
__u32 pid;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = cfile->pid;
else
pid = current->tgid;
cFYI(1, "write_end for page %p from pos %lld with %d bytes",
page, pos, copied);
......@@ -1406,8 +1377,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
/* BB check if anything else missing out of ppw
such as updating last write time */
page_data = kmap(page);
rc = cifs_write(file->private_data, page_data + offset,
copied, &pos);
rc = cifs_write(cfile, pid, page_data + offset, copied, &pos);
/* if (rc < 0) should we set writebehind rc? */
kunmap(page);
......@@ -1435,7 +1405,7 @@ int cifs_strict_fsync(struct file *file, int datasync)
{
int xid;
int rc = 0;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
struct cifsFileInfo *smbfile = file->private_data;
struct inode *inode = file->f_path.dentry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
......@@ -1465,7 +1435,7 @@ int cifs_fsync(struct file *file, int datasync)
{
int xid;
int rc = 0;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
struct cifsFileInfo *smbfile = file->private_data;
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
......@@ -1556,9 +1526,11 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
struct iov_iter it;
struct inode *inode;
struct cifsFileInfo *open_file;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct cifs_sb_info *cifs_sb;
struct cifs_io_parms io_parms;
int xid, rc;
__u32 pid;
len = iov_length(iov, nr_segs);
if (!len)
......@@ -1590,6 +1562,12 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
xid = GetXid();
open_file = file->private_data;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;
pTcon = tlink_tcon(open_file->tlink);
inode = file->f_path.dentry->d_inode;
......@@ -1616,9 +1594,13 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
if (rc != 0)
break;
}
rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid,
cur_len, *poffset, &written,
to_send, npages, 0);
io_parms.netfid = open_file->netfid;
io_parms.pid = pid;
io_parms.tcon = pTcon;
io_parms.offset = *poffset;
io_parms.length = cur_len;
rc = CIFSSMBWrite2(xid, &io_parms, &written, to_send,
npages, 0);
} while (rc == -EAGAIN);
for (i = 0; i < npages; i++)
......@@ -1711,10 +1693,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
size_t len, cur_len;
int iov_offset = 0;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct cifsFileInfo *open_file;
struct smb_com_read_rsp *pSMBr;
struct cifs_io_parms io_parms;
char *read_data;
__u32 pid;
if (!nr_segs)
return 0;
......@@ -1729,6 +1713,11 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
open_file = file->private_data;
pTcon = tlink_tcon(open_file->tlink);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;
if ((file->f_flags & O_ACCMODE) == O_WRONLY)
cFYI(1, "attempting read on write only file instance");
......@@ -1744,8 +1733,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
if (rc != 0)
break;
}
rc = CIFSSMBRead(xid, pTcon, open_file->netfid,
cur_len, *poffset, &bytes_read,
io_parms.netfid = open_file->netfid;
io_parms.pid = pid;
io_parms.tcon = pTcon;
io_parms.offset = *poffset;
io_parms.length = len;
rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
&read_data, &buf_type);
pSMBr = (struct smb_com_read_rsp *)read_data;
if (read_data) {
......@@ -1822,11 +1815,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
unsigned int total_read;
unsigned int current_read_size;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
int xid;
char *current_offset;
struct cifsFileInfo *open_file;
struct cifs_io_parms io_parms;
int buf_type = CIFS_NO_BUFFER;
__u32 pid;
xid = GetXid();
cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
......@@ -1839,6 +1834,11 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
open_file = file->private_data;
pTcon = tlink_tcon(open_file->tlink);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;
if ((file->f_flags & O_ACCMODE) == O_WRONLY)
cFYI(1, "attempting read on write only file instance");
......@@ -1861,11 +1861,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
if (rc != 0)
break;
}
rc = CIFSSMBRead(xid, pTcon,
open_file->netfid,
current_read_size, *poffset,
&bytes_read, &current_offset,
&buf_type);
io_parms.netfid = open_file->netfid;
io_parms.pid = pid;
io_parms.tcon = pTcon;
io_parms.offset = *poffset;
io_parms.length = current_read_size;
rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
&current_offset, &buf_type);
}
if (rc || (bytes_read == 0)) {
if (total_read) {
......@@ -1996,13 +1998,15 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
loff_t offset;
struct page *page;
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
unsigned int bytes_read = 0;
unsigned int read_size, i;
char *smb_read_data = NULL;
struct smb_com_read_rsp *pSMBr;
struct cifsFileInfo *open_file;
struct cifs_io_parms io_parms;
int buf_type = CIFS_NO_BUFFER;
__u32 pid;
xid = GetXid();
if (file->private_data == NULL) {
......@@ -2024,6 +2028,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
goto read_complete;
cFYI(DBG2, "rpages: num pages %d", num_pages);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;
for (i = 0; i < num_pages; ) {
unsigned contig_pages;
struct page *tmp_page;
......@@ -2065,12 +2074,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
if (rc != 0)
break;
}
rc = CIFSSMBRead(xid, pTcon,
open_file->netfid,
read_size, offset,
&bytes_read, &smb_read_data,
&buf_type);
io_parms.netfid = open_file->netfid;
io_parms.pid = pid;
io_parms.tcon = pTcon;
io_parms.offset = offset;
io_parms.length = read_size;
rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
&smb_read_data, &buf_type);
/* BB more RC checks ? */
if (rc == -EAGAIN) {
if (smb_read_data) {
......
......@@ -40,7 +40,7 @@ void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
server->fscache = NULL;
}
void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon)
void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
{
struct TCP_Server_Info *server = tcon->ses->server;
......@@ -51,7 +51,7 @@ void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon)
server->fscache, tcon->fscache);
}
void cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon)
void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
{
cFYI(1, "CIFS: releasing superblock cookie (0x%p)", tcon->fscache);
fscache_relinquish_cookie(tcon->fscache, 0);
......@@ -62,7 +62,7 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
{
struct cifsInodeInfo *cifsi = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
if (cifsi->fscache)
return;
......
......@@ -40,8 +40,8 @@ extern void cifs_fscache_unregister(void);
*/
extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
extern void cifs_fscache_get_super_cookie(struct cifsTconInfo *);
extern void cifs_fscache_release_super_cookie(struct cifsTconInfo *);
extern void cifs_fscache_get_super_cookie(struct cifs_tcon *);
extern void cifs_fscache_release_super_cookie(struct cifs_tcon *);
extern void cifs_fscache_release_inode_cookie(struct inode *);
extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *);
......@@ -99,9 +99,9 @@ static inline void
cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
static inline void
cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) {}
static inline void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon) {}
static inline void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) {}
static inline void
cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon) {}
cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) {}
static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {}
static inline void cifs_fscache_set_inode_cookie(struct inode *inode,
......
......@@ -295,7 +295,7 @@ int cifs_get_file_info_unix(struct file *filp)
struct inode *inode = filp->f_path.dentry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsFileInfo *cfile = filp->private_data;
struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
xid = GetXid();
rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
......@@ -318,7 +318,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
int rc;
FILE_UNIX_BASIC_INFO find_data;
struct cifs_fattr fattr;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
struct tcon_link *tlink;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
......@@ -373,7 +373,8 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
int oplock = 0;
__u16 netfid;
struct tcon_link *tlink;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
struct cifs_io_parms io_parms;
char buf[24];
unsigned int bytes_read;
char *pbuf;
......@@ -405,9 +406,13 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
if (rc == 0) {
int buf_type = CIFS_NO_BUFFER;
/* Read header */
rc = CIFSSMBRead(xid, tcon, netfid,
24 /* length */, 0 /* offset */,
&bytes_read, &pbuf, &buf_type);
io_parms.netfid = netfid;
io_parms.pid = current->tgid;
io_parms.tcon = tcon;
io_parms.offset = 0;
io_parms.length = 24;
rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf,
&buf_type);
if ((rc == 0) && (bytes_read >= 8)) {
if (memcmp("IntxBLK", pbuf, 8) == 0) {
cFYI(1, "Block device");
......@@ -468,7 +473,7 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
char ea_value[4];
__u32 mode;
struct tcon_link *tlink;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
......@@ -502,7 +507,7 @@ static void
cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
struct cifs_sb_info *cifs_sb, bool adjust_tz)
{
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
memset(fattr, 0, sizeof(*fattr));
fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
......@@ -553,7 +558,7 @@ int cifs_get_file_info(struct file *filp)
struct inode *inode = filp->f_path.dentry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsFileInfo *cfile = filp->private_data;
struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
xid = GetXid();
rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
......@@ -590,7 +595,7 @@ int cifs_get_inode_info(struct inode **pinode,
struct super_block *sb, int xid, const __u16 *pfid)
{
int rc = 0, tmprc;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct tcon_link *tlink;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
char *buf = NULL;
......@@ -735,10 +740,10 @@ static const struct inode_operations cifs_ipc_inode_ops = {
.lookup = cifs_lookup,
};
char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
struct cifsTconInfo *tcon)
char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
struct cifs_tcon *tcon)
{
int pplen = cifs_sb->prepathlen;
int pplen = vol->prepath ? strlen(vol->prepath) : 0;
int dfsplen;
char *full_path = NULL;
......@@ -772,7 +777,7 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
}
}
}
strncpy(full_path + dfsplen, cifs_sb->prepath, pplen);
strncpy(full_path + dfsplen, vol->prepath, pplen);
full_path[dfsplen + pplen] = 0; /* add trailing null */
return full_path;
}
......@@ -884,19 +889,13 @@ struct inode *cifs_root_iget(struct super_block *sb)
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct inode *inode = NULL;
long rc;
char *full_path;
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
full_path = cifs_build_path_to_root(cifs_sb, tcon);
if (full_path == NULL)
return ERR_PTR(-ENOMEM);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
xid = GetXid();
if (tcon->unix_ext)
rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
else
rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
xid, NULL);
rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
if (!inode) {
inode = ERR_PTR(rc);
......@@ -922,7 +921,6 @@ struct inode *cifs_root_iget(struct super_block *sb)
}
out:
kfree(full_path);
/* can not call macro FreeXid here since in a void func
* TODO: This is no longer true
*/
......@@ -943,7 +941,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
FILE_BASIC_INFO info_buf;
if (attrs == NULL)
......@@ -1061,7 +1059,7 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
__u32 dosattr, origattr;
FILE_BASIC_INFO *info_buf = NULL;
......@@ -1179,7 +1177,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
struct super_block *sb = dir->i_sb;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct tcon_link *tlink;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
struct iattr *attrs = NULL;
__u32 dosattr = 0, origattr = 0;
......@@ -1277,7 +1275,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
char *full_path = NULL;
struct inode *newinode = NULL;
struct cifs_fattr fattr;
......@@ -1455,7 +1453,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
char *full_path = NULL;
struct cifsInodeInfo *cifsInode;
......@@ -1512,7 +1510,7 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
{
struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
__u16 srcfid;
int oplock, rc;
......@@ -1564,7 +1562,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
char *toName = NULL;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
FILE_UNIX_BASIC_INFO *info_buf_target;
int xid, rc, tmprc;
......@@ -1794,7 +1792,7 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
struct inode *inode = dentry->d_inode;
int rc;
......@@ -1872,7 +1870,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL;
struct cifsTconInfo *pTcon = NULL;
struct cifs_tcon *pTcon = NULL;
struct cifs_io_parms io_parms;
/*
* To avoid spurious oplock breaks from server, in the case of
......@@ -1894,8 +1893,14 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
cFYI(1, "SetFSize for attrs rc = %d", rc);
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
unsigned int bytes_written;
rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
&bytes_written, NULL, NULL, 1);
io_parms.netfid = nfid;
io_parms.pid = npid;
io_parms.tcon = pTcon;
io_parms.offset = 0;
io_parms.length = attrs->ia_size;
rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
NULL, NULL, 1);
cFYI(1, "Wrt seteof rc %d", rc);
}
} else
......@@ -1930,10 +1935,15 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc == 0) {
unsigned int bytes_written;
rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
attrs->ia_size,
&bytes_written, NULL,
NULL, 1);
io_parms.netfid = netfid;
io_parms.pid = current->tgid;
io_parms.tcon = pTcon;
io_parms.offset = 0;
io_parms.length = attrs->ia_size;
rc = CIFSSMBWrite(xid, &io_parms,
&bytes_written,
NULL, NULL, 1);
cFYI(1, "wrt seteof rc %d", rc);
CIFSSMBClose(xid, pTcon, netfid);
}
......@@ -1961,7 +1971,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct cifs_unix_set_info_args *args = NULL;
struct cifsFileInfo *open_file;
......@@ -2247,7 +2257,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
{
struct inode *inode = direntry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsTconInfo *pTcon = cifs_sb_master_tcon(cifs_sb);
struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
if (pTcon->unix_ext)
return cifs_setattr_unix(direntry, attrs);
......
......@@ -38,7 +38,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
struct cifs_sb_info *cifs_sb;
#ifdef CONFIG_CIFS_POSIX
struct cifsFileInfo *pSMBFile = filep->private_data;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
__u64 ExtAttrBits = 0;
__u64 ExtAttrMask = 0;
__u64 caps;
......
......@@ -175,7 +175,7 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
}
static int
CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage, int remap)
{
......@@ -184,6 +184,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
__u16 netfid = 0;
u8 *buf;
unsigned int bytes_written = 0;
struct cifs_io_parms io_parms;
buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
if (!buf)
......@@ -203,10 +204,13 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
return rc;
}
rc = CIFSSMBWrite(xid, tcon, netfid,
CIFS_MF_SYMLINK_FILE_SIZE /* length */,
0 /* offset */,
&bytes_written, buf, NULL, 0);
io_parms.netfid = netfid;
io_parms.pid = current->tgid;
io_parms.tcon = tcon;
io_parms.offset = 0;
io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, buf, NULL, 0);
CIFSSMBClose(xid, tcon, netfid);
kfree(buf);
if (rc != 0)
......@@ -219,7 +223,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
}
static int
CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
CIFSQueryMFSymLink(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, char **symlinkinfo,
const struct nls_table *nls_codepage, int remap)
{
......@@ -231,6 +235,7 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
unsigned int bytes_read = 0;
int buf_type = CIFS_NO_BUFFER;
unsigned int link_len = 0;
struct cifs_io_parms io_parms;
FILE_ALL_INFO file_info;
rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
......@@ -249,11 +254,13 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
if (!buf)
return -ENOMEM;
pbuf = buf;
io_parms.netfid = netfid;
io_parms.pid = current->tgid;
io_parms.tcon = tcon;
io_parms.offset = 0;
io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
rc = CIFSSMBRead(xid, tcon, netfid,
CIFS_MF_SYMLINK_FILE_SIZE /* length */,
0 /* offset */,
&bytes_read, &pbuf, &buf_type);
rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
CIFSSMBClose(xid, tcon, netfid);
if (rc != 0) {
kfree(buf);
......@@ -291,7 +298,8 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
int oplock = 0;
__u16 netfid = 0;
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct cifs_io_parms io_parms;
u8 *buf;
char *pbuf;
unsigned int bytes_read = 0;
......@@ -328,11 +336,13 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
goto out;
}
pbuf = buf;
io_parms.netfid = netfid;
io_parms.pid = current->tgid;
io_parms.tcon = pTcon;
io_parms.offset = 0;
io_parms.length = CIFS_MF_SYMLINK_FILE_SIZE;
rc = CIFSSMBRead(xid, pTcon, netfid,
CIFS_MF_SYMLINK_FILE_SIZE /* length */,
0 /* offset */,
&bytes_read, &pbuf, &buf_type);
rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type);
CIFSSMBClose(xid, pTcon, netfid);
if (rc != 0) {
kfree(buf);
......@@ -370,7 +380,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
char *toName = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct cifsInodeInfo *cifsInode;
tlink = cifs_sb_tlink(cifs_sb);
......@@ -445,7 +455,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
char *target_path = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL;
struct cifsTconInfo *tcon;
struct cifs_tcon *tcon;
xid = GetXid();
......@@ -518,7 +528,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
int xid;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
char *full_path = NULL;
struct inode *newinode = NULL;
......
......@@ -67,12 +67,12 @@ _FreeXid(unsigned int xid)
spin_unlock(&GlobalMid_Lock);
}
struct cifsSesInfo *
struct cifs_ses *
sesInfoAlloc(void)
{
struct cifsSesInfo *ret_buf;
struct cifs_ses *ret_buf;
ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL);
ret_buf = kzalloc(sizeof(struct cifs_ses), GFP_KERNEL);
if (ret_buf) {
atomic_inc(&sesInfoAllocCount);
ret_buf->status = CifsNew;
......@@ -85,7 +85,7 @@ sesInfoAlloc(void)
}
void
sesInfoFree(struct cifsSesInfo *buf_to_free)
sesInfoFree(struct cifs_ses *buf_to_free)
{
if (buf_to_free == NULL) {
cFYI(1, "Null buffer passed to sesInfoFree");
......@@ -105,11 +105,11 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
kfree(buf_to_free);
}
struct cifsTconInfo *
struct cifs_tcon *
tconInfoAlloc(void)
{
struct cifsTconInfo *ret_buf;
ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL);
struct cifs_tcon *ret_buf;
ret_buf = kzalloc(sizeof(struct cifs_tcon), GFP_KERNEL);
if (ret_buf) {
atomic_inc(&tconInfoAllocCount);
ret_buf->tidStatus = CifsNew;
......@@ -124,7 +124,7 @@ tconInfoAlloc(void)
}
void
tconInfoFree(struct cifsTconInfo *buf_to_free)
tconInfoFree(struct cifs_tcon *buf_to_free)
{
if (buf_to_free == NULL) {
cFYI(1, "Null buffer passed to tconInfoFree");
......@@ -295,11 +295,11 @@ __u16 GetNextMid(struct TCP_Server_Info *server)
case it is responsbility of caller to set the mid */
void
header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
const struct cifsTconInfo *treeCon, int word_count
const struct cifs_tcon *treeCon, int word_count
/* length of fixed section (word count) in two byte units */)
{
struct list_head *temp_item;
struct cifsSesInfo *ses;
struct cifs_ses *ses;
char *temp = (char *) buffer;
memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
......@@ -359,7 +359,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
"did not match tcon uid");
spin_lock(&cifs_tcp_ses_lock);
list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
ses = list_entry(temp_item, struct cifs_ses, smb_ses_list);
if (ses->linux_uid == current_fsuid()) {
if (ses->server == treeCon->ses->server) {
cFYI(1, "found matching uid substitute right smb_uid");
......@@ -380,7 +380,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
if (treeCon->nocase)
buffer->Flags |= SMBFLG_CASELESS;
if ((treeCon->ses) && (treeCon->ses->server))
if (treeCon->ses->server->secMode &
if (treeCon->ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
}
......@@ -507,8 +507,8 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
{
struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
struct list_head *tmp, *tmp1, *tmp2;
struct cifsSesInfo *ses;
struct cifsTconInfo *tcon;
struct cifs_ses *ses;
struct cifs_tcon *tcon;
struct cifsInodeInfo *pCifsInode;
struct cifsFileInfo *netfile;
......@@ -566,9 +566,9 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
/* look up tcon based on tid & uid */
spin_lock(&cifs_tcp_ses_lock);
list_for_each(tmp, &srv->smb_ses_list) {
ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
list_for_each(tmp1, &ses->tcon_list) {
tcon = list_entry(tmp1, struct cifsTconInfo, tcon_list);
tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
if (tcon->tid != buf->Tid)
continue;
......
......@@ -836,7 +836,7 @@ ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode)
}
int
map_smb_to_linux_error(struct smb_hdr *smb, int logErr)
map_smb_to_linux_error(struct smb_hdr *smb, bool logErr)
{
unsigned int i;
int rc = -EIO; /* if transport error smb error may not be set */
......
......@@ -195,7 +195,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
int len;
int oplock = 0;
int rc;
struct cifsTconInfo *ptcon = cifs_sb_tcon(cifs_sb);
struct cifs_tcon *ptcon = cifs_sb_tcon(cifs_sb);
char *tmpbuffer;
rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ,
......@@ -223,7 +223,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
struct cifsFileInfo *cifsFile;
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
struct tcon_link *tlink = NULL;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
if (file->private_data == NULL) {
tlink = cifs_sb_tlink(cifs_sb);
......@@ -496,7 +496,7 @@ static int cifs_save_resume_key(const char *current_entry,
assume that they are located in the findfirst return buffer.*/
/* We start counting in the buffer with entry 2 and increment for every
entry (do not increment for . or .. entry) */
static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
struct file *file, char **ppCurrentEntry, int *num_to_ret)
{
int rc = 0;
......@@ -764,7 +764,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
{
int rc = 0;
int xid, i;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct cifsFileInfo *cifsFile = NULL;
char *current_entry;
int num_to_fill = 0;
......
......@@ -37,13 +37,13 @@
* the socket has been reestablished (so we know whether to use vc 0).
* Called while holding the cifs_tcp_ses_lock, so do not block
*/
static bool is_first_ses_reconnect(struct cifsSesInfo *ses)
static bool is_first_ses_reconnect(struct cifs_ses *ses)
{
struct list_head *tmp;
struct cifsSesInfo *tmp_ses;
struct cifs_ses *tmp_ses;
list_for_each(tmp, &ses->server->smb_ses_list) {
tmp_ses = list_entry(tmp, struct cifsSesInfo,
tmp_ses = list_entry(tmp, struct cifs_ses,
smb_ses_list);
if (tmp_ses->need_reconnect == false)
return false;
......@@ -61,11 +61,11 @@ static bool is_first_ses_reconnect(struct cifsSesInfo *ses)
* any vc but zero (some servers reset the connection on vcnum zero)
*
*/
static __le16 get_next_vcnum(struct cifsSesInfo *ses)
static __le16 get_next_vcnum(struct cifs_ses *ses)
{
__u16 vcnum = 0;
struct list_head *tmp;
struct cifsSesInfo *tmp_ses;
struct cifs_ses *tmp_ses;
__u16 max_vcs = ses->server->max_vcs;
__u16 i;
int free_vc_found = 0;
......@@ -87,7 +87,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
free_vc_found = 1;
list_for_each(tmp, &ses->server->smb_ses_list) {
tmp_ses = list_entry(tmp, struct cifsSesInfo,
tmp_ses = list_entry(tmp, struct cifs_ses,
smb_ses_list);
if (tmp_ses->vcnum == i) {
free_vc_found = 0;
......@@ -114,7 +114,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
return cpu_to_le16(vcnum);
}
static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
{
__u32 capabilities = 0;
......@@ -136,7 +136,7 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
if (ses->server->secMode &
if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
......@@ -181,7 +181,7 @@ unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
*pbcc_area = bcc_ptr;
}
static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
char *bcc_ptr = *pbcc_area;
......@@ -204,7 +204,7 @@ static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
}
static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
char *bcc_ptr = *pbcc_area;
......@@ -236,7 +236,7 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
*pbcc_area = bcc_ptr;
}
static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
char *bcc_ptr = *pbcc_area;
......@@ -276,7 +276,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
}
static void
decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
int len;
......@@ -310,7 +310,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
}
static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
struct cifsSesInfo *ses,
struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
int rc = 0;
......@@ -364,7 +364,7 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
}
static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
struct cifsSesInfo *ses)
struct cifs_ses *ses)
{
unsigned int tioffset; /* challenge message target info area */
unsigned int tilen; /* challenge message target info area length */
......@@ -411,7 +411,7 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
/* We do not malloc the blob, it is passed in pbuffer, because
it is fixed size, and small, making this approach cleaner */
static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
struct cifsSesInfo *ses)
struct cifs_ses *ses)
{
NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
__u32 flags;
......@@ -424,7 +424,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
if (ses->server->secMode &
if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
flags |= NTLMSSP_NEGOTIATE_SIGN;
if (!ses->server->session_estab)
......@@ -449,7 +449,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
This function returns the length of the data in the blob */
static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
u16 *buflen,
struct cifsSesInfo *ses,
struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
int rc;
......@@ -464,10 +464,10 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
if (ses->server->secMode &
if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
flags |= NTLMSSP_NEGOTIATE_SIGN;
if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED)
flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
......@@ -551,7 +551,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
}
int
CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
int rc = 0;
......@@ -657,7 +657,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
*/
rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
ses->server->secMode & SECMODE_PW_ENCRYPT ?
ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
true : false, lnm_session_key);
ses->flags |= CIFS_SES_LANMAN;
......
此差异已折叠。
......@@ -49,7 +49,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct super_block *sb;
char *full_path = NULL;
......@@ -109,7 +109,7 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct super_block *sb;
char *full_path;
struct cifs_ntsd *pacl;
......@@ -240,7 +240,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct super_block *sb;
char *full_path;
......@@ -372,7 +372,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
struct cifsTconInfo *pTcon;
struct cifs_tcon *pTcon;
struct super_block *sb;
char *full_path;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册