Blame view
fs/cifs/readdir.c
22.9 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 |
/* * fs/cifs/readdir.c * * Directory search handling |
6dc0f87e3 [CIFS] whitespace... |
5 |
* |
ad7a2926b [CIFS] reduce che... |
6 |
* Copyright (C) International Business Machines Corp., 2004, 2008 |
cda0ec6a8 cifs: introduce c... |
7 |
* Copyright (C) Red Hat, Inc., 2011 |
1da177e4c Linux-2.6.12-rc2 |
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
* Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/fs.h> |
273d81d6a [CIFS] Do not ove... |
25 |
#include <linux/pagemap.h> |
5a0e3ad6a include cleanup: ... |
26 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
27 |
#include <linux/stat.h> |
1da177e4c Linux-2.6.12-rc2 |
28 29 30 31 32 33 34 |
#include "cifspdu.h" #include "cifsglob.h" #include "cifsproto.h" #include "cifs_unicode.h" #include "cifs_debug.h" #include "cifs_fs_sb.h" #include "cifsfs.h" |
f58841666 cifs: change cifs... |
35 36 37 38 39 40 |
/* * To be safe - for UCS to UTF-8 with strings loaded with the rare long * characters alloc more to account for such multibyte target UTF-8 * characters. */ #define UNICODE_NAME_MAX ((4 * NAME_MAX) + 2) |
3979877e5 [CIFS] Support fo... |
41 42 |
#ifdef CONFIG_CIFS_DEBUG2 static void dump_cifs_file_struct(struct file *file, char *label) |
1da177e4c Linux-2.6.12-rc2 |
43 |
{ |
6dc0f87e3 [CIFS] whitespace... |
44 |
struct cifsFileInfo *cf; |
1da177e4c Linux-2.6.12-rc2 |
45 |
|
4523cc304 [CIFS] UID/GID ov... |
46 |
if (file) { |
1da177e4c Linux-2.6.12-rc2 |
47 |
cf = file->private_data; |
4523cc304 [CIFS] UID/GID ov... |
48 |
if (cf == NULL) { |
b6b38f704 [CIFS] Neaten cER... |
49 |
cFYI(1, "empty cifs private file data"); |
1da177e4c Linux-2.6.12-rc2 |
50 51 |
return; } |
ad7a2926b [CIFS] reduce che... |
52 |
if (cf->invalidHandle) |
b6b38f704 [CIFS] Neaten cER... |
53 |
cFYI(1, "invalid handle"); |
ad7a2926b [CIFS] reduce che... |
54 |
if (cf->srch_inf.endOfSearch) |
b6b38f704 [CIFS] Neaten cER... |
55 |
cFYI(1, "end of search"); |
ad7a2926b [CIFS] reduce che... |
56 |
if (cf->srch_inf.emptyDir) |
b6b38f704 [CIFS] Neaten cER... |
57 |
cFYI(1, "empty dir"); |
1da177e4c Linux-2.6.12-rc2 |
58 |
} |
3979877e5 [CIFS] Support fo... |
59 |
} |
90c81e0b0 [CIFS] clean up s... |
60 61 62 63 |
#else static inline void dump_cifs_file_struct(struct file *file, char *label) { } |
3979877e5 [CIFS] Support fo... |
64 |
#endif /* DEBUG2 */ |
1da177e4c Linux-2.6.12-rc2 |
65 |
|
cc0bad755 cifs: add new cif... |
66 67 68 69 70 71 72 73 74 75 76 |
/* * Find the dentry that matches "name". If there isn't one, create one. If it's * a negative dentry or the uniqueid changed, then drop it and recreate it. */ static struct dentry * cifs_readdir_lookup(struct dentry *parent, struct qstr *name, struct cifs_fattr *fattr) { struct dentry *dentry, *alias; struct inode *inode; struct super_block *sb = parent->d_inode->i_sb; |
b6b38f704 [CIFS] Neaten cER... |
77 |
cFYI(1, "For %s", name->name); |
cc0bad755 cifs: add new cif... |
78 |
|
05507fa2a cifs: fix dentry ... |
79 |
if (parent->d_op && parent->d_op->d_hash) |
b1e6a015a fs: change d_hash... |
80 |
parent->d_op->d_hash(parent, parent->d_inode, name); |
05507fa2a cifs: fix dentry ... |
81 82 |
else name->hash = full_name_hash(name->name, name->len); |
cc0bad755 cifs: add new cif... |
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
dentry = d_lookup(parent, name); if (dentry) { /* FIXME: check for inode number changes? */ if (dentry->d_inode != NULL) return dentry; d_drop(dentry); dput(dentry); } dentry = d_alloc(parent, name); if (dentry == NULL) return NULL; inode = cifs_iget(sb, fattr); if (!inode) { dput(dentry); return NULL; } |
cc0bad755 cifs: add new cif... |
101 102 103 104 105 106 107 108 109 110 |
alias = d_materialise_unique(dentry, inode); if (alias != NULL) { dput(dentry); if (IS_ERR(alias)) return NULL; dentry = alias; } return dentry; } |
0b8f18e35 cifs: convert cif... |
111 112 |
static void cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb) |
1da177e4c Linux-2.6.12-rc2 |
113 |
{ |
0b8f18e35 cifs: convert cif... |
114 115 |
fattr->cf_uid = cifs_sb->mnt_uid; fattr->cf_gid = cifs_sb->mnt_gid; |
1da177e4c Linux-2.6.12-rc2 |
116 |
|
0b8f18e35 cifs: convert cif... |
117 118 119 |
if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; fattr->cf_dtype = DT_DIR; |
1da177e4c Linux-2.6.12-rc2 |
120 |
} else { |
0b8f18e35 cifs: convert cif... |
121 122 |
fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; fattr->cf_dtype = DT_REG; |
1da177e4c Linux-2.6.12-rc2 |
123 |
} |
0b8f18e35 cifs: convert cif... |
124 125 |
if (fattr->cf_cifsattrs & ATTR_READONLY) fattr->cf_mode &= ~S_IWUGO; |
5bafd7659 [CIFS] Add suppor... |
126 |
|
0b8f18e35 cifs: convert cif... |
127 128 129 130 131 132 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL && fattr->cf_cifsattrs & ATTR_SYSTEM) { if (fattr->cf_eof == 0) { fattr->cf_mode &= ~S_IFMT; fattr->cf_mode |= S_IFIFO; fattr->cf_dtype = DT_FIFO; |
3020a1f58 [CIFS] Fix schedu... |
133 |
} else { |
4468eb3fd on non-posix shar... |
134 |
/* |
0b8f18e35 cifs: convert cif... |
135 136 137 |
* trying to get the type and mode via SFU can be slow, * so just call those regular files for now, and mark * for reval |
4468eb3fd on non-posix shar... |
138 |
*/ |
0b8f18e35 cifs: convert cif... |
139 |
fattr->cf_flags |= CIFS_FATTR_NEED_REVAL; |
4468eb3fd on non-posix shar... |
140 141 |
} } |
0b8f18e35 cifs: convert cif... |
142 |
} |
1da177e4c Linux-2.6.12-rc2 |
143 |
|
15dd47810 [CIFS] Remove bui... |
144 |
static void |
0b8f18e35 cifs: convert cif... |
145 146 147 148 149 150 151 |
cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info, struct cifs_sb_info *cifs_sb) { memset(fattr, 0, sizeof(*fattr)); fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes); fattr->cf_eof = le64_to_cpu(info->EndOfFile); fattr->cf_bytes = le64_to_cpu(info->AllocationSize); |
20054bd65 cifs: use Creatio... |
152 |
fattr->cf_createtime = le64_to_cpu(info->CreationTime); |
0b8f18e35 cifs: convert cif... |
153 154 155 156 157 158 |
fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); cifs_fill_common_info(fattr, cifs_sb); } |
1da177e4c Linux-2.6.12-rc2 |
159 |
|
15dd47810 [CIFS] Remove bui... |
160 |
static void |
0b8f18e35 cifs: convert cif... |
161 162 163 |
cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info, struct cifs_sb_info *cifs_sb) { |
0d424ad0a cifs: add cifs_sb... |
164 |
int offset = cifs_sb_master_tcon(cifs_sb)->ses->server->timeAdj; |
1da177e4c Linux-2.6.12-rc2 |
165 |
|
0b8f18e35 cifs: convert cif... |
166 167 168 169 170 171 172 173 174 175 176 177 178 |
memset(fattr, 0, sizeof(*fattr)); fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate, info->LastAccessTime, offset); fattr->cf_ctime = cnvrtDosUnixTm(info->LastWriteDate, info->LastWriteTime, offset); fattr->cf_mtime = cnvrtDosUnixTm(info->LastWriteDate, info->LastWriteTime, offset); fattr->cf_cifsattrs = le16_to_cpu(info->Attributes); fattr->cf_bytes = le32_to_cpu(info->AllocationSize); fattr->cf_eof = le32_to_cpu(info->DataSize); cifs_fill_common_info(fattr, cifs_sb); |
1da177e4c Linux-2.6.12-rc2 |
179 |
} |
0e0d2cf32 [CIFS] Remove spa... |
180 181 182 183 184 185 186 187 188 189 190 |
/* BB eventually need to add the following helper function to resolve NT_STATUS_STOPPED_ON_SYMLINK return code when we try to do FindFirst on (NTFS) directory symlinks */ /* int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb, int xid) { __u16 fid; int len; int oplock = 0; int rc; |
96daf2b09 [CIFS] Rename thr... |
191 |
struct cifs_tcon *ptcon = cifs_sb_tcon(cifs_sb); |
0e0d2cf32 [CIFS] Remove spa... |
192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
char *tmpbuffer; rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ, OPEN_REPARSE_POINT, &fid, &oplock, NULL, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (!rc) { tmpbuffer = kmalloc(maxpath); rc = CIFSSMBQueryReparseLinkInfo(xid, ptcon, full_path, tmpbuffer, maxpath -1, fid, cifs_sb->local_nls); if (CIFSSMBClose(xid, ptcon, fid)) { |
b6b38f704 [CIFS] Neaten cER... |
206 |
cFYI(1, "Error closing temporary reparsepoint open"); |
0e0d2cf32 [CIFS] Remove spa... |
207 208 209 210 |
} } } */ |
1da177e4c Linux-2.6.12-rc2 |
211 212 213 |
static int initiate_cifs_search(const int xid, struct file *file) { int rc = 0; |
7ffec3724 cifs: add refcoun... |
214 |
char *full_path = NULL; |
3870253ef [CIFS] more white... |
215 |
struct cifsFileInfo *cifsFile; |
7ffec3724 cifs: add refcoun... |
216 |
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); |
59c55ba1f cifs: don't take ... |
217 |
struct tcon_link *tlink = NULL; |
96daf2b09 [CIFS] Rename thr... |
218 |
struct cifs_tcon *pTcon; |
1da177e4c Linux-2.6.12-rc2 |
219 |
|
7ffec3724 cifs: add refcoun... |
220 |
if (file->private_data == NULL) { |
59c55ba1f cifs: don't take ... |
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); cifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); if (cifsFile == NULL) { rc = -ENOMEM; goto error_exit; } file->private_data = cifsFile; cifsFile->tlink = cifs_get_tlink(tlink); pTcon = tlink_tcon(tlink); } else { cifsFile = file->private_data; pTcon = tlink_tcon(cifsFile->tlink); |
7ffec3724 cifs: add refcoun... |
236 |
} |
1da177e4c Linux-2.6.12-rc2 |
237 |
|
4b18f2a9c [CIFS] convert us... |
238 239 |
cifsFile->invalidHandle = true; cifsFile->srch_inf.endOfSearch = false; |
1da177e4c Linux-2.6.12-rc2 |
240 |
|
e6a002964 [PATCH] cifs: cha... |
241 |
full_path = build_path_from_dentry(file->f_path.dentry); |
7ffec3724 cifs: add refcoun... |
242 243 244 245 |
if (full_path == NULL) { rc = -ENOMEM; goto error_exit; } |
1da177e4c Linux-2.6.12-rc2 |
246 |
|
b6b38f704 [CIFS] Neaten cER... |
247 |
cFYI(1, "Full path: %s start at: %lld", full_path, file->f_pos); |
1da177e4c Linux-2.6.12-rc2 |
248 |
|
75cf6bdc5 [PATCH] cifs: Gra... |
249 |
ffirst_retry: |
1da177e4c Linux-2.6.12-rc2 |
250 |
/* test for Unix extensions */ |
c18c842b1 [CIFS] Allow disa... |
251 252 |
/* but now check for them on the share/mount not on the SMB session */ /* if (pTcon->ses->capabilities & CAP_UNIX) { */ |
ad7a2926b [CIFS] reduce che... |
253 |
if (pTcon->unix_ext) |
5bafd7659 [CIFS] Add suppor... |
254 |
cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX; |
ad7a2926b [CIFS] reduce che... |
255 |
else if ((pTcon->ses->capabilities & |
5bafd7659 [CIFS] Add suppor... |
256 257 |
(CAP_NT_SMBS | CAP_NT_FIND)) == 0) { cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD; |
1da177e4c Linux-2.6.12-rc2 |
258 259 260 261 262 |
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO; } else /* not srvinos - BB fixme add check for backlevel? */ { cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO; } |
3870253ef [CIFS] more white... |
263 |
rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls, |
737b758c9 [PATCH] cifs: cha... |
264 |
&cifsFile->netfid, &cifsFile->srch_inf, |
3870253ef [CIFS] more white... |
265 |
cifs_sb->mnt_cifs_flags & |
eafe87012 [CIFS] Fix readdi... |
266 |
CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb)); |
4523cc304 [CIFS] UID/GID ov... |
267 |
if (rc == 0) |
4b18f2a9c [CIFS] convert us... |
268 |
cifsFile->invalidHandle = false; |
e836f015b [CIFS] Remove tra... |
269 |
/* BB add following call to handle readdir on new NTFS symlink errors |
0e0d2cf32 [CIFS] Remove spa... |
270 271 272 |
else if STATUS_STOPPED_ON_SYMLINK call get_symlink_reparse_path and retry with new path */ else if ((rc == -EOPNOTSUPP) && |
75cf6bdc5 [PATCH] cifs: Gra... |
273 274 275 276 |
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM; goto ffirst_retry; } |
7ffec3724 cifs: add refcoun... |
277 |
error_exit: |
1da177e4c Linux-2.6.12-rc2 |
278 |
kfree(full_path); |
7ffec3724 cifs: add refcoun... |
279 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
280 281 282 283 |
return rc; } /* return length of unicode string in bytes */ |
cda0ec6a8 cifs: introduce c... |
284 |
static int cifs_unicode_bytelen(const char *str) |
1da177e4c Linux-2.6.12-rc2 |
285 286 |
{ int len; |
cda0ec6a8 cifs: introduce c... |
287 |
const __le16 *ustr = (const __le16 *)str; |
1da177e4c Linux-2.6.12-rc2 |
288 |
|
3870253ef [CIFS] more white... |
289 |
for (len = 0; len <= PATH_MAX; len++) { |
4523cc304 [CIFS] UID/GID ov... |
290 |
if (ustr[len] == 0) |
1da177e4c Linux-2.6.12-rc2 |
291 292 |
return len << 1; } |
b6b38f704 [CIFS] Neaten cER... |
293 |
cFYI(1, "Unicode string longer than PATH_MAX found"); |
1da177e4c Linux-2.6.12-rc2 |
294 295 |
return len << 1; } |
5bafd7659 [CIFS] Add suppor... |
296 |
static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level) |
1da177e4c Linux-2.6.12-rc2 |
297 |
{ |
3870253ef [CIFS] more white... |
298 |
char *new_entry; |
ad7a2926b [CIFS] reduce che... |
299 |
FILE_DIRECTORY_INFO *pDirInfo = (FILE_DIRECTORY_INFO *)old_entry; |
1da177e4c Linux-2.6.12-rc2 |
300 |
|
4523cc304 [CIFS] UID/GID ov... |
301 |
if (level == SMB_FIND_FILE_INFO_STANDARD) { |
ad7a2926b [CIFS] reduce che... |
302 |
FIND_FILE_STANDARD_INFO *pfData; |
5bafd7659 [CIFS] Add suppor... |
303 304 305 306 307 308 |
pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo; new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) + pfData->FileNameLength; } else new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset); |
b6b38f704 [CIFS] Neaten cER... |
309 |
cFYI(1, "new entry %p old entry %p", new_entry, old_entry); |
1da177e4c Linux-2.6.12-rc2 |
310 |
/* validate that new_entry is not past end of SMB */ |
4523cc304 [CIFS] UID/GID ov... |
311 |
if (new_entry >= end_of_smb) { |
b6b38f704 [CIFS] Neaten cER... |
312 313 |
cERROR(1, "search entry %p began after end of SMB %p old entry %p", new_entry, end_of_smb, old_entry); |
1da177e4c Linux-2.6.12-rc2 |
314 |
return NULL; |
4523cc304 [CIFS] UID/GID ov... |
315 |
} else if (((level == SMB_FIND_FILE_INFO_STANDARD) && |
3870253ef [CIFS] more white... |
316 317 |
(new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb)) || ((level != SMB_FIND_FILE_INFO_STANDARD) && |
5bafd7659 [CIFS] Add suppor... |
318 |
(new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb))) { |
b6b38f704 [CIFS] Neaten cER... |
319 320 |
cERROR(1, "search entry %p extends after end of SMB %p", new_entry, end_of_smb); |
09d1db5c6 [PATCH] cifs: imp... |
321 |
return NULL; |
3870253ef [CIFS] more white... |
322 |
} else |
1da177e4c Linux-2.6.12-rc2 |
323 324 325 |
return new_entry; } |
cda0ec6a8 cifs: introduce c... |
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 |
struct cifs_dirent { const char *name; size_t namelen; u32 resume_key; u64 ino; }; static void cifs_fill_dirent_unix(struct cifs_dirent *de, const FILE_UNIX_INFO *info, bool is_unicode) { de->name = &info->FileName[0]; if (is_unicode) de->namelen = cifs_unicode_bytelen(de->name); else de->namelen = strnlen(de->name, PATH_MAX); de->resume_key = info->ResumeKey; de->ino = le64_to_cpu(info->basic.UniqueId); } static void cifs_fill_dirent_dir(struct cifs_dirent *de, const FILE_DIRECTORY_INFO *info) { de->name = &info->FileName[0]; de->namelen = le32_to_cpu(info->FileNameLength); de->resume_key = info->FileIndex; } static void cifs_fill_dirent_full(struct cifs_dirent *de, const FILE_FULL_DIRECTORY_INFO *info) { de->name = &info->FileName[0]; de->namelen = le32_to_cpu(info->FileNameLength); de->resume_key = info->FileIndex; } static void cifs_fill_dirent_search(struct cifs_dirent *de, const SEARCH_ID_FULL_DIR_INFO *info) { de->name = &info->FileName[0]; de->namelen = le32_to_cpu(info->FileNameLength); de->resume_key = info->FileIndex; de->ino = le64_to_cpu(info->UniqueId); } static void cifs_fill_dirent_both(struct cifs_dirent *de, const FILE_BOTH_DIRECTORY_INFO *info) { de->name = &info->FileName[0]; de->namelen = le32_to_cpu(info->FileNameLength); de->resume_key = info->FileIndex; } static void cifs_fill_dirent_std(struct cifs_dirent *de, const FIND_FILE_STANDARD_INFO *info) { de->name = &info->FileName[0]; /* one byte length, no endianess conversion */ de->namelen = info->FileNameLength; de->resume_key = info->ResumeKey; } static int cifs_fill_dirent(struct cifs_dirent *de, const void *info, u16 level, bool is_unicode) { memset(de, 0, sizeof(*de)); switch (level) { case SMB_FIND_FILE_UNIX: cifs_fill_dirent_unix(de, info, is_unicode); break; case SMB_FIND_FILE_DIRECTORY_INFO: cifs_fill_dirent_dir(de, info); break; case SMB_FIND_FILE_FULL_DIRECTORY_INFO: cifs_fill_dirent_full(de, info); break; case SMB_FIND_FILE_ID_FULL_DIR_INFO: cifs_fill_dirent_search(de, info); break; case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: cifs_fill_dirent_both(de, info); break; case SMB_FIND_FILE_INFO_STANDARD: cifs_fill_dirent_std(de, info); break; default: cFYI(1, "Unknown findfirst level %d", level); return -EINVAL; } return 0; } |
1da177e4c Linux-2.6.12-rc2 |
418 419 420 |
#define UNICODE_DOT cpu_to_le16(0x2e) /* return 0 if no match and 1 for . (current directory) and 2 for .. (parent) */ |
cda0ec6a8 cifs: introduce c... |
421 |
static int cifs_entry_is_dot(struct cifs_dirent *de, bool is_unicode) |
1da177e4c Linux-2.6.12-rc2 |
422 423 |
{ int rc = 0; |
1da177e4c Linux-2.6.12-rc2 |
424 |
|
cda0ec6a8 cifs: introduce c... |
425 426 |
if (!de->name) return 0; |
1da177e4c Linux-2.6.12-rc2 |
427 |
|
cda0ec6a8 cifs: introduce c... |
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 |
if (is_unicode) { __le16 *ufilename = (__le16 *)de->name; if (de->namelen == 2) { /* check for . */ if (ufilename[0] == UNICODE_DOT) rc = 1; } else if (de->namelen == 4) { /* check for .. */ if (ufilename[0] == UNICODE_DOT && ufilename[1] == UNICODE_DOT) rc = 2; } } else /* ASCII */ { if (de->namelen == 1) { if (de->name[0] == '.') rc = 1; } else if (de->namelen == 2) { if (de->name[0] == '.' && de->name[1] == '.') rc = 2; |
1da177e4c Linux-2.6.12-rc2 |
447 448 449 450 451 |
} } return rc; } |
eafe87012 [CIFS] Fix readdi... |
452 453 |
/* Check if directory that we are searching has changed so we can decide whether we can use the cached search results from the previous search */ |
3870253ef [CIFS] more white... |
454 |
static int is_dir_changed(struct file *file) |
eafe87012 [CIFS] Fix readdi... |
455 |
{ |
c33f8d327 [CIFS] Remove unn... |
456 457 |
struct inode *inode = file->f_path.dentry->d_inode; struct cifsInodeInfo *cifsInfo = CIFS_I(inode); |
eafe87012 [CIFS] Fix readdi... |
458 |
|
c33f8d327 [CIFS] Remove unn... |
459 |
if (cifsInfo->time == 0) |
eafe87012 [CIFS] Fix readdi... |
460 461 462 463 464 |
return 1; /* directory was changed, perhaps due to unlink */ else return 0; } |
0752f1522 [CIFS] make sure ... |
465 |
static int cifs_save_resume_key(const char *current_entry, |
eaf35b1ea cifs: use cifs_di... |
466 |
struct cifsFileInfo *file_info) |
0752f1522 [CIFS] make sure ... |
467 |
{ |
eaf35b1ea cifs: use cifs_di... |
468 469 |
struct cifs_dirent de; int rc; |
0752f1522 [CIFS] make sure ... |
470 |
|
eaf35b1ea cifs: use cifs_di... |
471 472 473 474 475 476 |
rc = cifs_fill_dirent(&de, current_entry, file_info->srch_inf.info_level, file_info->srch_inf.unicode); if (!rc) { file_info->srch_inf.presume_name = de.name; file_info->srch_inf.resume_name_len = de.namelen; file_info->srch_inf.resume_key = de.resume_key; |
0752f1522 [CIFS] make sure ... |
477 |
} |
0752f1522 [CIFS] make sure ... |
478 479 |
return rc; } |
1da177e4c Linux-2.6.12-rc2 |
480 481 482 483 484 485 |
/* find the corresponding entry in the search */ /* Note that the SMB server returns search entries for . and .. which complicates logic here if we choose to parse for them and we do not 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) */ |
96daf2b09 [CIFS] Rename thr... |
486 |
static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon, |
3870253ef [CIFS] more white... |
487 |
struct file *file, char **ppCurrentEntry, int *num_to_ret) |
1da177e4c Linux-2.6.12-rc2 |
488 489 490 491 492 |
{ int rc = 0; int pos_in_buf = 0; loff_t first_entry_in_buffer; loff_t index_to_find = file->f_pos; |
3870253ef [CIFS] more white... |
493 |
struct cifsFileInfo *cifsFile = file->private_data; |
1da177e4c Linux-2.6.12-rc2 |
494 |
/* check if index in the buffer */ |
50c2f7538 [CIFS] whitespace... |
495 |
|
3870253ef [CIFS] more white... |
496 |
if ((cifsFile == NULL) || (ppCurrentEntry == NULL) || |
eafe87012 [CIFS] Fix readdi... |
497 |
(num_to_ret == NULL)) |
1da177e4c Linux-2.6.12-rc2 |
498 |
return -ENOENT; |
50c2f7538 [CIFS] whitespace... |
499 |
|
1da177e4c Linux-2.6.12-rc2 |
500 |
*ppCurrentEntry = NULL; |
3870253ef [CIFS] more white... |
501 502 |
first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry - |
1da177e4c Linux-2.6.12-rc2 |
503 |
cifsFile->srch_inf.entries_in_buffer; |
60808233f [CIFS] Readdir fi... |
504 505 506 507 508 509 |
/* if first entry in buf is zero then is first buffer in search response data which means it is likely . and .. will be in this buffer, although some servers do not return . and .. for the root of a drive and for those we need to start two entries earlier */ |
3979877e5 [CIFS] Support fo... |
510 |
dump_cifs_file_struct(file, "In fce "); |
3870253ef [CIFS] more white... |
511 512 |
if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) && is_dir_changed(file)) || |
eafe87012 [CIFS] Fix readdi... |
513 |
(index_to_find < first_entry_in_buffer)) { |
1da177e4c Linux-2.6.12-rc2 |
514 |
/* close and restart search */ |
b6b38f704 [CIFS] Neaten cER... |
515 |
cFYI(1, "search backing up - close and restart search"); |
4477288a1 cifs: convert Glo... |
516 |
spin_lock(&cifs_file_list_lock); |
77c57ec89 [CIFS] don't expl... |
517 518 519 |
if (!cifsFile->srch_inf.endOfSearch && !cifsFile->invalidHandle) { cifsFile->invalidHandle = true; |
4477288a1 cifs: convert Glo... |
520 |
spin_unlock(&cifs_file_list_lock); |
77c57ec89 [CIFS] don't expl... |
521 |
CIFSFindClose(xid, pTcon, cifsFile->netfid); |
ddb4cbfc5 [CIFS] Do not att... |
522 |
} else |
4477288a1 cifs: convert Glo... |
523 |
spin_unlock(&cifs_file_list_lock); |
4523cc304 [CIFS] UID/GID ov... |
524 |
if (cifsFile->srch_inf.ntwrk_buf_start) { |
b6b38f704 [CIFS] Neaten cER... |
525 |
cFYI(1, "freeing SMB ff cache buf on search rewind"); |
4523cc304 [CIFS] UID/GID ov... |
526 |
if (cifsFile->srch_inf.smallBuf) |
d47d7c1a8 [CIFS] CIFS readd... |
527 528 529 530 531 |
cifs_small_buf_release(cifsFile->srch_inf. ntwrk_buf_start); else cifs_buf_release(cifsFile->srch_inf. ntwrk_buf_start); |
76c510ad2 [CIFS] Fix possib... |
532 |
cifsFile->srch_inf.ntwrk_buf_start = NULL; |
1da177e4c Linux-2.6.12-rc2 |
533 |
} |
3870253ef [CIFS] more white... |
534 |
rc = initiate_cifs_search(xid, file); |
4523cc304 [CIFS] UID/GID ov... |
535 |
if (rc) { |
b6b38f704 [CIFS] Neaten cER... |
536 537 |
cFYI(1, "error %d reinitiating a search on rewind", rc); |
1da177e4c Linux-2.6.12-rc2 |
538 539 |
return rc; } |
7023676f9 cifs: check for N... |
540 541 542 543 |
/* FindFirst/Next set last_entry to NULL on malformed reply */ if (cifsFile->srch_inf.last_entry) cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); |
1da177e4c Linux-2.6.12-rc2 |
544 |
} |
3870253ef [CIFS] more white... |
545 |
while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) && |
4b18f2a9c [CIFS] convert us... |
546 |
(rc == 0) && !cifsFile->srch_inf.endOfSearch) { |
b6b38f704 [CIFS] Neaten cER... |
547 |
cFYI(1, "calling findnext2"); |
3870253ef [CIFS] more white... |
548 |
rc = CIFSFindNext(xid, pTcon, cifsFile->netfid, |
dfb7533b5 [CIFS] Add stats ... |
549 |
&cifsFile->srch_inf); |
7023676f9 cifs: check for N... |
550 551 552 553 |
/* FindFirst/Next set last_entry to NULL on malformed reply */ if (cifsFile->srch_inf.last_entry) cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile); |
4523cc304 [CIFS] UID/GID ov... |
554 |
if (rc) |
1da177e4c Linux-2.6.12-rc2 |
555 556 |
return -ENOENT; } |
4523cc304 [CIFS] UID/GID ov... |
557 |
if (index_to_find < cifsFile->srch_inf.index_of_last_entry) { |
1da177e4c Linux-2.6.12-rc2 |
558 559 560 |
/* we found the buffer that contains the entry */ /* scan and find it */ int i; |
3870253ef [CIFS] more white... |
561 562 |
char *current_entry; char *end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + |
1da177e4c Linux-2.6.12-rc2 |
563 564 |
smbCalcSize((struct smb_hdr *) cifsFile->srch_inf.ntwrk_buf_start); |
60808233f [CIFS] Readdir fi... |
565 566 |
current_entry = cifsFile->srch_inf.srch_entries_start; |
1da177e4c Linux-2.6.12-rc2 |
567 568 569 |
first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry - cifsFile->srch_inf.entries_in_buffer; pos_in_buf = index_to_find - first_entry_in_buffer; |
b6b38f704 [CIFS] Neaten cER... |
570 |
cFYI(1, "found entry - pos_in_buf %d", pos_in_buf); |
5bafd7659 [CIFS] Add suppor... |
571 |
|
ad7a2926b [CIFS] reduce che... |
572 |
for (i = 0; (i < (pos_in_buf)) && (current_entry != NULL); i++) { |
dfb7533b5 [CIFS] Add stats ... |
573 |
/* go entry by entry figuring out which is first */ |
3870253ef [CIFS] more white... |
574 |
current_entry = nxt_dir_entry(current_entry, end_of_smb, |
5bafd7659 [CIFS] Add suppor... |
575 |
cifsFile->srch_inf.info_level); |
1da177e4c Linux-2.6.12-rc2 |
576 |
} |
790fe579f [CIFS] more white... |
577 |
if ((current_entry == NULL) && (i < pos_in_buf)) { |
1da177e4c Linux-2.6.12-rc2 |
578 |
/* BB fixme - check if we should flag this error */ |
b6b38f704 [CIFS] Neaten cER... |
579 |
cERROR(1, "reached end of buf searching for pos in buf" |
1da177e4c Linux-2.6.12-rc2 |
580 |
" %d index to find %lld rc %d", |
b6b38f704 [CIFS] Neaten cER... |
581 |
pos_in_buf, index_to_find, rc); |
1da177e4c Linux-2.6.12-rc2 |
582 583 584 585 |
} rc = 0; *ppCurrentEntry = current_entry; } else { |
b6b38f704 [CIFS] Neaten cER... |
586 |
cFYI(1, "index not in buffer - could not findnext into it"); |
1da177e4c Linux-2.6.12-rc2 |
587 588 |
return 0; } |
790fe579f [CIFS] more white... |
589 |
if (pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) { |
b6b38f704 [CIFS] Neaten cER... |
590 |
cFYI(1, "can not return entries pos_in_buf beyond last"); |
1da177e4c Linux-2.6.12-rc2 |
591 592 593 |
*num_to_ret = 0; } else *num_to_ret = cifsFile->srch_inf.entries_in_buffer - pos_in_buf; |
1da177e4c Linux-2.6.12-rc2 |
594 595 596 |
return rc; } |
9feed6f8f cifs: cleanup cif... |
597 598 |
static int cifs_filldir(char *find_entry, struct file *file, filldir_t filldir, void *dirent, char *scratch_buf, unsigned int max_len) |
1da177e4c Linux-2.6.12-rc2 |
599 |
{ |
9feed6f8f cifs: cleanup cif... |
600 601 602 |
struct cifsFileInfo *file_info = file->private_data; struct super_block *sb = file->f_path.dentry->d_sb; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
cda0ec6a8 cifs: introduce c... |
603 |
struct cifs_dirent de = { NULL, }; |
cc0bad755 cifs: add new cif... |
604 |
struct cifs_fattr fattr; |
9feed6f8f cifs: cleanup cif... |
605 606 |
struct dentry *dentry; struct qstr name; |
1da177e4c Linux-2.6.12-rc2 |
607 |
int rc = 0; |
9feed6f8f cifs: cleanup cif... |
608 |
ino_t ino; |
1da177e4c Linux-2.6.12-rc2 |
609 |
|
cda0ec6a8 cifs: introduce c... |
610 611 612 613 |
rc = cifs_fill_dirent(&de, find_entry, file_info->srch_inf.info_level, file_info->srch_inf.unicode); if (rc) return rc; |
5bafd7659 [CIFS] Add suppor... |
614 |
|
f16d59b41 cifs: use cifs_di... |
615 616 617 |
if (de.namelen > max_len) { cERROR(1, "bad search response length %zd past smb end", de.namelen); |
5bafd7659 [CIFS] Add suppor... |
618 619 |
return -EINVAL; } |
60808233f [CIFS] Readdir fi... |
620 |
/* skip . and .. since we added them first */ |
cda0ec6a8 cifs: introduce c... |
621 |
if (cifs_entry_is_dot(&de, file_info->srch_inf.unicode)) |
60808233f [CIFS] Readdir fi... |
622 |
return 0; |
f16d59b41 cifs: use cifs_di... |
623 624 |
if (file_info->srch_inf.unicode) { struct nls_table *nlt = cifs_sb->local_nls; |
1da177e4c Linux-2.6.12-rc2 |
625 |
|
f16d59b41 cifs: use cifs_di... |
626 627 628 629 630 631 632 633 634 635 636 637 |
name.name = scratch_buf; name.len = cifs_from_ucs2((char *)name.name, (__le16 *)de.name, UNICODE_NAME_MAX, min(de.namelen, (size_t)max_len), nlt, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); name.len -= nls_nullsize(nlt); } else { name.name = de.name; name.len = de.namelen; } |
1da177e4c Linux-2.6.12-rc2 |
638 |
|
9feed6f8f cifs: cleanup cif... |
639 640 |
switch (file_info->srch_inf.info_level) { case SMB_FIND_FILE_UNIX: |
cc0bad755 cifs: add new cif... |
641 |
cifs_unix_basic_to_fattr(&fattr, |
9feed6f8f cifs: cleanup cif... |
642 643 644 645 646 647 648 649 650 651 652 653 654 655 |
&((FILE_UNIX_INFO *)find_entry)->basic, cifs_sb); break; case SMB_FIND_FILE_INFO_STANDARD: cifs_std_info_to_fattr(&fattr, (FIND_FILE_STANDARD_INFO *)find_entry, cifs_sb); break; default: cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *)find_entry, cifs_sb); break; } |
b835bebe9 [CIFS] Fix CIFS r... |
656 |
|
f16d59b41 cifs: use cifs_di... |
657 658 |
if (de.ino && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) { fattr.cf_uniqueid = de.ino; |
ec06aedd4 cifs: clean up ha... |
659 |
} else { |
0b8f18e35 cifs: convert cif... |
660 |
fattr.cf_uniqueid = iunique(sb, ROOT_I); |
ec06aedd4 cifs: clean up ha... |
661 662 |
cifs_autodisable_serverino(cifs_sb); } |
50c2f7538 [CIFS] whitespace... |
663 |
|
1b12b9c15 cifs: use Minshal... |
664 665 666 667 668 669 670 671 |
if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) && CIFSCouldBeMFSymlink(&fattr)) /* * trying to get the type and mode can be slow, * so just call those regular files for now, and mark * for reval */ fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; |
0b8f18e35 cifs: convert cif... |
672 |
ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); |
9feed6f8f cifs: cleanup cif... |
673 |
dentry = cifs_readdir_lookup(file->f_dentry, &name, &fattr); |
3870253ef [CIFS] more white... |
674 |
|
9feed6f8f cifs: cleanup cif... |
675 676 |
rc = filldir(dirent, name.name, name.len, file->f_pos, ino, fattr.cf_dtype); |
0b8f18e35 cifs: convert cif... |
677 |
|
9feed6f8f cifs: cleanup cif... |
678 |
dput(dentry); |
1da177e4c Linux-2.6.12-rc2 |
679 680 |
return rc; } |
1da177e4c Linux-2.6.12-rc2 |
681 682 683 684 |
int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) { int rc = 0; |
3870253ef [CIFS] more white... |
685 |
int xid, i; |
96daf2b09 [CIFS] Rename thr... |
686 |
struct cifs_tcon *pTcon; |
1da177e4c Linux-2.6.12-rc2 |
687 |
struct cifsFileInfo *cifsFile = NULL; |
3870253ef [CIFS] more white... |
688 |
char *current_entry; |
1da177e4c Linux-2.6.12-rc2 |
689 |
int num_to_fill = 0; |
3870253ef [CIFS] more white... |
690 |
char *tmp_buf = NULL; |
50c2f7538 [CIFS] whitespace... |
691 |
char *end_of_smb; |
18295796a cifs: fix length ... |
692 |
unsigned int max_len; |
1da177e4c Linux-2.6.12-rc2 |
693 694 |
xid = GetXid(); |
6221ddd0f cifs: handle Find... |
695 696 697 698 699 700 701 702 703 704 |
/* * Ensure FindFirst doesn't fail before doing filldir() for '.' and * '..'. Otherwise we won't be able to notify VFS in case of failure. */ if (file->private_data == NULL) { rc = initiate_cifs_search(xid, file); cFYI(1, "initiate cifs search rc %d", rc); if (rc) goto rddir2_exit; } |
1da177e4c Linux-2.6.12-rc2 |
705 706 |
switch ((int) file->f_pos) { case 0: |
60808233f [CIFS] Readdir fi... |
707 |
if (filldir(direntry, ".", 1, file->f_pos, |
e6a002964 [PATCH] cifs: cha... |
708 |
file->f_path.dentry->d_inode->i_ino, DT_DIR) < 0) { |
b6b38f704 [CIFS] Neaten cER... |
709 |
cERROR(1, "Filldir for current dir failed"); |
1da177e4c Linux-2.6.12-rc2 |
710 711 712 |
rc = -ENOMEM; break; } |
60808233f [CIFS] Readdir fi... |
713 |
file->f_pos++; |
1da177e4c Linux-2.6.12-rc2 |
714 |
case 1: |
60808233f [CIFS] Readdir fi... |
715 |
if (filldir(direntry, "..", 2, file->f_pos, |
b85fd6bdc don't open-code p... |
716 |
parent_ino(file->f_path.dentry), DT_DIR) < 0) { |
b6b38f704 [CIFS] Neaten cER... |
717 |
cERROR(1, "Filldir for parent dir failed"); |
1da177e4c Linux-2.6.12-rc2 |
718 719 720 |
rc = -ENOMEM; break; } |
60808233f [CIFS] Readdir fi... |
721 722 |
file->f_pos++; default: |
3870253ef [CIFS] more white... |
723 724 |
/* 1) If search is active, is in current search buffer? |
1da177e4c Linux-2.6.12-rc2 |
725 726 |
if it before then restart search if after then keep searching till find it */ |
790fe579f [CIFS] more white... |
727 |
if (file->private_data == NULL) { |
1da177e4c Linux-2.6.12-rc2 |
728 729 730 731 732 733 |
rc = -EINVAL; FreeXid(xid); return rc; } cifsFile = file->private_data; if (cifsFile->srch_inf.endOfSearch) { |
790fe579f [CIFS] more white... |
734 |
if (cifsFile->srch_inf.emptyDir) { |
b6b38f704 [CIFS] Neaten cER... |
735 |
cFYI(1, "End of search, empty dir"); |
1da177e4c Linux-2.6.12-rc2 |
736 737 738 739 |
rc = 0; break; } } /* else { |
4b18f2a9c [CIFS] convert us... |
740 |
cifsFile->invalidHandle = true; |
1da177e4c Linux-2.6.12-rc2 |
741 |
CIFSFindClose(xid, pTcon, cifsFile->netfid); |
aaa9bbe03 [CIFS] remove unu... |
742 |
} */ |
1da177e4c Linux-2.6.12-rc2 |
743 |
|
13cfb7334 cifs: have cifsFi... |
744 |
pTcon = tlink_tcon(cifsFile->tlink); |
3870253ef [CIFS] more white... |
745 746 |
rc = find_cifs_entry(xid, pTcon, file, ¤t_entry, &num_to_fill); |
790fe579f [CIFS] more white... |
747 |
if (rc) { |
b6b38f704 [CIFS] Neaten cER... |
748 |
cFYI(1, "fce error %d", rc); |
1da177e4c Linux-2.6.12-rc2 |
749 750 |
goto rddir2_exit; } else if (current_entry != NULL) { |
b6b38f704 [CIFS] Neaten cER... |
751 |
cFYI(1, "entry %lld found", file->f_pos); |
1da177e4c Linux-2.6.12-rc2 |
752 |
} else { |
b6b38f704 [CIFS] Neaten cER... |
753 |
cFYI(1, "could not find entry"); |
1da177e4c Linux-2.6.12-rc2 |
754 755 |
goto rddir2_exit; } |
b6b38f704 [CIFS] Neaten cER... |
756 757 |
cFYI(1, "loop through %d times filling dir for net buf %p", num_to_fill, cifsFile->srch_inf.ntwrk_buf_start); |
5bafd7659 [CIFS] Add suppor... |
758 759 760 |
max_len = smbCalcSize((struct smb_hdr *) cifsFile->srch_inf.ntwrk_buf_start); end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len; |
f58841666 cifs: change cifs... |
761 |
tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL); |
f55fdcca6 fs: cifs: check k... |
762 763 764 765 |
if (tmp_buf == NULL) { rc = -ENOMEM; break; } |
790fe579f [CIFS] more white... |
766 767 |
for (i = 0; (i < num_to_fill) && (rc == 0); i++) { if (current_entry == NULL) { |
1da177e4c Linux-2.6.12-rc2 |
768 |
/* evaluate whether this case is an error */ |
b6b38f704 [CIFS] Neaten cER... |
769 770 |
cERROR(1, "past SMB end, num to fill %d i %d", num_to_fill, i); |
1da177e4c Linux-2.6.12-rc2 |
771 772 |
break; } |
60808233f [CIFS] Readdir fi... |
773 774 |
/* if buggy server returns . and .. late do we want to check for that here? */ |
5bafd7659 [CIFS] Add suppor... |
775 776 |
rc = cifs_filldir(current_entry, file, filldir, direntry, tmp_buf, max_len); |
790fe579f [CIFS] more white... |
777 |
if (rc == -EOVERFLOW) { |
7ca85ba75 [CIFS] Fix readdi... |
778 779 780 |
rc = 0; break; } |
1da177e4c Linux-2.6.12-rc2 |
781 |
file->f_pos++; |
790fe579f [CIFS] more white... |
782 |
if (file->f_pos == |
3979877e5 [CIFS] Support fo... |
783 |
cifsFile->srch_inf.index_of_last_entry) { |
b6b38f704 [CIFS] Neaten cER... |
784 785 |
cFYI(1, "last entry in buf at pos %lld %s", file->f_pos, tmp_buf); |
790fe579f [CIFS] more white... |
786 |
cifs_save_resume_key(current_entry, cifsFile); |
1da177e4c Linux-2.6.12-rc2 |
787 |
break; |
790fe579f [CIFS] more white... |
788 789 |
} else current_entry = |
5bafd7659 [CIFS] Add suppor... |
790 791 |
nxt_dir_entry(current_entry, end_of_smb, cifsFile->srch_inf.info_level); |
1da177e4c Linux-2.6.12-rc2 |
792 793 794 795 796 797 |
} kfree(tmp_buf); break; } /* end switch */ rddir2_exit: |
1da177e4c Linux-2.6.12-rc2 |
798 799 800 |
FreeXid(xid); return rc; } |