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