cifs: fix oplock request handling in posix codepath
[safe/jmp/linux-2.6] / 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->count, 1);
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                     __u32 *poplock, __u16 *pnetfid, int xid)
184 {
185         int rc;
186         bool write_only = false;
187         FILE_UNIX_BASIC_INFO *presp_data;
188         __u32 posix_flags = 0;
189         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
190         struct cifs_fattr fattr;
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, poplock, 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         if (!pinode)
240                 goto posix_open_ret; /* caller does not need info */
241
242         cifs_unix_basic_to_fattr(&fattr, presp_data, cifs_sb);
243
244         /* get new inode and set it up */
245         if (*pinode == NULL) {
246                 *pinode = cifs_iget(sb, &fattr);
247                 if (!*pinode) {
248                         rc = -ENOMEM;
249                         goto posix_open_ret;
250                 }
251         } else {
252                 cifs_fattr_to_inode(*pinode, &fattr);
253         }
254
255         cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only);
256
257 posix_open_ret:
258         kfree(presp_data);
259         return rc;
260 }
261
262 static void setup_cifs_dentry(struct cifsTconInfo *tcon,
263                               struct dentry *direntry,
264                               struct inode *newinode)
265 {
266         if (tcon->nocase)
267                 direntry->d_op = &cifs_ci_dentry_ops;
268         else
269                 direntry->d_op = &cifs_dentry_ops;
270         d_instantiate(direntry, newinode);
271 }
272
273 /* Inode operations in similar order to how they appear in Linux file fs.h */
274
275 int
276 cifs_create(struct inode *inode, struct dentry *direntry, int mode,
277                 struct nameidata *nd)
278 {
279         int rc = -ENOENT;
280         int xid;
281         int create_options = CREATE_NOT_DIR;
282         __u32 oplock = 0;
283         int oflags;
284         bool posix_create = false;
285         /*
286          * BB below access is probably too much for mknod to request
287          *    but we have to do query and setpathinfo so requesting
288          *    less could fail (unless we want to request getatr and setatr
289          *    permissions (only).  At least for POSIX we do not have to
290          *    request so much.
291          */
292         int desiredAccess = GENERIC_READ | GENERIC_WRITE;
293         __u16 fileHandle;
294         struct cifs_sb_info *cifs_sb;
295         struct cifsTconInfo *tcon;
296         char *full_path = NULL;
297         FILE_ALL_INFO *buf = NULL;
298         struct inode *newinode = NULL;
299         int disposition = FILE_OVERWRITE_IF;
300         bool write_only = false;
301
302         xid = GetXid();
303
304         cifs_sb = CIFS_SB(inode->i_sb);
305         tcon = cifs_sb->tcon;
306
307         full_path = build_path_from_dentry(direntry);
308         if (full_path == NULL) {
309                 rc = -ENOMEM;
310                 FreeXid(xid);
311                 return rc;
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                 CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args,
428                                         cifs_sb->local_nls,
429                                         cifs_sb->mnt_cifs_flags &
430                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
431         } else {
432                 /* BB implement mode setting via Windows security
433                    descriptors e.g. */
434                 /* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
435
436                 /* Could set r/o dos attribute if mode & 0222 == 0 */
437         }
438
439 cifs_create_get_file_info:
440         /* server might mask mode so we have to query for it */
441         if (tcon->unix_ext)
442                 rc = cifs_get_inode_info_unix(&newinode, full_path,
443                                               inode->i_sb, xid);
444         else {
445                 rc = cifs_get_inode_info(&newinode, full_path, buf,
446                                          inode->i_sb, xid, &fileHandle);
447                 if (newinode) {
448                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
449                                 newinode->i_mode = mode;
450                         if ((oplock & CIFS_CREATE_ACTION) &&
451                             (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) {
452                                 newinode->i_uid = current_fsuid();
453                                 if (inode->i_mode & S_ISGID)
454                                         newinode->i_gid = inode->i_gid;
455                                 else
456                                         newinode->i_gid = current_fsgid();
457                         }
458                 }
459         }
460
461 cifs_create_set_dentry:
462         if (rc == 0)
463                 setup_cifs_dentry(tcon, direntry, newinode);
464         else
465                 cFYI(1, ("Create worked, get_inode_info failed rc = %d", rc));
466
467         /* nfsd case - nfs srv does not set nd */
468         if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) {
469                 /* mknod case - do not leave file open */
470                 CIFSSMBClose(xid, tcon, fileHandle);
471         } else if (!(posix_create) && (newinode)) {
472                         cifs_fill_fileinfo(newinode, fileHandle,
473                                         cifs_sb->tcon, write_only);
474         }
475 cifs_create_out:
476         kfree(buf);
477         kfree(full_path);
478         FreeXid(xid);
479         return rc;
480 }
481
482 int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
483                 dev_t device_number)
484 {
485         int rc = -EPERM;
486         int xid;
487         struct cifs_sb_info *cifs_sb;
488         struct cifsTconInfo *pTcon;
489         char *full_path = NULL;
490         struct inode *newinode = NULL;
491
492         if (!old_valid_dev(device_number))
493                 return -EINVAL;
494
495         xid = GetXid();
496
497         cifs_sb = CIFS_SB(inode->i_sb);
498         pTcon = cifs_sb->tcon;
499
500         full_path = build_path_from_dentry(direntry);
501         if (full_path == NULL)
502                 rc = -ENOMEM;
503         else if (pTcon->unix_ext) {
504                 struct cifs_unix_set_info_args args = {
505                         .mode   = mode & ~current_umask(),
506                         .ctime  = NO_CHANGE_64,
507                         .atime  = NO_CHANGE_64,
508                         .mtime  = NO_CHANGE_64,
509                         .device = device_number,
510                 };
511                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
512                         args.uid = (__u64) current_fsuid();
513                         args.gid = (__u64) current_fsgid();
514                 } else {
515                         args.uid = NO_CHANGE_64;
516                         args.gid = NO_CHANGE_64;
517                 }
518                 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
519                                             cifs_sb->local_nls,
520                                             cifs_sb->mnt_cifs_flags &
521                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
522
523                 if (!rc) {
524                         rc = cifs_get_inode_info_unix(&newinode, full_path,
525                                                 inode->i_sb, xid);
526                         if (pTcon->nocase)
527                                 direntry->d_op = &cifs_ci_dentry_ops;
528                         else
529                                 direntry->d_op = &cifs_dentry_ops;
530                         if (rc == 0)
531                                 d_instantiate(direntry, newinode);
532                 }
533         } else {
534                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
535                         int oplock = 0;
536                         u16 fileHandle;
537                         FILE_ALL_INFO *buf;
538
539                         cFYI(1, ("sfu compat create special file"));
540
541                         buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
542                         if (buf == NULL) {
543                                 kfree(full_path);
544                                 rc = -ENOMEM;
545                                 FreeXid(xid);
546                                 return rc;
547                         }
548
549                         rc = CIFSSMBOpen(xid, pTcon, full_path,
550                                          FILE_CREATE, /* fail if exists */
551                                          GENERIC_WRITE /* BB would
552                                           WRITE_OWNER | WRITE_DAC be better? */,
553                                          /* Create a file and set the
554                                             file attribute to SYSTEM */
555                                          CREATE_NOT_DIR | CREATE_OPTION_SPECIAL,
556                                          &fileHandle, &oplock, buf,
557                                          cifs_sb->local_nls,
558                                          cifs_sb->mnt_cifs_flags &
559                                             CIFS_MOUNT_MAP_SPECIAL_CHR);
560
561                         /* BB FIXME - add handling for backlevel servers
562                            which need legacy open and check for all
563                            calls to SMBOpen for fallback to SMBLeagcyOpen */
564                         if (!rc) {
565                                 /* BB Do not bother to decode buf since no
566                                    local inode yet to put timestamps in,
567                                    but we can reuse it safely */
568                                 unsigned int bytes_written;
569                                 struct win_dev *pdev;
570                                 pdev = (struct win_dev *)buf;
571                                 if (S_ISCHR(mode)) {
572                                         memcpy(pdev->type, "IntxCHR", 8);
573                                         pdev->major =
574                                               cpu_to_le64(MAJOR(device_number));
575                                         pdev->minor =
576                                               cpu_to_le64(MINOR(device_number));
577                                         rc = CIFSSMBWrite(xid, pTcon,
578                                                 fileHandle,
579                                                 sizeof(struct win_dev),
580                                                 0, &bytes_written, (char *)pdev,
581                                                 NULL, 0);
582                                 } else if (S_ISBLK(mode)) {
583                                         memcpy(pdev->type, "IntxBLK", 8);
584                                         pdev->major =
585                                               cpu_to_le64(MAJOR(device_number));
586                                         pdev->minor =
587                                               cpu_to_le64(MINOR(device_number));
588                                         rc = CIFSSMBWrite(xid, pTcon,
589                                                 fileHandle,
590                                                 sizeof(struct win_dev),
591                                                 0, &bytes_written, (char *)pdev,
592                                                 NULL, 0);
593                                 } /* else if(S_ISFIFO */
594                                 CIFSSMBClose(xid, pTcon, fileHandle);
595                                 d_drop(direntry);
596                         }
597                         kfree(buf);
598                         /* add code here to set EAs */
599                 }
600         }
601
602         kfree(full_path);
603         FreeXid(xid);
604         return rc;
605 }
606
607 struct dentry *
608 cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
609             struct nameidata *nd)
610 {
611         int xid;
612         int rc = 0; /* to get around spurious gcc warning, set to zero here */
613         __u32 oplock = 0;
614         __u16 fileHandle = 0;
615         bool posix_open = false;
616         struct cifs_sb_info *cifs_sb;
617         struct cifsTconInfo *pTcon;
618         struct inode *newInode = NULL;
619         char *full_path = NULL;
620         struct file *filp;
621
622         xid = GetXid();
623
624         cFYI(1, ("parent inode = 0x%p name is: %s and dentry = 0x%p",
625               parent_dir_inode, direntry->d_name.name, direntry));
626
627         /* check whether path exists */
628
629         cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
630         pTcon = cifs_sb->tcon;
631
632         /*
633          * Don't allow the separator character in a path component.
634          * The VFS will not allow "/", but "\" is allowed by posix.
635          */
636         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
637                 int i;
638                 for (i = 0; i < direntry->d_name.len; i++)
639                         if (direntry->d_name.name[i] == '\\') {
640                                 cFYI(1, ("Invalid file name"));
641                                 FreeXid(xid);
642                                 return ERR_PTR(-EINVAL);
643                         }
644         }
645
646         /*
647          * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
648          * the VFS handle the create.
649          */
650         if (nd->flags & LOOKUP_EXCL) {
651                 d_instantiate(direntry, NULL);
652                 return 0;
653         }
654
655         /* can not grab the rename sem here since it would
656         deadlock in the cases (beginning of sys_rename itself)
657         in which we already have the sb rename sem */
658         full_path = build_path_from_dentry(direntry);
659         if (full_path == NULL) {
660                 FreeXid(xid);
661                 return ERR_PTR(-ENOMEM);
662         }
663
664         if (direntry->d_inode != NULL) {
665                 cFYI(1, ("non-NULL inode in lookup"));
666         } else {
667                 cFYI(1, ("NULL inode in lookup"));
668         }
669         cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode));
670
671         /* Posix open is only called (at lookup time) for file create now.
672          * For opens (rather than creates), because we do not know if it
673          * is a file or directory yet, and current Samba no longer allows
674          * us to do posix open on dirs, we could end up wasting an open call
675          * on what turns out to be a dir. For file opens, we wait to call posix
676          * open till cifs_open.  It could be added here (lookup) in the future
677          * but the performance tradeoff of the extra network request when EISDIR
678          * or EACCES is returned would have to be weighed against the 50%
679          * reduction in network traffic in the other paths.
680          */
681         if (pTcon->unix_ext) {
682                 if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
683                      (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
684                      (nd->intent.open.flags & O_CREAT)) {
685                         rc = cifs_posix_open(full_path, &newInode,
686                                         parent_dir_inode->i_sb,
687                                         nd->intent.open.create_mode,
688                                         nd->intent.open.flags, &oplock,
689                                         &fileHandle, xid);
690                         /*
691                          * The check below works around a bug in POSIX
692                          * open in samba versions 3.3.1 and earlier where
693                          * open could incorrectly fail with invalid parameter.
694                          * If either that or op not supported returned, follow
695                          * the normal lookup.
696                          */
697                         if ((rc == 0) || (rc == -ENOENT))
698                                 posix_open = true;
699                         else if ((rc == -EINVAL) || (rc != -EOPNOTSUPP))
700                                 pTcon->broken_posix_open = true;
701                 }
702                 if (!posix_open)
703                         rc = cifs_get_inode_info_unix(&newInode, full_path,
704                                                 parent_dir_inode->i_sb, xid);
705         } else
706                 rc = cifs_get_inode_info(&newInode, full_path, NULL,
707                                 parent_dir_inode->i_sb, xid, NULL);
708
709         if ((rc == 0) && (newInode != NULL)) {
710                 if (pTcon->nocase)
711                         direntry->d_op = &cifs_ci_dentry_ops;
712                 else
713                         direntry->d_op = &cifs_dentry_ops;
714                 d_add(direntry, newInode);
715                 if (posix_open)
716                         filp = lookup_instantiate_filp(nd, direntry, NULL);
717                 /* since paths are not looked up by component - the parent
718                    directories are presumed to be good here */
719                 renew_parental_timestamps(direntry);
720
721         } else if (rc == -ENOENT) {
722                 rc = 0;
723                 direntry->d_time = jiffies;
724                 if (pTcon->nocase)
725                         direntry->d_op = &cifs_ci_dentry_ops;
726                 else
727                         direntry->d_op = &cifs_dentry_ops;
728                 d_add(direntry, NULL);
729         /*      if it was once a directory (but how can we tell?) we could do
730                 shrink_dcache_parent(direntry); */
731         } else if (rc != -EACCES) {
732                 cERROR(1, ("Unexpected lookup error %d", rc));
733                 /* We special case check for Access Denied - since that
734                 is a common return code */
735         }
736
737         kfree(full_path);
738         FreeXid(xid);
739         return ERR_PTR(rc);
740 }
741
742 static int
743 cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
744 {
745         int isValid = 1;
746
747         if (direntry->d_inode) {
748                 if (cifs_revalidate(direntry))
749                         return 0;
750         } else {
751                 cFYI(1, ("neg dentry 0x%p name = %s",
752                          direntry, direntry->d_name.name));
753                 if (time_after(jiffies, direntry->d_time + HZ) ||
754                         !lookupCacheEnabled) {
755                         d_drop(direntry);
756                         isValid = 0;
757                 }
758         }
759
760         return isValid;
761 }
762
763 /* static int cifs_d_delete(struct dentry *direntry)
764 {
765         int rc = 0;
766
767         cFYI(1, ("In cifs d_delete, name = %s", direntry->d_name.name));
768
769         return rc;
770 }     */
771
772 const struct dentry_operations cifs_dentry_ops = {
773         .d_revalidate = cifs_d_revalidate,
774 /* d_delete:       cifs_d_delete,      */ /* not needed except for debugging */
775 };
776
777 static int cifs_ci_hash(struct dentry *dentry, struct qstr *q)
778 {
779         struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
780         unsigned long hash;
781         int i;
782
783         hash = init_name_hash();
784         for (i = 0; i < q->len; i++)
785                 hash = partial_name_hash(nls_tolower(codepage, q->name[i]),
786                                          hash);
787         q->hash = end_name_hash(hash);
788
789         return 0;
790 }
791
792 static int cifs_ci_compare(struct dentry *dentry, struct qstr *a,
793                            struct qstr *b)
794 {
795         struct nls_table *codepage = CIFS_SB(dentry->d_inode->i_sb)->local_nls;
796
797         if ((a->len == b->len) &&
798             (nls_strnicmp(codepage, a->name, b->name, a->len) == 0)) {
799                 /*
800                  * To preserve case, don't let an existing negative dentry's
801                  * case take precedence.  If a is not a negative dentry, this
802                  * should have no side effects
803                  */
804                 memcpy((void *)a->name, b->name, a->len);
805                 return 0;
806         }
807         return 1;
808 }
809
810 const struct dentry_operations cifs_ci_dentry_ops = {
811         .d_revalidate = cifs_d_revalidate,
812         .d_hash = cifs_ci_hash,
813         .d_compare = cifs_ci_compare,
814 };