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)
57 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
58 struct cifsTconInfo *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 pplen = cifs_sb->prepathlen;
67 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
68 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
72 namelen = pplen + dfsplen;
73 for (temp = direntry; !IS_ROOT(temp);) {
74 namelen += (1 + temp->d_name.len);
75 temp = temp->d_parent;
77 cERROR(1, "corrupt dentry");
82 full_path = kmalloc(namelen+1, GFP_KERNEL);
83 if (full_path == NULL)
85 full_path[namelen] = 0; /* trailing null */
86 for (temp = direntry; !IS_ROOT(temp);) {
87 namelen -= 1 + temp->d_name.len;
91 full_path[namelen] = dirsep;
92 strncpy(full_path + namelen + 1, temp->d_name.name,
94 cFYI(0, "name: %s", full_path + namelen);
96 temp = temp->d_parent;
98 cERROR(1, "corrupt dentry");
103 if (namelen != pplen + dfsplen) {
104 cERROR(1, "did not end path lookup where expected namelen is %d",
106 /* presumably this is only possible if racing with a rename
107 of one of the parent directories (we can not lock the dentries
108 above us to prevent this, but retrying should be harmless) */
110 goto cifs_bp_rename_retry;
112 /* DIR_SEP already set for byte 0 / vs \ but not for
113 subsequent slashes in prepath which currently must
114 be entered the right way - not sure if there is an alternative
115 since the '\' is a valid posix character so we can not switch
116 those safely to '/' if any are found in the middle of the prepath */
117 /* BB test paths to Windows with '/' in the midst of prepath */
120 strncpy(full_path, tcon->treeName, dfsplen);
121 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
123 for (i = 0; i < dfsplen; i++) {
124 if (full_path[i] == '\\')
129 strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen);
133 static void setup_cifs_dentry(struct cifsTconInfo *tcon,
134 struct dentry *direntry,
135 struct inode *newinode)
138 d_set_d_op(direntry, &cifs_ci_dentry_ops);
140 d_set_d_op(direntry, &cifs_dentry_ops);
141 d_instantiate(direntry, newinode);
144 /* Inode operations in similar order to how they appear in Linux file fs.h */
147 cifs_create(struct inode *inode, struct dentry *direntry, int mode,
148 struct nameidata *nd)
152 int create_options = CREATE_NOT_DIR;
156 * BB below access is probably too much for mknod to request
157 * but we have to do query and setpathinfo so requesting
158 * less could fail (unless we want to request getatr and setatr
159 * permissions (only). At least for POSIX we do not have to
162 int desiredAccess = GENERIC_READ | GENERIC_WRITE;
164 struct cifs_sb_info *cifs_sb;
165 struct tcon_link *tlink;
166 struct cifsTconInfo *tcon;
167 char *full_path = NULL;
168 FILE_ALL_INFO *buf = NULL;
169 struct inode *newinode = NULL;
170 int disposition = FILE_OVERWRITE_IF;
174 cifs_sb = CIFS_SB(inode->i_sb);
175 tlink = cifs_sb_tlink(cifs_sb);
178 return PTR_ERR(tlink);
180 tcon = tlink_tcon(tlink);
185 if (nd && (nd->flags & LOOKUP_OPEN))
186 oflags = nd->intent.open.file->f_flags;
188 oflags = O_RDONLY | O_CREAT;
190 full_path = build_path_from_dentry(direntry);
191 if (full_path == NULL) {
193 goto cifs_create_out;
196 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
197 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
198 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
199 rc = cifs_posix_open(full_path, &newinode,
200 inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
201 /* EIO could indicate that (posix open) operation is not
202 supported, despite what server claimed in capability
203 negotation. EREMOTE indicates DFS junction, which is not
204 handled in posix open */
207 if (newinode == NULL) /* query inode info */
208 goto cifs_create_get_file_info;
209 else /* success, no need to query */
210 goto cifs_create_set_dentry;
211 } else if ((rc != -EIO) && (rc != -EREMOTE) &&
212 (rc != -EOPNOTSUPP) && (rc != -EINVAL))
213 goto cifs_create_out;
214 /* else fallthrough to retry, using older open call, this is
215 case where server does not support this SMB level, and
216 falsely claims capability (also get here for DFS case
217 which should be rare for path not covered on files) */
220 if (nd && (nd->flags & LOOKUP_OPEN)) {
221 /* if the file is going to stay open, then we
222 need to set the desired access properly */
224 if (OPEN_FMODE(oflags) & FMODE_READ)
225 desiredAccess |= GENERIC_READ; /* is this too little? */
226 if (OPEN_FMODE(oflags) & FMODE_WRITE)
227 desiredAccess |= GENERIC_WRITE;
229 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
230 disposition = FILE_CREATE;
231 else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
232 disposition = FILE_OVERWRITE_IF;
233 else if ((oflags & O_CREAT) == O_CREAT)
234 disposition = FILE_OPEN_IF;
236 cFYI(1, "Create flag not set in create function");
239 /* BB add processing to set equivalent of mode - e.g. via CreateX with
242 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
245 goto cifs_create_out;
249 * if we're not using unix extensions, see if we need to set
250 * ATTR_READONLY on the create call
252 if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
253 create_options |= CREATE_OPTION_READONLY;
255 if (tcon->ses->capabilities & CAP_NT_SMBS)
256 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
257 desiredAccess, create_options,
258 &fileHandle, &oplock, buf, cifs_sb->local_nls,
259 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
261 rc = -EIO; /* no NT SMB support fall into legacy open below */
264 /* old server, retry the open legacy style */
265 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
266 desiredAccess, create_options,
267 &fileHandle, &oplock, buf, cifs_sb->local_nls,
268 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
271 cFYI(1, "cifs_create returned 0x%x", rc);
272 goto cifs_create_out;
275 /* If Open reported that we actually created a file
276 then we now have to set the mode if possible */
277 if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
278 struct cifs_unix_set_info_args args = {
280 .ctime = NO_CHANGE_64,
281 .atime = NO_CHANGE_64,
282 .mtime = NO_CHANGE_64,
286 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
287 args.uid = (__u64) current_fsuid();
288 if (inode->i_mode & S_ISGID)
289 args.gid = (__u64) inode->i_gid;
291 args.gid = (__u64) current_fsgid();
293 args.uid = NO_CHANGE_64;
294 args.gid = NO_CHANGE_64;
296 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle,
299 /* BB implement mode setting via Windows security
301 /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
303 /* Could set r/o dos attribute if mode & 0222 == 0 */
306 cifs_create_get_file_info:
307 /* server might mask mode so we have to query for it */
309 rc = cifs_get_inode_info_unix(&newinode, full_path,
312 rc = cifs_get_inode_info(&newinode, full_path, buf,
313 inode->i_sb, xid, &fileHandle);
315 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
316 newinode->i_mode = mode;
317 if ((oplock & CIFS_CREATE_ACTION) &&
318 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
319 newinode->i_uid = current_fsuid();
320 if (inode->i_mode & S_ISGID)
321 newinode->i_gid = inode->i_gid;
323 newinode->i_gid = current_fsgid();
328 cifs_create_set_dentry:
330 setup_cifs_dentry(tcon, direntry, newinode);
332 cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
334 if (newinode && nd && (nd->flags & LOOKUP_OPEN)) {
335 struct cifsFileInfo *pfile_info;
338 filp = lookup_instantiate_filp(nd, direntry, generic_file_open);
341 CIFSSMBClose(xid, tcon, fileHandle);
342 goto cifs_create_out;
345 pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
346 if (pfile_info == NULL) {
348 CIFSSMBClose(xid, tcon, fileHandle);
352 CIFSSMBClose(xid, tcon, fileHandle);
358 cifs_put_tlink(tlink);
363 int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
368 struct cifs_sb_info *cifs_sb;
369 struct tcon_link *tlink;
370 struct cifsTconInfo *pTcon;
371 char *full_path = NULL;
372 struct inode *newinode = NULL;
375 FILE_ALL_INFO *buf = NULL;
376 unsigned int bytes_written;
377 struct win_dev *pdev;
379 if (!old_valid_dev(device_number))
382 cifs_sb = CIFS_SB(inode->i_sb);
383 tlink = cifs_sb_tlink(cifs_sb);
385 return PTR_ERR(tlink);
387 pTcon = tlink_tcon(tlink);
391 full_path = build_path_from_dentry(direntry);
392 if (full_path == NULL) {
397 if (pTcon->unix_ext) {
398 struct cifs_unix_set_info_args args = {
399 .mode = mode & ~current_umask(),
400 .ctime = NO_CHANGE_64,
401 .atime = NO_CHANGE_64,
402 .mtime = NO_CHANGE_64,
403 .device = device_number,
405 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
406 args.uid = (__u64) current_fsuid();
407 args.gid = (__u64) current_fsgid();
409 args.uid = NO_CHANGE_64;
410 args.gid = NO_CHANGE_64;
412 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
414 cifs_sb->mnt_cifs_flags &
415 CIFS_MOUNT_MAP_SPECIAL_CHR);
419 rc = cifs_get_inode_info_unix(&newinode, full_path,
422 d_set_d_op(direntry, &cifs_ci_dentry_ops);
424 d_set_d_op(direntry, &cifs_dentry_ops);
427 d_instantiate(direntry, newinode);
431 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
435 cFYI(1, "sfu compat create special file");
437 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
445 /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */
446 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
447 GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
448 &fileHandle, &oplock, buf, cifs_sb->local_nls,
449 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
453 /* BB Do not bother to decode buf since no local inode yet to put
454 * timestamps in, but we can reuse it safely */
456 pdev = (struct win_dev *)buf;
458 memcpy(pdev->type, "IntxCHR", 8);
460 cpu_to_le64(MAJOR(device_number));
462 cpu_to_le64(MINOR(device_number));
463 rc = CIFSSMBWrite(xid, pTcon,
465 sizeof(struct win_dev),
466 0, &bytes_written, (char *)pdev,
468 } else if (S_ISBLK(mode)) {
469 memcpy(pdev->type, "IntxBLK", 8);
471 cpu_to_le64(MAJOR(device_number));
473 cpu_to_le64(MINOR(device_number));
474 rc = CIFSSMBWrite(xid, pTcon,
476 sizeof(struct win_dev),
477 0, &bytes_written, (char *)pdev,
479 } /* else if (S_ISFIFO) */
480 CIFSSMBClose(xid, pTcon, fileHandle);
483 /* FIXME: add code here to set EAs */
489 cifs_put_tlink(tlink);
494 cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
495 struct nameidata *nd)
498 int rc = 0; /* to get around spurious gcc warning, set to zero here */
500 __u16 fileHandle = 0;
501 bool posix_open = false;
502 struct cifs_sb_info *cifs_sb;
503 struct tcon_link *tlink;
504 struct cifsTconInfo *pTcon;
505 struct cifsFileInfo *cfile;
506 struct inode *newInode = NULL;
507 char *full_path = NULL;
512 cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
513 parent_dir_inode, direntry->d_name.name, direntry);
515 /* check whether path exists */
517 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
518 tlink = cifs_sb_tlink(cifs_sb);
521 return (struct dentry *)tlink;
523 pTcon = tlink_tcon(tlink);
526 * Don't allow the separator character in a path component.
527 * The VFS will not allow "/", but "\" is allowed by posix.
529 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
531 for (i = 0; i < direntry->d_name.len; i++)
532 if (direntry->d_name.name[i] == '\\') {
533 cFYI(1, "Invalid file name");
540 * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
541 * the VFS handle the create.
543 if (nd && (nd->flags & LOOKUP_EXCL)) {
544 d_instantiate(direntry, NULL);
549 /* can not grab the rename sem here since it would
550 deadlock in the cases (beginning of sys_rename itself)
551 in which we already have the sb rename sem */
552 full_path = build_path_from_dentry(direntry);
553 if (full_path == NULL) {
558 if (direntry->d_inode != NULL) {
559 cFYI(1, "non-NULL inode in lookup");
561 cFYI(1, "NULL inode in lookup");
563 cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
565 /* Posix open is only called (at lookup time) for file create now.
566 * For opens (rather than creates), because we do not know if it
567 * is a file or directory yet, and current Samba no longer allows
568 * us to do posix open on dirs, we could end up wasting an open call
569 * on what turns out to be a dir. For file opens, we wait to call posix
570 * open till cifs_open. It could be added here (lookup) in the future
571 * but the performance tradeoff of the extra network request when EISDIR
572 * or EACCES is returned would have to be weighed against the 50%
573 * reduction in network traffic in the other paths.
575 if (pTcon->unix_ext) {
576 if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
577 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
578 (nd->intent.open.file->f_flags & O_CREAT)) {
579 rc = cifs_posix_open(full_path, &newInode,
580 parent_dir_inode->i_sb,
581 nd->intent.open.create_mode,
582 nd->intent.open.file->f_flags, &oplock,
585 * The check below works around a bug in POSIX
586 * open in samba versions 3.3.1 and earlier where
587 * open could incorrectly fail with invalid parameter.
588 * If either that or op not supported returned, follow
591 if ((rc == 0) || (rc == -ENOENT))
593 else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
594 pTcon->broken_posix_open = true;
597 rc = cifs_get_inode_info_unix(&newInode, full_path,
598 parent_dir_inode->i_sb, xid);
600 rc = cifs_get_inode_info(&newInode, full_path, NULL,
601 parent_dir_inode->i_sb, xid, NULL);
603 if ((rc == 0) && (newInode != NULL)) {
605 d_set_d_op(direntry, &cifs_ci_dentry_ops);
607 d_set_d_op(direntry, &cifs_dentry_ops);
608 d_add(direntry, newInode);
610 filp = lookup_instantiate_filp(nd, direntry,
614 CIFSSMBClose(xid, pTcon, fileHandle);
618 cfile = cifs_new_fileinfo(fileHandle, filp, tlink,
622 CIFSSMBClose(xid, pTcon, fileHandle);
627 /* since paths are not looked up by component - the parent
628 directories are presumed to be good here */
629 renew_parental_timestamps(direntry);
631 } else if (rc == -ENOENT) {
633 direntry->d_time = jiffies;
635 d_set_d_op(direntry, &cifs_ci_dentry_ops);
637 d_set_d_op(direntry, &cifs_dentry_ops);
638 d_add(direntry, NULL);
639 /* if it was once a directory (but how can we tell?) we could do
640 shrink_dcache_parent(direntry); */
641 } else if (rc != -EACCES) {
642 cERROR(1, "Unexpected lookup error %d", rc);
643 /* We special case check for Access Denied - since that
644 is a common return code */
649 cifs_put_tlink(tlink);
655 cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
657 if (nd->flags & LOOKUP_RCU)
660 if (direntry->d_inode) {
661 if (cifs_revalidate_dentry(direntry))
668 * This may be nfsd (or something), anyway, we can't see the
669 * intent of this. So, since this can be for creation, drop it.
675 * Drop the negative dentry, in order to make sure to use the
676 * case sensitive name which is specified by user if this is
679 if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) {
680 if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
684 if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
690 /* static int cifs_d_delete(struct dentry *direntry)
694 cFYI(1, "In cifs d_delete, name = %s", direntry->d_name.name);
699 const struct dentry_operations cifs_dentry_ops = {
700 .d_revalidate = cifs_d_revalidate,
701 /* d_delete: cifs_d_delete, */ /* not needed except for debugging */
704 static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
707 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
711 hash = init_name_hash();
712 for (i = 0; i < q->len; i++)
713 hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
715 q->hash = end_name_hash(hash);
720 static int cifs_ci_compare(const struct dentry *parent,
721 const struct inode *pinode,
722 const struct dentry *dentry, const struct inode *inode,
723 unsigned int len, const char *str, const struct qstr *name)
725 struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
727 if ((name->len == len) &&
728 (nls_strnicmp(codepage, name->name, str, len) == 0))
733 const struct dentry_operations cifs_ci_dentry_ops = {
734 .d_revalidate = cifs_d_revalidate,
735 .d_hash = cifs_ci_hash,
736 .d_compare = cifs_ci_compare,