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 
36 static void
renew_parental_timestamps(struct dentry * direntry)37 renew_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 */
48 char *
build_path_from_dentry(struct dentry * direntry)49 build_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;
65 cifs_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 
138 int
cifs_create(struct inode * inode,struct dentry * direntry,umode_t mode,struct nameidata * nd)139 cifs_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 (enable_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 
301 cifs_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 
323 cifs_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 
350 cifs_create_out:
351 	kfree(buf);
352 	kfree(full_path);
353 	cifs_put_tlink(tlink);
354 	FreeXid(xid);
355 	return rc;
356 }
357 
cifs_mknod(struct inode * inode,struct dentry * direntry,umode_t mode,dev_t device_number)358 int 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 
481 mknod_out:
482 	kfree(full_path);
483 	kfree(buf);
484 	FreeXid(xid);
485 	cifs_put_tlink(tlink);
486 	return rc;
487 }
488 
489 struct dentry *
cifs_lookup(struct inode * parent_dir_inode,struct dentry * direntry,struct nameidata * nd)490 cifs_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 = enable_oplocks ? REQ_OPLOCK : 0;
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 	/*
522 	 * Don't allow the separator character in a path component.
523 	 * The VFS will not allow "/", but "\" is allowed by posix.
524 	 */
525 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
526 		int i;
527 		for (i = 0; i < direntry->d_name.len; i++)
528 			if (direntry->d_name.name[i] == '\\') {
529 				cFYI(1, "Invalid file name");
530 				rc = -EINVAL;
531 				goto lookup_out;
532 			}
533 	}
534 
535 	/*
536 	 * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
537 	 * the VFS handle the create.
538 	 */
539 	if (nd && (nd->flags & LOOKUP_EXCL)) {
540 		d_instantiate(direntry, NULL);
541 		rc = 0;
542 		goto lookup_out;
543 	}
544 
545 	/* can not grab the rename sem here since it would
546 	deadlock in the cases (beginning of sys_rename itself)
547 	in which we already have the sb rename sem */
548 	full_path = build_path_from_dentry(direntry);
549 	if (full_path == NULL) {
550 		rc = -ENOMEM;
551 		goto lookup_out;
552 	}
553 
554 	if (direntry->d_inode != NULL) {
555 		cFYI(1, "non-NULL inode in lookup");
556 	} else {
557 		cFYI(1, "NULL inode in lookup");
558 	}
559 	cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
560 
561 	/* Posix open is only called (at lookup time) for file create now.
562 	 * For opens (rather than creates), because we do not know if it
563 	 * is a file or directory yet, and current Samba no longer allows
564 	 * us to do posix open on dirs, we could end up wasting an open call
565 	 * on what turns out to be a dir. For file opens, we wait to call posix
566 	 * open till cifs_open.  It could be added here (lookup) in the future
567 	 * but the performance tradeoff of the extra network request when EISDIR
568 	 * or EACCES is returned would have to be weighed against the 50%
569 	 * reduction in network traffic in the other paths.
570 	 */
571 	if (pTcon->unix_ext) {
572 		if (nd && !(nd->flags & LOOKUP_DIRECTORY) &&
573 		     (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
574 		     (nd->intent.open.file->f_flags & O_CREAT)) {
575 			rc = cifs_posix_open(full_path, &newInode,
576 					parent_dir_inode->i_sb,
577 					nd->intent.open.create_mode,
578 					nd->intent.open.file->f_flags, &oplock,
579 					&fileHandle, xid);
580 			/*
581 			 * The check below works around a bug in POSIX
582 			 * open in samba versions 3.3.1 and earlier where
583 			 * open could incorrectly fail with invalid parameter.
584 			 * If either that or op not supported returned, follow
585 			 * the normal lookup.
586 			 */
587 			switch (rc) {
588 			case 0:
589 				/*
590 				 * The server may allow us to open things like
591 				 * FIFOs, but the client isn't set up to deal
592 				 * with that. If it's not a regular file, just
593 				 * close it and proceed as if it were a normal
594 				 * lookup.
595 				 */
596 				if (newInode && !S_ISREG(newInode->i_mode)) {
597 					CIFSSMBClose(xid, pTcon, fileHandle);
598 					break;
599 				}
600 			case -ENOENT:
601 				posix_open = true;
602 			case -EOPNOTSUPP:
603 				break;
604 			default:
605 				pTcon->broken_posix_open = true;
606 			}
607 		}
608 		if (!posix_open)
609 			rc = cifs_get_inode_info_unix(&newInode, full_path,
610 						parent_dir_inode->i_sb, xid);
611 	} else
612 		rc = cifs_get_inode_info(&newInode, full_path, NULL,
613 				parent_dir_inode->i_sb, xid, NULL);
614 
615 	if ((rc == 0) && (newInode != NULL)) {
616 		d_add(direntry, newInode);
617 		if (posix_open) {
618 			filp = lookup_instantiate_filp(nd, direntry,
619 						       generic_file_open);
620 			if (IS_ERR(filp)) {
621 				rc = PTR_ERR(filp);
622 				CIFSSMBClose(xid, pTcon, fileHandle);
623 				goto lookup_out;
624 			}
625 
626 			cfile = cifs_new_fileinfo(fileHandle, filp, tlink,
627 						  oplock);
628 			if (cfile == NULL) {
629 				fput(filp);
630 				CIFSSMBClose(xid, pTcon, fileHandle);
631 				rc = -ENOMEM;
632 				goto lookup_out;
633 			}
634 		}
635 		/* since paths are not looked up by component - the parent
636 		   directories are presumed to be good here */
637 		renew_parental_timestamps(direntry);
638 
639 	} else if (rc == -ENOENT) {
640 		rc = 0;
641 		direntry->d_time = jiffies;
642 		d_add(direntry, NULL);
643 	/*	if it was once a directory (but how can we tell?) we could do
644 		shrink_dcache_parent(direntry); */
645 	} else if (rc != -EACCES) {
646 		cERROR(1, "Unexpected lookup error %d", rc);
647 		/* We special case check for Access Denied - since that
648 		is a common return code */
649 	}
650 
651 lookup_out:
652 	kfree(full_path);
653 	cifs_put_tlink(tlink);
654 	FreeXid(xid);
655 	return ERR_PTR(rc);
656 }
657 
658 static int
cifs_d_revalidate(struct dentry * direntry,struct nameidata * nd)659 cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
660 {
661 	if (nd && (nd->flags & LOOKUP_RCU))
662 		return -ECHILD;
663 
664 	if (direntry->d_inode) {
665 		if (cifs_revalidate_dentry(direntry))
666 			return 0;
667 		else {
668 			/*
669 			 * Forcibly invalidate automounting directory inodes
670 			 * (remote DFS directories) so to have them
671 			 * instantiated again for automount
672 			 */
673 			if (IS_AUTOMOUNT(direntry->d_inode))
674 				return 0;
675 			return 1;
676 		}
677 	}
678 
679 	/*
680 	 * This may be nfsd (or something), anyway, we can't see the
681 	 * intent of this. So, since this can be for creation, drop it.
682 	 */
683 	if (!nd)
684 		return 0;
685 
686 	/*
687 	 * Drop the negative dentry, in order to make sure to use the
688 	 * case sensitive name which is specified by user if this is
689 	 * for creation.
690 	 */
691 	if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
692 		return 0;
693 
694 	if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
695 		return 0;
696 
697 	return 1;
698 }
699 
700 /* static int cifs_d_delete(struct dentry *direntry)
701 {
702 	int rc = 0;
703 
704 	cFYI(1, "In cifs d_delete, name = %s", direntry->d_name.name);
705 
706 	return rc;
707 }     */
708 
709 const struct dentry_operations cifs_dentry_ops = {
710 	.d_revalidate = cifs_d_revalidate,
711 	.d_automount = cifs_dfs_d_automount,
712 /* d_delete:       cifs_d_delete,      */ /* not needed except for debugging */
713 };
714 
cifs_ci_hash(const struct dentry * dentry,const struct inode * inode,struct qstr * q)715 static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
716 		struct qstr *q)
717 {
718 	struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
719 	unsigned long hash;
720 	int i;
721 
722 	hash = init_name_hash();
723 	for (i = 0; i < q->len; i++)
724 		hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
725 					 hash);
726 	q->hash = end_name_hash(hash);
727 
728 	return 0;
729 }
730 
cifs_ci_compare(const struct dentry * parent,const struct inode * pinode,const struct dentry * dentry,const struct inode * inode,unsigned int len,const char * str,const struct qstr * name)731 static int cifs_ci_compare(const struct dentry *parent,
732 		const struct inode *pinode,
733 		const struct dentry *dentry, const struct inode *inode,
734 		unsigned int len, const char *str, const struct qstr *name)
735 {
736 	struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
737 
738 	if ((name->len == len) &&
739 	    (nls_strnicmp(codepage, name->name, str, len) == 0))
740 		return 0;
741 	return 1;
742 }
743 
744 const struct dentry_operations cifs_ci_dentry_ops = {
745 	.d_revalidate = cifs_d_revalidate,
746 	.d_hash = cifs_ci_hash,
747 	.d_compare = cifs_ci_compare,
748 	.d_automount = cifs_dfs_d_automount,
749 };
750