diff options
author | Shirish Pargaonkar <shirishpargaonkar@gmail.com> | 2012-09-28 13:21:14 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2012-09-28 16:32:28 -0400 |
commit | c052e2b423f3eabe9f3f32e60744afa5cf26f6b9 (patch) | |
tree | 03530fe0622d19a7d4e8d80e4e17e7681e95dc42 /fs/cifs/cifssmb.c | |
parent | f065fd099fc475333fc7a55677a7f64764445d55 (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.c | 43 |
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 */ |
4215 | int | 4215 | int |
4216 | CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon, | 4216 | CIFSFindFirst(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 | } |