Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 326328
b: refs/heads/master
c: c052e2b
h: refs/heads/master
v: v3
  • Loading branch information
Shirish Pargaonkar authored and Steve French committed Sep 28, 2012
1 parent dd7eb15 commit 02800b3
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 42 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f065fd099fc475333fc7a55677a7f64764445d55
refs/heads/master: c052e2b423f3eabe9f3f32e60744afa5cf26f6b9
6 changes: 4 additions & 2 deletions trunk/fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,8 @@ void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr);
extern void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr,
FILE_UNIX_BASIC_INFO *info,
struct cifs_sb_info *cifs_sb);
extern void cifs_dir_info_to_fattr(struct cifs_fattr *, FILE_DIRECTORY_INFO *,
struct cifs_sb_info *);
extern void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr);
extern struct inode *cifs_iget(struct super_block *sb,
struct cifs_fattr *fattr);
Expand Down Expand Up @@ -216,10 +218,10 @@ extern int CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
const struct nls_table *);

extern int CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
const char *searchName, const struct nls_table *nls_codepage,
const char *searchName, struct cifs_sb_info *cifs_sb,
__u16 *searchHandle, __u16 search_flags,
struct cifs_search_info *psrch_inf,
int map, const char dirsep);
bool msearch);

extern int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
__u16 searchHandle, __u16 search_flags,
Expand Down
43 changes: 26 additions & 17 deletions trunk/fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -4214,19 +4214,19 @@ CIFSSMBUnixQPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
/* xid, tcon, searchName and codepage are input parms, rest are returned */
int
CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
const char *searchName,
const struct nls_table *nls_codepage,
const char *searchName, struct cifs_sb_info *cifs_sb,
__u16 *pnetfid, __u16 search_flags,
struct cifs_search_info *psrch_inf, int remap, const char dirsep)
struct cifs_search_info *psrch_inf, bool msearch)
{
/* level 257 SMB_ */
TRANSACTION2_FFIRST_REQ *pSMB = NULL;
TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
T2_FFIRST_RSP_PARMS *parms;
int rc = 0;
int bytes_returned = 0;
int name_len;
int name_len, remap;
__u16 params, byte_count;
struct nls_table *nls_codepage;

cFYI(1, "In FindFirst for %s", searchName);

Expand All @@ -4236,6 +4236,9 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
if (rc)
return rc;

nls_codepage = cifs_sb->local_nls;
remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;

if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
name_len =
cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
Expand All @@ -4244,24 +4247,29 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
it got remapped to 0xF03A as if it were part of the
directory name instead of a wildcard */
name_len *= 2;
pSMB->FileName[name_len] = dirsep;
pSMB->FileName[name_len+1] = 0;
pSMB->FileName[name_len+2] = '*';
pSMB->FileName[name_len+3] = 0;
name_len += 4; /* now the trailing null */
pSMB->FileName[name_len] = 0; /* null terminate just in case */
pSMB->FileName[name_len+1] = 0;
name_len += 2;
if (msearch) {
pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
pSMB->FileName[name_len+1] = 0;
pSMB->FileName[name_len+2] = '*';
pSMB->FileName[name_len+3] = 0;
name_len += 4; /* now the trailing null */
/* null terminate just in case */
pSMB->FileName[name_len] = 0;
pSMB->FileName[name_len+1] = 0;
name_len += 2;
}
} else { /* BB add check for overrun of SMB buf BB */
name_len = strnlen(searchName, PATH_MAX);
/* BB fix here and in unicode clause above ie
if (name_len > buffersize-header)
free buffer exit; BB */
strncpy(pSMB->FileName, searchName, name_len);
pSMB->FileName[name_len] = dirsep;
pSMB->FileName[name_len+1] = '*';
pSMB->FileName[name_len+2] = 0;
name_len += 3;
if (msearch) {
pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
pSMB->FileName[name_len+1] = '*';
pSMB->FileName[name_len+2] = 0;
name_len += 3;
}
}

params = 12 + name_len /* includes null */ ;
Expand Down Expand Up @@ -4349,7 +4357,8 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
psrch_inf->last_entry = psrch_inf->srch_entries_start +
lnoff;

*pnetfid = parms->SearchHandle;
if (pnetfid)
*pnetfid = parms->SearchHandle;
} else {
cifs_buf_release(pSMB);
}
Expand Down
64 changes: 47 additions & 17 deletions trunk/fs/cifs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,14 +607,17 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
FILE_ALL_INFO *data, struct super_block *sb, int xid,
const __u16 *fid)
{
int rc = 0, tmprc;
bool validinum = false;
__u16 srchflgs;
int rc = 0, tmprc = ENOSYS;
struct cifs_tcon *tcon;
struct TCP_Server_Info *server;
struct tcon_link *tlink;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
char *buf = NULL;
bool adjust_tz = false;
struct cifs_fattr fattr;
struct cifs_search_info *srchinf = NULL;

tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
Expand Down Expand Up @@ -653,9 +656,38 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
} else if (rc == -EREMOTE) {
cifs_create_dfs_fattr(&fattr, sb);
rc = 0;
} else {
} else if (rc == -EACCES && backup_cred(cifs_sb)) {
srchinf = kzalloc(sizeof(struct cifs_search_info),
GFP_KERNEL);
if (srchinf == NULL) {
rc = -ENOMEM;
goto cgii_exit;
}

srchinf->endOfSearch = false;
srchinf->info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;

srchflgs = CIFS_SEARCH_CLOSE_ALWAYS |
CIFS_SEARCH_CLOSE_AT_END |
CIFS_SEARCH_BACKUP_SEARCH;

rc = CIFSFindFirst(xid, tcon, full_path,
cifs_sb, NULL, srchflgs, srchinf, false);
if (!rc) {
data =
(FILE_ALL_INFO *)srchinf->srch_entries_start;

cifs_dir_info_to_fattr(&fattr,
(FILE_DIRECTORY_INFO *)data, cifs_sb);
fattr.cf_uniqueid = le64_to_cpu(
((SEARCH_ID_FULL_DIR_INFO *)data)->UniqueId);
validinum = true;

cifs_buf_release(srchinf->ntwrk_buf_start);
}
kfree(srchinf);
} else
goto cgii_exit;
}

/*
* If an inode wasn't passed in, then get the inode number
Expand All @@ -666,23 +698,21 @@ cifs_get_inode_info(struct inode **inode, const char *full_path,
*/
if (*inode == NULL) {
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
if (server->ops->get_srv_inum)
tmprc = server->ops->get_srv_inum(xid, tcon,
cifs_sb, full_path, &fattr.cf_uniqueid,
data);
else
tmprc = -ENOSYS;
if (tmprc || !fattr.cf_uniqueid) {
cFYI(1, "GetSrvInodeNum rc %d", tmprc);
fattr.cf_uniqueid = iunique(sb, ROOT_I);
cifs_autodisable_serverino(cifs_sb);
if (validinum == false) {
if (server->ops->get_srv_inum)
tmprc = server->ops->get_srv_inum(xid,
tcon, cifs_sb, full_path,
&fattr.cf_uniqueid, data);
if (tmprc) {
cFYI(1, "GetSrvInodeNum rc %d", tmprc);
fattr.cf_uniqueid = iunique(sb, ROOT_I);
cifs_autodisable_serverino(cifs_sb);
}
}
} else {
} else
fattr.cf_uniqueid = iunique(sb, ROOT_I);
}
} else {
} else
fattr.cf_uniqueid = CIFS_I(*inode)->uniqueid;
}

/* query for SFU type info if supported and needed */
if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/cifs/readdir.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
}
}

static void
void
cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info,
struct cifs_sb_info *cifs_sb)
{
Expand Down
6 changes: 2 additions & 4 deletions trunk/fs/cifs/smb1ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,10 +837,8 @@ cifs_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_fid *fid, __u16 search_flags,
struct cifs_search_info *srch_inf)
{
return CIFSFindFirst(xid, tcon, path, cifs_sb->local_nls,
&fid->netfid, search_flags, srch_inf,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));
return CIFSFindFirst(xid, tcon, path, cifs_sb,
&fid->netfid, search_flags, srch_inf, true);
}

static int
Expand Down

0 comments on commit 02800b3

Please sign in to comment.