4 * vfs operations that deal with dentries
6 * Copyright (C) International Business Machines Corp., 2002,2009
7 * Author(s): Steve French (sfrench@us.ibm.com)
9 * This library is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as published
11 * by the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
17 * the GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <linux/stat.h>
25 #include <linux/slab.h>
26 #include <linux/namei.h>
27 #include <linux/mount.h>
28 #include <linux/file.h>
32 #include "cifsproto.h"
33 #include "cifs_debug.h"
34 #include "cifs_fs_sb.h"
37 renew_parental_timestamps(struct dentry
*direntry
)
39 /* BB check if there is a way to get the kernel to do this or if we
42 direntry
->d_time
= jiffies
;
43 direntry
= direntry
->d_parent
;
44 } while (!IS_ROOT(direntry
));
47 /* Note: caller must free return buffer */
49 build_path_from_dentry(struct dentry
*direntry
)
56 struct cifs_sb_info
*cifs_sb
= CIFS_SB(direntry
->d_sb
);
57 struct cifs_tcon
*tcon
= cifs_sb_master_tcon(cifs_sb
);
61 return NULL
; /* not much we can do if dentry is freed and
62 we need to reopen the file after it was closed implicitly
63 when the server crashed */
65 dirsep
= CIFS_DIR_SEP(cifs_sb
);
66 if (tcon
->Flags
& SMB_SHARE_IS_IN_DFS
)
67 dfsplen
= strnlen(tcon
->treeName
, MAX_TREE_SIZE
+ 1);
72 seq
= read_seqbegin(&rename_lock
);
74 for (temp
= direntry
; !IS_ROOT(temp
);) {
75 namelen
+= (1 + temp
->d_name
.len
);
76 temp
= temp
->d_parent
;
78 cERROR(1, "corrupt dentry");
85 full_path
= kmalloc(namelen
+1, GFP_KERNEL
);
86 if (full_path
== NULL
)
88 full_path
[namelen
] = 0; /* trailing null */
90 for (temp
= direntry
; !IS_ROOT(temp
);) {
91 spin_lock(&temp
->d_lock
);
92 namelen
-= 1 + temp
->d_name
.len
;
94 spin_unlock(&temp
->d_lock
);
97 full_path
[namelen
] = dirsep
;
98 strncpy(full_path
+ namelen
+ 1, temp
->d_name
.name
,
100 cFYI(0, "name: %s", full_path
+ namelen
);
102 spin_unlock(&temp
->d_lock
);
103 temp
= temp
->d_parent
;
105 cERROR(1, "corrupt dentry");
112 if (namelen
!= dfsplen
|| read_seqretry(&rename_lock
, seq
)) {
113 cERROR(1, "did not end path lookup where expected namelen is %d",
115 /* presumably this is only possible if racing with a rename
116 of one of the parent directories (we can not lock the dentries
117 above us to prevent this, but retrying should be harmless) */
119 goto cifs_bp_rename_retry
;
121 /* DIR_SEP already set for byte 0 / vs \ but not for
122 subsequent slashes in prepath which currently must
123 be entered the right way - not sure if there is an alternative
124 since the '\' is a valid posix character so we can not switch
125 those safely to '/' if any are found in the middle of the prepath */
126 /* BB test paths to Windows with '/' in the midst of prepath */
129 strncpy(full_path
, tcon
->treeName
, dfsplen
);
130 if (cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_POSIX_PATHS
) {
132 for (i
= 0; i
< dfsplen
; i
++) {
133 if (full_path
[i
] == '\\')
141 /* Inode operations in similar order to how they appear in Linux file fs.h */
144 cifs_create(struct inode
*inode
, struct dentry
*direntry
, int mode
,
145 struct nameidata
*nd
)
149 int create_options
= CREATE_NOT_DIR
;
153 * BB below access is probably too much for mknod to request
154 * but we have to do query and setpathinfo so requesting
155 * less could fail (unless we want to request getatr and setatr
156 * permissions (only). At least for POSIX we do not have to
159 int desiredAccess
= GENERIC_READ
| GENERIC_WRITE
;
161 struct cifs_sb_info
*cifs_sb
;
162 struct tcon_link
*tlink
;
163 struct cifs_tcon
*tcon
;
164 char *full_path
= NULL
;
165 FILE_ALL_INFO
*buf
= NULL
;
166 struct inode
*newinode
= NULL
;
167 int disposition
= FILE_OVERWRITE_IF
;
171 cifs_sb
= CIFS_SB(inode
->i_sb
);
172 tlink
= cifs_sb_tlink(cifs_sb
);
175 return PTR_ERR(tlink
);
177 tcon
= tlink_tcon(tlink
);
182 if (nd
&& (nd
->flags
& LOOKUP_OPEN
))
183 oflags
= nd
->intent
.open
.file
->f_flags
;
185 oflags
= O_RDONLY
| O_CREAT
;
187 full_path
= build_path_from_dentry(direntry
);
188 if (full_path
== NULL
) {
190 goto cifs_create_out
;
193 if (tcon
->unix_ext
&& (tcon
->ses
->capabilities
& CAP_UNIX
) &&
194 (CIFS_UNIX_POSIX_PATH_OPS_CAP
&
195 le64_to_cpu(tcon
->fsUnixInfo
.Capability
))) {
196 rc
= cifs_posix_open(full_path
, &newinode
,
197 inode
->i_sb
, mode
, oflags
, &oplock
, &fileHandle
, xid
);
198 /* EIO could indicate that (posix open) operation is not
199 supported, despite what server claimed in capability
200 negotiation. EREMOTE indicates DFS junction, which is not
201 handled in posix open */
204 if (newinode
== NULL
) /* query inode info */
205 goto cifs_create_get_file_info
;
206 else /* success, no need to query */
207 goto cifs_create_set_dentry
;
208 } else if ((rc
!= -EIO
) && (rc
!= -EREMOTE
) &&
209 (rc
!= -EOPNOTSUPP
) && (rc
!= -EINVAL
))
210 goto cifs_create_out
;
211 /* else fallthrough to retry, using older open call, this is
212 case where server does not support this SMB level, and
213 falsely claims capability (also get here for DFS case
214 which should be rare for path not covered on files) */
217 if (nd
&& (nd
->flags
& LOOKUP_OPEN
)) {
218 /* if the file is going to stay open, then we
219 need to set the desired access properly */
221 if (OPEN_FMODE(oflags
) & FMODE_READ
)
222 desiredAccess
|= GENERIC_READ
; /* is this too little? */
223 if (OPEN_FMODE(oflags
) & FMODE_WRITE
)
224 desiredAccess
|= GENERIC_WRITE
;
226 if ((oflags
& (O_CREAT
| O_EXCL
)) == (O_CREAT
| O_EXCL
))
227 disposition
= FILE_CREATE
;
228 else if ((oflags
& (O_CREAT
| O_TRUNC
)) == (O_CREAT
| O_TRUNC
))
229 disposition
= FILE_OVERWRITE_IF
;
230 else if ((oflags
& O_CREAT
) == O_CREAT
)
231 disposition
= FILE_OPEN_IF
;
233 cFYI(1, "Create flag not set in create function");
236 /* BB add processing to set equivalent of mode - e.g. via CreateX with
239 buf
= kmalloc(sizeof(FILE_ALL_INFO
), GFP_KERNEL
);
242 goto cifs_create_out
;
246 * if we're not using unix extensions, see if we need to set
247 * ATTR_READONLY on the create call
249 if (!tcon
->unix_ext
&& (mode
& S_IWUGO
) == 0)
250 create_options
|= CREATE_OPTION_READONLY
;
252 if (tcon
->ses
->capabilities
& CAP_NT_SMBS
)
253 rc
= CIFSSMBOpen(xid
, tcon
, full_path
, disposition
,
254 desiredAccess
, create_options
,
255 &fileHandle
, &oplock
, buf
, cifs_sb
->local_nls
,
256 cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
);
258 rc
= -EIO
; /* no NT SMB support fall into legacy open below */
261 /* old server, retry the open legacy style */
262 rc
= SMBLegacyOpen(xid
, tcon
, full_path
, disposition
,
263 desiredAccess
, create_options
,
264 &fileHandle
, &oplock
, buf
, cifs_sb
->local_nls
,
265 cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
);
268 cFYI(1, "cifs_create returned 0x%x", rc
);
269 goto cifs_create_out
;
272 /* If Open reported that we actually created a file
273 then we now have to set the mode if possible */
274 if ((tcon
->unix_ext
) && (oplock
& CIFS_CREATE_ACTION
)) {
275 struct cifs_unix_set_info_args args
= {
277 .ctime
= NO_CHANGE_64
,
278 .atime
= NO_CHANGE_64
,
279 .mtime
= NO_CHANGE_64
,
283 if (cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_SET_UID
) {
284 args
.uid
= (__u64
) current_fsuid();
285 if (inode
->i_mode
& S_ISGID
)
286 args
.gid
= (__u64
) inode
->i_gid
;
288 args
.gid
= (__u64
) current_fsgid();
290 args
.uid
= NO_CHANGE_64
;
291 args
.gid
= NO_CHANGE_64
;
293 CIFSSMBUnixSetFileInfo(xid
, tcon
, &args
, fileHandle
,
296 /* BB implement mode setting via Windows security
298 /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
300 /* Could set r/o dos attribute if mode & 0222 == 0 */
303 cifs_create_get_file_info
:
304 /* server might mask mode so we have to query for it */
306 rc
= cifs_get_inode_info_unix(&newinode
, full_path
,
309 rc
= cifs_get_inode_info(&newinode
, full_path
, buf
,
310 inode
->i_sb
, xid
, &fileHandle
);
312 if (cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_DYNPERM
)
313 newinode
->i_mode
= mode
;
314 if ((oplock
& CIFS_CREATE_ACTION
) &&
315 (cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_SET_UID
)) {
316 newinode
->i_uid
= current_fsuid();
317 if (inode
->i_mode
& S_ISGID
)
318 newinode
->i_gid
= inode
->i_gid
;
320 newinode
->i_gid
= current_fsgid();
325 cifs_create_set_dentry
:
327 d_instantiate(direntry
, newinode
);
329 cFYI(1, "Create worked, get_inode_info failed rc = %d", rc
);
331 if (newinode
&& nd
&& (nd
->flags
& LOOKUP_OPEN
)) {
332 struct cifsFileInfo
*pfile_info
;
335 filp
= lookup_instantiate_filp(nd
, direntry
, generic_file_open
);
338 CIFSSMBClose(xid
, tcon
, fileHandle
);
339 goto cifs_create_out
;
342 pfile_info
= cifs_new_fileinfo(fileHandle
, filp
, tlink
, oplock
);
343 if (pfile_info
== NULL
) {
345 CIFSSMBClose(xid
, tcon
, fileHandle
);
349 CIFSSMBClose(xid
, tcon
, fileHandle
);
355 cifs_put_tlink(tlink
);
360 int cifs_mknod(struct inode
*inode
, struct dentry
*direntry
, int mode
,
365 struct cifs_sb_info
*cifs_sb
;
366 struct tcon_link
*tlink
;
367 struct cifs_tcon
*pTcon
;
368 struct cifs_io_parms io_parms
;
369 char *full_path
= NULL
;
370 struct inode
*newinode
= NULL
;
373 FILE_ALL_INFO
*buf
= NULL
;
374 unsigned int bytes_written
;
375 struct win_dev
*pdev
;
377 if (!old_valid_dev(device_number
))
380 cifs_sb
= CIFS_SB(inode
->i_sb
);
381 tlink
= cifs_sb_tlink(cifs_sb
);
383 return PTR_ERR(tlink
);
385 pTcon
= tlink_tcon(tlink
);
389 full_path
= build_path_from_dentry(direntry
);
390 if (full_path
== NULL
) {
395 if (pTcon
->unix_ext
) {
396 struct cifs_unix_set_info_args args
= {
397 .mode
= mode
& ~current_umask(),
398 .ctime
= NO_CHANGE_64
,
399 .atime
= NO_CHANGE_64
,
400 .mtime
= NO_CHANGE_64
,
401 .device
= device_number
,
403 if (cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_SET_UID
) {
404 args
.uid
= (__u64
) current_fsuid();
405 args
.gid
= (__u64
) current_fsgid();
407 args
.uid
= NO_CHANGE_64
;
408 args
.gid
= NO_CHANGE_64
;
410 rc
= CIFSSMBUnixSetPathInfo(xid
, pTcon
, full_path
, &args
,
412 cifs_sb
->mnt_cifs_flags
&
413 CIFS_MOUNT_MAP_SPECIAL_CHR
);
417 rc
= cifs_get_inode_info_unix(&newinode
, full_path
,
421 d_instantiate(direntry
, newinode
);
425 if (!(cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_UNX_EMUL
))
429 cFYI(1, "sfu compat create special file");
431 buf
= kmalloc(sizeof(FILE_ALL_INFO
), GFP_KERNEL
);
439 /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */
440 rc
= CIFSSMBOpen(xid
, pTcon
, full_path
, FILE_CREATE
,
441 GENERIC_WRITE
, CREATE_NOT_DIR
| CREATE_OPTION_SPECIAL
,
442 &fileHandle
, &oplock
, buf
, cifs_sb
->local_nls
,
443 cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_MAP_SPECIAL_CHR
);
447 /* BB Do not bother to decode buf since no local inode yet to put
448 * timestamps in, but we can reuse it safely */
450 pdev
= (struct win_dev
*)buf
;
451 io_parms
.netfid
= fileHandle
;
452 io_parms
.pid
= current
->tgid
;
453 io_parms
.tcon
= pTcon
;
455 io_parms
.length
= sizeof(struct win_dev
);
457 memcpy(pdev
->type
, "IntxCHR", 8);
459 cpu_to_le64(MAJOR(device_number
));
461 cpu_to_le64(MINOR(device_number
));
462 rc
= CIFSSMBWrite(xid
, &io_parms
,
463 &bytes_written
, (char *)pdev
,
465 } else if (S_ISBLK(mode
)) {
466 memcpy(pdev
->type
, "IntxBLK", 8);
468 cpu_to_le64(MAJOR(device_number
));
470 cpu_to_le64(MINOR(device_number
));
471 rc
= CIFSSMBWrite(xid
, &io_parms
,
472 &bytes_written
, (char *)pdev
,
474 } /* else if (S_ISFIFO) */
475 CIFSSMBClose(xid
, pTcon
, fileHandle
);
478 /* FIXME: add code here to set EAs */
484 cifs_put_tlink(tlink
);
489 cifs_lookup(struct inode
*parent_dir_inode
, struct dentry
*direntry
,
490 struct nameidata
*nd
)
493 int rc
= 0; /* to get around spurious gcc warning, set to zero here */
495 __u16 fileHandle
= 0;
496 bool posix_open
= false;
497 struct cifs_sb_info
*cifs_sb
;
498 struct tcon_link
*tlink
;
499 struct cifs_tcon
*pTcon
;
500 struct cifsFileInfo
*cfile
;
501 struct inode
*newInode
= NULL
;
502 char *full_path
= NULL
;
507 cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
508 parent_dir_inode
, direntry
->d_name
.name
, direntry
);
510 /* check whether path exists */
512 cifs_sb
= CIFS_SB(parent_dir_inode
->i_sb
);
513 tlink
= cifs_sb_tlink(cifs_sb
);
516 return (struct dentry
*)tlink
;
518 pTcon
= tlink_tcon(tlink
);
521 * Don't allow the separator character in a path component.
522 * The VFS will not allow "/", but "\" is allowed by posix.
524 if (!(cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_POSIX_PATHS
)) {
526 for (i
= 0; i
< direntry
->d_name
.len
; i
++)
527 if (direntry
->d_name
.name
[i
] == '\\') {
528 cFYI(1, "Invalid file name");
535 * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
536 * the VFS handle the create.
538 if (nd
&& (nd
->flags
& LOOKUP_EXCL
)) {
539 d_instantiate(direntry
, NULL
);
544 /* can not grab the rename sem here since it would
545 deadlock in the cases (beginning of sys_rename itself)
546 in which we already have the sb rename sem */
547 full_path
= build_path_from_dentry(direntry
);
548 if (full_path
== NULL
) {
553 if (direntry
->d_inode
!= NULL
) {
554 cFYI(1, "non-NULL inode in lookup");
556 cFYI(1, "NULL inode in lookup");
558 cFYI(1, "Full path: %s inode = 0x%p", full_path
, direntry
->d_inode
);
560 /* Posix open is only called (at lookup time) for file create now.
561 * For opens (rather than creates), because we do not know if it
562 * is a file or directory yet, and current Samba no longer allows
563 * us to do posix open on dirs, we could end up wasting an open call
564 * on what turns out to be a dir. For file opens, we wait to call posix
565 * open till cifs_open. It could be added here (lookup) in the future
566 * but the performance tradeoff of the extra network request when EISDIR
567 * or EACCES is returned would have to be weighed against the 50%
568 * reduction in network traffic in the other paths.
570 if (pTcon
->unix_ext
) {
571 if (nd
&& !(nd
->flags
& (LOOKUP_PARENT
| LOOKUP_DIRECTORY
)) &&
572 (nd
->flags
& LOOKUP_OPEN
) && !pTcon
->broken_posix_open
&&
573 (nd
->intent
.open
.file
->f_flags
& O_CREAT
)) {
574 rc
= cifs_posix_open(full_path
, &newInode
,
575 parent_dir_inode
->i_sb
,
576 nd
->intent
.open
.create_mode
,
577 nd
->intent
.open
.file
->f_flags
, &oplock
,
580 * The check below works around a bug in POSIX
581 * open in samba versions 3.3.1 and earlier where
582 * open could incorrectly fail with invalid parameter.
583 * If either that or op not supported returned, follow
586 if ((rc
== 0) || (rc
== -ENOENT
))
588 else if ((rc
== -EINVAL
) || (rc
!= -EOPNOTSUPP
))
589 pTcon
->broken_posix_open
= true;
592 rc
= cifs_get_inode_info_unix(&newInode
, full_path
,
593 parent_dir_inode
->i_sb
, xid
);
595 rc
= cifs_get_inode_info(&newInode
, full_path
, NULL
,
596 parent_dir_inode
->i_sb
, xid
, NULL
);
598 if ((rc
== 0) && (newInode
!= NULL
)) {
599 d_add(direntry
, newInode
);
601 filp
= lookup_instantiate_filp(nd
, direntry
,
605 CIFSSMBClose(xid
, pTcon
, fileHandle
);
609 cfile
= cifs_new_fileinfo(fileHandle
, filp
, tlink
,
613 CIFSSMBClose(xid
, pTcon
, fileHandle
);
618 /* since paths are not looked up by component - the parent
619 directories are presumed to be good here */
620 renew_parental_timestamps(direntry
);
622 } else if (rc
== -ENOENT
) {
624 direntry
->d_time
= jiffies
;
625 d_add(direntry
, NULL
);
626 /* if it was once a directory (but how can we tell?) we could do
627 shrink_dcache_parent(direntry); */
628 } else if (rc
!= -EACCES
) {
629 cERROR(1, "Unexpected lookup error %d", rc
);
630 /* We special case check for Access Denied - since that
631 is a common return code */
636 cifs_put_tlink(tlink
);
642 cifs_d_revalidate(struct dentry
*direntry
, struct nameidata
*nd
)
644 if (nd
->flags
& LOOKUP_RCU
)
647 if (direntry
->d_inode
) {
648 if (cifs_revalidate_dentry(direntry
))
655 * This may be nfsd (or something), anyway, we can't see the
656 * intent of this. So, since this can be for creation, drop it.
662 * Drop the negative dentry, in order to make sure to use the
663 * case sensitive name which is specified by user if this is
666 if (!(nd
->flags
& (LOOKUP_CONTINUE
| LOOKUP_PARENT
))) {
667 if (nd
->flags
& (LOOKUP_CREATE
| LOOKUP_RENAME_TARGET
))
671 if (time_after(jiffies
, direntry
->d_time
+ HZ
) || !lookupCacheEnabled
)
677 /* static int cifs_d_delete(struct dentry *direntry)
681 cFYI(1, "In cifs d_delete, name = %s", direntry->d_name.name);
686 const struct dentry_operations cifs_dentry_ops
= {
687 .d_revalidate
= cifs_d_revalidate
,
688 .d_automount
= cifs_dfs_d_automount
,
689 /* d_delete: cifs_d_delete, */ /* not needed except for debugging */
692 static int cifs_ci_hash(const struct dentry
*dentry
, const struct inode
*inode
,
695 struct nls_table
*codepage
= CIFS_SB(dentry
->d_sb
)->local_nls
;
699 hash
= init_name_hash();
700 for (i
= 0; i
< q
->len
; i
++)
701 hash
= partial_name_hash(nls_tolower(codepage
, q
->name
[i
]),
703 q
->hash
= end_name_hash(hash
);
708 static int cifs_ci_compare(const struct dentry
*parent
,
709 const struct inode
*pinode
,
710 const struct dentry
*dentry
, const struct inode
*inode
,
711 unsigned int len
, const char *str
, const struct qstr
*name
)
713 struct nls_table
*codepage
= CIFS_SB(pinode
->i_sb
)->local_nls
;
715 if ((name
->len
== len
) &&
716 (nls_strnicmp(codepage
, name
->name
, str
, len
) == 0))
721 const struct dentry_operations cifs_ci_dentry_ops
= {
722 .d_revalidate
= cifs_d_revalidate
,
723 .d_hash
= cifs_ci_hash
,
724 .d_compare
= cifs_ci_compare
,
725 .d_automount
= cifs_dfs_d_automount
,