don't pass nameidata to vfs_create() from ecryptfs_create()
[linux-2.6-block.git] / fs / cifs / dir.c
CommitLineData
1da177e4
LT
1/*
2 * fs/cifs/dir.c
3 *
4 * vfs operations that deal with dentries
5fdae1f6 5 *
c3b2a0c6 6 * Copyright (C) International Business Machines Corp., 2002,2009
1da177e4
LT
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>
3bc303c2 27#include <linux/mount.h>
6ca9f3ba 28#include <linux/file.h>
1da177e4
LT
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
99ee4dbd 36static void
1da177e4
LT
37renew_parental_timestamps(struct dentry *direntry)
38{
5fdae1f6
SF
39 /* BB check if there is a way to get the kernel to do this or if we
40 really need this */
1da177e4
LT
41 do {
42 direntry->d_time = jiffies;
43 direntry = direntry->d_parent;
5fdae1f6 44 } while (!IS_ROOT(direntry));
1da177e4
LT
45}
46
47/* Note: caller must free return buffer */
48char *
49build_path_from_dentry(struct dentry *direntry)
50{
51 struct dentry *temp;
2fe87f02 52 int namelen;
646dd539 53 int dfsplen;
1da177e4 54 char *full_path;
88274815 55 char dirsep;
0d424ad0 56 struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
96daf2b0 57 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
dc137bf5 58 unsigned seq;
1da177e4 59
5fdae1f6 60 if (direntry == NULL)
1da177e4
LT
61 return NULL; /* not much we can do if dentry is freed and
62 we need to reopen the file after it was closed implicitly
63 when the server crashed */
64
646dd539 65 dirsep = CIFS_DIR_SEP(cifs_sb);
0d424ad0
JL
66 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
67 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
646dd539
SF
68 else
69 dfsplen = 0;
1da177e4 70cifs_bp_rename_retry:
f87d39d9 71 namelen = dfsplen;
dc137bf5
AV
72 seq = read_seqbegin(&rename_lock);
73 rcu_read_lock();
1da177e4
LT
74 for (temp = direntry; !IS_ROOT(temp);) {
75 namelen += (1 + temp->d_name.len);
76 temp = temp->d_parent;
5fdae1f6 77 if (temp == NULL) {
b6b38f70 78 cERROR(1, "corrupt dentry");
dc137bf5 79 rcu_read_unlock();
1da177e4
LT
80 return NULL;
81 }
82 }
dc137bf5 83 rcu_read_unlock();
1da177e4
LT
84
85 full_path = kmalloc(namelen+1, GFP_KERNEL);
5fdae1f6 86 if (full_path == NULL)
1da177e4
LT
87 return full_path;
88 full_path[namelen] = 0; /* trailing null */
dc137bf5 89 rcu_read_lock();
1da177e4 90 for (temp = direntry; !IS_ROOT(temp);) {
dc137bf5 91 spin_lock(&temp->d_lock);
1da177e4
LT
92 namelen -= 1 + temp->d_name.len;
93 if (namelen < 0) {
dc137bf5 94 spin_unlock(&temp->d_lock);
1da177e4
LT
95 break;
96 } else {
7f57356b 97 full_path[namelen] = dirsep;
1da177e4
LT
98 strncpy(full_path + namelen + 1, temp->d_name.name,
99 temp->d_name.len);
b6b38f70 100 cFYI(0, "name: %s", full_path + namelen);
1da177e4 101 }
dc137bf5 102 spin_unlock(&temp->d_lock);
1da177e4 103 temp = temp->d_parent;
5fdae1f6 104 if (temp == NULL) {
b6b38f70 105 cERROR(1, "corrupt dentry");
dc137bf5 106 rcu_read_unlock();
1da177e4
LT
107 kfree(full_path);
108 return NULL;
109 }
110 }
dc137bf5
AV
111 rcu_read_unlock();
112 if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) {
b6b38f70
JP
113 cERROR(1, "did not end path lookup where expected namelen is %d",
114 namelen);
5fdae1f6 115 /* presumably this is only possible if racing with a rename
1da177e4
LT
116 of one of the parent directories (we can not lock the dentries
117 above us to prevent this, but retrying should be harmless) */
118 kfree(full_path);
1da177e4
LT
119 goto cifs_bp_rename_retry;
120 }
2fe87f02
SF
121 /* DIR_SEP already set for byte 0 / vs \ but not for
122 subsequent slashes in prepath which currently must
123 be entered the right way - not sure if there is an alternative
124 since the '\' is a valid posix character so we can not switch
125 those safely to '/' if any are found in the middle of the prepath */
126 /* BB test paths to Windows with '/' in the midst of prepath */
646dd539
SF
127
128 if (dfsplen) {
0d424ad0 129 strncpy(full_path, tcon->treeName, dfsplen);
646dd539
SF
130 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
131 int i;
132 for (i = 0; i < dfsplen; i++) {
133 if (full_path[i] == '\\')
134 full_path[i] = '/';
135 }
136 }
137 }
1da177e4
LT
138 return full_path;
139}
140
3979877e 141/* Inode operations in similar order to how they appear in Linux file fs.h */
1da177e4
LT
142
143int
144cifs_create(struct inode *inode, struct dentry *direntry, int mode,
145 struct nameidata *nd)
146{
147 int rc = -ENOENT;
148 int xid;
67750fb9 149 int create_options = CREATE_NOT_DIR;
590a3fe0 150 __u32 oplock = 0;
c3b2a0c6
SF
151 int oflags;
152 /*
153 * BB below access is probably too much for mknod to request
154 * but we have to do query and setpathinfo so requesting
155 * less could fail (unless we want to request getatr and setatr
156 * permissions (only). At least for POSIX we do not have to
157 * request so much.
158 */
1da177e4
LT
159 int desiredAccess = GENERIC_READ | GENERIC_WRITE;
160 __u16 fileHandle;
161 struct cifs_sb_info *cifs_sb;
7ffec372 162 struct tcon_link *tlink;
96daf2b0 163 struct cifs_tcon *tcon;
1da177e4 164 char *full_path = NULL;
fb8c4b14 165 FILE_ALL_INFO *buf = NULL;
1da177e4 166 struct inode *newinode = NULL;
1da177e4 167 int disposition = FILE_OVERWRITE_IF;
1da177e4
LT
168
169 xid = GetXid();
170
171 cifs_sb = CIFS_SB(inode->i_sb);
7ffec372
JL
172 tlink = cifs_sb_tlink(cifs_sb);
173 if (IS_ERR(tlink)) {
174 FreeXid(xid);
175 return PTR_ERR(tlink);
1da177e4 176 }
7ffec372 177 tcon = tlink_tcon(tlink);
1da177e4 178
c3b2a0c6
SF
179 if (oplockEnabled)
180 oplock = REQ_OPLOCK;
f818dd55 181
c3b2a0c6 182 if (nd && (nd->flags & LOOKUP_OPEN))
608712fe 183 oflags = nd->intent.open.file->f_flags;
c3b2a0c6 184 else
608712fe 185 oflags = O_RDONLY | O_CREAT;
c3b2a0c6 186
7ffec372
JL
187 full_path = build_path_from_dentry(direntry);
188 if (full_path == NULL) {
189 rc = -ENOMEM;
190 goto cifs_create_out;
191 }
192
c3b2a0c6
SF
193 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
194 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
195 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
fa588e0c 196 rc = cifs_posix_open(full_path, &newinode,
fa588e0c 197 inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
c3b2a0c6
SF
198 /* EIO could indicate that (posix open) operation is not
199 supported, despite what server claimed in capability
25985edc 200 negotiation. EREMOTE indicates DFS junction, which is not
c3b2a0c6
SF
201 handled in posix open */
202
90e4ee5d 203 if (rc == 0) {
90e4ee5d
SF
204 if (newinode == NULL) /* query inode info */
205 goto cifs_create_get_file_info;
206 else /* success, no need to query */
207 goto cifs_create_set_dentry;
208 } else if ((rc != -EIO) && (rc != -EREMOTE) &&
703a3b8e 209 (rc != -EOPNOTSUPP) && (rc != -EINVAL))
c3b2a0c6
SF
210 goto cifs_create_out;
211 /* else fallthrough to retry, using older open call, this is
212 case where server does not support this SMB level, and
213 falsely claims capability (also get here for DFS case
214 which should be rare for path not covered on files) */
215 }
e08fc045 216
c3b2a0c6
SF
217 if (nd && (nd->flags & LOOKUP_OPEN)) {
218 /* if the file is going to stay open, then we
219 need to set the desired access properly */
e08fc045 220 desiredAccess = 0;
608712fe 221 if (OPEN_FMODE(oflags) & FMODE_READ)
c3b2a0c6 222 desiredAccess |= GENERIC_READ; /* is this too little? */
608712fe 223 if (OPEN_FMODE(oflags) & FMODE_WRITE)
e08fc045 224 desiredAccess |= GENERIC_WRITE;
1da177e4 225
5fdae1f6 226 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
1da177e4 227 disposition = FILE_CREATE;
5fdae1f6 228 else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
1da177e4 229 disposition = FILE_OVERWRITE_IF;
5fdae1f6 230 else if ((oflags & O_CREAT) == O_CREAT)
1da177e4 231 disposition = FILE_OPEN_IF;
ad7a2926 232 else
b6b38f70 233 cFYI(1, "Create flag not set in create function");
1da177e4
LT
234 }
235
5fdae1f6
SF
236 /* BB add processing to set equivalent of mode - e.g. via CreateX with
237 ACLs */
1da177e4 238
5fdae1f6
SF
239 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
240 if (buf == NULL) {
232341ba
JL
241 rc = -ENOMEM;
242 goto cifs_create_out;
1da177e4 243 }
67750fb9 244
67750fb9
JL
245 /*
246 * if we're not using unix extensions, see if we need to set
247 * ATTR_READONLY on the create call
248 */
f818dd55 249 if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
67750fb9
JL
250 create_options |= CREATE_OPTION_READONLY;
251
a6e8a845 252 if (tcon->ses->capabilities & CAP_NT_SMBS)
f818dd55 253 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
67750fb9 254 desiredAccess, create_options,
737b758c
SF
255 &fileHandle, &oplock, buf, cifs_sb->local_nls,
256 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
5bafd765
SF
257 else
258 rc = -EIO; /* no NT SMB support fall into legacy open below */
259
5fdae1f6 260 if (rc == -EIO) {
a9d02ad4 261 /* old server, retry the open legacy style */
f818dd55 262 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
67750fb9 263 desiredAccess, create_options,
a9d02ad4
SF
264 &fileHandle, &oplock, buf, cifs_sb->local_nls,
265 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
5fdae1f6 266 }
1da177e4 267 if (rc) {
b6b38f70 268 cFYI(1, "cifs_create returned 0x%x", rc);
c3b2a0c6
SF
269 goto cifs_create_out;
270 }
271
272 /* If Open reported that we actually created a file
273 then we now have to set the mode if possible */
274 if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
275 struct cifs_unix_set_info_args args = {
4e1e7fb9
JL
276 .mode = mode,
277 .ctime = NO_CHANGE_64,
278 .atime = NO_CHANGE_64,
279 .mtime = NO_CHANGE_64,
280 .device = 0,
c3b2a0c6
SF
281 };
282
283 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
284 args.uid = (__u64) current_fsuid();
285 if (inode->i_mode & S_ISGID)
286 args.gid = (__u64) inode->i_gid;
287 else
288 args.gid = (__u64) current_fsgid();
3ce53fc4 289 } else {
c3b2a0c6
SF
290 args.uid = NO_CHANGE_64;
291 args.gid = NO_CHANGE_64;
1da177e4 292 }
d44a9fe2
JL
293 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle,
294 current->tgid);
c3b2a0c6
SF
295 } else {
296 /* BB implement mode setting via Windows security
297 descriptors e.g. */
298 /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
299
300 /* Could set r/o dos attribute if mode & 0222 == 0 */
301 }
1da177e4 302
c3b2a0c6
SF
303cifs_create_get_file_info:
304 /* server might mask mode so we have to query for it */
305 if (tcon->unix_ext)
306 rc = cifs_get_inode_info_unix(&newinode, full_path,
307 inode->i_sb, xid);
308 else {
309 rc = cifs_get_inode_info(&newinode, full_path, buf,
310 inode->i_sb, xid, &fileHandle);
311 if (newinode) {
312 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
313 newinode->i_mode = mode;
314 if ((oplock & CIFS_CREATE_ACTION) &&
315 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
316 newinode->i_uid = current_fsuid();
317 if (inode->i_mode & S_ISGID)
318 newinode->i_gid = inode->i_gid;
319 else
320 newinode->i_gid = current_fsgid();
6473a559 321 }
1da177e4 322 }
c3b2a0c6 323 }
1da177e4 324
c3b2a0c6
SF
325cifs_create_set_dentry:
326 if (rc == 0)
1c929cfe 327 d_instantiate(direntry, newinode);
c3b2a0c6 328 else
b6b38f70 329 cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
c3b2a0c6 330
2422f676 331 if (newinode && nd && (nd->flags & LOOKUP_OPEN)) {
fdb36038 332 struct cifsFileInfo *pfile_info;
6ca9f3ba
JL
333 struct file *filp;
334
335 filp = lookup_instantiate_filp(nd, direntry, generic_file_open);
336 if (IS_ERR(filp)) {
337 rc = PTR_ERR(filp);
338 CIFSSMBClose(xid, tcon, fileHandle);
339 goto cifs_create_out;
340 }
341
abfe1eed 342 pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
6ca9f3ba
JL
343 if (pfile_info == NULL) {
344 fput(filp);
345 CIFSSMBClose(xid, tcon, fileHandle);
fdb36038 346 rc = -ENOMEM;
6ca9f3ba 347 }
2422f676
JL
348 } else {
349 CIFSSMBClose(xid, tcon, fileHandle);
5fdae1f6 350 }
2422f676 351
d14537f1
SF
352cifs_create_out:
353 kfree(buf);
354 kfree(full_path);
7ffec372 355 cifs_put_tlink(tlink);
1da177e4 356 FreeXid(xid);
1da177e4
LT
357 return rc;
358}
359
5fdae1f6
SF
360int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
361 dev_t device_number)
1da177e4
LT
362{
363 int rc = -EPERM;
364 int xid;
365 struct cifs_sb_info *cifs_sb;
7ffec372 366 struct tcon_link *tlink;
96daf2b0 367 struct cifs_tcon *pTcon;
fa2989f4 368 struct cifs_io_parms io_parms;
1da177e4 369 char *full_path = NULL;
fb8c4b14 370 struct inode *newinode = NULL;
5d9ac7fd
JL
371 int oplock = 0;
372 u16 fileHandle;
373 FILE_ALL_INFO *buf = NULL;
374 unsigned int bytes_written;
375 struct win_dev *pdev;
1da177e4
LT
376
377 if (!old_valid_dev(device_number))
378 return -EINVAL;
379
1da177e4 380 cifs_sb = CIFS_SB(inode->i_sb);
7ffec372
JL
381 tlink = cifs_sb_tlink(cifs_sb);
382 if (IS_ERR(tlink))
383 return PTR_ERR(tlink);
384
385 pTcon = tlink_tcon(tlink);
386
387 xid = GetXid();
1da177e4 388
1da177e4 389 full_path = build_path_from_dentry(direntry);
5d9ac7fd 390 if (full_path == NULL) {
1da177e4 391 rc = -ENOMEM;
5d9ac7fd
JL
392 goto mknod_out;
393 }
394
395 if (pTcon->unix_ext) {
4e1e7fb9 396 struct cifs_unix_set_info_args args = {
ce3b0f8d 397 .mode = mode & ~current_umask(),
4e1e7fb9
JL
398 .ctime = NO_CHANGE_64,
399 .atime = NO_CHANGE_64,
400 .mtime = NO_CHANGE_64,
401 .device = device_number,
402 };
5fdae1f6 403 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
a001e5b5
DH
404 args.uid = (__u64) current_fsuid();
405 args.gid = (__u64) current_fsgid();
1da177e4 406 } else {
4e1e7fb9
JL
407 args.uid = NO_CHANGE_64;
408 args.gid = NO_CHANGE_64;
1da177e4 409 }
01ea95e3
JL
410 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
411 cifs_sb->local_nls,
412 cifs_sb->mnt_cifs_flags &
413 CIFS_MOUNT_MAP_SPECIAL_CHR);
5d9ac7fd
JL
414 if (rc)
415 goto mknod_out;
1da177e4 416
5d9ac7fd 417 rc = cifs_get_inode_info_unix(&newinode, full_path,
5fdae1f6 418 inode->i_sb, xid);
eda3c029 419
5d9ac7fd
JL
420 if (rc == 0)
421 d_instantiate(direntry, newinode);
422 goto mknod_out;
1da177e4
LT
423 }
424
5d9ac7fd
JL
425 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL))
426 goto mknod_out;
427
428
429 cFYI(1, "sfu compat create special file");
430
431 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
432 if (buf == NULL) {
433 kfree(full_path);
434 rc = -ENOMEM;
435 FreeXid(xid);
436 return rc;
437 }
438
439 /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */
440 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
441 GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
442 &fileHandle, &oplock, buf, cifs_sb->local_nls,
443 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
444 if (rc)
445 goto mknod_out;
446
447 /* BB Do not bother to decode buf since no local inode yet to put
448 * timestamps in, but we can reuse it safely */
449
450 pdev = (struct win_dev *)buf;
fa2989f4
PS
451 io_parms.netfid = fileHandle;
452 io_parms.pid = current->tgid;
453 io_parms.tcon = pTcon;
454 io_parms.offset = 0;
455 io_parms.length = sizeof(struct win_dev);
5d9ac7fd
JL
456 if (S_ISCHR(mode)) {
457 memcpy(pdev->type, "IntxCHR", 8);
458 pdev->major =
459 cpu_to_le64(MAJOR(device_number));
460 pdev->minor =
461 cpu_to_le64(MINOR(device_number));
fa2989f4
PS
462 rc = CIFSSMBWrite(xid, &io_parms,
463 &bytes_written, (char *)pdev,
5d9ac7fd
JL
464 NULL, 0);
465 } else if (S_ISBLK(mode)) {
466 memcpy(pdev->type, "IntxBLK", 8);
467 pdev->major =
468 cpu_to_le64(MAJOR(device_number));
469 pdev->minor =
470 cpu_to_le64(MINOR(device_number));
fa2989f4
PS
471 rc = CIFSSMBWrite(xid, &io_parms,
472 &bytes_written, (char *)pdev,
5d9ac7fd
JL
473 NULL, 0);
474 } /* else if (S_ISFIFO) */
475 CIFSSMBClose(xid, pTcon, fileHandle);
476 d_drop(direntry);
477
478 /* FIXME: add code here to set EAs */
479
480mknod_out:
d14537f1 481 kfree(full_path);
5d9ac7fd 482 kfree(buf);
1da177e4 483 FreeXid(xid);
7ffec372 484 cifs_put_tlink(tlink);
1da177e4
LT
485 return rc;
486}
487
1da177e4 488struct dentry *
5fdae1f6
SF
489cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
490 struct nameidata *nd)
1da177e4
LT
491{
492 int xid;
493 int rc = 0; /* to get around spurious gcc warning, set to zero here */
590a3fe0 494 __u32 oplock = 0;
a6ce4932
SF
495 __u16 fileHandle = 0;
496 bool posix_open = false;
1da177e4 497 struct cifs_sb_info *cifs_sb;
7ffec372 498 struct tcon_link *tlink;
96daf2b0 499 struct cifs_tcon *pTcon;
2422f676 500 struct cifsFileInfo *cfile;
1da177e4
LT
501 struct inode *newInode = NULL;
502 char *full_path = NULL;
a6ce4932 503 struct file *filp;
1da177e4
LT
504
505 xid = GetXid();
506
b6b38f70
JP
507 cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
508 parent_dir_inode, direntry->d_name.name, direntry);
1da177e4 509
1da177e4
LT
510 /* check whether path exists */
511
512 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
7ffec372
JL
513 tlink = cifs_sb_tlink(cifs_sb);
514 if (IS_ERR(tlink)) {
515 FreeXid(xid);
516 return (struct dentry *)tlink;
517 }
518 pTcon = tlink_tcon(tlink);
1da177e4 519
296034f7
SF
520 /*
521 * Don't allow the separator character in a path component.
522 * The VFS will not allow "/", but "\" is allowed by posix.
523 */
524 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
525 int i;
526 for (i = 0; i < direntry->d_name.len; i++)
527 if (direntry->d_name.name[i] == '\\') {
b6b38f70 528 cFYI(1, "Invalid file name");
7ffec372
JL
529 rc = -EINVAL;
530 goto lookup_out;
296034f7
SF
531 }
532 }
533
5ddf1e0f
JL
534 /*
535 * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
536 * the VFS handle the create.
537 */
8e6c0332 538 if (nd && (nd->flags & LOOKUP_EXCL)) {
5ddf1e0f 539 d_instantiate(direntry, NULL);
7ffec372
JL
540 rc = 0;
541 goto lookup_out;
5ddf1e0f
JL
542 }
543
1da177e4
LT
544 /* can not grab the rename sem here since it would
545 deadlock in the cases (beginning of sys_rename itself)
546 in which we already have the sb rename sem */
547 full_path = build_path_from_dentry(direntry);
5fdae1f6 548 if (full_path == NULL) {
7ffec372
JL
549 rc = -ENOMEM;
550 goto lookup_out;
1da177e4
LT
551 }
552
553 if (direntry->d_inode != NULL) {
b6b38f70 554 cFYI(1, "non-NULL inode in lookup");
1da177e4 555 } else {
b6b38f70 556 cFYI(1, "NULL inode in lookup");
1da177e4 557 }
b6b38f70 558 cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
1da177e4 559
8db14ca1
SF
560 /* Posix open is only called (at lookup time) for file create now.
561 * For opens (rather than creates), because we do not know if it
562 * is a file or directory yet, and current Samba no longer allows
563 * us to do posix open on dirs, we could end up wasting an open call
564 * on what turns out to be a dir. For file opens, we wait to call posix
565 * open till cifs_open. It could be added here (lookup) in the future
566 * but the performance tradeoff of the extra network request when EISDIR
567 * or EACCES is returned would have to be weighed against the 50%
568 * reduction in network traffic in the other paths.
569 */
a6ce4932 570 if (pTcon->unix_ext) {
8e6c0332 571 if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
8db14ca1 572 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
608712fe 573 (nd->intent.open.file->f_flags & O_CREAT)) {
2422f676 574 rc = cifs_posix_open(full_path, &newInode,
fa588e0c 575 parent_dir_inode->i_sb,
703a3b8e 576 nd->intent.open.create_mode,
608712fe 577 nd->intent.open.file->f_flags, &oplock,
a6ce4932 578 &fileHandle, xid);
8db14ca1
SF
579 /*
580 * The check below works around a bug in POSIX
581 * open in samba versions 3.3.1 and earlier where
582 * open could incorrectly fail with invalid parameter.
583 * If either that or op not supported returned, follow
584 * the normal lookup.
585 */
586 if ((rc == 0) || (rc == -ENOENT))
587 posix_open = true;
588 else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
589 pTcon->broken_posix_open = true;
a6ce4932
SF
590 }
591 if (!posix_open)
592 rc = cifs_get_inode_info_unix(&newInode, full_path,
593 parent_dir_inode->i_sb, xid);
594 } else
1da177e4 595 rc = cifs_get_inode_info(&newInode, full_path, NULL,
a6ce4932 596 parent_dir_inode->i_sb, xid, NULL);
1da177e4
LT
597
598 if ((rc == 0) && (newInode != NULL)) {
1da177e4 599 d_add(direntry, newInode);
2422f676 600 if (posix_open) {
6ca9f3ba
JL
601 filp = lookup_instantiate_filp(nd, direntry,
602 generic_file_open);
603 if (IS_ERR(filp)) {
604 rc = PTR_ERR(filp);
605 CIFSSMBClose(xid, pTcon, fileHandle);
606 goto lookup_out;
607 }
608
abfe1eed
JL
609 cfile = cifs_new_fileinfo(fileHandle, filp, tlink,
610 oplock);
2422f676 611 if (cfile == NULL) {
6ca9f3ba 612 fput(filp);
2422f676
JL
613 CIFSSMBClose(xid, pTcon, fileHandle);
614 rc = -ENOMEM;
615 goto lookup_out;
616 }
2422f676 617 }
5fdae1f6 618 /* since paths are not looked up by component - the parent
3abb9272 619 directories are presumed to be good here */
1da177e4
LT
620 renew_parental_timestamps(direntry);
621
622 } else if (rc == -ENOENT) {
623 rc = 0;
3abb9272 624 direntry->d_time = jiffies;
1da177e4 625 d_add(direntry, NULL);
5fdae1f6
SF
626 /* if it was once a directory (but how can we tell?) we could do
627 shrink_dcache_parent(direntry); */
ed2b9170 628 } else if (rc != -EACCES) {
b6b38f70 629 cERROR(1, "Unexpected lookup error %d", rc);
ed2b9170
SF
630 /* We special case check for Access Denied - since that
631 is a common return code */
1da177e4
LT
632 }
633
2422f676 634lookup_out:
d14537f1 635 kfree(full_path);
7ffec372 636 cifs_put_tlink(tlink);
1da177e4
LT
637 FreeXid(xid);
638 return ERR_PTR(rc);
639}
640
1da177e4
LT
641static int
642cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
643{
34286d66
NP
644 if (nd->flags & LOOKUP_RCU)
645 return -ECHILD;
646
1da177e4 647 if (direntry->d_inode) {
df2cf170 648 if (cifs_revalidate_dentry(direntry))
1da177e4 649 return 0;
262f86ad
NP
650 else
651 return 1;
1da177e4
LT
652 }
653
262f86ad
NP
654 /*
655 * This may be nfsd (or something), anyway, we can't see the
656 * intent of this. So, since this can be for creation, drop it.
657 */
658 if (!nd)
659 return 0;
660
661 /*
662 * Drop the negative dentry, in order to make sure to use the
663 * case sensitive name which is specified by user if this is
664 * for creation.
665 */
666 if (!(nd->flags & (LOOKUP_CONTINUE | LOOKUP_PARENT))) {
667 if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
668 return 0;
669 }
670
671 if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
672 return 0;
673
674 return 1;
1da177e4
LT
675}
676
677/* static int cifs_d_delete(struct dentry *direntry)
678{
679 int rc = 0;
680
b6b38f70 681 cFYI(1, "In cifs d_delete, name = %s", direntry->d_name.name);
1da177e4
LT
682
683 return rc;
684} */
685
4fd03e84 686const struct dentry_operations cifs_dentry_ops = {
1da177e4 687 .d_revalidate = cifs_d_revalidate,
01c64fea 688 .d_automount = cifs_dfs_d_automount,
5fdae1f6 689/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
1da177e4 690};
b92327fe 691
b1e6a015
NP
692static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
693 struct qstr *q)
b92327fe 694{
b1e6a015 695 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
b92327fe
SF
696 unsigned long hash;
697 int i;
698
699 hash = init_name_hash();
700 for (i = 0; i < q->len; i++)
701 hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
702 hash);
703 q->hash = end_name_hash(hash);
704
705 return 0;
706}
707
621e155a
NP
708static int cifs_ci_compare(const struct dentry *parent,
709 const struct inode *pinode,
710 const struct dentry *dentry, const struct inode *inode,
711 unsigned int len, const char *str, const struct qstr *name)
b92327fe 712{
621e155a 713 struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
b92327fe 714
621e155a
NP
715 if ((name->len == len) &&
716 (nls_strnicmp(codepage, name->name, str, len) == 0))
b92327fe 717 return 0;
b92327fe
SF
718 return 1;
719}
720
4fd03e84 721const struct dentry_operations cifs_ci_dentry_ops = {
b92327fe
SF
722 .d_revalidate = cifs_d_revalidate,
723 .d_hash = cifs_ci_hash,
724 .d_compare = cifs_ci_compare,
01c64fea 725 .d_automount = cifs_dfs_d_automount,
b92327fe 726};