aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/cifssmb.c
diff options
context:
space:
mode:
authorShirish Pargaonkar <shirishpargaonkar@gmail.com>2012-09-28 13:21:14 -0400
committerSteve French <smfrench@gmail.com>2012-09-28 16:32:28 -0400
commitc052e2b423f3eabe9f3f32e60744afa5cf26f6b9 (patch)
tree03530fe0622d19a7d4e8d80e4e17e7681e95dc42 /fs/cifs/cifssmb.c
parentf065fd099fc475333fc7a55677a7f64764445d55 (diff)
cifs: obtain file access during backup intent lookup (resend)
Rebased and resending the patch. Path based queries can fail for lack of access, especially during lookup during open. open itself would actually succeed becasue of back up intent bit but queries (either path or file handle based) do not have a means to specifiy backup intent bit. So query the file info during lookup using trans2 / findfirst / file_id_full_dir_info to obtain file info as well as file_id/inode value. Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com> Acked-by: Jeff Layton <jlayton@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/cifssmb.c')
-rw-r--r--fs/cifs/cifssmb.c43
1 files changed, 26 insertions, 17 deletions
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 88bbb3ef95b3..76d0d2998850 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -4214,10 +4214,9 @@ UnixQPathInfoRetry:
4214/* xid, tcon, searchName and codepage are input parms, rest are returned */ 4214/* xid, tcon, searchName and codepage are input parms, rest are returned */
4215int 4215int
4216CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon, 4216CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4217 const char *searchName, 4217 const char *searchName, struct cifs_sb_info *cifs_sb,
4218 const struct nls_table *nls_codepage,
4219 __u16 *pnetfid, __u16 search_flags, 4218 __u16 *pnetfid, __u16 search_flags,
4220 struct cifs_search_info *psrch_inf, int remap, const char dirsep) 4219 struct cifs_search_info *psrch_inf, bool msearch)
4221{ 4220{
4222/* level 257 SMB_ */ 4221/* level 257 SMB_ */
4223 TRANSACTION2_FFIRST_REQ *pSMB = NULL; 4222 TRANSACTION2_FFIRST_REQ *pSMB = NULL;
@@ -4225,8 +4224,9 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
4225 T2_FFIRST_RSP_PARMS *parms; 4224 T2_FFIRST_RSP_PARMS *parms;
4226 int rc = 0; 4225 int rc = 0;
4227 int bytes_returned = 0; 4226 int bytes_returned = 0;
4228 int name_len; 4227 int name_len, remap;
4229 __u16 params, byte_count; 4228 __u16 params, byte_count;
4229 struct nls_table *nls_codepage;
4230 4230
4231 cFYI(1, "In FindFirst for %s", searchName); 4231 cFYI(1, "In FindFirst for %s", searchName);
4232 4232
@@ -4236,6 +4236,9 @@ findFirstRetry:
4236 if (rc) 4236 if (rc)
4237 return rc; 4237 return rc;
4238 4238
4239 nls_codepage = cifs_sb->local_nls;
4240 remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
4241
4239 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { 4242 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
4240 name_len = 4243 name_len =
4241 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName, 4244 cifsConvertToUTF16((__le16 *) pSMB->FileName, searchName,
@@ -4244,24 +4247,29 @@ findFirstRetry:
4244 it got remapped to 0xF03A as if it were part of the 4247 it got remapped to 0xF03A as if it were part of the
4245 directory name instead of a wildcard */ 4248 directory name instead of a wildcard */
4246 name_len *= 2; 4249 name_len *= 2;
4247 pSMB->FileName[name_len] = dirsep; 4250 if (msearch) {
4248 pSMB->FileName[name_len+1] = 0; 4251 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4249 pSMB->FileName[name_len+2] = '*'; 4252 pSMB->FileName[name_len+1] = 0;
4250 pSMB->FileName[name_len+3] = 0; 4253 pSMB->FileName[name_len+2] = '*';
4251 name_len += 4; /* now the trailing null */ 4254 pSMB->FileName[name_len+3] = 0;
4252 pSMB->FileName[name_len] = 0; /* null terminate just in case */ 4255 name_len += 4; /* now the trailing null */
4253 pSMB->FileName[name_len+1] = 0; 4256 /* null terminate just in case */
4254 name_len += 2; 4257 pSMB->FileName[name_len] = 0;
4258 pSMB->FileName[name_len+1] = 0;
4259 name_len += 2;
4260 }
4255 } else { /* BB add check for overrun of SMB buf BB */ 4261 } else { /* BB add check for overrun of SMB buf BB */
4256 name_len = strnlen(searchName, PATH_MAX); 4262 name_len = strnlen(searchName, PATH_MAX);
4257/* BB fix here and in unicode clause above ie 4263/* BB fix here and in unicode clause above ie
4258 if (name_len > buffersize-header) 4264 if (name_len > buffersize-header)
4259 free buffer exit; BB */ 4265 free buffer exit; BB */
4260 strncpy(pSMB->FileName, searchName, name_len); 4266 strncpy(pSMB->FileName, searchName, name_len);
4261 pSMB->FileName[name_len] = dirsep; 4267 if (msearch) {
4262 pSMB->FileName[name_len+1] = '*'; 4268 pSMB->FileName[name_len] = CIFS_DIR_SEP(cifs_sb);
4263 pSMB->FileName[name_len+2] = 0; 4269 pSMB->FileName[name_len+1] = '*';
4264 name_len += 3; 4270 pSMB->FileName[name_len+2] = 0;
4271 name_len += 3;
4272 }
4265 } 4273 }
4266 4274
4267 params = 12 + name_len /* includes null */ ; 4275 params = 12 + name_len /* includes null */ ;
@@ -4349,7 +4357,8 @@ findFirstRetry:
4349 psrch_inf->last_entry = psrch_inf->srch_entries_start + 4357 psrch_inf->last_entry = psrch_inf->srch_entries_start +
4350 lnoff; 4358 lnoff;
4351 4359
4352 *pnetfid = parms->SearchHandle; 4360 if (pnetfid)
4361 *pnetfid = parms->SearchHandle;
4353 } else { 4362 } else {
4354 cifs_buf_release(pSMB); 4363 cifs_buf_release(pSMB);
4355 } 4364 }