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