Loading...
1/*
2 * fs/cifs/dir.c
3 *
4 * vfs operations that deal with dentries
5 *
6 * Copyright (C) International Business Machines Corp., 2002,2009
7 * Author(s): Steve French (sfrench@us.ibm.com)
8 *
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.
13 *
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.
18 *
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
22 */
23#include <linux/fs.h>
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>
29#include "cifsfs.h"
30#include "cifspdu.h"
31#include "cifsglob.h"
32#include "cifsproto.h"
33#include "cifs_debug.h"
34#include "cifs_fs_sb.h"
35
36static void
37renew_parental_timestamps(struct dentry *direntry)
38{
39 /* BB check if there is a way to get the kernel to do this or if we
40 really need this */
41 do {
42 direntry->d_time = jiffies;
43 direntry = direntry->d_parent;
44 } while (!IS_ROOT(direntry));
45}
46
47/* Note: caller must free return buffer */
48char *
49build_path_from_dentry(struct dentry *direntry)
50{
51 struct dentry *temp;
52 int namelen;
53 int dfsplen;
54 char *full_path;
55 char dirsep;
56 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
57 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
58 unsigned seq;
59
60 dirsep = CIFS_DIR_SEP(cifs_sb);
61 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
62 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
63 else
64 dfsplen = 0;
65cifs_bp_rename_retry:
66 namelen = dfsplen;
67 seq = read_seqbegin(&rename_lock);
68 rcu_read_lock();
69 for (temp = direntry; !IS_ROOT(temp);) {
70 namelen += (1 + temp->d_name.len);
71 temp = temp->d_parent;
72 if (temp == NULL) {
73 cERROR(1, "corrupt dentry");
74 rcu_read_unlock();
75 return NULL;
76 }
77 }
78 rcu_read_unlock();
79
80 full_path = kmalloc(namelen+1, GFP_KERNEL);
81 if (full_path == NULL)
82 return full_path;
83 full_path[namelen] = 0; /* trailing null */
84 rcu_read_lock();
85 for (temp = direntry; !IS_ROOT(temp);) {
86 spin_lock(&temp->d_lock);
87 namelen -= 1 + temp->d_name.len;
88 if (namelen < 0) {
89 spin_unlock(&temp->d_lock);
90 break;
91 } else {
92 full_path[namelen] = dirsep;
93 strncpy(full_path + namelen + 1, temp->d_name.name,
94 temp->d_name.len);
95 cFYI(0, "name: %s", full_path + namelen);
96 }
97 spin_unlock(&temp->d_lock);
98 temp = temp->d_parent;
99 if (temp == NULL) {
100 cERROR(1, "corrupt dentry");
101 rcu_read_unlock();
102 kfree(full_path);
103 return NULL;
104 }
105 }
106 rcu_read_unlock();
107 if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) {
108 cFYI(1, "did not end path lookup where expected. namelen=%d "
109 "dfsplen=%d", namelen, dfsplen);
110 /* presumably this is only possible if racing with a rename
111 of one of the parent directories (we can not lock the dentries
112 above us to prevent this, but retrying should be harmless) */
113 kfree(full_path);
114 goto cifs_bp_rename_retry;
115 }
116 /* DIR_SEP already set for byte 0 / vs \ but not for
117 subsequent slashes in prepath which currently must
118 be entered the right way - not sure if there is an alternative
119 since the '\' is a valid posix character so we can not switch
120 those safely to '/' if any are found in the middle of the prepath */
121 /* BB test paths to Windows with '/' in the midst of prepath */
122
123 if (dfsplen) {
124 strncpy(full_path, tcon->treeName, dfsplen);
125 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
126 int i;
127 for (i = 0; i < dfsplen; i++) {
128 if (full_path[i] == '\\')
129 full_path[i] = '/';
130 }
131 }
132 }
133 return full_path;
134}
135
136/* Inode operations in similar order to how they appear in Linux file fs.h */
137
138int
139cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
140 struct nameidata *nd)
141{
142 int rc = -ENOENT;
143 int xid;
144 int create_options = CREATE_NOT_DIR;
145 __u32 oplock = 0;
146 int oflags;
147 /*
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;
160 FILE_ALL_INFO *buf = NULL;
161 struct inode *newinode = NULL;
162 int disposition = FILE_OVERWRITE_IF;
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 if (tcon->ses->server->oplocks)
175 oplock = REQ_OPLOCK;
176
177 if (nd)
178 oflags = nd->intent.open.file->f_flags;
179 else
180 oflags = O_RDONLY | O_CREAT;
181
182 full_path = build_path_from_dentry(direntry);
183 if (full_path == NULL) {
184 rc = -ENOMEM;
185 goto cifs_create_out;
186 }
187
188 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
189 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
190 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
191 rc = cifs_posix_open(full_path, &newinode,
192 inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
193 /* EIO could indicate that (posix open) operation is not
194 supported, despite what server claimed in capability
195 negotiation. EREMOTE indicates DFS junction, which is not
196 handled in posix open */
197
198 if (rc == 0) {
199 if (newinode == NULL) /* query inode info */
200 goto cifs_create_get_file_info;
201 else /* success, no need to query */
202 goto cifs_create_set_dentry;
203 } else if ((rc != -EIO) && (rc != -EREMOTE) &&
204 (rc != -EOPNOTSUPP) && (rc != -EINVAL))
205 goto cifs_create_out;
206 /* else fallthrough to retry, using older open call, this is
207 case where server does not support this SMB level, and
208 falsely claims capability (also get here for DFS case
209 which should be rare for path not covered on files) */
210 }
211
212 if (nd) {
213 /* if the file is going to stay open, then we
214 need to set the desired access properly */
215 desiredAccess = 0;
216 if (OPEN_FMODE(oflags) & FMODE_READ)
217 desiredAccess |= GENERIC_READ; /* is this too little? */
218 if (OPEN_FMODE(oflags) & FMODE_WRITE)
219 desiredAccess |= GENERIC_WRITE;
220
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 }
230
231 /* BB add processing to set equivalent of mode - e.g. via CreateX with
232 ACLs */
233
234 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
235 if (buf == NULL) {
236 rc = -ENOMEM;
237 goto cifs_create_out;
238 }
239
240 /*
241 * if we're not using unix extensions, see if we need to set
242 * ATTR_READONLY on the create call
243 */
244 if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
245 create_options |= CREATE_OPTION_READONLY;
246
247 if (backup_cred(cifs_sb))
248 create_options |= CREATE_OPEN_BACKUP_INTENT;
249
250 if (tcon->ses->capabilities & CAP_NT_SMBS)
251 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
252 desiredAccess, create_options,
253 &fileHandle, &oplock, buf, cifs_sb->local_nls,
254 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
255 else
256 rc = -EIO; /* no NT SMB support fall into legacy open below */
257
258 if (rc == -EIO) {
259 /* old server, retry the open legacy style */
260 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
261 desiredAccess, create_options,
262 &fileHandle, &oplock, buf, cifs_sb->local_nls,
263 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
264 }
265 if (rc) {
266 cFYI(1, "cifs_create returned 0x%x", rc);
267 goto cifs_create_out;
268 }
269
270 /* If Open reported that we actually created a file
271 then we now have to set the mode if possible */
272 if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
273 struct cifs_unix_set_info_args args = {
274 .mode = mode,
275 .ctime = NO_CHANGE_64,
276 .atime = NO_CHANGE_64,
277 .mtime = NO_CHANGE_64,
278 .device = 0,
279 };
280
281 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
282 args.uid = (__u64) current_fsuid();
283 if (inode->i_mode & S_ISGID)
284 args.gid = (__u64) inode->i_gid;
285 else
286 args.gid = (__u64) current_fsgid();
287 } else {
288 args.uid = NO_CHANGE_64;
289 args.gid = NO_CHANGE_64;
290 }
291 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle,
292 current->tgid);
293 } else {
294 /* BB implement mode setting via Windows security
295 descriptors e.g. */
296 /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
297
298 /* Could set r/o dos attribute if mode & 0222 == 0 */
299 }
300
301cifs_create_get_file_info:
302 /* server might mask mode so we have to query for it */
303 if (tcon->unix_ext)
304 rc = cifs_get_inode_info_unix(&newinode, full_path,
305 inode->i_sb, xid);
306 else {
307 rc = cifs_get_inode_info(&newinode, full_path, buf,
308 inode->i_sb, xid, &fileHandle);
309 if (newinode) {
310 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
311 newinode->i_mode = mode;
312 if ((oplock & CIFS_CREATE_ACTION) &&
313 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
314 newinode->i_uid = current_fsuid();
315 if (inode->i_mode & S_ISGID)
316 newinode->i_gid = inode->i_gid;
317 else
318 newinode->i_gid = current_fsgid();
319 }
320 }
321 }
322
323cifs_create_set_dentry:
324 if (rc == 0)
325 d_instantiate(direntry, newinode);
326 else
327 cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
328
329 if (newinode && nd) {
330 struct cifsFileInfo *pfile_info;
331 struct file *filp;
332
333 filp = lookup_instantiate_filp(nd, direntry, generic_file_open);
334 if (IS_ERR(filp)) {
335 rc = PTR_ERR(filp);
336 CIFSSMBClose(xid, tcon, fileHandle);
337 goto cifs_create_out;
338 }
339
340 pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
341 if (pfile_info == NULL) {
342 fput(filp);
343 CIFSSMBClose(xid, tcon, fileHandle);
344 rc = -ENOMEM;
345 }
346 } else {
347 CIFSSMBClose(xid, tcon, fileHandle);
348 }
349
350cifs_create_out:
351 kfree(buf);
352 kfree(full_path);
353 cifs_put_tlink(tlink);
354 FreeXid(xid);
355 return rc;
356}
357
358int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
359 dev_t device_number)
360{
361 int rc = -EPERM;
362 int xid;
363 int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
364 struct cifs_sb_info *cifs_sb;
365 struct tcon_link *tlink;
366 struct cifs_tcon *pTcon;
367 struct cifs_io_parms io_parms;
368 char *full_path = NULL;
369 struct inode *newinode = NULL;
370 int oplock = 0;
371 u16 fileHandle;
372 FILE_ALL_INFO *buf = NULL;
373 unsigned int bytes_written;
374 struct win_dev *pdev;
375
376 if (!old_valid_dev(device_number))
377 return -EINVAL;
378
379 cifs_sb = CIFS_SB(inode->i_sb);
380 tlink = cifs_sb_tlink(cifs_sb);
381 if (IS_ERR(tlink))
382 return PTR_ERR(tlink);
383
384 pTcon = tlink_tcon(tlink);
385
386 xid = GetXid();
387
388 full_path = build_path_from_dentry(direntry);
389 if (full_path == NULL) {
390 rc = -ENOMEM;
391 goto mknod_out;
392 }
393
394 if (pTcon->unix_ext) {
395 struct cifs_unix_set_info_args args = {
396 .mode = mode & ~current_umask(),
397 .ctime = NO_CHANGE_64,
398 .atime = NO_CHANGE_64,
399 .mtime = NO_CHANGE_64,
400 .device = device_number,
401 };
402 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
403 args.uid = (__u64) current_fsuid();
404 args.gid = (__u64) current_fsgid();
405 } else {
406 args.uid = NO_CHANGE_64;
407 args.gid = NO_CHANGE_64;
408 }
409 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
410 cifs_sb->local_nls,
411 cifs_sb->mnt_cifs_flags &
412 CIFS_MOUNT_MAP_SPECIAL_CHR);
413 if (rc)
414 goto mknod_out;
415
416 rc = cifs_get_inode_info_unix(&newinode, full_path,
417 inode->i_sb, xid);
418
419 if (rc == 0)
420 d_instantiate(direntry, newinode);
421 goto mknod_out;
422 }
423
424 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
425 goto mknod_out;
426
427
428 cFYI(1, "sfu compat create special file");
429
430 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
431 if (buf == NULL) {
432 kfree(full_path);
433 rc = -ENOMEM;
434 FreeXid(xid);
435 return rc;
436 }
437
438 if (backup_cred(cifs_sb))
439 create_options |= CREATE_OPEN_BACKUP_INTENT;
440
441 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
442 GENERIC_WRITE, create_options,
443 &fileHandle, &oplock, buf, cifs_sb->local_nls,
444 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
445 if (rc)
446 goto mknod_out;
447
448 /* BB Do not bother to decode buf since no local inode yet to put
449 * timestamps in, but we can reuse it safely */
450
451 pdev = (struct win_dev *)buf;
452 io_parms.netfid = fileHandle;
453 io_parms.pid = current->tgid;
454 io_parms.tcon = pTcon;
455 io_parms.offset = 0;
456 io_parms.length = sizeof(struct win_dev);
457 if (S_ISCHR(mode)) {
458 memcpy(pdev->type, "IntxCHR", 8);
459 pdev->major =
460 cpu_to_le64(MAJOR(device_number));
461 pdev->minor =
462 cpu_to_le64(MINOR(device_number));
463 rc = CIFSSMBWrite(xid, &io_parms,
464 &bytes_written, (char *)pdev,
465 NULL, 0);
466 } else if (S_ISBLK(mode)) {
467 memcpy(pdev->type, "IntxBLK", 8);
468 pdev->major =
469 cpu_to_le64(MAJOR(device_number));
470 pdev->minor =
471 cpu_to_le64(MINOR(device_number));
472 rc = CIFSSMBWrite(xid, &io_parms,
473 &bytes_written, (char *)pdev,
474 NULL, 0);
475 } /* else if (S_ISFIFO) */
476 CIFSSMBClose(xid, pTcon, fileHandle);
477 d_drop(direntry);
478
479 /* FIXME: add code here to set EAs */
480
481mknod_out:
482 kfree(full_path);
483 kfree(buf);
484 FreeXid(xid);
485 cifs_put_tlink(tlink);
486 return rc;
487}
488
489struct dentry *
490cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
491 struct nameidata *nd)
492{
493 int xid;
494 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;
499 struct tcon_link *tlink;
500 struct cifs_tcon *pTcon;
501 struct cifsFileInfo *cfile;
502 struct inode *newInode = NULL;
503 char *full_path = NULL;
504 struct file *filp;
505
506 xid = GetXid();
507
508 cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
509 parent_dir_inode, direntry->d_name.name, direntry);
510
511 /* check whether path exists */
512
513 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
514 tlink = cifs_sb_tlink(cifs_sb);
515 if (IS_ERR(tlink)) {
516 FreeXid(xid);
517 return (struct dentry *)tlink;
518 }
519 pTcon = tlink_tcon(tlink);
520
521 oplock = pTcon->ses->server->oplocks ? REQ_OPLOCK : 0;
522
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;
545 }
546
547 /* can not grab the rename sem here since it would
548 deadlock in the cases (beginning of sys_rename itself)
549 in which we already have the sb rename sem */
550 full_path = build_path_from_dentry(direntry);
551 if (full_path == NULL) {
552 rc = -ENOMEM;
553 goto lookup_out;
554 }
555
556 if (direntry->d_inode != NULL) {
557 cFYI(1, "non-NULL inode in lookup");
558 } else {
559 cFYI(1, "NULL inode in lookup");
560 }
561 cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
562
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) {
574 if (nd && !(nd->flags & LOOKUP_DIRECTORY) &&
575 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
576 (nd->intent.open.file->f_flags & O_CREAT)) {
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,
615 parent_dir_inode->i_sb, xid, NULL);
616
617 if ((rc == 0) && (newInode != NULL)) {
618 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
638 directories are presumed to be good here */
639 renew_parental_timestamps(direntry);
640
641 } else if (rc == -ENOENT) {
642 rc = 0;
643 direntry->d_time = jiffies;
644 d_add(direntry, NULL);
645 /* if it was once a directory (but how can we tell?) we could do
646 shrink_dcache_parent(direntry); */
647 } else if (rc != -EACCES) {
648 cERROR(1, "Unexpected lookup error %d", rc);
649 /* We special case check for Access Denied - since that
650 is a common return code */
651 }
652
653lookup_out:
654 kfree(full_path);
655 cifs_put_tlink(tlink);
656 FreeXid(xid);
657 return ERR_PTR(rc);
658}
659
660static int
661cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
662{
663 if (nd && (nd->flags & LOOKUP_RCU))
664 return -ECHILD;
665
666 if (direntry->d_inode) {
667 if (cifs_revalidate_dentry(direntry))
668 return 0;
669 else {
670 /*
671 * If the inode wasn't known to be a dfs entry when
672 * the dentry was instantiated, such as when created
673 * via ->readdir(), it needs to be set now since the
674 * attributes will have been updated by
675 * cifs_revalidate_dentry().
676 */
677 if (IS_AUTOMOUNT(direntry->d_inode) &&
678 !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) {
679 spin_lock(&direntry->d_lock);
680 direntry->d_flags |= DCACHE_NEED_AUTOMOUNT;
681 spin_unlock(&direntry->d_lock);
682 }
683
684 return 1;
685 }
686 }
687
688 /*
689 * 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.
691 */
692 if (!nd)
693 return 0;
694
695 /*
696 * Drop the negative dentry, in order to make sure to use the
697 * case sensitive name which is specified by user if this is
698 * for creation.
699 */
700 if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
701 return 0;
702
703 if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
704 return 0;
705
706 return 1;
707}
708
709/* static int cifs_d_delete(struct dentry *direntry)
710{
711 int rc = 0;
712
713 cFYI(1, "In cifs d_delete, name = %s", direntry->d_name.name);
714
715 return rc;
716} */
717
718const struct dentry_operations cifs_dentry_ops = {
719 .d_revalidate = cifs_d_revalidate,
720 .d_automount = cifs_dfs_d_automount,
721/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
722};
723
724static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
725 struct qstr *q)
726{
727 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
728 unsigned long hash;
729 int i;
730
731 hash = init_name_hash();
732 for (i = 0; i < q->len; i++)
733 hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
734 hash);
735 q->hash = end_name_hash(hash);
736
737 return 0;
738}
739
740static int cifs_ci_compare(const struct dentry *parent,
741 const struct inode *pinode,
742 const struct dentry *dentry, const struct inode *inode,
743 unsigned int len, const char *str, const struct qstr *name)
744{
745 struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
746
747 if ((name->len == len) &&
748 (nls_strnicmp(codepage, name->name, str, len) == 0))
749 return 0;
750 return 1;
751}
752
753const struct dentry_operations cifs_ci_dentry_ops = {
754 .d_revalidate = cifs_d_revalidate,
755 .d_hash = cifs_ci_hash,
756 .d_compare = cifs_ci_compare,
757 .d_automount = cifs_dfs_d_automount,
758};
1// SPDX-License-Identifier: LGPL-2.1
2/*
3 *
4 * vfs operations that deal with dentries
5 *
6 * Copyright (C) International Business Machines Corp., 2002,2009
7 * Author(s): Steve French (sfrench@us.ibm.com)
8 *
9 */
10#include <linux/fs.h>
11#include <linux/stat.h>
12#include <linux/slab.h>
13#include <linux/namei.h>
14#include <linux/mount.h>
15#include <linux/file.h>
16#include "cifsfs.h"
17#include "cifspdu.h"
18#include "cifsglob.h"
19#include "cifsproto.h"
20#include "cifs_debug.h"
21#include "cifs_fs_sb.h"
22#include "cifs_unicode.h"
23#include "fs_context.h"
24#include "cifs_ioctl.h"
25#include "fscache.h"
26
27static void
28renew_parental_timestamps(struct dentry *direntry)
29{
30 /* BB check if there is a way to get the kernel to do this or if we
31 really need this */
32 do {
33 cifs_set_time(direntry, jiffies);
34 direntry = direntry->d_parent;
35 } while (!IS_ROOT(direntry));
36}
37
38char *
39cifs_build_path_to_root(struct smb3_fs_context *ctx, struct cifs_sb_info *cifs_sb,
40 struct cifs_tcon *tcon, int add_treename)
41{
42 int pplen = ctx->prepath ? strlen(ctx->prepath) + 1 : 0;
43 int dfsplen;
44 char *full_path = NULL;
45
46 /* if no prefix path, simply set path to the root of share to "" */
47 if (pplen == 0) {
48 full_path = kzalloc(1, GFP_KERNEL);
49 return full_path;
50 }
51
52 if (add_treename)
53 dfsplen = strnlen(tcon->tree_name, MAX_TREE_SIZE + 1);
54 else
55 dfsplen = 0;
56
57 full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
58 if (full_path == NULL)
59 return full_path;
60
61 if (dfsplen)
62 memcpy(full_path, tcon->tree_name, dfsplen);
63 full_path[dfsplen] = CIFS_DIR_SEP(cifs_sb);
64 memcpy(full_path + dfsplen + 1, ctx->prepath, pplen);
65 convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
66 return full_path;
67}
68
69/* Note: caller must free return buffer */
70const char *
71build_path_from_dentry(struct dentry *direntry, void *page)
72{
73 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
74 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
75 bool prefix = tcon->Flags & SMB_SHARE_IS_IN_DFS;
76
77 return build_path_from_dentry_optional_prefix(direntry, page,
78 prefix);
79}
80
81char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
82 const char *tree, int tree_len,
83 bool prefix)
84{
85 int dfsplen;
86 int pplen = 0;
87 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
88 char dirsep = CIFS_DIR_SEP(cifs_sb);
89 char *s;
90
91 if (unlikely(!page))
92 return ERR_PTR(-ENOMEM);
93
94 if (prefix)
95 dfsplen = strnlen(tree, tree_len + 1);
96 else
97 dfsplen = 0;
98
99 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH)
100 pplen = cifs_sb->prepath ? strlen(cifs_sb->prepath) + 1 : 0;
101
102 s = dentry_path_raw(direntry, page, PATH_MAX);
103 if (IS_ERR(s))
104 return s;
105 if (!s[1]) // for root we want "", not "/"
106 s++;
107 if (s < (char *)page + pplen + dfsplen)
108 return ERR_PTR(-ENAMETOOLONG);
109 if (pplen) {
110 cifs_dbg(FYI, "using cifs_sb prepath <%s>\n", cifs_sb->prepath);
111 s -= pplen;
112 memcpy(s + 1, cifs_sb->prepath, pplen - 1);
113 *s = '/';
114 }
115 if (dirsep != '/') {
116 /* BB test paths to Windows with '/' in the midst of prepath */
117 char *p;
118
119 for (p = s; *p; p++)
120 if (*p == '/')
121 *p = dirsep;
122 }
123 if (dfsplen) {
124 s -= dfsplen;
125 memcpy(s, tree, dfsplen);
126 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
127 int i;
128 for (i = 0; i < dfsplen; i++) {
129 if (s[i] == '\\')
130 s[i] = '/';
131 }
132 }
133 }
134 return s;
135}
136
137char *build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
138 bool prefix)
139{
140 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
141 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
142
143 return __build_path_from_dentry_optional_prefix(direntry, page, tcon->tree_name,
144 MAX_TREE_SIZE, prefix);
145}
146
147/*
148 * Don't allow path components longer than the server max.
149 * Don't allow the separator character in a path component.
150 * The VFS will not allow "/", but "\" is allowed by posix.
151 */
152static int
153check_name(struct dentry *direntry, struct cifs_tcon *tcon)
154{
155 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
156 int i;
157
158 if (unlikely(tcon->fsAttrInfo.MaxPathNameComponentLength &&
159 direntry->d_name.len >
160 le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength)))
161 return -ENAMETOOLONG;
162
163 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
164 for (i = 0; i < direntry->d_name.len; i++) {
165 if (direntry->d_name.name[i] == '\\') {
166 cifs_dbg(FYI, "Invalid file name\n");
167 return -EINVAL;
168 }
169 }
170 }
171 return 0;
172}
173
174
175/* Inode operations in similar order to how they appear in Linux file fs.h */
176
177static int cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
178 struct tcon_link *tlink, unsigned int oflags, umode_t mode, __u32 *oplock,
179 struct cifs_fid *fid, struct cifs_open_info_data *buf)
180{
181 int rc = -ENOENT;
182 int create_options = CREATE_NOT_DIR;
183 int desired_access;
184 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
185 struct cifs_tcon *tcon = tlink_tcon(tlink);
186 const char *full_path;
187 void *page = alloc_dentry_path();
188 struct inode *newinode = NULL;
189 int disposition;
190 struct TCP_Server_Info *server = tcon->ses->server;
191 struct cifs_open_parms oparms;
192
193 *oplock = 0;
194 if (tcon->ses->server->oplocks)
195 *oplock = REQ_OPLOCK;
196
197 full_path = build_path_from_dentry(direntry, page);
198 if (IS_ERR(full_path)) {
199 free_dentry_path(page);
200 return PTR_ERR(full_path);
201 }
202
203#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
204 if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open &&
205 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
206 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
207 rc = cifs_posix_open(full_path, &newinode, inode->i_sb, mode,
208 oflags, oplock, &fid->netfid, xid);
209 switch (rc) {
210 case 0:
211 if (newinode == NULL) {
212 /* query inode info */
213 goto cifs_create_get_file_info;
214 }
215
216 if (S_ISDIR(newinode->i_mode)) {
217 CIFSSMBClose(xid, tcon, fid->netfid);
218 iput(newinode);
219 rc = -EISDIR;
220 goto out;
221 }
222
223 if (!S_ISREG(newinode->i_mode)) {
224 /*
225 * The server may allow us to open things like
226 * FIFOs, but the client isn't set up to deal
227 * with that. If it's not a regular file, just
228 * close it and proceed as if it were a normal
229 * lookup.
230 */
231 CIFSSMBClose(xid, tcon, fid->netfid);
232 goto cifs_create_get_file_info;
233 }
234 /* success, no need to query */
235 goto cifs_create_set_dentry;
236
237 case -ENOENT:
238 goto cifs_create_get_file_info;
239
240 case -EIO:
241 case -EINVAL:
242 /*
243 * EIO could indicate that (posix open) operation is not
244 * supported, despite what server claimed in capability
245 * negotiation.
246 *
247 * POSIX open in samba versions 3.3.1 and earlier could
248 * incorrectly fail with invalid parameter.
249 */
250 tcon->broken_posix_open = true;
251 break;
252
253 case -EREMOTE:
254 case -EOPNOTSUPP:
255 /*
256 * EREMOTE indicates DFS junction, which is not handled
257 * in posix open. If either that or op not supported
258 * returned, follow the normal lookup.
259 */
260 break;
261
262 default:
263 goto out;
264 }
265 /*
266 * fallthrough to retry, using older open call, this is case
267 * where server does not support this SMB level, and falsely
268 * claims capability (also get here for DFS case which should be
269 * rare for path not covered on files)
270 */
271 }
272#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
273
274 desired_access = 0;
275 if (OPEN_FMODE(oflags) & FMODE_READ)
276 desired_access |= GENERIC_READ; /* is this too little? */
277 if (OPEN_FMODE(oflags) & FMODE_WRITE)
278 desired_access |= GENERIC_WRITE;
279
280 disposition = FILE_OVERWRITE_IF;
281 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
282 disposition = FILE_CREATE;
283 else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
284 disposition = FILE_OVERWRITE_IF;
285 else if ((oflags & O_CREAT) == O_CREAT)
286 disposition = FILE_OPEN_IF;
287 else
288 cifs_dbg(FYI, "Create flag not set in create function\n");
289
290 /*
291 * BB add processing to set equivalent of mode - e.g. via CreateX with
292 * ACLs
293 */
294
295 if (!server->ops->open) {
296 rc = -ENOSYS;
297 goto out;
298 }
299
300 /*
301 * if we're not using unix extensions, see if we need to set
302 * ATTR_READONLY on the create call
303 */
304 if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
305 create_options |= CREATE_OPTION_READONLY;
306
307 oparms.tcon = tcon;
308 oparms.cifs_sb = cifs_sb;
309 oparms.desired_access = desired_access;
310 oparms.create_options = cifs_create_options(cifs_sb, create_options);
311 oparms.disposition = disposition;
312 oparms.path = full_path;
313 oparms.fid = fid;
314 oparms.reconnect = false;
315 oparms.mode = mode;
316 rc = server->ops->open(xid, &oparms, oplock, buf);
317 if (rc) {
318 cifs_dbg(FYI, "cifs_create returned 0x%x\n", rc);
319 goto out;
320 }
321
322#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
323 /*
324 * If Open reported that we actually created a file then we now have to
325 * set the mode if possible.
326 */
327 if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) {
328 struct cifs_unix_set_info_args args = {
329 .mode = mode,
330 .ctime = NO_CHANGE_64,
331 .atime = NO_CHANGE_64,
332 .mtime = NO_CHANGE_64,
333 .device = 0,
334 };
335
336 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
337 args.uid = current_fsuid();
338 if (inode->i_mode & S_ISGID)
339 args.gid = inode->i_gid;
340 else
341 args.gid = current_fsgid();
342 } else {
343 args.uid = INVALID_UID; /* no change */
344 args.gid = INVALID_GID; /* no change */
345 }
346 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid->netfid,
347 current->tgid);
348 } else {
349 /*
350 * BB implement mode setting via Windows security
351 * descriptors e.g.
352 */
353 /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
354
355 /* Could set r/o dos attribute if mode & 0222 == 0 */
356 }
357
358cifs_create_get_file_info:
359 /* server might mask mode so we have to query for it */
360 if (tcon->unix_ext)
361 rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb,
362 xid);
363 else {
364#else
365 {
366#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
367 /* TODO: Add support for calling POSIX query info here, but passing in fid */
368 rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, xid, fid);
369 if (newinode) {
370 if (server->ops->set_lease_key)
371 server->ops->set_lease_key(newinode, fid);
372 if ((*oplock & CIFS_CREATE_ACTION) && S_ISREG(newinode->i_mode)) {
373 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
374 newinode->i_mode = mode;
375 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
376 newinode->i_uid = current_fsuid();
377 if (inode->i_mode & S_ISGID)
378 newinode->i_gid = inode->i_gid;
379 else
380 newinode->i_gid = current_fsgid();
381 }
382 }
383 }
384 }
385
386#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
387cifs_create_set_dentry:
388#endif /* CONFIG_CIFS_ALLOW_INSECURE_LEGACY */
389 if (rc != 0) {
390 cifs_dbg(FYI, "Create worked, get_inode_info failed rc = %d\n",
391 rc);
392 goto out_err;
393 }
394
395 if (newinode)
396 if (S_ISDIR(newinode->i_mode)) {
397 rc = -EISDIR;
398 goto out_err;
399 }
400
401 d_drop(direntry);
402 d_add(direntry, newinode);
403
404out:
405 free_dentry_path(page);
406 return rc;
407
408out_err:
409 if (server->ops->close)
410 server->ops->close(xid, tcon, fid);
411 if (newinode)
412 iput(newinode);
413 goto out;
414}
415
416int
417cifs_atomic_open(struct inode *inode, struct dentry *direntry,
418 struct file *file, unsigned oflags, umode_t mode)
419{
420 int rc;
421 unsigned int xid;
422 struct tcon_link *tlink;
423 struct cifs_tcon *tcon;
424 struct TCP_Server_Info *server;
425 struct cifs_fid fid = {};
426 struct cifs_pending_open open;
427 __u32 oplock;
428 struct cifsFileInfo *file_info;
429 struct cifs_open_info_data buf = {};
430
431 if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb))))
432 return -EIO;
433
434 /*
435 * Posix open is only called (at lookup time) for file create now. For
436 * opens (rather than creates), because we do not know if it is a file
437 * or directory yet, and current Samba no longer allows us to do posix
438 * open on dirs, we could end up wasting an open call on what turns out
439 * to be a dir. For file opens, we wait to call posix open till
440 * cifs_open. It could be added to atomic_open in the future but the
441 * performance tradeoff of the extra network request when EISDIR or
442 * EACCES is returned would have to be weighed against the 50% reduction
443 * in network traffic in the other paths.
444 */
445 if (!(oflags & O_CREAT)) {
446 struct dentry *res;
447
448 /*
449 * Check for hashed negative dentry. We have already revalidated
450 * the dentry and it is fine. No need to perform another lookup.
451 */
452 if (!d_in_lookup(direntry))
453 return -ENOENT;
454
455 res = cifs_lookup(inode, direntry, 0);
456 if (IS_ERR(res))
457 return PTR_ERR(res);
458
459 return finish_no_open(file, res);
460 }
461
462 xid = get_xid();
463
464 cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
465 inode, direntry, direntry);
466
467 tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
468 if (IS_ERR(tlink)) {
469 rc = PTR_ERR(tlink);
470 goto out_free_xid;
471 }
472
473 tcon = tlink_tcon(tlink);
474
475 rc = check_name(direntry, tcon);
476 if (rc)
477 goto out;
478
479 server = tcon->ses->server;
480
481 if (server->ops->new_lease_key)
482 server->ops->new_lease_key(&fid);
483
484 cifs_add_pending_open(&fid, tlink, &open);
485
486 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
487 &oplock, &fid, &buf);
488 if (rc) {
489 cifs_del_pending_open(&open);
490 goto out;
491 }
492
493 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
494 file->f_mode |= FMODE_CREATED;
495
496 rc = finish_open(file, direntry, generic_file_open);
497 if (rc) {
498 if (server->ops->close)
499 server->ops->close(xid, tcon, &fid);
500 cifs_del_pending_open(&open);
501 goto out;
502 }
503
504 if (file->f_flags & O_DIRECT &&
505 CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
506 if (CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
507 file->f_op = &cifs_file_direct_nobrl_ops;
508 else
509 file->f_op = &cifs_file_direct_ops;
510 }
511
512 file_info = cifs_new_fileinfo(&fid, file, tlink, oplock, buf.symlink_target);
513 if (file_info == NULL) {
514 if (server->ops->close)
515 server->ops->close(xid, tcon, &fid);
516 cifs_del_pending_open(&open);
517 rc = -ENOMEM;
518 goto out;
519 }
520
521 fscache_use_cookie(cifs_inode_cookie(file_inode(file)),
522 file->f_mode & FMODE_WRITE);
523
524out:
525 cifs_put_tlink(tlink);
526out_free_xid:
527 free_xid(xid);
528 cifs_free_open_info(&buf);
529 return rc;
530}
531
532int cifs_create(struct user_namespace *mnt_userns, struct inode *inode,
533 struct dentry *direntry, umode_t mode, bool excl)
534{
535 int rc;
536 unsigned int xid = get_xid();
537 /*
538 * BB below access is probably too much for mknod to request
539 * but we have to do query and setpathinfo so requesting
540 * less could fail (unless we want to request getatr and setatr
541 * permissions (only). At least for POSIX we do not have to
542 * request so much.
543 */
544 unsigned oflags = O_EXCL | O_CREAT | O_RDWR;
545 struct tcon_link *tlink;
546 struct cifs_tcon *tcon;
547 struct TCP_Server_Info *server;
548 struct cifs_fid fid;
549 __u32 oplock;
550 struct cifs_open_info_data buf = {};
551
552 cifs_dbg(FYI, "cifs_create parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
553 inode, direntry, direntry);
554
555 if (unlikely(cifs_forced_shutdown(CIFS_SB(inode->i_sb)))) {
556 rc = -EIO;
557 goto out_free_xid;
558 }
559
560 tlink = cifs_sb_tlink(CIFS_SB(inode->i_sb));
561 rc = PTR_ERR(tlink);
562 if (IS_ERR(tlink))
563 goto out_free_xid;
564
565 tcon = tlink_tcon(tlink);
566 server = tcon->ses->server;
567
568 if (server->ops->new_lease_key)
569 server->ops->new_lease_key(&fid);
570
571 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, &buf);
572 if (!rc && server->ops->close)
573 server->ops->close(xid, tcon, &fid);
574
575 cifs_free_open_info(&buf);
576 cifs_put_tlink(tlink);
577out_free_xid:
578 free_xid(xid);
579 return rc;
580}
581
582int cifs_mknod(struct user_namespace *mnt_userns, struct inode *inode,
583 struct dentry *direntry, umode_t mode, dev_t device_number)
584{
585 int rc = -EPERM;
586 unsigned int xid;
587 struct cifs_sb_info *cifs_sb;
588 struct tcon_link *tlink;
589 struct cifs_tcon *tcon;
590 const char *full_path;
591 void *page;
592
593 if (!old_valid_dev(device_number))
594 return -EINVAL;
595
596 cifs_sb = CIFS_SB(inode->i_sb);
597 if (unlikely(cifs_forced_shutdown(cifs_sb)))
598 return -EIO;
599
600 tlink = cifs_sb_tlink(cifs_sb);
601 if (IS_ERR(tlink))
602 return PTR_ERR(tlink);
603
604 page = alloc_dentry_path();
605 tcon = tlink_tcon(tlink);
606 xid = get_xid();
607
608 full_path = build_path_from_dentry(direntry, page);
609 if (IS_ERR(full_path)) {
610 rc = PTR_ERR(full_path);
611 goto mknod_out;
612 }
613
614 rc = tcon->ses->server->ops->make_node(xid, inode, direntry, tcon,
615 full_path, mode,
616 device_number);
617
618mknod_out:
619 free_dentry_path(page);
620 free_xid(xid);
621 cifs_put_tlink(tlink);
622 return rc;
623}
624
625struct dentry *
626cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
627 unsigned int flags)
628{
629 unsigned int xid;
630 int rc = 0; /* to get around spurious gcc warning, set to zero here */
631 struct cifs_sb_info *cifs_sb;
632 struct tcon_link *tlink;
633 struct cifs_tcon *pTcon;
634 struct inode *newInode = NULL;
635 const char *full_path;
636 void *page;
637 int retry_count = 0;
638
639 xid = get_xid();
640
641 cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
642 parent_dir_inode, direntry, direntry);
643
644 /* check whether path exists */
645
646 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
647 tlink = cifs_sb_tlink(cifs_sb);
648 if (IS_ERR(tlink)) {
649 free_xid(xid);
650 return ERR_CAST(tlink);
651 }
652 pTcon = tlink_tcon(tlink);
653
654 rc = check_name(direntry, pTcon);
655 if (unlikely(rc)) {
656 cifs_put_tlink(tlink);
657 free_xid(xid);
658 return ERR_PTR(rc);
659 }
660
661 /* can not grab the rename sem here since it would
662 deadlock in the cases (beginning of sys_rename itself)
663 in which we already have the sb rename sem */
664 page = alloc_dentry_path();
665 full_path = build_path_from_dentry(direntry, page);
666 if (IS_ERR(full_path)) {
667 cifs_put_tlink(tlink);
668 free_xid(xid);
669 free_dentry_path(page);
670 return ERR_CAST(full_path);
671 }
672
673 if (d_really_is_positive(direntry)) {
674 cifs_dbg(FYI, "non-NULL inode in lookup\n");
675 } else {
676 cifs_dbg(FYI, "NULL inode in lookup\n");
677 }
678 cifs_dbg(FYI, "Full path: %s inode = 0x%p\n",
679 full_path, d_inode(direntry));
680
681again:
682 if (pTcon->posix_extensions)
683 rc = smb311_posix_get_inode_info(&newInode, full_path, parent_dir_inode->i_sb, xid);
684 else if (pTcon->unix_ext) {
685 rc = cifs_get_inode_info_unix(&newInode, full_path,
686 parent_dir_inode->i_sb, xid);
687 } else {
688 rc = cifs_get_inode_info(&newInode, full_path, NULL,
689 parent_dir_inode->i_sb, xid, NULL);
690 }
691
692 if (rc == 0) {
693 /* since paths are not looked up by component - the parent
694 directories are presumed to be good here */
695 renew_parental_timestamps(direntry);
696 } else if (rc == -EAGAIN && retry_count++ < 10) {
697 goto again;
698 } else if (rc == -ENOENT) {
699 cifs_set_time(direntry, jiffies);
700 newInode = NULL;
701 } else {
702 if (rc != -EACCES) {
703 cifs_dbg(FYI, "Unexpected lookup error %d\n", rc);
704 /* We special case check for Access Denied - since that
705 is a common return code */
706 }
707 newInode = ERR_PTR(rc);
708 }
709 free_dentry_path(page);
710 cifs_put_tlink(tlink);
711 free_xid(xid);
712 return d_splice_alias(newInode, direntry);
713}
714
715static int
716cifs_d_revalidate(struct dentry *direntry, unsigned int flags)
717{
718 struct inode *inode;
719 int rc;
720
721 if (flags & LOOKUP_RCU)
722 return -ECHILD;
723
724 if (d_really_is_positive(direntry)) {
725 inode = d_inode(direntry);
726 if ((flags & LOOKUP_REVAL) && !CIFS_CACHE_READ(CIFS_I(inode)))
727 CIFS_I(inode)->time = 0; /* force reval */
728
729 rc = cifs_revalidate_dentry(direntry);
730 if (rc) {
731 cifs_dbg(FYI, "cifs_revalidate_dentry failed with rc=%d", rc);
732 switch (rc) {
733 case -ENOENT:
734 case -ESTALE:
735 /*
736 * Those errors mean the dentry is invalid
737 * (file was deleted or recreated)
738 */
739 return 0;
740 default:
741 /*
742 * Otherwise some unexpected error happened
743 * report it as-is to VFS layer
744 */
745 return rc;
746 }
747 }
748 else {
749 /*
750 * If the inode wasn't known to be a dfs entry when
751 * the dentry was instantiated, such as when created
752 * via ->readdir(), it needs to be set now since the
753 * attributes will have been updated by
754 * cifs_revalidate_dentry().
755 */
756 if (IS_AUTOMOUNT(inode) &&
757 !(direntry->d_flags & DCACHE_NEED_AUTOMOUNT)) {
758 spin_lock(&direntry->d_lock);
759 direntry->d_flags |= DCACHE_NEED_AUTOMOUNT;
760 spin_unlock(&direntry->d_lock);
761 }
762
763 return 1;
764 }
765 }
766
767 /*
768 * This may be nfsd (or something), anyway, we can't see the
769 * intent of this. So, since this can be for creation, drop it.
770 */
771 if (!flags)
772 return 0;
773
774 /*
775 * Drop the negative dentry, in order to make sure to use the
776 * case sensitive name which is specified by user if this is
777 * for creation.
778 */
779 if (flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
780 return 0;
781
782 if (time_after(jiffies, cifs_get_time(direntry) + HZ) || !lookupCacheEnabled)
783 return 0;
784
785 return 1;
786}
787
788/* static int cifs_d_delete(struct dentry *direntry)
789{
790 int rc = 0;
791
792 cifs_dbg(FYI, "In cifs d_delete, name = %pd\n", direntry);
793
794 return rc;
795} */
796
797const struct dentry_operations cifs_dentry_ops = {
798 .d_revalidate = cifs_d_revalidate,
799 .d_automount = cifs_dfs_d_automount,
800/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
801};
802
803static int cifs_ci_hash(const struct dentry *dentry, struct qstr *q)
804{
805 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
806 unsigned long hash;
807 wchar_t c;
808 int i, charlen;
809
810 hash = init_name_hash(dentry);
811 for (i = 0; i < q->len; i += charlen) {
812 charlen = codepage->char2uni(&q->name[i], q->len - i, &c);
813 /* error out if we can't convert the character */
814 if (unlikely(charlen < 0))
815 return charlen;
816 hash = partial_name_hash(cifs_toupper(c), hash);
817 }
818 q->hash = end_name_hash(hash);
819
820 return 0;
821}
822
823static int cifs_ci_compare(const struct dentry *dentry,
824 unsigned int len, const char *str, const struct qstr *name)
825{
826 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
827 wchar_t c1, c2;
828 int i, l1, l2;
829
830 /*
831 * We make the assumption here that uppercase characters in the local
832 * codepage are always the same length as their lowercase counterparts.
833 *
834 * If that's ever not the case, then this will fail to match it.
835 */
836 if (name->len != len)
837 return 1;
838
839 for (i = 0; i < len; i += l1) {
840 /* Convert characters in both strings to UTF-16. */
841 l1 = codepage->char2uni(&str[i], len - i, &c1);
842 l2 = codepage->char2uni(&name->name[i], name->len - i, &c2);
843
844 /*
845 * If we can't convert either character, just declare it to
846 * be 1 byte long and compare the original byte.
847 */
848 if (unlikely(l1 < 0 && l2 < 0)) {
849 if (str[i] != name->name[i])
850 return 1;
851 l1 = 1;
852 continue;
853 }
854
855 /*
856 * Here, we again ass|u|me that upper/lowercase versions of
857 * a character are the same length in the local NLS.
858 */
859 if (l1 != l2)
860 return 1;
861
862 /* Now compare uppercase versions of these characters */
863 if (cifs_toupper(c1) != cifs_toupper(c2))
864 return 1;
865 }
866
867 return 0;
868}
869
870const struct dentry_operations cifs_ci_dentry_ops = {
871 .d_revalidate = cifs_d_revalidate,
872 .d_hash = cifs_ci_hash,
873 .d_compare = cifs_ci_compare,
874 .d_automount = cifs_dfs_d_automount,
875};