Commit fdc9ecbb authored by Pavel Shilovsky's avatar Pavel Shilovsky

Update 3.7 sources from stable (v3.7)

parent 57a74735
......@@ -225,6 +225,13 @@ sid_to_str(struct cifs_sid *sidptr, char *sidstr)
}
static void
cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src)
{
memcpy(dst, src, sizeof(*dst));
dst->num_subauth = min_t(u8, src->num_subauth, NUM_SUBAUTHS);
}
static void
id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
struct cifs_sid_id **psidid, char *typestr)
{
......@@ -248,7 +255,7 @@ id_rb_insert(struct rb_root *root, struct cifs_sid *sidptr,
}
}
memcpy(&(*psidid)->sid, sidptr, sizeof(struct cifs_sid));
cifs_copy_sid(&(*psidid)->sid, sidptr);
(*psidid)->time = jiffies - (SID_MAP_RETRY + 1);
(*psidid)->refcount = 0;
......@@ -354,7 +361,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
* any fields of the node after a reference is put .
*/
if (test_bit(SID_ID_MAPPED, &psidid->state)) {
memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
cifs_copy_sid(ssid, &psidid->sid);
psidid->time = jiffies; /* update ts for accessing */
goto id_sid_out;
}
......@@ -370,14 +377,14 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
if (IS_ERR(sidkey)) {
rc = -EINVAL;
cFYI(1, "%s: Can't map and id to a SID", __func__);
} else if (sidkey->datalen < sizeof(struct cifs_sid)) {
rc = -EIO;
cFYI(1, "%s: Downcall contained malformed key "
"(datalen=%hu)", __func__, sidkey->datalen);
} else {
lsid = (struct cifs_sid *)sidkey->payload.data;
memcpy(&psidid->sid, lsid,
sidkey->datalen < sizeof(struct cifs_sid) ?
sidkey->datalen : sizeof(struct cifs_sid));
memcpy(ssid, &psidid->sid,
sidkey->datalen < sizeof(struct cifs_sid) ?
sidkey->datalen : sizeof(struct cifs_sid));
cifs_copy_sid(&psidid->sid, lsid);
cifs_copy_sid(ssid, &psidid->sid);
set_bit(SID_ID_MAPPED, &psidid->state);
key_put(sidkey);
kfree(psidid->sidstr);
......@@ -396,7 +403,7 @@ id_to_sid(unsigned long cid, uint sidtype, struct cifs_sid *ssid)
return rc;
}
if (test_bit(SID_ID_MAPPED, &psidid->state))
memcpy(ssid, &psidid->sid, sizeof(struct cifs_sid));
cifs_copy_sid(ssid, &psidid->sid);
else
rc = -EINVAL;
}
......@@ -675,8 +682,6 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
static void copy_sec_desc(const struct cifs_ntsd *pntsd,
struct cifs_ntsd *pnntsd, __u32 sidsoffset)
{
int i;
struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
......@@ -692,26 +697,14 @@ static void copy_sec_desc(const struct cifs_ntsd *pntsd,
owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
le32_to_cpu(pntsd->osidoffset));
nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
nowner_sid_ptr->revision = owner_sid_ptr->revision;
nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
for (i = 0; i < 6; i++)
nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
for (i = 0; i < 5; i++)
nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
cifs_copy_sid(nowner_sid_ptr, owner_sid_ptr);
/* copy group sid */
group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
le32_to_cpu(pntsd->gsidoffset));
ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
sizeof(struct cifs_sid));
ngroup_sid_ptr->revision = group_sid_ptr->revision;
ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
for (i = 0; i < 6; i++)
ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
for (i = 0; i < 5; i++)
ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
cifs_copy_sid(ngroup_sid_ptr, group_sid_ptr);
return;
}
......@@ -1120,8 +1113,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
kfree(nowner_sid_ptr);
return rc;
}
memcpy(owner_sid_ptr, nowner_sid_ptr,
sizeof(struct cifs_sid));
cifs_copy_sid(owner_sid_ptr, nowner_sid_ptr);
kfree(nowner_sid_ptr);
*aclflag = CIFS_ACL_OWNER;
}
......@@ -1139,8 +1131,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
kfree(ngroup_sid_ptr);
return rc;
}
memcpy(group_sid_ptr, ngroup_sid_ptr,
sizeof(struct cifs_sid));
cifs_copy_sid(group_sid_ptr, ngroup_sid_ptr);
kfree(ngroup_sid_ptr);
*aclflag = CIFS_ACL_GROUP;
}
......
......@@ -402,7 +402,16 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
* in network traffic in the other paths.
*/
if (!(oflags & O_CREAT)) {
struct dentry *res = cifs_lookup(inode, direntry, 0);
struct dentry *res;
/*
* Check for hashed negative dentry. We have already revalidated
* the dentry and it is fine. No need to perform another lookup.
*/
if (!d_unhashed(direntry))
return -ENOENT;
res = cifs_lookup(inode, direntry, 0);
if (IS_ERR(res))
return PTR_ERR(res);
......
......@@ -1800,7 +1800,6 @@ static int cifs_writepages(struct address_space *mapping,
struct TCP_Server_Info *server;
struct page *page;
int rc = 0;
loff_t isize = i_size_read(mapping->host);
/*
* If wsize is smaller than the page cache size, default to writing
......@@ -1905,7 +1904,7 @@ retry:
*/
set_page_writeback(page);
if (page_offset(page) >= isize) {
if (page_offset(page) >= i_size_read(mapping->host)) {
done = true;
unlock_page(page);
end_page_writeback(page);
......@@ -1938,7 +1937,8 @@ retry:
wdata->offset = page_offset(wdata->pages[0]);
wdata->pagesz = PAGE_CACHE_SIZE;
wdata->tailsz =
min(isize - page_offset(wdata->pages[nr_pages - 1]),
min(i_size_read(mapping->host) -
page_offset(wdata->pages[nr_pages - 1]),
(loff_t)PAGE_CACHE_SIZE);
wdata->bytes = ((nr_pages - 1) * PAGE_CACHE_SIZE) +
wdata->tailsz;
......
......@@ -86,14 +86,17 @@ cifs_readdir_lookup(struct dentry *parent, struct qstr *name,
dentry = d_lookup(parent, name);
if (dentry) {
int err;
inode = dentry->d_inode;
/* update inode in place if i_ino didn't change */
if (inode && CIFS_I(inode)->uniqueid == fattr->cf_uniqueid) {
cifs_fattr_to_inode(inode, fattr);
return dentry;
}
d_drop(dentry);
err = d_invalidate(dentry);
dput(dentry);
if (err)
return NULL;
}
dentry = d_alloc(parent, name);
......
......@@ -766,7 +766,6 @@ smb_set_file_info(struct inode *inode, const char *full_path,
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL;
struct cifs_tcon *tcon;
FILE_BASIC_INFO info_buf;
/* if the file is already open for write, just use that fileid */
open_file = find_writable_file(cinode, true);
......@@ -818,7 +817,7 @@ smb_set_file_info(struct inode *inode, const char *full_path,
netpid = current->tgid;
set_via_filehandle:
rc = CIFSSMBSetFileInfo(xid, tcon, &info_buf, netfid, netpid);
rc = CIFSSMBSetFileInfo(xid, tcon, buf, netfid, netpid);
if (!rc)
cinode->cifsAttrs = le32_to_cpu(buf->Attributes);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment