aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r--fs/cifs/dir.c448
1 files changed, 245 insertions, 203 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index ec4e9a2a12f8..a180265a10b5 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -133,108 +133,141 @@ cifs_bp_rename_retry:
133 return full_path; 133 return full_path;
134} 134}
135 135
136/*
137 * Don't allow the separator character in a path component.
138 * The VFS will not allow "/", but "\" is allowed by posix.
139 */
140static int
141check_name(struct dentry *direntry)
142{
143 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
144 int i;
145
146 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
147 for (i = 0; i < direntry->d_name.len; i++) {
148 if (direntry->d_name.name[i] == '\\') {
149 cFYI(1, "Invalid file name");
150 return -EINVAL;
151 }
152 }
153 }
154 return 0;
155}
156
157
136/* Inode operations in similar order to how they appear in Linux file fs.h */ 158/* Inode operations in similar order to how they appear in Linux file fs.h */
137 159
138int 160static int cifs_do_create(struct inode *inode, struct dentry *direntry,
139cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, 161 int xid, struct tcon_link *tlink, unsigned oflags,
140 struct nameidata *nd) 162 umode_t mode, __u32 *oplock, __u16 *fileHandle,
163 int *created)
141{ 164{
142 int rc = -ENOENT; 165 int rc = -ENOENT;
143 int xid;
144 int create_options = CREATE_NOT_DIR; 166 int create_options = CREATE_NOT_DIR;
145 __u32 oplock = 0; 167 int desiredAccess;
146 int oflags; 168 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
147 /* 169 struct cifs_tcon *tcon = tlink_tcon(tlink);
148 * BB below access is probably too much for mknod to request
149 * but we have to do query and setpathinfo so requesting
150 * less could fail (unless we want to request getatr and setatr
151 * permissions (only). At least for POSIX we do not have to
152 * request so much.
153 */
154 int desiredAccess = GENERIC_READ | GENERIC_WRITE;
155 __u16 fileHandle;
156 struct cifs_sb_info *cifs_sb;
157 struct tcon_link *tlink;
158 struct cifs_tcon *tcon;
159 char *full_path = NULL; 170 char *full_path = NULL;
160 FILE_ALL_INFO *buf = NULL; 171 FILE_ALL_INFO *buf = NULL;
161 struct inode *newinode = NULL; 172 struct inode *newinode = NULL;
162 int disposition = FILE_OVERWRITE_IF; 173 int disposition;
163
164 xid = GetXid();
165
166 cifs_sb = CIFS_SB(inode->i_sb);
167 tlink = cifs_sb_tlink(cifs_sb);
168 if (IS_ERR(tlink)) {
169 FreeXid(xid);
170 return PTR_ERR(tlink);
171 }
172 tcon = tlink_tcon(tlink);
173 174
175 *oplock = 0;
174 if (tcon->ses->server->oplocks) 176 if (tcon->ses->server->oplocks)
175 oplock = REQ_OPLOCK; 177 *oplock = REQ_OPLOCK;
176
177 if (nd)
178 oflags = nd->intent.open.file->f_flags;
179 else
180 oflags = O_RDONLY | O_CREAT;
181 178
182 full_path = build_path_from_dentry(direntry); 179 full_path = build_path_from_dentry(direntry);
183 if (full_path == NULL) { 180 if (full_path == NULL) {
184 rc = -ENOMEM; 181 rc = -ENOMEM;
185 goto cifs_create_out; 182 goto out;
186 } 183 }
187 184
188 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) && 185 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
186 !tcon->broken_posix_open &&
189 (CIFS_UNIX_POSIX_PATH_OPS_CAP & 187 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
190 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 188 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
191 rc = cifs_posix_open(full_path, &newinode, 189 rc = cifs_posix_open(full_path, &newinode,
192 inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); 190 inode->i_sb, mode, oflags, oplock, fileHandle, xid);
193 /* EIO could indicate that (posix open) operation is not 191 switch (rc) {
194 supported, despite what server claimed in capability 192 case 0:
195 negotiation. EREMOTE indicates DFS junction, which is not 193 if (newinode == NULL) {
196 handled in posix open */ 194 /* query inode info */
197
198 if (rc == 0) {
199 if (newinode == NULL) /* query inode info */
200 goto cifs_create_get_file_info; 195 goto cifs_create_get_file_info;
201 else /* success, no need to query */ 196 }
202 goto cifs_create_set_dentry; 197
203 } else if ((rc != -EIO) && (rc != -EREMOTE) && 198 if (!S_ISREG(newinode->i_mode)) {
204 (rc != -EOPNOTSUPP) && (rc != -EINVAL)) 199 /*
205 goto cifs_create_out; 200 * The server may allow us to open things like
206 /* else fallthrough to retry, using older open call, this is 201 * FIFOs, but the client isn't set up to deal
207 case where server does not support this SMB level, and 202 * with that. If it's not a regular file, just
208 falsely claims capability (also get here for DFS case 203 * close it and proceed as if it were a normal
209 which should be rare for path not covered on files) */ 204 * lookup.
210 } 205 */
206 CIFSSMBClose(xid, tcon, *fileHandle);
207 goto cifs_create_get_file_info;
208 }
209 /* success, no need to query */
210 goto cifs_create_set_dentry;
211
212 case -ENOENT:
213 goto cifs_create_get_file_info;
214
215 case -EIO:
216 case -EINVAL:
217 /*
218 * EIO could indicate that (posix open) operation is not
219 * supported, despite what server claimed in capability
220 * negotiation.
221 *
222 * POSIX open in samba versions 3.3.1 and earlier could
223 * incorrectly fail with invalid parameter.
224 */
225 tcon->broken_posix_open = true;
226 break;
227
228 case -EREMOTE:
229 case -EOPNOTSUPP:
230 /*
231 * EREMOTE indicates DFS junction, which is not handled
232 * in posix open. If either that or op not supported
233 * returned, follow the normal lookup.
234 */
235 break;
211 236
212 if (nd) { 237 default:
213 /* if the file is going to stay open, then we 238 goto out;
214 need to set the desired access properly */ 239 }
215 desiredAccess = 0; 240 /*
216 if (OPEN_FMODE(oflags) & FMODE_READ) 241 * fallthrough to retry, using older open call, this is case
217 desiredAccess |= GENERIC_READ; /* is this too little? */ 242 * where server does not support this SMB level, and falsely
218 if (OPEN_FMODE(oflags) & FMODE_WRITE) 243 * claims capability (also get here for DFS case which should be
219 desiredAccess |= GENERIC_WRITE; 244 * rare for path not covered on files)
220 245 */
221 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
222 disposition = FILE_CREATE;
223 else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
224 disposition = FILE_OVERWRITE_IF;
225 else if ((oflags & O_CREAT) == O_CREAT)
226 disposition = FILE_OPEN_IF;
227 else
228 cFYI(1, "Create flag not set in create function");
229 } 246 }
230 247
248 desiredAccess = 0;
249 if (OPEN_FMODE(oflags) & FMODE_READ)
250 desiredAccess |= GENERIC_READ; /* is this too little? */
251 if (OPEN_FMODE(oflags) & FMODE_WRITE)
252 desiredAccess |= GENERIC_WRITE;
253
254 disposition = FILE_OVERWRITE_IF;
255 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
256 disposition = FILE_CREATE;
257 else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
258 disposition = FILE_OVERWRITE_IF;
259 else if ((oflags & O_CREAT) == O_CREAT)
260 disposition = FILE_OPEN_IF;
261 else
262 cFYI(1, "Create flag not set in create function");
263
231 /* BB add processing to set equivalent of mode - e.g. via CreateX with 264 /* BB add processing to set equivalent of mode - e.g. via CreateX with
232 ACLs */ 265 ACLs */
233 266
234 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); 267 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
235 if (buf == NULL) { 268 if (buf == NULL) {
236 rc = -ENOMEM; 269 rc = -ENOMEM;
237 goto cifs_create_out; 270 goto out;
238 } 271 }
239 272
240 /* 273 /*
@@ -250,7 +283,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
250 if (tcon->ses->capabilities & CAP_NT_SMBS) 283 if (tcon->ses->capabilities & CAP_NT_SMBS)
251 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, 284 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
252 desiredAccess, create_options, 285 desiredAccess, create_options,
253 &fileHandle, &oplock, buf, cifs_sb->local_nls, 286 fileHandle, oplock, buf, cifs_sb->local_nls,
254 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 287 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
255 else 288 else
256 rc = -EIO; /* no NT SMB support fall into legacy open below */ 289 rc = -EIO; /* no NT SMB support fall into legacy open below */
@@ -259,17 +292,17 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
259 /* old server, retry the open legacy style */ 292 /* old server, retry the open legacy style */
260 rc = SMBLegacyOpen(xid, tcon, full_path, disposition, 293 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
261 desiredAccess, create_options, 294 desiredAccess, create_options,
262 &fileHandle, &oplock, buf, cifs_sb->local_nls, 295 fileHandle, oplock, buf, cifs_sb->local_nls,
263 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 296 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
264 } 297 }
265 if (rc) { 298 if (rc) {
266 cFYI(1, "cifs_create returned 0x%x", rc); 299 cFYI(1, "cifs_create returned 0x%x", rc);
267 goto cifs_create_out; 300 goto out;
268 } 301 }
269 302
270 /* If Open reported that we actually created a file 303 /* If Open reported that we actually created a file
271 then we now have to set the mode if possible */ 304 then we now have to set the mode if possible */
272 if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { 305 if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) {
273 struct cifs_unix_set_info_args args = { 306 struct cifs_unix_set_info_args args = {
274 .mode = mode, 307 .mode = mode,
275 .ctime = NO_CHANGE_64, 308 .ctime = NO_CHANGE_64,
@@ -278,6 +311,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
278 .device = 0, 311 .device = 0,
279 }; 312 };
280 313
314 *created |= FILE_CREATED;
281 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 315 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
282 args.uid = (__u64) current_fsuid(); 316 args.uid = (__u64) current_fsuid();
283 if (inode->i_mode & S_ISGID) 317 if (inode->i_mode & S_ISGID)
@@ -288,7 +322,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
288 args.uid = NO_CHANGE_64; 322 args.uid = NO_CHANGE_64;
289 args.gid = NO_CHANGE_64; 323 args.gid = NO_CHANGE_64;
290 } 324 }
291 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle, 325 CIFSSMBUnixSetFileInfo(xid, tcon, &args, *fileHandle,
292 current->tgid); 326 current->tgid);
293 } else { 327 } else {
294 /* BB implement mode setting via Windows security 328 /* BB implement mode setting via Windows security
@@ -305,11 +339,11 @@ cifs_create_get_file_info:
305 inode->i_sb, xid); 339 inode->i_sb, xid);
306 else { 340 else {
307 rc = cifs_get_inode_info(&newinode, full_path, buf, 341 rc = cifs_get_inode_info(&newinode, full_path, buf,
308 inode->i_sb, xid, &fileHandle); 342 inode->i_sb, xid, fileHandle);
309 if (newinode) { 343 if (newinode) {
310 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) 344 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
311 newinode->i_mode = mode; 345 newinode->i_mode = mode;
312 if ((oplock & CIFS_CREATE_ACTION) && 346 if ((*oplock & CIFS_CREATE_ACTION) &&
313 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) { 347 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
314 newinode->i_uid = current_fsuid(); 348 newinode->i_uid = current_fsuid();
315 if (inode->i_mode & S_ISGID) 349 if (inode->i_mode & S_ISGID)
@@ -321,40 +355,139 @@ cifs_create_get_file_info:
321 } 355 }
322 356
323cifs_create_set_dentry: 357cifs_create_set_dentry:
324 if (rc == 0) 358 if (rc != 0) {
325 d_instantiate(direntry, newinode);
326 else
327 cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); 359 cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
360 goto out;
361 }
362 d_drop(direntry);
363 d_add(direntry, newinode);
328 364
329 if (newinode && nd) { 365 /* ENOENT for create? How weird... */
330 struct cifsFileInfo *pfile_info; 366 rc = -ENOENT;
331 struct file *filp; 367 if (!newinode) {
368 CIFSSMBClose(xid, tcon, *fileHandle);
369 goto out;
370 }
371 rc = 0;
332 372
333 filp = lookup_instantiate_filp(nd, direntry, generic_file_open); 373out:
334 if (IS_ERR(filp)) { 374 kfree(buf);
335 rc = PTR_ERR(filp); 375 kfree(full_path);
336 CIFSSMBClose(xid, tcon, fileHandle); 376 return rc;
337 goto cifs_create_out; 377}
338 }
339 378
340 pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock); 379int
341 if (pfile_info == NULL) { 380cifs_atomic_open(struct inode *inode, struct dentry *direntry,
342 fput(filp); 381 struct file *file, unsigned oflags, umode_t mode,
343 CIFSSMBClose(xid, tcon, fileHandle); 382 int *opened)
344 rc = -ENOMEM; 383{
345 } 384 int rc;
346 } else { 385 int xid;
386 struct tcon_link *tlink;
387 struct cifs_tcon *tcon;
388 __u16 fileHandle;
389 __u32 oplock;
390 struct file *filp;
391 struct cifsFileInfo *pfile_info;
392
393 /* Posix open is only called (at lookup time) for file create now. For
394 * opens (rather than creates), because we do not know if it is a file
395 * or directory yet, and current Samba no longer allows us to do posix
396 * open on dirs, we could end up wasting an open call on what turns out
397 * to be a dir. For file opens, we wait to call posix open till
398 * cifs_open. It could be added to atomic_open in the future but the
399 * performance tradeoff of the extra network request when EISDIR or
400 * EACCES is returned would have to be weighed against the 50% reduction
401 * in network traffic in the other paths.
402 */
403 if (!(oflags & O_CREAT)) {
404 struct dentry *res = cifs_lookup(inode, direntry, 0);
405 if (IS_ERR(res))
406 return PTR_ERR(res);
407
408 return finish_no_open(file, res);
409 }
410
411 rc = check_name(direntry);
412 if (rc)
413 return rc;
414
415 xid = GetXid();
416
417 cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
418 inode, direntry->d_name.name, direntry);
419
420 tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
421 filp = ERR_CAST(tlink);
422 if (IS_ERR(tlink))
423 goto free_xid;
424
425 tcon = tlink_tcon(tlink);
426
427 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
428 &oplock, &fileHandle, opened);
429
430 if (rc)
431 goto out;
432
433 rc = finish_open(file, direntry, generic_file_open, opened);
434 if (rc) {
347 CIFSSMBClose(xid, tcon, fileHandle); 435 CIFSSMBClose(xid, tcon, fileHandle);
436 goto out;
348 } 437 }
349 438
350cifs_create_out: 439 pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
351 kfree(buf); 440 if (pfile_info == NULL) {
352 kfree(full_path); 441 CIFSSMBClose(xid, tcon, fileHandle);
442 fput(filp);
443 rc = -ENOMEM;
444 }
445
446out:
353 cifs_put_tlink(tlink); 447 cifs_put_tlink(tlink);
448free_xid:
354 FreeXid(xid); 449 FreeXid(xid);
355 return rc; 450 return rc;
356} 451}
357 452
453int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
454 bool excl)
455{
456 int rc;
457 int xid = GetXid();
458 /*
459 * BB below access is probably too much for mknod to request
460 * but we have to do query and setpathinfo so requesting
461 * less could fail (unless we want to request getatr and setatr
462 * permissions (only). At least for POSIX we do not have to
463 * request so much.
464 */
465 unsigned oflags = O_EXCL | O_CREAT | O_RDWR;
466 struct tcon_link *tlink;
467 __u16 fileHandle;
468 __u32 oplock;
469 int created = FILE_CREATED;
470
471 cFYI(1, "cifs_create parent inode = 0x%p name is: %s and dentry = 0x%p",
472 inode, direntry->d_name.name, direntry);
473
474 tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
475 rc = PTR_ERR(tlink);
476 if (IS_ERR(tlink))
477 goto free_xid;
478
479 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
480 &oplock, &fileHandle, &created);
481 if (!rc)
482 CIFSSMBClose(xid, tlink_tcon(tlink), fileHandle);
483
484 cifs_put_tlink(tlink);
485free_xid:
486 FreeXid(xid);
487
488 return rc;
489}
490
358int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode, 491int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
359 dev_t device_number) 492 dev_t device_number)
360{ 493{
@@ -488,20 +621,15 @@ mknod_out:
488 621
489struct dentry * 622struct dentry *
490cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, 623cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
491 struct nameidata *nd) 624 unsigned int flags)
492{ 625{
493 int xid; 626 int xid;
494 int rc = 0; /* to get around spurious gcc warning, set to zero here */ 627 int rc = 0; /* to get around spurious gcc warning, set to zero here */
495 __u32 oplock;
496 __u16 fileHandle = 0;
497 bool posix_open = false;
498 struct cifs_sb_info *cifs_sb; 628 struct cifs_sb_info *cifs_sb;
499 struct tcon_link *tlink; 629 struct tcon_link *tlink;
500 struct cifs_tcon *pTcon; 630 struct cifs_tcon *pTcon;
501 struct cifsFileInfo *cfile;
502 struct inode *newInode = NULL; 631 struct inode *newInode = NULL;
503 char *full_path = NULL; 632 char *full_path = NULL;
504 struct file *filp;
505 633
506 xid = GetXid(); 634 xid = GetXid();
507 635
@@ -518,31 +646,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
518 } 646 }
519 pTcon = tlink_tcon(tlink); 647 pTcon = tlink_tcon(tlink);
520 648
521 oplock = pTcon->ses->server->oplocks ? REQ_OPLOCK : 0; 649 rc = check_name(direntry);
522 650 if (rc)
523 /*
524 * Don't allow the separator character in a path component.
525 * The VFS will not allow "/", but "\" is allowed by posix.
526 */
527 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
528 int i;
529 for (i = 0; i < direntry->d_name.len; i++)
530 if (direntry->d_name.name[i] == '\\') {
531 cFYI(1, "Invalid file name");
532 rc = -EINVAL;
533 goto lookup_out;
534 }
535 }
536
537 /*
538 * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
539 * the VFS handle the create.
540 */
541 if (nd && (nd->flags & LOOKUP_EXCL)) {
542 d_instantiate(direntry, NULL);
543 rc = 0;
544 goto lookup_out; 651 goto lookup_out;
545 }
546 652
547 /* can not grab the rename sem here since it would 653 /* can not grab the rename sem here since it would
548 deadlock in the cases (beginning of sys_rename itself) 654 deadlock in the cases (beginning of sys_rename itself)
@@ -560,80 +666,16 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
560 } 666 }
561 cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode); 667 cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
562 668
563 /* Posix open is only called (at lookup time) for file create now.
564 * For opens (rather than creates), because we do not know if it
565 * is a file or directory yet, and current Samba no longer allows
566 * us to do posix open on dirs, we could end up wasting an open call
567 * on what turns out to be a dir. For file opens, we wait to call posix
568 * open till cifs_open. It could be added here (lookup) in the future
569 * but the performance tradeoff of the extra network request when EISDIR
570 * or EACCES is returned would have to be weighed against the 50%
571 * reduction in network traffic in the other paths.
572 */
573 if (pTcon->unix_ext) { 669 if (pTcon->unix_ext) {
574 if (nd && !(nd->flags & LOOKUP_DIRECTORY) && 670 rc = cifs_get_inode_info_unix(&newInode, full_path,
575 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && 671 parent_dir_inode->i_sb, xid);
576 (nd->intent.open.file->f_flags & O_CREAT)) { 672 } else {
577 rc = cifs_posix_open(full_path, &newInode,
578 parent_dir_inode->i_sb,
579 nd->intent.open.create_mode,
580 nd->intent.open.file->f_flags, &oplock,
581 &fileHandle, xid);
582 /*
583 * The check below works around a bug in POSIX
584 * open in samba versions 3.3.1 and earlier where
585 * open could incorrectly fail with invalid parameter.
586 * If either that or op not supported returned, follow
587 * the normal lookup.
588 */
589 switch (rc) {
590 case 0:
591 /*
592 * The server may allow us to open things like
593 * FIFOs, but the client isn't set up to deal
594 * with that. If it's not a regular file, just
595 * close it and proceed as if it were a normal
596 * lookup.
597 */
598 if (newInode && !S_ISREG(newInode->i_mode)) {
599 CIFSSMBClose(xid, pTcon, fileHandle);
600 break;
601 }
602 case -ENOENT:
603 posix_open = true;
604 case -EOPNOTSUPP:
605 break;
606 default:
607 pTcon->broken_posix_open = true;
608 }
609 }
610 if (!posix_open)
611 rc = cifs_get_inode_info_unix(&newInode, full_path,
612 parent_dir_inode->i_sb, xid);
613 } else
614 rc = cifs_get_inode_info(&newInode, full_path, NULL, 673 rc = cifs_get_inode_info(&newInode, full_path, NULL,
615 parent_dir_inode->i_sb, xid, NULL); 674 parent_dir_inode->i_sb, xid, NULL);
675 }
616 676
617 if ((rc == 0) && (newInode != NULL)) { 677 if ((rc == 0) && (newInode != NULL)) {
618 d_add(direntry, newInode); 678 d_add(direntry, newInode);
619 if (posix_open) {
620 filp = lookup_instantiate_filp(nd, direntry,
621 generic_file_open);
622 if (IS_ERR(filp)) {
623 rc = PTR_ERR(filp);
624 CIFSSMBClose(xid, pTcon, fileHandle);
625 goto lookup_out;
626 }
627
628 cfile = cifs_new_fileinfo(fileHandle, filp, tlink,
629 oplock);
630 if (cfile == NULL) {
631 fput(filp);
632 CIFSSMBClose(xid, pTcon, fileHandle);
633 rc = -ENOMEM;
634 goto lookup_out;
635 }
636 }
637 /* since paths are not looked up by component - the parent 679 /* since paths are not looked up by component - the parent
638 directories are presumed to be good here */ 680 directories are presumed to be good here */
639 renew_parental_timestamps(direntry); 681 renew_parental_timestamps(direntry);
@@ -658,9 +700,9 @@ lookup_out:
658} 700}
659 701
660static int 702static int
661cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) 703cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
662{ 704{
663 if (nd && (nd->flags & LOOKUP_RCU)) 705 if (flags & LOOKUP_RCU)
664 return -ECHILD; 706 return -ECHILD;
665 707
666 if (direntry->d_inode) { 708 if (direntry->d_inode) {
@@ -689,7 +731,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
689 * This may be nfsd (or something), anyway, we can't see the 731 * This may be nfsd (or something), anyway, we can't see the
690 * intent of this. So, since this can be for creation, drop it. 732 * intent of this. So, since this can be for creation, drop it.
691 */ 733 */
692 if (!nd) 734 if (!flags)
693 return 0; 735 return 0;
694 736
695 /* 737 /*
@@ -697,7 +739,7 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
697 * case sensitive name which is specified by user if this is 739 * case sensitive name which is specified by user if this is
698 * for creation. 740 * for creation.
699 */ 741 */
700 if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET)) 742 if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
701 return 0; 743 return 0;
702 744
703 if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled) 745 if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)