UBIFS: rename dumping functions
[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
646dd539 60 dirsep = CIFS_DIR_SEP(cifs_sb);
0d424ad0
JL
61 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
62 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
646dd539
SF
63 else
64 dfsplen = 0;
1da177e4 65cifs_bp_rename_retry:
f87d39d9 66 namelen = dfsplen;
dc137bf5
AV
67 seq = read_seqbegin(&rename_lock);
68 rcu_read_lock();
1da177e4
LT
69 for (temp = direntry; !IS_ROOT(temp);) {
70 namelen += (1 + temp->d_name.len);
71 temp = temp->d_parent;
5fdae1f6 72 if (temp == NULL) {
b6b38f70 73 cERROR(1, "corrupt dentry");
dc137bf5 74 rcu_read_unlock();
1da177e4
LT
75 return NULL;
76 }
77 }
dc137bf5 78 rcu_read_unlock();
1da177e4
LT
79
80 full_path = kmalloc(namelen+1, GFP_KERNEL);
5fdae1f6 81 if (full_path == NULL)
1da177e4
LT
82 return full_path;
83 full_path[namelen] = 0; /* trailing null */
dc137bf5 84 rcu_read_lock();
1da177e4 85 for (temp = direntry; !IS_ROOT(temp);) {
dc137bf5 86 spin_lock(&temp->d_lock);
1da177e4
LT
87 namelen -= 1 + temp->d_name.len;
88 if (namelen < 0) {
dc137bf5 89 spin_unlock(&temp->d_lock);
1da177e4
LT
90 break;
91 } else {
7f57356b 92 full_path[namelen] = dirsep;
1da177e4
LT
93 strncpy(full_path + namelen + 1, temp->d_name.name,
94 temp->d_name.len);
b6b38f70 95 cFYI(0, "name: %s", full_path + namelen);
1da177e4 96 }
dc137bf5 97 spin_unlock(&temp->d_lock);
1da177e4 98 temp = temp->d_parent;
5fdae1f6 99 if (temp == NULL) {
b6b38f70 100 cERROR(1, "corrupt dentry");
dc137bf5 101 rcu_read_unlock();
1da177e4
LT
102 kfree(full_path);
103 return NULL;
104 }
105 }
dc137bf5
AV
106 rcu_read_unlock();
107 if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) {
fa71f447
JL
108 cFYI(1, "did not end path lookup where expected. namelen=%d "
109 "dfsplen=%d", namelen, dfsplen);
5fdae1f6 110 /* presumably this is only possible if racing with a rename
1da177e4
LT
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);
1da177e4
LT
114 goto cifs_bp_rename_retry;
115 }
2fe87f02
SF
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 */
646dd539
SF
122
123 if (dfsplen) {
0d424ad0 124 strncpy(full_path, tcon->treeName, dfsplen);
646dd539
SF
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 }
1da177e4
LT
133 return full_path;
134}
135
3979877e 136/* Inode operations in similar order to how they appear in Linux file fs.h */
1da177e4
LT
137
138int
4acdaf27 139cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
1da177e4
LT
140 struct nameidata *nd)
141{
142 int rc = -ENOENT;
143 int xid;
67750fb9 144 int create_options = CREATE_NOT_DIR;
590a3fe0 145 __u32 oplock = 0;
c3b2a0c6
SF
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 */
1da177e4
LT
154 int desiredAccess = GENERIC_READ | GENERIC_WRITE;
155 __u16 fileHandle;
156 struct cifs_sb_info *cifs_sb;
7ffec372 157 struct tcon_link *tlink;
96daf2b0 158 struct cifs_tcon *tcon;
1da177e4 159 char *full_path = NULL;
fb8c4b14 160 FILE_ALL_INFO *buf = NULL;
1da177e4 161 struct inode *newinode = NULL;
1da177e4 162 int disposition = FILE_OVERWRITE_IF;
1da177e4
LT
163
164 xid = GetXid();
165
166 cifs_sb = CIFS_SB(inode->i_sb);
7ffec372
JL
167 tlink = cifs_sb_tlink(cifs_sb);
168 if (IS_ERR(tlink)) {
169 FreeXid(xid);
170 return PTR_ERR(tlink);
1da177e4 171 }
7ffec372 172 tcon = tlink_tcon(tlink);
1da177e4 173
10b9b98e 174 if (tcon->ses->server->oplocks)
c3b2a0c6 175 oplock = REQ_OPLOCK;
f818dd55 176
dd7dd556 177 if (nd)
608712fe 178 oflags = nd->intent.open.file->f_flags;
c3b2a0c6 179 else
608712fe 180 oflags = O_RDONLY | O_CREAT;
c3b2a0c6 181
7ffec372
JL
182 full_path = build_path_from_dentry(direntry);
183 if (full_path == NULL) {
184 rc = -ENOMEM;
185 goto cifs_create_out;
186 }
187
c3b2a0c6
SF
188 if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
189 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
190 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
fa588e0c 191 rc = cifs_posix_open(full_path, &newinode,
fa588e0c 192 inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
c3b2a0c6
SF
193 /* EIO could indicate that (posix open) operation is not
194 supported, despite what server claimed in capability
25985edc 195 negotiation. EREMOTE indicates DFS junction, which is not
c3b2a0c6
SF
196 handled in posix open */
197
90e4ee5d 198 if (rc == 0) {
90e4ee5d
SF
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) &&
703a3b8e 204 (rc != -EOPNOTSUPP) && (rc != -EINVAL))
c3b2a0c6
SF
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 }
e08fc045 211
dd7dd556 212 if (nd) {
c3b2a0c6
SF
213 /* if the file is going to stay open, then we
214 need to set the desired access properly */
e08fc045 215 desiredAccess = 0;
608712fe 216 if (OPEN_FMODE(oflags) & FMODE_READ)
c3b2a0c6 217 desiredAccess |= GENERIC_READ; /* is this too little? */
608712fe 218 if (OPEN_FMODE(oflags) & FMODE_WRITE)
e08fc045 219 desiredAccess |= GENERIC_WRITE;
1da177e4 220
5fdae1f6 221 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
1da177e4 222 disposition = FILE_CREATE;
5fdae1f6 223 else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
1da177e4 224 disposition = FILE_OVERWRITE_IF;
5fdae1f6 225 else if ((oflags & O_CREAT) == O_CREAT)
1da177e4 226 disposition = FILE_OPEN_IF;
ad7a2926 227 else
b6b38f70 228 cFYI(1, "Create flag not set in create function");
1da177e4
LT
229 }
230
5fdae1f6
SF
231 /* BB add processing to set equivalent of mode - e.g. via CreateX with
232 ACLs */
1da177e4 233
5fdae1f6
SF
234 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
235 if (buf == NULL) {
232341ba
JL
236 rc = -ENOMEM;
237 goto cifs_create_out;
1da177e4 238 }
67750fb9 239
67750fb9
JL
240 /*
241 * if we're not using unix extensions, see if we need to set
242 * ATTR_READONLY on the create call
243 */
f818dd55 244 if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
67750fb9
JL
245 create_options |= CREATE_OPTION_READONLY;
246
3d3ea8e6
SP
247 if (backup_cred(cifs_sb))
248 create_options |= CREATE_OPEN_BACKUP_INTENT;
249
a6e8a845 250 if (tcon->ses->capabilities & CAP_NT_SMBS)
f818dd55 251 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
67750fb9 252 desiredAccess, create_options,
737b758c
SF
253 &fileHandle, &oplock, buf, cifs_sb->local_nls,
254 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
5bafd765
SF
255 else
256 rc = -EIO; /* no NT SMB support fall into legacy open below */
257
5fdae1f6 258 if (rc == -EIO) {
a9d02ad4 259 /* old server, retry the open legacy style */
f818dd55 260 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
67750fb9 261 desiredAccess, create_options,
a9d02ad4
SF
262 &fileHandle, &oplock, buf, cifs_sb->local_nls,
263 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
5fdae1f6 264 }
1da177e4 265 if (rc) {
b6b38f70 266 cFYI(1, "cifs_create returned 0x%x", rc);
c3b2a0c6
SF
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 = {
4e1e7fb9
JL
274 .mode = mode,
275 .ctime = NO_CHANGE_64,
276 .atime = NO_CHANGE_64,
277 .mtime = NO_CHANGE_64,
278 .device = 0,
c3b2a0c6
SF
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();
3ce53fc4 287 } else {
c3b2a0c6
SF
288 args.uid = NO_CHANGE_64;
289 args.gid = NO_CHANGE_64;
1da177e4 290 }
d44a9fe2
JL
291 CIFSSMBUnixSetFileInfo(xid, tcon, &args, fileHandle,
292 current->tgid);
c3b2a0c6
SF
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 }
1da177e4 300
c3b2a0c6
SF
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();
6473a559 319 }
1da177e4 320 }
c3b2a0c6 321 }
1da177e4 322
c3b2a0c6
SF
323cifs_create_set_dentry:
324 if (rc == 0)
1c929cfe 325 d_instantiate(direntry, newinode);
c3b2a0c6 326 else
b6b38f70 327 cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
c3b2a0c6 328
dd7dd556 329 if (newinode && nd) {
fdb36038 330 struct cifsFileInfo *pfile_info;
6ca9f3ba
JL
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
abfe1eed 340 pfile_info = cifs_new_fileinfo(fileHandle, filp, tlink, oplock);
6ca9f3ba
JL
341 if (pfile_info == NULL) {
342 fput(filp);
343 CIFSSMBClose(xid, tcon, fileHandle);
fdb36038 344 rc = -ENOMEM;
6ca9f3ba 345 }
2422f676
JL
346 } else {
347 CIFSSMBClose(xid, tcon, fileHandle);
5fdae1f6 348 }
2422f676 349
d14537f1
SF
350cifs_create_out:
351 kfree(buf);
352 kfree(full_path);
7ffec372 353 cifs_put_tlink(tlink);
1da177e4 354 FreeXid(xid);
1da177e4
LT
355 return rc;
356}
357
1a67aafb 358int cifs_mknod(struct inode *inode, struct dentry *direntry, umode_t mode,
5fdae1f6 359 dev_t device_number)
1da177e4
LT
360{
361 int rc = -EPERM;
362 int xid;
3d3ea8e6 363 int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
1da177e4 364 struct cifs_sb_info *cifs_sb;
7ffec372 365 struct tcon_link *tlink;
96daf2b0 366 struct cifs_tcon *pTcon;
fa2989f4 367 struct cifs_io_parms io_parms;
1da177e4 368 char *full_path = NULL;
fb8c4b14 369 struct inode *newinode = NULL;
5d9ac7fd
JL
370 int oplock = 0;
371 u16 fileHandle;
372 FILE_ALL_INFO *buf = NULL;
373 unsigned int bytes_written;
374 struct win_dev *pdev;
1da177e4
LT
375
376 if (!old_valid_dev(device_number))
377 return -EINVAL;
378
1da177e4 379 cifs_sb = CIFS_SB(inode->i_sb);
7ffec372
JL
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();
1da177e4 387
1da177e4 388 full_path = build_path_from_dentry(direntry);
5d9ac7fd 389 if (full_path == NULL) {
1da177e4 390 rc = -ENOMEM;
5d9ac7fd
JL
391 goto mknod_out;
392 }
393
394 if (pTcon->unix_ext) {
4e1e7fb9 395 struct cifs_unix_set_info_args args = {
ce3b0f8d 396 .mode = mode & ~current_umask(),
4e1e7fb9
JL
397 .ctime = NO_CHANGE_64,
398 .atime = NO_CHANGE_64,
399 .mtime = NO_CHANGE_64,
400 .device = device_number,
401 };
5fdae1f6 402 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
a001e5b5
DH
403 args.uid = (__u64) current_fsuid();
404 args.gid = (__u64) current_fsgid();
1da177e4 405 } else {
4e1e7fb9
JL
406 args.uid = NO_CHANGE_64;
407 args.gid = NO_CHANGE_64;
1da177e4 408 }
01ea95e3
JL
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);
5d9ac7fd
JL
413 if (rc)
414 goto mknod_out;
1da177e4 415
5d9ac7fd 416 rc = cifs_get_inode_info_unix(&newinode, full_path,
5fdae1f6 417 inode->i_sb, xid);
eda3c029 418
5d9ac7fd
JL
419 if (rc == 0)
420 d_instantiate(direntry, newinode);
421 goto mknod_out;
1da177e4
LT
422 }
423
5d9ac7fd
JL
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
3d3ea8e6
SP
438 if (backup_cred(cifs_sb))
439 create_options |= CREATE_OPEN_BACKUP_INTENT;
440
5d9ac7fd 441 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
3d3ea8e6 442 GENERIC_WRITE, create_options,
5d9ac7fd
JL
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;
fa2989f4
PS
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);
5d9ac7fd
JL
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));
fa2989f4
PS
463 rc = CIFSSMBWrite(xid, &io_parms,
464 &bytes_written, (char *)pdev,
5d9ac7fd
JL
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));
fa2989f4
PS
472 rc = CIFSSMBWrite(xid, &io_parms,
473 &bytes_written, (char *)pdev,
5d9ac7fd
JL
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:
d14537f1 482 kfree(full_path);
5d9ac7fd 483 kfree(buf);
1da177e4 484 FreeXid(xid);
7ffec372 485 cifs_put_tlink(tlink);
1da177e4
LT
486 return rc;
487}
488
1da177e4 489struct dentry *
5fdae1f6
SF
490cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
491 struct nameidata *nd)
1da177e4
LT
492{
493 int xid;
494 int rc = 0; /* to get around spurious gcc warning, set to zero here */
10b9b98e 495 __u32 oplock;
a6ce4932
SF
496 __u16 fileHandle = 0;
497 bool posix_open = false;
1da177e4 498 struct cifs_sb_info *cifs_sb;
7ffec372 499 struct tcon_link *tlink;
96daf2b0 500 struct cifs_tcon *pTcon;
2422f676 501 struct cifsFileInfo *cfile;
1da177e4
LT
502 struct inode *newInode = NULL;
503 char *full_path = NULL;
a6ce4932 504 struct file *filp;
1da177e4
LT
505
506 xid = GetXid();
507
b6b38f70
JP
508 cFYI(1, "parent inode = 0x%p name is: %s and dentry = 0x%p",
509 parent_dir_inode, direntry->d_name.name, direntry);
1da177e4 510
1da177e4
LT
511 /* check whether path exists */
512
513 cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
7ffec372
JL
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);
1da177e4 520
10b9b98e
PS
521 oplock = pTcon->ses->server->oplocks ? REQ_OPLOCK : 0;
522
296034f7
SF
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] == '\\') {
b6b38f70 531 cFYI(1, "Invalid file name");
7ffec372
JL
532 rc = -EINVAL;
533 goto lookup_out;
296034f7
SF
534 }
535 }
536
5ddf1e0f
JL
537 /*
538 * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
539 * the VFS handle the create.
540 */
8e6c0332 541 if (nd && (nd->flags & LOOKUP_EXCL)) {
5ddf1e0f 542 d_instantiate(direntry, NULL);
7ffec372
JL
543 rc = 0;
544 goto lookup_out;
5ddf1e0f
JL
545 }
546
1da177e4
LT
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);
5fdae1f6 551 if (full_path == NULL) {
7ffec372
JL
552 rc = -ENOMEM;
553 goto lookup_out;
1da177e4
LT
554 }
555
556 if (direntry->d_inode != NULL) {
b6b38f70 557 cFYI(1, "non-NULL inode in lookup");
1da177e4 558 } else {
b6b38f70 559 cFYI(1, "NULL inode in lookup");
1da177e4 560 }
b6b38f70 561 cFYI(1, "Full path: %s inode = 0x%p", full_path, direntry->d_inode);
1da177e4 562
8db14ca1
SF
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 */
a6ce4932 573 if (pTcon->unix_ext) {
43527803 574 if (nd && !(nd->flags & LOOKUP_DIRECTORY) &&
8db14ca1 575 (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
608712fe 576 (nd->intent.open.file->f_flags & O_CREAT)) {
2422f676 577 rc = cifs_posix_open(full_path, &newInode,
fa588e0c 578 parent_dir_inode->i_sb,
703a3b8e 579 nd->intent.open.create_mode,
608712fe 580 nd->intent.open.file->f_flags, &oplock,
a6ce4932 581 &fileHandle, xid);
8db14ca1
SF
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 */
5bccda0e
JL
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:
8db14ca1 603 posix_open = true;
5bccda0e
JL
604 case -EOPNOTSUPP:
605 break;
606 default:
8db14ca1 607 pTcon->broken_posix_open = true;
5bccda0e 608 }
a6ce4932
SF
609 }
610 if (!posix_open)
611 rc = cifs_get_inode_info_unix(&newInode, full_path,
612 parent_dir_inode->i_sb, xid);
613 } else
1da177e4 614 rc = cifs_get_inode_info(&newInode, full_path, NULL,
a6ce4932 615 parent_dir_inode->i_sb, xid, NULL);
1da177e4
LT
616
617 if ((rc == 0) && (newInode != NULL)) {
1da177e4 618 d_add(direntry, newInode);
2422f676 619 if (posix_open) {
6ca9f3ba
JL
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
abfe1eed
JL
628 cfile = cifs_new_fileinfo(fileHandle, filp, tlink,
629 oplock);
2422f676 630 if (cfile == NULL) {
6ca9f3ba 631 fput(filp);
2422f676
JL
632 CIFSSMBClose(xid, pTcon, fileHandle);
633 rc = -ENOMEM;
634 goto lookup_out;
635 }
2422f676 636 }
5fdae1f6 637 /* since paths are not looked up by component - the parent
3abb9272 638 directories are presumed to be good here */
1da177e4
LT
639 renew_parental_timestamps(direntry);
640
641 } else if (rc == -ENOENT) {
642 rc = 0;
3abb9272 643 direntry->d_time = jiffies;
1da177e4 644 d_add(direntry, NULL);
5fdae1f6
SF
645 /* if it was once a directory (but how can we tell?) we could do
646 shrink_dcache_parent(direntry); */
ed2b9170 647 } else if (rc != -EACCES) {
b6b38f70 648 cERROR(1, "Unexpected lookup error %d", rc);
ed2b9170
SF
649 /* We special case check for Access Denied - since that
650 is a common return code */
1da177e4
LT
651 }
652
2422f676 653lookup_out:
d14537f1 654 kfree(full_path);
7ffec372 655 cifs_put_tlink(tlink);
1da177e4
LT
656 FreeXid(xid);
657 return ERR_PTR(rc);
658}
659
1da177e4
LT
660static int
661cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
662{
3ca30d40 663 if (nd && (nd->flags & LOOKUP_RCU))
34286d66
NP
664 return -ECHILD;
665
1da177e4 666 if (direntry->d_inode) {
df2cf170 667 if (cifs_revalidate_dentry(direntry))
1da177e4 668 return 0;
ad4778fb
GF
669 else {
670 /*
671 * Forcibly invalidate automounting directory inodes
672 * (remote DFS directories) so to have them
673 * instantiated again for automount
674 */
675 if (IS_AUTOMOUNT(direntry->d_inode))
676 return 0;
262f86ad 677 return 1;
ad4778fb 678 }
1da177e4
LT
679 }
680
262f86ad
NP
681 /*
682 * This may be nfsd (or something), anyway, we can't see the
683 * intent of this. So, since this can be for creation, drop it.
684 */
685 if (!nd)
686 return 0;
687
688 /*
689 * Drop the negative dentry, in order to make sure to use the
690 * case sensitive name which is specified by user if this is
691 * for creation.
692 */
407938e7
AV
693 if (nd->flags & (LOOKUP_CREATE | LOOKUP_RENAME_TARGET))
694 return 0;
262f86ad
NP
695
696 if (time_after(jiffies, direntry->d_time + HZ) || !lookupCacheEnabled)
697 return 0;
698
699 return 1;
1da177e4
LT
700}
701
702/* static int cifs_d_delete(struct dentry *direntry)
703{
704 int rc = 0;
705
b6b38f70 706 cFYI(1, "In cifs d_delete, name = %s", direntry->d_name.name);
1da177e4
LT
707
708 return rc;
709} */
710
4fd03e84 711const struct dentry_operations cifs_dentry_ops = {
1da177e4 712 .d_revalidate = cifs_d_revalidate,
01c64fea 713 .d_automount = cifs_dfs_d_automount,
5fdae1f6 714/* d_delete: cifs_d_delete, */ /* not needed except for debugging */
1da177e4 715};
b92327fe 716
b1e6a015
NP
717static int cifs_ci_hash(const struct dentry *dentry, const struct inode *inode,
718 struct qstr *q)
b92327fe 719{
b1e6a015 720 struct nls_table *codepage = CIFS_SB(dentry->d_sb)->local_nls;
b92327fe
SF
721 unsigned long hash;
722 int i;
723
724 hash = init_name_hash();
725 for (i = 0; i < q->len; i++)
726 hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
727 hash);
728 q->hash = end_name_hash(hash);
729
730 return 0;
731}
732
621e155a
NP
733static int cifs_ci_compare(const struct dentry *parent,
734 const struct inode *pinode,
735 const struct dentry *dentry, const struct inode *inode,
736 unsigned int len, const char *str, const struct qstr *name)
b92327fe 737{
621e155a 738 struct nls_table *codepage = CIFS_SB(pinode->i_sb)->local_nls;
b92327fe 739
621e155a
NP
740 if ((name->len == len) &&
741 (nls_strnicmp(codepage, name->name, str, len) == 0))
b92327fe 742 return 0;
b92327fe
SF
743 return 1;
744}
745
4fd03e84 746const struct dentry_operations cifs_ci_dentry_ops = {
b92327fe
SF
747 .d_revalidate = cifs_d_revalidate,
748 .d_hash = cifs_ci_hash,
749 .d_compare = cifs_ci_compare,
01c64fea 750 .d_automount = cifs_dfs_d_automount,
b92327fe 751};