Merge branch 'timers-for-linus-migration' of git://git.kernel.org/pub/scm/linux/kerne...
[pandora-kernel.git] / fs / cifs / dir.c
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 "cifsfs.h"
28 #include "cifspdu.h"
29 #include "cifsglob.h"
30 #include "cifsproto.h"
31 #include "cifs_debug.h"
32 #include "cifs_fs_sb.h"
33
34 static void
35 renew_parental_timestamps(struct dentry *direntry)
36 {
37         /* BB check if there is a way to get the kernel to do this or if we
38            really need this */
39         do {
40                 direntry->d_time = jiffies;
41                 direntry = direntry->d_parent;
42         } while (!IS_ROOT(direntry));
43 }
44
45 /* Note: caller must free return buffer */
46 char *
47 build_path_from_dentry(struct dentry *direntry)
48 {
49         struct dentry *temp;
50         int namelen;
51         int pplen;
52         int dfsplen;
53         char *full_path;
54         char dirsep;
55         struct cifs_sb_info *cifs_sb;
56
57         if (direntry == NULL)
58                 return NULL;  /* not much we can do if dentry is freed and
59                 we need to reopen the file after it was closed implicitly
60                 when the server crashed */
61
62         cifs_sb = CIFS_SB(direntry->d_sb);
63         dirsep = CIFS_DIR_SEP(cifs_sb);
64         pplen = cifs_sb->prepathlen;
65         if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS))
66                 dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1);
67         else
68                 dfsplen = 0;
69 cifs_bp_rename_retry:
70         namelen = pplen + dfsplen;
71         for (temp = direntry; !IS_ROOT(temp);) {
72                 namelen += (1 + temp->d_name.len);
73                 temp = temp->d_parent;
74                 if (temp == NULL) {
75                         cERROR(1, ("corrupt dentry"));
76                         return NULL;
77                 }
78         }
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         for (temp = direntry; !IS_ROOT(temp);) {
85                 namelen -= 1 + temp->d_name.len;
86                 if (namelen < 0) {
87                         break;
88                 } else {
89                         full_path[namelen] = dirsep;
90                         strncpy(full_path + namelen + 1, temp->d_name.name,
91                                 temp->d_name.len);
92                         cFYI(0, ("name: %s", full_path + namelen));
93                 }
94                 temp = temp->d_parent;
95                 if (temp == NULL) {
96                         cERROR(1, ("corrupt dentry"));
97                         kfree(full_path);
98                         return NULL;
99                 }
100         }
101         if (namelen != pplen + dfsplen) {
102                 cERROR(1,
103                        ("did not end path lookup where expected namelen is %d",
104                         namelen));
105                 /* presumably this is only possible if racing with a rename
106                 of one of the parent directories  (we can not lock the dentries
107                 above us to prevent this, but retrying should be harmless) */
108                 kfree(full_path);
109                 goto cifs_bp_rename_retry;
110         }
111         /* DIR_SEP already set for byte  0 / vs \ but not for
112            subsequent slashes in prepath which currently must
113            be entered the right way - not sure if there is an alternative
114            since the '\' is a valid posix character so we can not switch
115            those safely to '/' if any are found in the middle of the prepath */
116         /* BB test paths to Windows with '/' in the midst of prepath */
117
118         if (dfsplen) {
119                 strncpy(full_path, cifs_sb->tcon->treeName, dfsplen);
120                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
121                         int i;
122                         for (i = 0; i < dfsplen; i++) {
123                                 if (full_path[i] == '\\')
124                                         full_path[i] = '/';
125                         }
126                 }
127         }
128         strncpy(full_path + dfsplen, CIFS_SB(direntry->d_sb)->prepath, pplen);
129         return full_path;
130 }
131
132 static void
133 cifs_fill_fileinfo(struct inode *newinode, __u16 fileHandle,
134                         struct cifsTconInfo *tcon, bool write_only)
135 {
136         int oplock = 0;
137         struct cifsFileInfo *pCifsFile;
138         struct cifsInodeInfo *pCifsInode;
139
140         pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
141
142         if (pCifsFile == NULL)
143                 return;
144
145         if (oplockEnabled)
146                 oplock = REQ_OPLOCK;
147
148         pCifsFile->netfid = fileHandle;
149         pCifsFile->pid = current->tgid;
150         pCifsFile->pInode = newinode;
151         pCifsFile->invalidHandle = false;
152         pCifsFile->closePend = false;
153         mutex_init(&pCifsFile->fh_mutex);
154         mutex_init(&pCifsFile->lock_mutex);
155         INIT_LIST_HEAD(&pCifsFile->llist);
156         atomic_set(&pCifsFile->wrtPending, 0);
157
158         /* set the following in open now
159                         pCifsFile->pfile = file; */
160         write_lock(&GlobalSMBSeslock);
161         list_add(&pCifsFile->tlist, &tcon->openFileList);
162         pCifsInode = CIFS_I(newinode);
163         if (pCifsInode) {
164                 /* if readable file instance put first in list*/
165                 if (write_only)
166                         list_add_tail(&pCifsFile->flist,
167                                       &pCifsInode->openFileList);
168                 else
169                         list_add(&pCifsFile->flist, &pCifsInode->openFileList);
170
171                 if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
172                         pCifsInode->clientCanCacheAll = true;
173                         pCifsInode->clientCanCacheRead = true;
174                         cFYI(1, ("Exclusive Oplock inode %p", newinode));
175                 } else if ((oplock & 0xF) == OPLOCK_READ)
176                                 pCifsInode->clientCanCacheRead = true;
177         }
178         write_unlock(&GlobalSMBSeslock);
179 }
180
181 int cifs_posix_open(char *full_path, struct inode **pinode,
182                     struct super_block *sb, int mode, int oflags,
183                     int *poplock, __u16 *pnetfid, int xid)
184 {
185         int rc;
186         __u32 oplock;
187         bool write_only = false;
188         FILE_UNIX_BASIC_INFO *presp_data;
189         __u32 posix_flags = 0;
190         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
191
192         cFYI(1, ("posix open %s", full_path));
193
194         presp_data = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
195         if (presp_data == NULL)
196                 return -ENOMEM;
197
198 /* So far cifs posix extensions can only map the following flags.
199    There are other valid fmode oflags such as FMODE_LSEEK, FMODE_PREAD, but
200    so far we do not seem to need them, and we can treat them as local only */
201         if ((oflags & (FMODE_READ | FMODE_WRITE)) ==
202                 (FMODE_READ | FMODE_WRITE))
203                 posix_flags = SMB_O_RDWR;
204         else if (oflags & FMODE_READ)
205                 posix_flags = SMB_O_RDONLY;
206         else if (oflags & FMODE_WRITE)
207                 posix_flags = SMB_O_WRONLY;
208         if (oflags & O_CREAT)
209                 posix_flags |= SMB_O_CREAT;
210         if (oflags & O_EXCL)
211                 posix_flags |= SMB_O_EXCL;
212         if (oflags & O_TRUNC)
213                 posix_flags |= SMB_O_TRUNC;
214         if (oflags & O_APPEND)
215                 posix_flags |= SMB_O_APPEND;
216         if (oflags & O_SYNC)
217                 posix_flags |= SMB_O_SYNC;
218         if (oflags & O_DIRECTORY)
219                 posix_flags |= SMB_O_DIRECTORY;
220         if (oflags & O_NOFOLLOW)
221                 posix_flags |= SMB_O_NOFOLLOW;
222         if (oflags & O_DIRECT)
223                 posix_flags |= SMB_O_DIRECT;
224
225         if (!(oflags & FMODE_READ))
226                 write_only = true;
227
228         mode &= ~current_umask();
229         rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode,
230                         pnetfid, presp_data, &oplock, full_path,
231                         cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
232                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
233         if (rc)
234                 goto posix_open_ret;
235
236         if (presp_data->Type == cpu_to_le32(-1))
237                 goto posix_open_ret; /* open ok, caller does qpathinfo */
238
239         /* get new inode and set it up */
240         if (!pinode)
241                 goto posix_open_ret; /* caller does not need info */
242
243         if (*pinode == NULL) {
244                 __u64 unique_id = le64_to_cpu(presp_data->UniqueId);
245                 *pinode = cifs_new_inode(sb, &unique_id);
246         }
247         /* else an inode was passed in. Update its info, don't create one */
248
249         /* We do not need to close the file if new_inode fails since
250            the caller will retry qpathinfo as long as inode is null */
251         if (*pinode == NULL)
252                 goto posix_open_ret;
253
254         posix_fill_in_inode(*pinode, presp_data, 1);
255
256         cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only);
257
258 posix_open_ret:
259         kfree(presp_data);
260         return rc;
261 }
262
263 static void setup_cifs_dentry(struct cifsTconInfo *tcon,
264                               struct dentry *direntry,
265                               struct inode *newinode)
266 {
267         if (tcon->nocase)
268                 direntry->d_op = &cifs_ci_dentry_ops;
269         else
270                 direntry->d_op = &cifs_dentry_ops;
271         d_instantiate(direntry, newinode);
272 }
273
274 /* Inode operations in similar order to how they appear in Linux file fs.h */
275
276 int
277 cifs_create(struct inode *inode, struct dentry *direntry, int mode,
278                 struct nameidata *nd)
279 {
280         int rc = -ENOENT;
281         int xid;
282         int create_options = CREATE_NOT_DIR;
283         int oplock = 0;
284         int oflags;
285         bool posix_create = false;
286         /*
287          * BB below access is probably too much for mknod to request
288          *    but we have to do query and setpathinfo so requesting
289          *    less could fail (unless we want to request getatr and setatr
290          *    permissions (only).  At least for POSIX we do not have to
291          *    request so much.
292          */
293         int desiredAccess = GENERIC_READ | GENERIC_WRITE;
294         __u16 fileHandle;
295         struct cifs_sb_info *cifs_sb;
296         struct cifsTconInfo *tcon;
297         char *full_path = NULL;
298         FILE_ALL_INFO *buf = NULL;
299         struct inode *newinode = NULL;
300         int disposition = FILE_OVERWRITE_IF;
301         bool write_only = false;
302
303         xid = GetXid();
304
305         cifs_sb = CIFS_SB(inode->i_sb);
306         tcon = cifs_sb->tcon;
307
308         full_path = build_path_from_dentry(direntry);
309         if (full_path == NULL) {
310                 FreeXid(xid);
311                 return -ENOMEM;
312         }
313
314         if (oplockEnabled)
315                 oplock = REQ_OPLOCK;
316
317         if (nd && (nd->flags & LOOKUP_OPEN))
318                 oflags = nd->intent.open.flags;
319         else
320                 oflags = FMODE_READ;
321
322         if (tcon->unix_ext && (tcon->ses->capabilities & CAP_UNIX) &&
323             (CIFS_UNIX_POSIX_PATH_OPS_CAP &
324                         le64_to_cpu(tcon->fsUnixInfo.Capability))) {
325                 rc = cifs_posix_open(full_path, &newinode, inode->i_sb,
326                                      mode, oflags, &oplock, &fileHandle, xid);
327                 /* EIO could indicate that (posix open) operation is not
328                    supported, despite what server claimed in capability
329                    negotation.  EREMOTE indicates DFS junction, which is not
330                    handled in posix open */
331
332                 if (rc == 0) {
333                         posix_create = true;
334                         if (newinode == NULL) /* query inode info */
335                                 goto cifs_create_get_file_info;
336                         else /* success, no need to query */
337                                 goto cifs_create_set_dentry;
338                 } else if ((rc != -EIO) && (rc != -EREMOTE) &&
339                          (rc != -EOPNOTSUPP) && (rc != -EINVAL))
340                         goto cifs_create_out;
341                 /* else fallthrough to retry, using older open call, this is
342                    case where server does not support this SMB level, and
343                    falsely claims capability (also get here for DFS case
344                    which should be rare for path not covered on files) */
345         }
346
347         if (nd && (nd->flags & LOOKUP_OPEN)) {
348                 /* if the file is going to stay open, then we
349                    need to set the desired access properly */
350                 desiredAccess = 0;
351                 if (oflags & FMODE_READ)
352                         desiredAccess |= GENERIC_READ; /* is this too little? */
353                 if (oflags & FMODE_WRITE) {
354                         desiredAccess |= GENERIC_WRITE;
355                         if (!(oflags & FMODE_READ))
356                                 write_only = true;
357                 }
358
359                 if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
360                         disposition = FILE_CREATE;
361                 else if ((oflags & (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))
362                         disposition = FILE_OVERWRITE_IF;
363                 else if ((oflags & O_CREAT) == O_CREAT)
364                         disposition = FILE_OPEN_IF;
365                 else
366                         cFYI(1, ("Create flag not set in create function"));
367         }
368
369         /* BB add processing to set equivalent of mode - e.g. via CreateX with
370            ACLs */
371
372         buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
373         if (buf == NULL) {
374                 kfree(full_path);
375                 FreeXid(xid);
376                 return -ENOMEM;
377         }
378
379         /*
380          * if we're not using unix extensions, see if we need to set
381          * ATTR_READONLY on the create call
382          */
383         if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
384                 create_options |= CREATE_OPTION_READONLY;
385
386         if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS)
387                 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
388                          desiredAccess, create_options,
389                          &fileHandle, &oplock, buf, cifs_sb->local_nls,
390                          cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
391         else
392                 rc = -EIO; /* no NT SMB support fall into legacy open below */
393
394         if (rc == -EIO) {
395                 /* old server, retry the open legacy style */
396                 rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
397                         desiredAccess, create_options,
398                         &fileHandle, &oplock, buf, cifs_sb->local_nls,
399                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
400         }
401         if (rc) {
402                 cFYI(1, ("cifs_create returned 0x%x", rc));
403                 goto cifs_create_out;
404         }
405
406         /* If Open reported that we actually created a file
407            then we now have to set the mode if possible */
408         if ((tcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) {
409                 struct cifs_unix_set_info_args args = {
410                                 .mode   = mode,
411                                 .ctime  = NO_CHANGE_64,
412                                 .atime  = NO_CHANGE_64,
413                                 .mtime  = NO_CHANGE_64,
414                                 .device = 0,
415                 };
416
417                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
418                         args.uid = (__u64) current_fsuid();
419                         if (inode->i_mode & S_ISGID)
420                                 args.gid = (__u64) inode->i_gid;
421                         else
422                                 args.gid = (__u64) current_fsgid();
423                 } else {
424                         args.uid = NO_CHANGE_64;
425                         args.gid = NO_CHANGE_64;
426                 }
427                 CIFSSMBUnixSetInfo(xid, tcon, full_path, &args,
428                         cifs_sb->local_nls,
429                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
430         } else {
431                 /* BB implement mode setting via Windows security
432                    descriptors e.g. */
433                 /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
434
435                 /* Could set r/o dos attribute if mode & 0222 == 0 */
436         }
437
438 cifs_create_get_file_info:
439         /* server might mask mode so we have to query for it */
440         if (tcon->unix_ext)
441                 rc = cifs_get_inode_info_unix(&newinode, full_path,
442                                               inode->i_sb, xid);
443         else {
444                 rc = cifs_get_inode_info(&newinode, full_path, buf,
445                                          inode->i_sb, xid, &fileHandle);
446                 if (newinode) {
447                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
448                                 newinode->i_mode = mode;
449                         if ((oplock & CIFS_CREATE_ACTION) &&
450                             (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
451                                 newinode->i_uid = current_fsuid();
452                                 if (inode->i_mode & S_ISGID)
453                                         newinode->i_gid = inode->i_gid;
454                                 else
455                                         newinode->i_gid = current_fsgid();
456                         }
457                 }
458         }
459
460 cifs_create_set_dentry:
461         if (rc == 0)
462                 setup_cifs_dentry(tcon, direntry, newinode);
463         else
464                 cFYI(1, ("Create worked, get_inode_info failed rc = %d", rc));
465
466         /* nfsd case - nfs srv does not set nd */
467         if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) {
468                 /* mknod case - do not leave file open */
469                 CIFSSMBClose(xid, tcon, fileHandle);
470         } else if (!(posix_create) && (newinode)) {
471                         cifs_fill_fileinfo(newinode, fileHandle,
472                                         cifs_sb->tcon, write_only);
473         }
474 cifs_create_out:
475         kfree(buf);
476         kfree(full_path);
477         FreeXid(xid);
478         return rc;
479 }
480
481 int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
482                 dev_t device_number)
483 {
484         int rc = -EPERM;
485         int xid;
486         struct cifs_sb_info *cifs_sb;
487         struct cifsTconInfo *pTcon;
488         char *full_path = NULL;
489         struct inode *newinode = NULL;
490
491         if (!old_valid_dev(device_number))
492                 return -EINVAL;
493
494         xid = GetXid();
495
496         cifs_sb = CIFS_SB(inode->i_sb);
497         pTcon = cifs_sb->tcon;
498
499         full_path = build_path_from_dentry(direntry);
500         if (full_path == NULL)
501                 rc = -ENOMEM;
502         else if (pTcon->unix_ext) {
503                 struct cifs_unix_set_info_args args = {
504                         .mode   = mode & ~current_umask(),
505                         .ctime  = NO_CHANGE_64,
506                         .atime  = NO_CHANGE_64,
507                         .mtime  = NO_CHANGE_64,
508                         .device = device_number,
509                 };
510                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
511                         args.uid = (__u64) current_fsuid();
512                         args.gid = (__u64) current_fsgid();
513                 } else {
514                         args.uid = NO_CHANGE_64;
515                         args.gid = NO_CHANGE_64;
516                 }
517                 rc = CIFSSMBUnixSetInfo(xid, pTcon, full_path,
518                         &args, cifs_sb->local_nls,
519                         cifs_sb->mnt_cifs_flags &
520                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
521
522                 if (!rc) {
523                         rc = cifs_get_inode_info_unix(&newinode, full_path,
524                                                 inode->i_sb, xid);
525                         if (pTcon->nocase)
526                                 direntry->d_op = &cifs_ci_dentry_ops;
527                         else
528                                 direntry->d_op = &cifs_dentry_ops;
529                         if (rc == 0)
530                                 d_instantiate(direntry, newinode);
531                 }
532         } else {
533                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
534                         int oplock = 0;
535                         u16 fileHandle;
536                         FILE_ALL_INFO *buf;
537
538                         cFYI(1, ("sfu compat create special file"));
539
540                         buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
541                         if (buf == NULL) {
542                                 kfree(full_path);
543                                 FreeXid(xid);
544                                 return -ENOMEM;
545                         }
546
547                         rc = CIFSSMBOpen(xid, pTcon, full_path,
548                                          FILE_CREATE, /* fail if exists */
549                                          GENERIC_WRITE /* BB would
550                                           WRITE_OWNER | WRITE_DAC be better? */,
551                                          /* Create a file and set the
552                                             file attribute to SYSTEM */
553                                          CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
554                                          &fileHandle, &oplock, buf,
555                                          cifs_sb->local_nls,
556                                          cifs_sb->mnt_cifs_flags &
557                                             CIFS_MOUNT_MAP_SPECIAL_CHR);
558
559                         /* BB FIXME - add handling for backlevel servers
560                            which need legacy open and check for all
561                            calls to SMBOpen for fallback to SMBLeagcyOpen */
562                         if (!rc) {
563                                 /* BB Do not bother to decode buf since no
564                                    local inode yet to put timestamps in,
565                                    but we can reuse it safely */
566                                 unsigned int bytes_written;
567                                 struct win_dev *pdev;
568                                 pdev = (struct win_dev *)buf;
569                                 if (S_ISCHR(mode)) {
570                                         memcpy(pdev->type, "IntxCHR", 8);
571                                         pdev->major =
572                                               cpu_to_le64(MAJOR(device_number));
573                                         pdev->minor =
574                                               cpu_to_le64(MINOR(device_number));
575                                         rc = CIFSSMBWrite(xid, pTcon,
576                                                 fileHandle,
577                                                 sizeof(struct win_dev),
578                                                 0, &bytes_written, (char *)pdev,
579                                                 NULL, 0);
580                                 } else if (S_ISBLK(mode)) {
581                                         memcpy(pdev->type, "IntxBLK", 8);
582                                         pdev->major =
583                                               cpu_to_le64(MAJOR(device_number));
584                                         pdev->minor =
585                                               cpu_to_le64(MINOR(device_number));
586                                         rc = CIFSSMBWrite(xid, pTcon,
587                                                 fileHandle,
588                                                 sizeof(struct win_dev),
589                                                 0, &bytes_written, (char *)pdev,
590                                                 NULL, 0);
591                                 } /* else if(S_ISFIFO */
592                                 CIFSSMBClose(xid, pTcon, fileHandle);
593                                 d_drop(direntry);
594                         }
595                         kfree(buf);
596                         /* add code here to set EAs */
597                 }
598         }
599
600         kfree(full_path);
601         FreeXid(xid);
602         return rc;
603 }
604
605 struct dentry *
606 cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
607             struct nameidata *nd)
608 {
609         int xid;
610         int rc = 0; /* to get around spurious gcc warning, set to zero here */
611         int oplock = 0;
612         __u16 fileHandle = 0;
613         bool posix_open = false;
614         struct cifs_sb_info *cifs_sb;
615         struct cifsTconInfo *pTcon;
616         struct inode *newInode = NULL;
617         char *full_path = NULL;
618         struct file *filp;
619
620         xid = GetXid();
621
622         cFYI(1, ("parent inode = 0x%p name is: %s and dentry = 0x%p",
623               parent_dir_inode, direntry->d_name.name, direntry));
624
625         /* check whether path exists */
626
627         cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
628         pTcon = cifs_sb->tcon;
629
630         /*
631          * Don't allow the separator character in a path component.
632          * The VFS will not allow "/", but "\" is allowed by posix.
633          */
634         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
635                 int i;
636                 for (i = 0; i < direntry->d_name.len; i++)
637                         if (direntry->d_name.name[i] == '\\') {
638                                 cFYI(1, ("Invalid file name"));
639                                 FreeXid(xid);
640                                 return ERR_PTR(-EINVAL);
641                         }
642         }
643
644         /* can not grab the rename sem here since it would
645         deadlock in the cases (beginning of sys_rename itself)
646         in which we already have the sb rename sem */
647         full_path = build_path_from_dentry(direntry);
648         if (full_path == NULL) {
649                 FreeXid(xid);
650                 return ERR_PTR(-ENOMEM);
651         }
652
653         if (direntry->d_inode != NULL) {
654                 cFYI(1, ("non-NULL inode in lookup"));
655         } else {
656                 cFYI(1, ("NULL inode in lookup"));
657         }
658         cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode));
659
660         /* Posix open is only called (at lookup time) for file create now.
661          * For opens (rather than creates), because we do not know if it
662          * is a file or directory yet, and current Samba no longer allows
663          * us to do posix open on dirs, we could end up wasting an open call
664          * on what turns out to be a dir. For file opens, we wait to call posix
665          * open till cifs_open.  It could be added here (lookup) in the future
666          * but the performance tradeoff of the extra network request when EISDIR
667          * or EACCES is returned would have to be weighed against the 50%
668          * reduction in network traffic in the other paths.
669          */
670         if (pTcon->unix_ext) {
671                 if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
672                      (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
673                      (nd->intent.open.flags & O_CREAT)) {
674                         rc = cifs_posix_open(full_path, &newInode,
675                                         parent_dir_inode->i_sb,
676                                         nd->intent.open.create_mode,
677                                         nd->intent.open.flags, &oplock,
678                                         &fileHandle, xid);
679                         /*
680                          * The check below works around a bug in POSIX
681                          * open in samba versions 3.3.1 and earlier where
682                          * open could incorrectly fail with invalid parameter.
683                          * If either that or op not supported returned, follow
684                          * the normal lookup.
685                          */
686                         if ((rc == 0) || (rc == -ENOENT))
687                                 posix_open = true;
688                         else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
689                                 pTcon->broken_posix_open = true;
690                 }
691                 if (!posix_open)
692                         rc = cifs_get_inode_info_unix(&newInode, full_path,
693                                                 parent_dir_inode->i_sb, xid);
694         } else
695                 rc = cifs_get_inode_info(&newInode, full_path, NULL,
696                                 parent_dir_inode->i_sb, xid, NULL);
697
698         if ((rc == 0) && (newInode != NULL)) {
699                 if (pTcon->nocase)
700                         direntry->d_op = &cifs_ci_dentry_ops;
701                 else
702                         direntry->d_op = &cifs_dentry_ops;
703                 d_add(direntry, newInode);
704                 if (posix_open)
705                         filp = lookup_instantiate_filp(nd, direntry, NULL);
706                 /* since paths are not looked up by component - the parent
707                    directories are presumed to be good here */
708                 renew_parental_timestamps(direntry);
709
710         } else if (rc == -ENOENT) {
711                 rc = 0;
712                 direntry->d_time = jiffies;
713                 if (pTcon->nocase)
714                         direntry->d_op = &cifs_ci_dentry_ops;
715                 else
716                         direntry->d_op = &cifs_dentry_ops;
717                 d_add(direntry, NULL);
718         /*      if it was once a directory (but how can we tell?) we could do
719                 shrink_dcache_parent(direntry); */
720         } else if (rc != -EACCES) {
721                 cERROR(1, ("Unexpected lookup error %d", rc));
722                 /* We special case check for Access Denied - since that
723                 is a common return code */
724         }
725
726         kfree(full_path);
727         FreeXid(xid);
728         return ERR_PTR(rc);
729 }
730
731 static int
732 cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
733 {
734         int isValid = 1;
735
736         if (direntry->d_inode) {
737                 if (cifs_revalidate(direntry))
738                         return 0;
739         } else {
740                 cFYI(1, ("neg dentry 0x%p name = %s",
741                          direntry, direntry->d_name.name));
742                 if (time_after(jiffies, direntry->d_time + HZ) ||
743                         !lookupCacheEnabled) {
744                         d_drop(direntry);
745                         isValid = 0;
746                 }
747         }
748
749         return isValid;
750 }
751
752 /* static int cifs_d_delete(struct dentry *direntry)
753 {
754         int rc = 0;
755
756         cFYI(1, ("In cifs d_delete, name = %s", direntry->d_name.name));
757
758         return rc;
759 }     */
760
761 const struct dentry_operations cifs_dentry_ops = {
762         .d_revalidate = cifs_d_revalidate,
763 /* d_delete:       cifs_d_delete,      */ /* not needed except for debugging */
764 };
765
766 static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
767 {
768         struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
769         unsigned long hash;
770         int i;
771
772         hash = init_name_hash();
773         for (i = 0; i < q->len; i++)
774                 hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
775                                          hash);
776         q->hash = end_name_hash(hash);
777
778         return 0;
779 }
780
781 static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
782                            struct qstr *b)
783 {
784         struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
785
786         if ((a->len == b->len) &&
787             (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) {
788                 /*
789                  * To preserve case, don't let an existing negative dentry's
790                  * case take precedence.  If a is not a negative dentry, this
791                  * should have no side effects
792                  */
793                 memcpy((void *)a->name, b->name, a->len);
794                 return 0;
795         }
796         return 1;
797 }
798
799 const struct dentry_operations cifs_ci_dentry_ops = {
800         .d_revalidate = cifs_d_revalidate,
801         .d_hash = cifs_ci_hash,
802         .d_compare = cifs_ci_compare,
803 };