diff options
Diffstat (limited to 'fs/cifs/dir.c')
-rw-r--r-- | fs/cifs/dir.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 16b21522e8fe..fed55e3c53df 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * vfs operations that deal with dentries | 4 | * vfs operations that deal with dentries |
5 | * | 5 | * |
6 | * Copyright (C) International Business Machines Corp., 2002,2003 | 6 | * Copyright (C) International Business Machines Corp., 2002,2005 |
7 | * Author(s): Steve French (sfrench@us.ibm.com) | 7 | * Author(s): Steve French (sfrench@us.ibm.com) |
8 | * | 8 | * |
9 | * This library is free software; you can redistribute it and/or modify | 9 | * This library is free software; you can redistribute it and/or modify |
@@ -200,8 +200,8 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
200 | (oplock & CIFS_CREATE_ACTION)) | 200 | (oplock & CIFS_CREATE_ACTION)) |
201 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 201 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
202 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, | 202 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, |
203 | (__u64)current->euid, | 203 | (__u64)current->fsuid, |
204 | (__u64)current->egid, | 204 | (__u64)current->fsgid, |
205 | 0 /* dev */, | 205 | 0 /* dev */, |
206 | cifs_sb->local_nls, | 206 | cifs_sb->local_nls, |
207 | cifs_sb->mnt_cifs_flags & | 207 | cifs_sb->mnt_cifs_flags & |
@@ -228,8 +228,15 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
228 | else { | 228 | else { |
229 | rc = cifs_get_inode_info(&newinode, full_path, | 229 | rc = cifs_get_inode_info(&newinode, full_path, |
230 | buf, inode->i_sb,xid); | 230 | buf, inode->i_sb,xid); |
231 | if(newinode) | 231 | if(newinode) { |
232 | newinode->i_mode = mode; | 232 | newinode->i_mode = mode; |
233 | if((oplock & CIFS_CREATE_ACTION) && | ||
234 | (cifs_sb->mnt_cifs_flags & | ||
235 | CIFS_MOUNT_SET_UID)) { | ||
236 | newinode->i_uid = current->fsuid; | ||
237 | newinode->i_gid = current->fsgid; | ||
238 | } | ||
239 | } | ||
233 | } | 240 | } |
234 | 241 | ||
235 | if (rc != 0) { | 242 | if (rc != 0) { |
@@ -318,7 +325,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
318 | else if (pTcon->ses->capabilities & CAP_UNIX) { | 325 | else if (pTcon->ses->capabilities & CAP_UNIX) { |
319 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 326 | if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
320 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 327 | rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
321 | mode,(__u64)current->euid,(__u64)current->egid, | 328 | mode,(__u64)current->fsuid,(__u64)current->fsgid, |
322 | device_number, cifs_sb->local_nls, | 329 | device_number, cifs_sb->local_nls, |
323 | cifs_sb->mnt_cifs_flags & | 330 | cifs_sb->mnt_cifs_flags & |
324 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 331 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
@@ -465,12 +472,20 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
465 | direntry->d_op = &cifs_dentry_ops; | 472 | direntry->d_op = &cifs_dentry_ops; |
466 | d_add(direntry, newInode); | 473 | d_add(direntry, newInode); |
467 | 474 | ||
468 | /* since paths are not looked up by component - the parent directories are presumed to be good here */ | 475 | /* since paths are not looked up by component - the parent |
476 | directories are presumed to be good here */ | ||
469 | renew_parental_timestamps(direntry); | 477 | renew_parental_timestamps(direntry); |
470 | 478 | ||
471 | } else if (rc == -ENOENT) { | 479 | } else if (rc == -ENOENT) { |
472 | rc = 0; | 480 | rc = 0; |
481 | direntry->d_time = jiffies; | ||
482 | if (pTcon->nocase) | ||
483 | direntry->d_op = &cifs_ci_dentry_ops; | ||
484 | else | ||
485 | direntry->d_op = &cifs_dentry_ops; | ||
473 | d_add(direntry, NULL); | 486 | d_add(direntry, NULL); |
487 | /* if it was once a directory (but how can we tell?) we could do | ||
488 | shrink_dcache_parent(direntry); */ | ||
474 | } else { | 489 | } else { |
475 | cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", | 490 | cERROR(1,("Error 0x%x on cifs_get_inode_info in lookup of %s", |
476 | rc,full_path)); | 491 | rc,full_path)); |
@@ -489,21 +504,20 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) | |||
489 | { | 504 | { |
490 | int isValid = 1; | 505 | int isValid = 1; |
491 | 506 | ||
492 | /* lock_kernel(); *//* surely we do not want to lock the kernel for a whole network round trip which could take seconds */ | ||
493 | |||
494 | if (direntry->d_inode) { | 507 | if (direntry->d_inode) { |
495 | if (cifs_revalidate(direntry)) { | 508 | if (cifs_revalidate(direntry)) { |
496 | /* unlock_kernel(); */ | ||
497 | return 0; | 509 | return 0; |
498 | } | 510 | } |
499 | } else { | 511 | } else { |
500 | cFYI(1, | 512 | cFYI(1, ("neg dentry 0x%p name = %s", |
501 | ("In cifs_d_revalidate with no inode but name = %s and dentry 0x%p", | 513 | direntry, direntry->d_name.name)); |
502 | direntry->d_name.name, direntry)); | 514 | if(time_after(jiffies, direntry->d_time + HZ) || |
515 | !lookupCacheEnabled) { | ||
516 | d_drop(direntry); | ||
517 | isValid = 0; | ||
518 | } | ||
503 | } | 519 | } |
504 | 520 | ||
505 | /* unlock_kernel(); */ | ||
506 | |||
507 | return isValid; | 521 | return isValid; |
508 | } | 522 | } |
509 | 523 | ||