]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - fs/cifs/inode.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-rc-fixes-2.6
[linux-2.6.git] / fs / cifs / inode.c
1 /*
2  *   fs/cifs/inode.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2010
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   This library is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU Lesser General Public License as published
9  *   by the Free Software Foundation; either version 2.1 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This library is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15  *   the GNU Lesser General Public License for more details.
16  *
17  *   You should have received a copy of the GNU Lesser General Public License
18  *   along with this library; if not, write to the Free Software
19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 #include <linux/fs.h>
22 #include <linux/stat.h>
23 #include <linux/slab.h>
24 #include <linux/pagemap.h>
25 #include <asm/div64.h>
26 #include "cifsfs.h"
27 #include "cifspdu.h"
28 #include "cifsglob.h"
29 #include "cifsproto.h"
30 #include "cifs_debug.h"
31 #include "cifs_fs_sb.h"
32
33
34 static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
35 {
36         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
37
38         switch (inode->i_mode & S_IFMT) {
39         case S_IFREG:
40                 inode->i_op = &cifs_file_inode_ops;
41                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
42                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
43                                 inode->i_fop = &cifs_file_direct_nobrl_ops;
44                         else
45                                 inode->i_fop = &cifs_file_direct_ops;
46                 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
47                         inode->i_fop = &cifs_file_nobrl_ops;
48                 else { /* not direct, send byte range locks */
49                         inode->i_fop = &cifs_file_ops;
50                 }
51
52
53                 /* check if server can support readpages */
54                 if (cifs_sb->tcon->ses->server->maxBuf <
55                                 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
56                         inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
57                 else
58                         inode->i_data.a_ops = &cifs_addr_ops;
59                 break;
60         case S_IFDIR:
61 #ifdef CONFIG_CIFS_DFS_UPCALL
62                 if (is_dfs_referral) {
63                         inode->i_op = &cifs_dfs_referral_inode_operations;
64                 } else {
65 #else /* NO DFS support, treat as a directory */
66                 {
67 #endif
68                         inode->i_op = &cifs_dir_inode_ops;
69                         inode->i_fop = &cifs_dir_ops;
70                 }
71                 break;
72         case S_IFLNK:
73                 inode->i_op = &cifs_symlink_inode_ops;
74                 break;
75         default:
76                 init_special_inode(inode, inode->i_mode, inode->i_rdev);
77                 break;
78         }
79 }
80
81 /* check inode attributes against fattr. If they don't match, tag the
82  * inode for cache invalidation
83  */
84 static void
85 cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
86 {
87         struct cifsInodeInfo *cifs_i = CIFS_I(inode);
88
89         cFYI(1, "%s: revalidating inode %llu", __func__, cifs_i->uniqueid);
90
91         if (inode->i_state & I_NEW) {
92                 cFYI(1, "%s: inode %llu is new", __func__, cifs_i->uniqueid);
93                 return;
94         }
95
96         /* don't bother with revalidation if we have an oplock */
97         if (cifs_i->clientCanCacheRead) {
98                 cFYI(1, "%s: inode %llu is oplocked", __func__,
99                          cifs_i->uniqueid);
100                 return;
101         }
102
103          /* revalidate if mtime or size have changed */
104         if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
105             cifs_i->server_eof == fattr->cf_eof) {
106                 cFYI(1, "%s: inode %llu is unchanged", __func__,
107                          cifs_i->uniqueid);
108                 return;
109         }
110
111         cFYI(1, "%s: invalidating inode %llu mapping", __func__,
112                  cifs_i->uniqueid);
113         cifs_i->invalid_mapping = true;
114 }
115
116 /* populate an inode with info from a cifs_fattr struct */
117 void
118 cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
119 {
120         struct cifsInodeInfo *cifs_i = CIFS_I(inode);
121         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
122         unsigned long oldtime = cifs_i->time;
123
124         cifs_revalidate_cache(inode, fattr);
125
126         inode->i_atime = fattr->cf_atime;
127         inode->i_mtime = fattr->cf_mtime;
128         inode->i_ctime = fattr->cf_ctime;
129         inode->i_rdev = fattr->cf_rdev;
130         inode->i_nlink = fattr->cf_nlink;
131         inode->i_uid = fattr->cf_uid;
132         inode->i_gid = fattr->cf_gid;
133
134         /* if dynperm is set, don't clobber existing mode */
135         if (inode->i_state & I_NEW ||
136             !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
137                 inode->i_mode = fattr->cf_mode;
138
139         cifs_i->cifsAttrs = fattr->cf_cifsattrs;
140
141         if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
142                 cifs_i->time = 0;
143         else
144                 cifs_i->time = jiffies;
145
146         cFYI(1, "inode 0x%p old_time=%ld new_time=%ld", inode,
147                  oldtime, cifs_i->time);
148
149         cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
150
151         cifs_i->server_eof = fattr->cf_eof;
152         /*
153          * Can't safely change the file size here if the client is writing to
154          * it due to potential races.
155          */
156         spin_lock(&inode->i_lock);
157         if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
158                 i_size_write(inode, fattr->cf_eof);
159
160                 /*
161                  * i_blocks is not related to (i_size / i_blksize),
162                  * but instead 512 byte (2**9) size is required for
163                  * calculating num blocks.
164                  */
165                 inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
166         }
167         spin_unlock(&inode->i_lock);
168
169         cifs_set_ops(inode, fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL);
170 }
171
172 void
173 cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr)
174 {
175         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
176
177         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
178                 return;
179
180         fattr->cf_uniqueid = iunique(sb, ROOT_I);
181 }
182
183 /* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
184 void
185 cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
186                          struct cifs_sb_info *cifs_sb)
187 {
188         memset(fattr, 0, sizeof(*fattr));
189         fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
190         fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
191         fattr->cf_eof = le64_to_cpu(info->EndOfFile);
192
193         fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
194         fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
195         fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
196         fattr->cf_mode = le64_to_cpu(info->Permissions);
197
198         /*
199          * Since we set the inode type below we need to mask off
200          * to avoid strange results if bits set above.
201          */
202         fattr->cf_mode &= ~S_IFMT;
203         switch (le32_to_cpu(info->Type)) {
204         case UNIX_FILE:
205                 fattr->cf_mode |= S_IFREG;
206                 fattr->cf_dtype = DT_REG;
207                 break;
208         case UNIX_SYMLINK:
209                 fattr->cf_mode |= S_IFLNK;
210                 fattr->cf_dtype = DT_LNK;
211                 break;
212         case UNIX_DIR:
213                 fattr->cf_mode |= S_IFDIR;
214                 fattr->cf_dtype = DT_DIR;
215                 break;
216         case UNIX_CHARDEV:
217                 fattr->cf_mode |= S_IFCHR;
218                 fattr->cf_dtype = DT_CHR;
219                 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
220                                        le64_to_cpu(info->DevMinor) & MINORMASK);
221                 break;
222         case UNIX_BLOCKDEV:
223                 fattr->cf_mode |= S_IFBLK;
224                 fattr->cf_dtype = DT_BLK;
225                 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
226                                        le64_to_cpu(info->DevMinor) & MINORMASK);
227                 break;
228         case UNIX_FIFO:
229                 fattr->cf_mode |= S_IFIFO;
230                 fattr->cf_dtype = DT_FIFO;
231                 break;
232         case UNIX_SOCKET:
233                 fattr->cf_mode |= S_IFSOCK;
234                 fattr->cf_dtype = DT_SOCK;
235                 break;
236         default:
237                 /* safest to call it a file if we do not know */
238                 fattr->cf_mode |= S_IFREG;
239                 fattr->cf_dtype = DT_REG;
240                 cFYI(1, "unknown type %d", le32_to_cpu(info->Type));
241                 break;
242         }
243
244         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
245                 fattr->cf_uid = cifs_sb->mnt_uid;
246         else
247                 fattr->cf_uid = le64_to_cpu(info->Uid);
248
249         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
250                 fattr->cf_gid = cifs_sb->mnt_gid;
251         else
252                 fattr->cf_gid = le64_to_cpu(info->Gid);
253
254         fattr->cf_nlink = le64_to_cpu(info->Nlinks);
255 }
256
257 /*
258  * Fill a cifs_fattr struct with fake inode info.
259  *
260  * Needed to setup cifs_fattr data for the directory which is the
261  * junction to the new submount (ie to setup the fake directory
262  * which represents a DFS referral).
263  */
264 static void
265 cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
266 {
267         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
268
269         cFYI(1, "creating fake fattr for DFS referral");
270
271         memset(fattr, 0, sizeof(*fattr));
272         fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
273         fattr->cf_uid = cifs_sb->mnt_uid;
274         fattr->cf_gid = cifs_sb->mnt_gid;
275         fattr->cf_atime = CURRENT_TIME;
276         fattr->cf_ctime = CURRENT_TIME;
277         fattr->cf_mtime = CURRENT_TIME;
278         fattr->cf_nlink = 2;
279         fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
280 }
281
282 int cifs_get_file_info_unix(struct file *filp)
283 {
284         int rc;
285         int xid;
286         FILE_UNIX_BASIC_INFO find_data;
287         struct cifs_fattr fattr;
288         struct inode *inode = filp->f_path.dentry->d_inode;
289         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
290         struct cifsTconInfo *tcon = cifs_sb->tcon;
291         struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
292
293         xid = GetXid();
294         rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
295         if (!rc) {
296                 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
297         } else if (rc == -EREMOTE) {
298                 cifs_create_dfs_fattr(&fattr, inode->i_sb);
299                 rc = 0;
300         }
301
302         cifs_fattr_to_inode(inode, &fattr);
303         FreeXid(xid);
304         return rc;
305 }
306
307 int cifs_get_inode_info_unix(struct inode **pinode,
308                              const unsigned char *full_path,
309                              struct super_block *sb, int xid)
310 {
311         int rc;
312         FILE_UNIX_BASIC_INFO find_data;
313         struct cifs_fattr fattr;
314         struct cifsTconInfo *tcon;
315         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
316
317         tcon = cifs_sb->tcon;
318         cFYI(1, "Getting info on %s", full_path);
319
320         /* could have done a find first instead but this returns more info */
321         rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
322                                   cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
323                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
324
325         if (!rc) {
326                 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
327         } else if (rc == -EREMOTE) {
328                 cifs_create_dfs_fattr(&fattr, sb);
329                 rc = 0;
330         } else {
331                 return rc;
332         }
333
334         if (*pinode == NULL) {
335                 /* get new inode */
336                 cifs_fill_uniqueid(sb, &fattr);
337                 *pinode = cifs_iget(sb, &fattr);
338                 if (!*pinode)
339                         rc = -ENOMEM;
340         } else {
341                 /* we already have inode, update it */
342                 cifs_fattr_to_inode(*pinode, &fattr);
343         }
344
345         return rc;
346 }
347
348 static int
349 cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
350               struct cifs_sb_info *cifs_sb, int xid)
351 {
352         int rc;
353         int oplock = 0;
354         __u16 netfid;
355         struct cifsTconInfo *pTcon = cifs_sb->tcon;
356         char buf[24];
357         unsigned int bytes_read;
358         char *pbuf;
359
360         pbuf = buf;
361
362         fattr->cf_mode &= ~S_IFMT;
363
364         if (fattr->cf_eof == 0) {
365                 fattr->cf_mode |= S_IFIFO;
366                 fattr->cf_dtype = DT_FIFO;
367                 return 0;
368         } else if (fattr->cf_eof < 8) {
369                 fattr->cf_mode |= S_IFREG;
370                 fattr->cf_dtype = DT_REG;
371                 return -EINVAL;  /* EOPNOTSUPP? */
372         }
373
374         rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
375                          CREATE_NOT_DIR, &netfid, &oplock, NULL,
376                          cifs_sb->local_nls,
377                          cifs_sb->mnt_cifs_flags &
378                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
379         if (rc == 0) {
380                 int buf_type = CIFS_NO_BUFFER;
381                         /* Read header */
382                 rc = CIFSSMBRead(xid, pTcon, netfid,
383                                  24 /* length */, 0 /* offset */,
384                                  &bytes_read, &pbuf, &buf_type);
385                 if ((rc == 0) && (bytes_read >= 8)) {
386                         if (memcmp("IntxBLK", pbuf, 8) == 0) {
387                                 cFYI(1, "Block device");
388                                 fattr->cf_mode |= S_IFBLK;
389                                 fattr->cf_dtype = DT_BLK;
390                                 if (bytes_read == 24) {
391                                         /* we have enough to decode dev num */
392                                         __u64 mjr; /* major */
393                                         __u64 mnr; /* minor */
394                                         mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
395                                         mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
396                                         fattr->cf_rdev = MKDEV(mjr, mnr);
397                                 }
398                         } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
399                                 cFYI(1, "Char device");
400                                 fattr->cf_mode |= S_IFCHR;
401                                 fattr->cf_dtype = DT_CHR;
402                                 if (bytes_read == 24) {
403                                         /* we have enough to decode dev num */
404                                         __u64 mjr; /* major */
405                                         __u64 mnr; /* minor */
406                                         mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
407                                         mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
408                                         fattr->cf_rdev = MKDEV(mjr, mnr);
409                                 }
410                         } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
411                                 cFYI(1, "Symlink");
412                                 fattr->cf_mode |= S_IFLNK;
413                                 fattr->cf_dtype = DT_LNK;
414                         } else {
415                                 fattr->cf_mode |= S_IFREG; /* file? */
416                                 fattr->cf_dtype = DT_REG;
417                                 rc = -EOPNOTSUPP;
418                         }
419                 } else {
420                         fattr->cf_mode |= S_IFREG; /* then it is a file */
421                         fattr->cf_dtype = DT_REG;
422                         rc = -EOPNOTSUPP; /* or some unknown SFU type */
423                 }
424                 CIFSSMBClose(xid, pTcon, netfid);
425         }
426         return rc;
427 }
428
429 #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID)  /* SETFILEBITS valid bits */
430
431 /*
432  * Fetch mode bits as provided by SFU.
433  *
434  * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ?
435  */
436 static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
437                          struct cifs_sb_info *cifs_sb, int xid)
438 {
439 #ifdef CONFIG_CIFS_XATTR
440         ssize_t rc;
441         char ea_value[4];
442         __u32 mode;
443
444         rc = CIFSSMBQAllEAs(xid, cifs_sb->tcon, path, "SETFILEBITS",
445                             ea_value, 4 /* size of buf */, cifs_sb->local_nls,
446                             cifs_sb->mnt_cifs_flags &
447                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
448         if (rc < 0)
449                 return (int)rc;
450         else if (rc > 3) {
451                 mode = le32_to_cpu(*((__le32 *)ea_value));
452                 fattr->cf_mode &= ~SFBITS_MASK;
453                 cFYI(1, "special bits 0%o org mode 0%o", mode,
454                          fattr->cf_mode);
455                 fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
456                 cFYI(1, "special mode bits 0%o", mode);
457         }
458
459         return 0;
460 #else
461         return -EOPNOTSUPP;
462 #endif
463 }
464
465 /* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
466 static void
467 cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
468                        struct cifs_sb_info *cifs_sb, bool adjust_tz)
469 {
470         memset(fattr, 0, sizeof(*fattr));
471         fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
472         if (info->DeletePending)
473                 fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;
474
475         if (info->LastAccessTime)
476                 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
477         else
478                 fattr->cf_atime = CURRENT_TIME;
479
480         fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
481         fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
482
483         if (adjust_tz) {
484                 fattr->cf_ctime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
485                 fattr->cf_mtime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
486         }
487
488         fattr->cf_eof = le64_to_cpu(info->EndOfFile);
489         fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
490
491         if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
492                 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
493                 fattr->cf_dtype = DT_DIR;
494         } else {
495                 fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
496                 fattr->cf_dtype = DT_REG;
497
498                 /* clear write bits if ATTR_READONLY is set */
499                 if (fattr->cf_cifsattrs & ATTR_READONLY)
500                         fattr->cf_mode &= ~(S_IWUGO);
501         }
502
503         fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
504
505         fattr->cf_uid = cifs_sb->mnt_uid;
506         fattr->cf_gid = cifs_sb->mnt_gid;
507 }
508
509 int cifs_get_file_info(struct file *filp)
510 {
511         int rc;
512         int xid;
513         FILE_ALL_INFO find_data;
514         struct cifs_fattr fattr;
515         struct inode *inode = filp->f_path.dentry->d_inode;
516         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
517         struct cifsTconInfo *tcon = cifs_sb->tcon;
518         struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
519
520         xid = GetXid();
521         rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
522         if (rc == -EOPNOTSUPP || rc == -EINVAL) {
523                 /*
524                  * FIXME: legacy server -- fall back to path-based call?
525                  * for now, just skip revalidating and mark inode for
526                  * immediate reval.
527                  */
528                 rc = 0;
529                 CIFS_I(inode)->time = 0;
530                 goto cgfi_exit;
531         } else if (rc == -EREMOTE) {
532                 cifs_create_dfs_fattr(&fattr, inode->i_sb);
533                 rc = 0;
534         } else if (rc)
535                 goto cgfi_exit;
536
537         /*
538          * don't bother with SFU junk here -- just mark inode as needing
539          * revalidation.
540          */
541         cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
542         fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
543         fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
544         cifs_fattr_to_inode(inode, &fattr);
545 cgfi_exit:
546         FreeXid(xid);
547         return rc;
548 }
549
550 int cifs_get_inode_info(struct inode **pinode,
551         const unsigned char *full_path, FILE_ALL_INFO *pfindData,
552         struct super_block *sb, int xid, const __u16 *pfid)
553 {
554         int rc = 0, tmprc;
555         struct cifsTconInfo *pTcon;
556         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
557         char *buf = NULL;
558         bool adjustTZ = false;
559         struct cifs_fattr fattr;
560
561         pTcon = cifs_sb->tcon;
562         cFYI(1, "Getting info on %s", full_path);
563
564         if ((pfindData == NULL) && (*pinode != NULL)) {
565                 if (CIFS_I(*pinode)->clientCanCacheRead) {
566                         cFYI(1, "No need to revalidate cached inode sizes");
567                         return rc;
568                 }
569         }
570
571         /* if file info not passed in then get it from server */
572         if (pfindData == NULL) {
573                 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
574                 if (buf == NULL)
575                         return -ENOMEM;
576                 pfindData = (FILE_ALL_INFO *)buf;
577
578                 /* could do find first instead but this returns more info */
579                 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
580                               0 /* not legacy */,
581                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
582                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
583                 /* BB optimize code so we do not make the above call
584                 when server claims no NT SMB support and the above call
585                 failed at least once - set flag in tcon or mount */
586                 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
587                         rc = SMBQueryInformation(xid, pTcon, full_path,
588                                         pfindData, cifs_sb->local_nls,
589                                         cifs_sb->mnt_cifs_flags &
590                                           CIFS_MOUNT_MAP_SPECIAL_CHR);
591                         adjustTZ = true;
592                 }
593         }
594
595         if (!rc) {
596                 cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
597                                        cifs_sb, adjustTZ);
598         } else if (rc == -EREMOTE) {
599                 cifs_create_dfs_fattr(&fattr, sb);
600                 rc = 0;
601         } else {
602                 goto cgii_exit;
603         }
604
605         /*
606          * If an inode wasn't passed in, then get the inode number
607          *
608          * Is an i_ino of zero legal? Can we use that to check if the server
609          * supports returning inode numbers?  Are there other sanity checks we
610          * can use to ensure that the server is really filling in that field?
611          *
612          * We can not use the IndexNumber field by default from Windows or
613          * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA
614          * CIFS spec claims that this value is unique within the scope of a
615          * share, and the windows docs hint that it's actually unique
616          * per-machine.
617          *
618          * There may be higher info levels that work but are there Windows
619          * server or network appliances for which IndexNumber field is not
620          * guaranteed unique?
621          */
622         if (*pinode == NULL) {
623                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
624                         int rc1 = 0;
625
626                         rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
627                                         full_path, &fattr.cf_uniqueid,
628                                         cifs_sb->local_nls,
629                                         cifs_sb->mnt_cifs_flags &
630                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
631                         if (rc1 || !fattr.cf_uniqueid) {
632                                 cFYI(1, "GetSrvInodeNum rc %d", rc1);
633                                 fattr.cf_uniqueid = iunique(sb, ROOT_I);
634                                 cifs_autodisable_serverino(cifs_sb);
635                         }
636                 } else {
637                         fattr.cf_uniqueid = iunique(sb, ROOT_I);
638                 }
639         } else {
640                 fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
641         }
642
643         /* query for SFU type info if supported and needed */
644         if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
645             cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
646                 tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
647                 if (tmprc)
648                         cFYI(1, "cifs_sfu_type failed: %d", tmprc);
649         }
650
651 #ifdef CONFIG_CIFS_EXPERIMENTAL
652         /* fill in 0777 bits from ACL */
653         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
654                 cFYI(1, "Getting mode bits from ACL");
655                 cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
656         }
657 #endif
658
659         /* fill in remaining high mode bits e.g. SUID, VTX */
660         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
661                 cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
662
663         if (!*pinode) {
664                 *pinode = cifs_iget(sb, &fattr);
665                 if (!*pinode)
666                         rc = -ENOMEM;
667         } else {
668                 cifs_fattr_to_inode(*pinode, &fattr);
669         }
670
671 cgii_exit:
672         kfree(buf);
673         return rc;
674 }
675
676 static const struct inode_operations cifs_ipc_inode_ops = {
677         .lookup = cifs_lookup,
678 };
679
680 char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
681 {
682         int pplen = cifs_sb->prepathlen;
683         int dfsplen;
684         char *full_path = NULL;
685
686         /* if no prefix path, simply set path to the root of share to "" */
687         if (pplen == 0) {
688                 full_path = kmalloc(1, GFP_KERNEL);
689                 if (full_path)
690                         full_path[0] = 0;
691                 return full_path;
692         }
693
694         if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS))
695                 dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1);
696         else
697                 dfsplen = 0;
698
699         full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
700         if (full_path == NULL)
701                 return full_path;
702
703         if (dfsplen) {
704                 strncpy(full_path, cifs_sb->tcon->treeName, dfsplen);
705                 /* switch slash direction in prepath depending on whether
706                  * windows or posix style path names
707                  */
708                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
709                         int i;
710                         for (i = 0; i < dfsplen; i++) {
711                                 if (full_path[i] == '\\')
712                                         full_path[i] = '/';
713                         }
714                 }
715         }
716         strncpy(full_path + dfsplen, cifs_sb->prepath, pplen);
717         full_path[dfsplen + pplen] = 0; /* add trailing null */
718         return full_path;
719 }
720
721 static int
722 cifs_find_inode(struct inode *inode, void *opaque)
723 {
724         struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
725
726         if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
727                 return 0;
728
729         /*
730          * uh oh -- it's a directory. We can't use it since hardlinked dirs are
731          * verboten. Disable serverino and return it as if it were found, the
732          * caller can discard it, generate a uniqueid and retry the find
733          */
734         if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) {
735                 fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
736                 cifs_autodisable_serverino(CIFS_SB(inode->i_sb));
737         }
738
739         return 1;
740 }
741
742 static int
743 cifs_init_inode(struct inode *inode, void *opaque)
744 {
745         struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
746
747         CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
748         return 0;
749 }
750
751 /* Given fattrs, get a corresponding inode */
752 struct inode *
753 cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
754 {
755         unsigned long hash;
756         struct inode *inode;
757
758 retry_iget5_locked:
759         cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid);
760
761         /* hash down to 32-bits on 32-bit arch */
762         hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
763
764         inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
765         if (inode) {
766                 /* was there a problematic inode number collision? */
767                 if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {
768                         iput(inode);
769                         fattr->cf_uniqueid = iunique(sb, ROOT_I);
770                         fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;
771                         goto retry_iget5_locked;
772                 }
773
774                 cifs_fattr_to_inode(inode, fattr);
775                 if (sb->s_flags & MS_NOATIME)
776                         inode->i_flags |= S_NOATIME | S_NOCMTIME;
777                 if (inode->i_state & I_NEW) {
778                         inode->i_ino = hash;
779                         unlock_new_inode(inode);
780                 }
781         }
782
783         return inode;
784 }
785
786 /* gets root inode */
787 struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
788 {
789         int xid;
790         struct cifs_sb_info *cifs_sb;
791         struct inode *inode = NULL;
792         long rc;
793         char *full_path;
794
795         cifs_sb = CIFS_SB(sb);
796         full_path = cifs_build_path_to_root(cifs_sb);
797         if (full_path == NULL)
798                 return ERR_PTR(-ENOMEM);
799
800         xid = GetXid();
801         if (cifs_sb->tcon->unix_ext)
802                 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
803         else
804                 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
805                                                 xid, NULL);
806
807         if (!inode)
808                 return ERR_PTR(-ENOMEM);
809
810         if (rc && cifs_sb->tcon->ipc) {
811                 cFYI(1, "ipc connection - fake read inode");
812                 inode->i_mode |= S_IFDIR;
813                 inode->i_nlink = 2;
814                 inode->i_op = &cifs_ipc_inode_ops;
815                 inode->i_fop = &simple_dir_operations;
816                 inode->i_uid = cifs_sb->mnt_uid;
817                 inode->i_gid = cifs_sb->mnt_gid;
818         } else if (rc) {
819                 kfree(full_path);
820                 _FreeXid(xid);
821                 iget_failed(inode);
822                 return ERR_PTR(rc);
823         }
824
825
826         kfree(full_path);
827         /* can not call macro FreeXid here since in a void func
828          * TODO: This is no longer true
829          */
830         _FreeXid(xid);
831         return inode;
832 }
833
834 static int
835 cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
836                     char *full_path, __u32 dosattr)
837 {
838         int rc;
839         int oplock = 0;
840         __u16 netfid;
841         __u32 netpid;
842         bool set_time = false;
843         struct cifsFileInfo *open_file;
844         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
845         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
846         struct cifsTconInfo *pTcon = cifs_sb->tcon;
847         FILE_BASIC_INFO info_buf;
848
849         if (attrs == NULL)
850                 return -EINVAL;
851
852         if (attrs->ia_valid & ATTR_ATIME) {
853                 set_time = true;
854                 info_buf.LastAccessTime =
855                         cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
856         } else
857                 info_buf.LastAccessTime = 0;
858
859         if (attrs->ia_valid & ATTR_MTIME) {
860                 set_time = true;
861                 info_buf.LastWriteTime =
862                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
863         } else
864                 info_buf.LastWriteTime = 0;
865
866         /*
867          * Samba throws this field away, but windows may actually use it.
868          * Do not set ctime unless other time stamps are changed explicitly
869          * (i.e. by utimes()) since we would then have a mix of client and
870          * server times.
871          */
872         if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
873                 cFYI(1, "CIFS - CTIME changed");
874                 info_buf.ChangeTime =
875                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
876         } else
877                 info_buf.ChangeTime = 0;
878
879         info_buf.CreationTime = 0;      /* don't change */
880         info_buf.Attributes = cpu_to_le32(dosattr);
881
882         /*
883          * If the file is already open for write, just use that fileid
884          */
885         open_file = find_writable_file(cifsInode);
886         if (open_file) {
887                 netfid = open_file->netfid;
888                 netpid = open_file->pid;
889                 goto set_via_filehandle;
890         }
891
892         /*
893          * NT4 apparently returns success on this call, but it doesn't
894          * really work.
895          */
896         if (!(pTcon->ses->flags & CIFS_SES_NT4)) {
897                 rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
898                                      &info_buf, cifs_sb->local_nls,
899                                      cifs_sb->mnt_cifs_flags &
900                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
901                 if (rc == 0) {
902                         cifsInode->cifsAttrs = dosattr;
903                         goto out;
904                 } else if (rc != -EOPNOTSUPP && rc != -EINVAL)
905                         goto out;
906         }
907
908         cFYI(1, "calling SetFileInfo since SetPathInfo for "
909                  "times not supported by this server");
910         rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
911                          SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
912                          CREATE_NOT_DIR, &netfid, &oplock,
913                          NULL, cifs_sb->local_nls,
914                          cifs_sb->mnt_cifs_flags &
915                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
916
917         if (rc != 0) {
918                 if (rc == -EIO)
919                         rc = -EINVAL;
920                 goto out;
921         }
922
923         netpid = current->tgid;
924
925 set_via_filehandle:
926         rc = CIFSSMBSetFileInfo(xid, pTcon, &info_buf, netfid, netpid);
927         if (!rc)
928                 cifsInode->cifsAttrs = dosattr;
929
930         if (open_file == NULL)
931                 CIFSSMBClose(xid, pTcon, netfid);
932         else
933                 cifsFileInfo_put(open_file);
934 out:
935         return rc;
936 }
937
938 /*
939  * open the given file (if it isn't already), set the DELETE_ON_CLOSE bit
940  * and rename it to a random name that hopefully won't conflict with
941  * anything else.
942  */
943 static int
944 cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
945 {
946         int oplock = 0;
947         int rc;
948         __u16 netfid;
949         struct inode *inode = dentry->d_inode;
950         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
951         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
952         struct cifsTconInfo *tcon = cifs_sb->tcon;
953         __u32 dosattr, origattr;
954         FILE_BASIC_INFO *info_buf = NULL;
955
956         rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
957                          DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
958                          &netfid, &oplock, NULL, cifs_sb->local_nls,
959                          cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
960         if (rc != 0)
961                 goto out;
962
963         origattr = cifsInode->cifsAttrs;
964         if (origattr == 0)
965                 origattr |= ATTR_NORMAL;
966
967         dosattr = origattr & ~ATTR_READONLY;
968         if (dosattr == 0)
969                 dosattr |= ATTR_NORMAL;
970         dosattr |= ATTR_HIDDEN;
971
972         /* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */
973         if (dosattr != origattr) {
974                 info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
975                 if (info_buf == NULL) {
976                         rc = -ENOMEM;
977                         goto out_close;
978                 }
979                 info_buf->Attributes = cpu_to_le32(dosattr);
980                 rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
981                                         current->tgid);
982                 /* although we would like to mark the file hidden
983                    if that fails we will still try to rename it */
984                 if (rc != 0)
985                         cifsInode->cifsAttrs = dosattr;
986                 else
987                         dosattr = origattr; /* since not able to change them */
988         }
989
990         /* rename the file */
991         rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
992                                    cifs_sb->mnt_cifs_flags &
993                                             CIFS_MOUNT_MAP_SPECIAL_CHR);
994         if (rc != 0) {
995                 rc = -ETXTBSY;
996                 goto undo_setattr;
997         }
998
999         /* try to set DELETE_ON_CLOSE */
1000         if (!cifsInode->delete_pending) {
1001                 rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid,
1002                                                current->tgid);
1003                 /*
1004                  * some samba versions return -ENOENT when we try to set the
1005                  * file disposition here. Likely a samba bug, but work around
1006                  * it for now. This means that some cifsXXX files may hang
1007                  * around after they shouldn't.
1008                  *
1009                  * BB: remove this hack after more servers have the fix
1010                  */
1011                 if (rc == -ENOENT)
1012                         rc = 0;
1013                 else if (rc != 0) {
1014                         rc = -ETXTBSY;
1015                         goto undo_rename;
1016                 }
1017                 cifsInode->delete_pending = true;
1018         }
1019
1020 out_close:
1021         CIFSSMBClose(xid, tcon, netfid);
1022 out:
1023         kfree(info_buf);
1024         return rc;
1025
1026         /*
1027          * reset everything back to the original state. Don't bother
1028          * dealing with errors here since we can't do anything about
1029          * them anyway.
1030          */
1031 undo_rename:
1032         CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name,
1033                                 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1034                                             CIFS_MOUNT_MAP_SPECIAL_CHR);
1035 undo_setattr:
1036         if (dosattr != origattr) {
1037                 info_buf->Attributes = cpu_to_le32(origattr);
1038                 if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
1039                                         current->tgid))
1040                         cifsInode->cifsAttrs = origattr;
1041         }
1042
1043         goto out_close;
1044 }
1045
1046
1047 /*
1048  * If dentry->d_inode is null (usually meaning the cached dentry
1049  * is a negative dentry) then we would attempt a standard SMB delete, but
1050  * if that fails we can not attempt the fall back mechanisms on EACCESS
1051  * but will return the EACCESS to the caller. Note that the VFS does not call
1052  * unlink on negative dentries currently.
1053  */
1054 int cifs_unlink(struct inode *dir, struct dentry *dentry)
1055 {
1056         int rc = 0;
1057         int xid;
1058         char *full_path = NULL;
1059         struct inode *inode = dentry->d_inode;
1060         struct cifsInodeInfo *cifs_inode;
1061         struct super_block *sb = dir->i_sb;
1062         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1063         struct cifsTconInfo *tcon = cifs_sb->tcon;
1064         struct iattr *attrs = NULL;
1065         __u32 dosattr = 0, origattr = 0;
1066
1067         cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry);
1068
1069         xid = GetXid();
1070
1071         /* Unlink can be called from rename so we can not take the
1072          * sb->s_vfs_rename_mutex here */
1073         full_path = build_path_from_dentry(dentry);
1074         if (full_path == NULL) {
1075                 rc = -ENOMEM;
1076                 FreeXid(xid);
1077                 return rc;
1078         }
1079
1080         if ((tcon->ses->capabilities & CAP_UNIX) &&
1081                 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1082                         le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1083                 rc = CIFSPOSIXDelFile(xid, tcon, full_path,
1084                         SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
1085                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1086                 cFYI(1, "posix del rc %d", rc);
1087                 if ((rc == 0) || (rc == -ENOENT))
1088                         goto psx_del_no_retry;
1089         }
1090
1091 retry_std_delete:
1092         rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls,
1093                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1094
1095 psx_del_no_retry:
1096         if (!rc) {
1097                 if (inode)
1098                         drop_nlink(inode);
1099         } else if (rc == -ENOENT) {
1100                 d_drop(dentry);
1101         } else if (rc == -ETXTBSY) {
1102                 rc = cifs_rename_pending_delete(full_path, dentry, xid);
1103                 if (rc == 0)
1104                         drop_nlink(inode);
1105         } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
1106                 attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
1107                 if (attrs == NULL) {
1108                         rc = -ENOMEM;
1109                         goto out_reval;
1110                 }
1111
1112                 /* try to reset dos attributes */
1113                 cifs_inode = CIFS_I(inode);
1114                 origattr = cifs_inode->cifsAttrs;
1115                 if (origattr == 0)
1116                         origattr |= ATTR_NORMAL;
1117                 dosattr = origattr & ~ATTR_READONLY;
1118                 if (dosattr == 0)
1119                         dosattr |= ATTR_NORMAL;
1120                 dosattr |= ATTR_HIDDEN;
1121
1122                 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
1123                 if (rc != 0)
1124                         goto out_reval;
1125
1126                 goto retry_std_delete;
1127         }
1128
1129         /* undo the setattr if we errored out and it's needed */
1130         if (rc != 0 && dosattr != 0)
1131                 cifs_set_file_info(inode, attrs, xid, full_path, origattr);
1132
1133 out_reval:
1134         if (inode) {
1135                 cifs_inode = CIFS_I(inode);
1136                 cifs_inode->time = 0;   /* will force revalidate to get info
1137                                            when needed */
1138                 inode->i_ctime = current_fs_time(sb);
1139         }
1140         dir->i_ctime = dir->i_mtime = current_fs_time(sb);
1141         cifs_inode = CIFS_I(dir);
1142         CIFS_I(dir)->time = 0;  /* force revalidate of dir as well */
1143
1144         kfree(full_path);
1145         kfree(attrs);
1146         FreeXid(xid);
1147         return rc;
1148 }
1149
1150 int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1151 {
1152         int rc = 0, tmprc;
1153         int xid;
1154         struct cifs_sb_info *cifs_sb;
1155         struct cifsTconInfo *pTcon;
1156         char *full_path = NULL;
1157         struct inode *newinode = NULL;
1158         struct cifs_fattr fattr;
1159
1160         cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode);
1161
1162         xid = GetXid();
1163
1164         cifs_sb = CIFS_SB(inode->i_sb);
1165         pTcon = cifs_sb->tcon;
1166
1167         full_path = build_path_from_dentry(direntry);
1168         if (full_path == NULL) {
1169                 rc = -ENOMEM;
1170                 FreeXid(xid);
1171                 return rc;
1172         }
1173
1174         if ((pTcon->ses->capabilities & CAP_UNIX) &&
1175                 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1176                         le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
1177                 u32 oplock = 0;
1178                 FILE_UNIX_BASIC_INFO *pInfo =
1179                         kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1180                 if (pInfo == NULL) {
1181                         rc = -ENOMEM;
1182                         goto mkdir_out;
1183                 }
1184
1185                 mode &= ~current_umask();
1186                 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
1187                                 mode, NULL /* netfid */, pInfo, &oplock,
1188                                 full_path, cifs_sb->local_nls,
1189                                 cifs_sb->mnt_cifs_flags &
1190                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1191                 if (rc == -EOPNOTSUPP) {
1192                         kfree(pInfo);
1193                         goto mkdir_retry_old;
1194                 } else if (rc) {
1195                         cFYI(1, "posix mkdir returned 0x%x", rc);
1196                         d_drop(direntry);
1197                 } else {
1198                         if (pInfo->Type == cpu_to_le32(-1)) {
1199                                 /* no return info, go query for it */
1200                                 kfree(pInfo);
1201                                 goto mkdir_get_info;
1202                         }
1203 /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
1204         to set uid/gid */
1205                         inc_nlink(inode);
1206                         if (pTcon->nocase)
1207                                 direntry->d_op = &cifs_ci_dentry_ops;
1208                         else
1209                                 direntry->d_op = &cifs_dentry_ops;
1210
1211                         cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
1212                         cifs_fill_uniqueid(inode->i_sb, &fattr);
1213                         newinode = cifs_iget(inode->i_sb, &fattr);
1214                         if (!newinode) {
1215                                 kfree(pInfo);
1216                                 goto mkdir_get_info;
1217                         }
1218
1219                         d_instantiate(direntry, newinode);
1220
1221 #ifdef CONFIG_CIFS_DEBUG2
1222                         cFYI(1, "instantiated dentry %p %s to inode %p",
1223                                 direntry, direntry->d_name.name, newinode);
1224
1225                         if (newinode->i_nlink != 2)
1226                                 cFYI(1, "unexpected number of links %d",
1227                                         newinode->i_nlink);
1228 #endif
1229                 }
1230                 kfree(pInfo);
1231                 goto mkdir_out;
1232         }
1233 mkdir_retry_old:
1234         /* BB add setting the equivalent of mode via CreateX w/ACLs */
1235         rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
1236                           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1237         if (rc) {
1238                 cFYI(1, "cifs_mkdir returned 0x%x", rc);
1239                 d_drop(direntry);
1240         } else {
1241 mkdir_get_info:
1242                 inc_nlink(inode);
1243                 if (pTcon->unix_ext)
1244                         rc = cifs_get_inode_info_unix(&newinode, full_path,
1245                                                       inode->i_sb, xid);
1246                 else
1247                         rc = cifs_get_inode_info(&newinode, full_path, NULL,
1248                                                  inode->i_sb, xid, NULL);
1249
1250                 if (pTcon->nocase)
1251                         direntry->d_op = &cifs_ci_dentry_ops;
1252                 else
1253                         direntry->d_op = &cifs_dentry_ops;
1254                 d_instantiate(direntry, newinode);
1255                  /* setting nlink not necessary except in cases where we
1256                   * failed to get it from the server or was set bogus */
1257                 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
1258                                 direntry->d_inode->i_nlink = 2;
1259
1260                 mode &= ~current_umask();
1261                 /* must turn on setgid bit if parent dir has it */
1262                 if (inode->i_mode & S_ISGID)
1263                         mode |= S_ISGID;
1264
1265                 if (pTcon->unix_ext) {
1266                         struct cifs_unix_set_info_args args = {
1267                                 .mode   = mode,
1268                                 .ctime  = NO_CHANGE_64,
1269                                 .atime  = NO_CHANGE_64,
1270                                 .mtime  = NO_CHANGE_64,
1271                                 .device = 0,
1272                         };
1273                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
1274                                 args.uid = (__u64)current_fsuid();
1275                                 if (inode->i_mode & S_ISGID)
1276                                         args.gid = (__u64)inode->i_gid;
1277                                 else
1278                                         args.gid = (__u64)current_fsgid();
1279                         } else {
1280                                 args.uid = NO_CHANGE_64;
1281                                 args.gid = NO_CHANGE_64;
1282                         }
1283                         CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
1284                                                cifs_sb->local_nls,
1285                                                cifs_sb->mnt_cifs_flags &
1286                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1287                 } else {
1288                         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
1289                             (mode & S_IWUGO) == 0) {
1290                                 FILE_BASIC_INFO pInfo;
1291                                 struct cifsInodeInfo *cifsInode;
1292                                 u32 dosattrs;
1293
1294                                 memset(&pInfo, 0, sizeof(pInfo));
1295                                 cifsInode = CIFS_I(newinode);
1296                                 dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
1297                                 pInfo.Attributes = cpu_to_le32(dosattrs);
1298                                 tmprc = CIFSSMBSetPathInfo(xid, pTcon,
1299                                                 full_path, &pInfo,
1300                                                 cifs_sb->local_nls,
1301                                                 cifs_sb->mnt_cifs_flags &
1302                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1303                                 if (tmprc == 0)
1304                                         cifsInode->cifsAttrs = dosattrs;
1305                         }
1306                         if (direntry->d_inode) {
1307                                 if (cifs_sb->mnt_cifs_flags &
1308                                      CIFS_MOUNT_DYNPERM)
1309                                         direntry->d_inode->i_mode =
1310                                                 (mode | S_IFDIR);
1311
1312                                 if (cifs_sb->mnt_cifs_flags &
1313                                      CIFS_MOUNT_SET_UID) {
1314                                         direntry->d_inode->i_uid =
1315                                                 current_fsuid();
1316                                         if (inode->i_mode & S_ISGID)
1317                                                 direntry->d_inode->i_gid =
1318                                                         inode->i_gid;
1319                                         else
1320                                                 direntry->d_inode->i_gid =
1321                                                         current_fsgid();
1322                                 }
1323                         }
1324                 }
1325         }
1326 mkdir_out:
1327         kfree(full_path);
1328         FreeXid(xid);
1329         return rc;
1330 }
1331
1332 int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1333 {
1334         int rc = 0;
1335         int xid;
1336         struct cifs_sb_info *cifs_sb;
1337         struct cifsTconInfo *pTcon;
1338         char *full_path = NULL;
1339         struct cifsInodeInfo *cifsInode;
1340
1341         cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
1342
1343         xid = GetXid();
1344
1345         cifs_sb = CIFS_SB(inode->i_sb);
1346         pTcon = cifs_sb->tcon;
1347
1348         full_path = build_path_from_dentry(direntry);
1349         if (full_path == NULL) {
1350                 rc = -ENOMEM;
1351                 FreeXid(xid);
1352                 return rc;
1353         }
1354
1355         rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1356                           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1357
1358         if (!rc) {
1359                 drop_nlink(inode);
1360                 spin_lock(&direntry->d_inode->i_lock);
1361                 i_size_write(direntry->d_inode, 0);
1362                 clear_nlink(direntry->d_inode);
1363                 spin_unlock(&direntry->d_inode->i_lock);
1364         }
1365
1366         cifsInode = CIFS_I(direntry->d_inode);
1367         cifsInode->time = 0;    /* force revalidate to go get info when
1368                                    needed */
1369
1370         cifsInode = CIFS_I(inode);
1371         cifsInode->time = 0;    /* force revalidate to get parent dir info
1372                                    since cached search results now invalid */
1373
1374         direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1375                 current_fs_time(inode->i_sb);
1376
1377         kfree(full_path);
1378         FreeXid(xid);
1379         return rc;
1380 }
1381
1382 static int
1383 cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1384                 struct dentry *to_dentry, const char *toPath)
1385 {
1386         struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
1387         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1388         __u16 srcfid;
1389         int oplock, rc;
1390
1391         /* try path-based rename first */
1392         rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
1393                            cifs_sb->mnt_cifs_flags &
1394                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1395
1396         /*
1397          * don't bother with rename by filehandle unless file is busy and
1398          * source Note that cross directory moves do not work with
1399          * rename by filehandle to various Windows servers.
1400          */
1401         if (rc == 0 || rc != -ETXTBSY)
1402                 return rc;
1403
1404         /* open-file renames don't work across directories */
1405         if (to_dentry->d_parent != from_dentry->d_parent)
1406                 return rc;
1407
1408         /* open the file to be renamed -- we need DELETE perms */
1409         rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE,
1410                          CREATE_NOT_DIR, &srcfid, &oplock, NULL,
1411                          cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1412                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1413
1414         if (rc == 0) {
1415                 rc = CIFSSMBRenameOpenFile(xid, pTcon, srcfid,
1416                                 (const char *) to_dentry->d_name.name,
1417                                 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1418                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1419
1420                 CIFSSMBClose(xid, pTcon, srcfid);
1421         }
1422
1423         return rc;
1424 }
1425
1426 int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1427         struct inode *target_dir, struct dentry *target_dentry)
1428 {
1429         char *fromName = NULL;
1430         char *toName = NULL;
1431         struct cifs_sb_info *cifs_sb_source;
1432         struct cifs_sb_info *cifs_sb_target;
1433         struct cifsTconInfo *tcon;
1434         FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1435         FILE_UNIX_BASIC_INFO *info_buf_target;
1436         int xid, rc, tmprc;
1437
1438         cifs_sb_target = CIFS_SB(target_dir->i_sb);
1439         cifs_sb_source = CIFS_SB(source_dir->i_sb);
1440         tcon = cifs_sb_source->tcon;
1441
1442         xid = GetXid();
1443
1444         /*
1445          * BB: this might be allowed if same server, but different share.
1446          * Consider adding support for this
1447          */
1448         if (tcon != cifs_sb_target->tcon) {
1449                 rc = -EXDEV;
1450                 goto cifs_rename_exit;
1451         }
1452
1453         /*
1454          * we already have the rename sem so we do not need to
1455          * grab it again here to protect the path integrity
1456          */
1457         fromName = build_path_from_dentry(source_dentry);
1458         if (fromName == NULL) {
1459                 rc = -ENOMEM;
1460                 goto cifs_rename_exit;
1461         }
1462
1463         toName = build_path_from_dentry(target_dentry);
1464         if (toName == NULL) {
1465                 rc = -ENOMEM;
1466                 goto cifs_rename_exit;
1467         }
1468
1469         rc = cifs_do_rename(xid, source_dentry, fromName,
1470                             target_dentry, toName);
1471
1472         if (rc == -EEXIST && tcon->unix_ext) {
1473                 /*
1474                  * Are src and dst hardlinks of same inode? We can
1475                  * only tell with unix extensions enabled
1476                  */
1477                 info_buf_source =
1478                         kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
1479                                         GFP_KERNEL);
1480                 if (info_buf_source == NULL) {
1481                         rc = -ENOMEM;
1482                         goto cifs_rename_exit;
1483                 }
1484
1485                 info_buf_target = info_buf_source + 1;
1486                 tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
1487                                         info_buf_source,
1488                                         cifs_sb_source->local_nls,
1489                                         cifs_sb_source->mnt_cifs_flags &
1490                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1491                 if (tmprc != 0)
1492                         goto unlink_target;
1493
1494                 tmprc = CIFSSMBUnixQPathInfo(xid, tcon,
1495                                         toName, info_buf_target,
1496                                         cifs_sb_target->local_nls,
1497                                         /* remap based on source sb */
1498                                         cifs_sb_source->mnt_cifs_flags &
1499                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1500
1501                 if (tmprc == 0 && (info_buf_source->UniqueId ==
1502                                    info_buf_target->UniqueId)) {
1503                         /* same file, POSIX says that this is a noop */
1504                         rc = 0;
1505                         goto cifs_rename_exit;
1506                 }
1507         } /* else ... BB we could add the same check for Windows by
1508                      checking the UniqueId via FILE_INTERNAL_INFO */
1509
1510 unlink_target:
1511         /* Try unlinking the target dentry if it's not negative */
1512         if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) {
1513                 tmprc = cifs_unlink(target_dir, target_dentry);
1514                 if (tmprc)
1515                         goto cifs_rename_exit;
1516
1517                 rc = cifs_do_rename(xid, source_dentry, fromName,
1518                                     target_dentry, toName);
1519         }
1520
1521 cifs_rename_exit:
1522         kfree(info_buf_source);
1523         kfree(fromName);
1524         kfree(toName);
1525         FreeXid(xid);
1526         return rc;
1527 }
1528
1529 static bool
1530 cifs_inode_needs_reval(struct inode *inode)
1531 {
1532         struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1533
1534         if (cifs_i->clientCanCacheRead)
1535                 return false;
1536
1537         if (!lookupCacheEnabled)
1538                 return true;
1539
1540         if (cifs_i->time == 0)
1541                 return true;
1542
1543         /* FIXME: the actimeo should be tunable */
1544         if (time_after_eq(jiffies, cifs_i->time + HZ))
1545                 return true;
1546
1547         /* hardlinked files w/ noserverino get "special" treatment */
1548         if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
1549             S_ISREG(inode->i_mode) && inode->i_nlink != 1)
1550                 return true;
1551
1552         return false;
1553 }
1554
1555 /* check invalid_mapping flag and zap the cache if it's set */
1556 static void
1557 cifs_invalidate_mapping(struct inode *inode)
1558 {
1559         int rc;
1560         struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1561
1562         cifs_i->invalid_mapping = false;
1563
1564         /* write back any cached data */
1565         if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
1566                 rc = filemap_write_and_wait(inode->i_mapping);
1567                 if (rc)
1568                         cifs_i->write_behind_rc = rc;
1569         }
1570         invalidate_remote_inode(inode);
1571 }
1572
1573 int cifs_revalidate_file(struct file *filp)
1574 {
1575         int rc = 0;
1576         struct inode *inode = filp->f_path.dentry->d_inode;
1577
1578         if (!cifs_inode_needs_reval(inode))
1579                 goto check_inval;
1580
1581         if (CIFS_SB(inode->i_sb)->tcon->unix_ext)
1582                 rc = cifs_get_file_info_unix(filp);
1583         else
1584                 rc = cifs_get_file_info(filp);
1585
1586 check_inval:
1587         if (CIFS_I(inode)->invalid_mapping)
1588                 cifs_invalidate_mapping(inode);
1589
1590         return rc;
1591 }
1592
1593 /* revalidate a dentry's inode attributes */
1594 int cifs_revalidate_dentry(struct dentry *dentry)
1595 {
1596         int xid;
1597         int rc = 0;
1598         char *full_path = NULL;
1599         struct inode *inode = dentry->d_inode;
1600         struct super_block *sb = dentry->d_sb;
1601
1602         if (inode == NULL)
1603                 return -ENOENT;
1604
1605         xid = GetXid();
1606
1607         if (!cifs_inode_needs_reval(inode))
1608                 goto check_inval;
1609
1610         /* can not safely grab the rename sem here if rename calls revalidate
1611            since that would deadlock */
1612         full_path = build_path_from_dentry(dentry);
1613         if (full_path == NULL) {
1614                 rc = -ENOMEM;
1615                 goto check_inval;
1616         }
1617
1618         cFYI(1, "Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
1619                  "jiffies %ld", full_path, inode, inode->i_count.counter,
1620                  dentry, dentry->d_time, jiffies);
1621
1622         if (CIFS_SB(sb)->tcon->unix_ext)
1623                 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
1624         else
1625                 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
1626                                          xid, NULL);
1627
1628 check_inval:
1629         if (CIFS_I(inode)->invalid_mapping)
1630                 cifs_invalidate_mapping(inode);
1631
1632         kfree(full_path);
1633         FreeXid(xid);
1634         return rc;
1635 }
1636
1637 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1638         struct kstat *stat)
1639 {
1640         int err = cifs_revalidate_dentry(dentry);
1641         if (!err) {
1642                 generic_fillattr(dentry->d_inode, stat);
1643                 stat->blksize = CIFS_MAX_MSGSIZE;
1644                 stat->ino = CIFS_I(dentry->d_inode)->uniqueid;
1645         }
1646         return err;
1647 }
1648
1649 static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1650 {
1651         pgoff_t index = from >> PAGE_CACHE_SHIFT;
1652         unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1653         struct page *page;
1654         int rc = 0;
1655
1656         page = grab_cache_page(mapping, index);
1657         if (!page)
1658                 return -ENOMEM;
1659
1660         zero_user_segment(page, offset, PAGE_CACHE_SIZE);
1661         unlock_page(page);
1662         page_cache_release(page);
1663         return rc;
1664 }
1665
1666 static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1667 {
1668         loff_t oldsize;
1669         int err;
1670
1671         spin_lock(&inode->i_lock);
1672         err = inode_newsize_ok(inode, offset);
1673         if (err) {
1674                 spin_unlock(&inode->i_lock);
1675                 goto out;
1676         }
1677
1678         oldsize = inode->i_size;
1679         i_size_write(inode, offset);
1680         spin_unlock(&inode->i_lock);
1681         truncate_pagecache(inode, oldsize, offset);
1682         if (inode->i_op->truncate)
1683                 inode->i_op->truncate(inode);
1684 out:
1685         return err;
1686 }
1687
1688 static int
1689 cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1690                    int xid, char *full_path)
1691 {
1692         int rc;
1693         struct cifsFileInfo *open_file;
1694         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1695         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1696         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1697
1698         /*
1699          * To avoid spurious oplock breaks from server, in the case of
1700          * inodes that we already have open, avoid doing path based
1701          * setting of file size if we can do it by handle.
1702          * This keeps our caching token (oplock) and avoids timeouts
1703          * when the local oplock break takes longer to flush
1704          * writebehind data than the SMB timeout for the SetPathInfo
1705          * request would allow
1706          */
1707         open_file = find_writable_file(cifsInode);
1708         if (open_file) {
1709                 __u16 nfid = open_file->netfid;
1710                 __u32 npid = open_file->pid;
1711                 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1712                                         npid, false);
1713                 cifsFileInfo_put(open_file);
1714                 cFYI(1, "SetFSize for attrs rc = %d", rc);
1715                 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1716                         unsigned int bytes_written;
1717                         rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
1718                                           &bytes_written, NULL, NULL, 1);
1719                         cFYI(1, "Wrt seteof rc %d", rc);
1720                 }
1721         } else
1722                 rc = -EINVAL;
1723
1724         if (rc != 0) {
1725                 /* Set file size by pathname rather than by handle
1726                    either because no valid, writeable file handle for
1727                    it was found or because there was an error setting
1728                    it by handle */
1729                 rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,
1730                                    false, cifs_sb->local_nls,
1731                                    cifs_sb->mnt_cifs_flags &
1732                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1733                 cFYI(1, "SetEOF by path (setattrs) rc = %d", rc);
1734                 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1735                         __u16 netfid;
1736                         int oplock = 0;
1737
1738                         rc = SMBLegacyOpen(xid, pTcon, full_path,
1739                                 FILE_OPEN, GENERIC_WRITE,
1740                                 CREATE_NOT_DIR, &netfid, &oplock, NULL,
1741                                 cifs_sb->local_nls,
1742                                 cifs_sb->mnt_cifs_flags &
1743                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1744                         if (rc == 0) {
1745                                 unsigned int bytes_written;
1746                                 rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
1747                                                   attrs->ia_size,
1748                                                   &bytes_written, NULL,
1749                                                   NULL, 1);
1750                                 cFYI(1, "wrt seteof rc %d", rc);
1751                                 CIFSSMBClose(xid, pTcon, netfid);
1752                         }
1753                 }
1754         }
1755
1756         if (rc == 0) {
1757                 cifsInode->server_eof = attrs->ia_size;
1758                 rc = cifs_vmtruncate(inode, attrs->ia_size);
1759                 cifs_truncate_page(inode->i_mapping, inode->i_size);
1760         }
1761
1762         return rc;
1763 }
1764
1765 static int
1766 cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1767 {
1768         int rc;
1769         int xid;
1770         char *full_path = NULL;
1771         struct inode *inode = direntry->d_inode;
1772         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1773         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1774         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1775         struct cifs_unix_set_info_args *args = NULL;
1776         struct cifsFileInfo *open_file;
1777
1778         cFYI(1, "setattr_unix on file %s attrs->ia_valid=0x%x",
1779                  direntry->d_name.name, attrs->ia_valid);
1780
1781         xid = GetXid();
1782
1783         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1784                 /* check if we have permission to change attrs */
1785                 rc = inode_change_ok(inode, attrs);
1786                 if (rc < 0)
1787                         goto out;
1788                 else
1789                         rc = 0;
1790         }
1791
1792         full_path = build_path_from_dentry(direntry);
1793         if (full_path == NULL) {
1794                 rc = -ENOMEM;
1795                 goto out;
1796         }
1797
1798         /*
1799          * Attempt to flush data before changing attributes. We need to do
1800          * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1801          * ownership or mode then we may also need to do this. Here, we take
1802          * the safe way out and just do the flush on all setattr requests. If
1803          * the flush returns error, store it to report later and continue.
1804          *
1805          * BB: This should be smarter. Why bother flushing pages that
1806          * will be truncated anyway? Also, should we error out here if
1807          * the flush returns error?
1808          */
1809         rc = filemap_write_and_wait(inode->i_mapping);
1810         if (rc != 0) {
1811                 cifsInode->write_behind_rc = rc;
1812                 rc = 0;
1813         }
1814
1815         if (attrs->ia_valid & ATTR_SIZE) {
1816                 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1817                 if (rc != 0)
1818                         goto out;
1819         }
1820
1821         /* skip mode change if it's just for clearing setuid/setgid */
1822         if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1823                 attrs->ia_valid &= ~ATTR_MODE;
1824
1825         args = kmalloc(sizeof(*args), GFP_KERNEL);
1826         if (args == NULL) {
1827                 rc = -ENOMEM;
1828                 goto out;
1829         }
1830
1831         /* set up the struct */
1832         if (attrs->ia_valid & ATTR_MODE)
1833                 args->mode = attrs->ia_mode;
1834         else
1835                 args->mode = NO_CHANGE_64;
1836
1837         if (attrs->ia_valid & ATTR_UID)
1838                 args->uid = attrs->ia_uid;
1839         else
1840                 args->uid = NO_CHANGE_64;
1841
1842         if (attrs->ia_valid & ATTR_GID)
1843                 args->gid = attrs->ia_gid;
1844         else
1845                 args->gid = NO_CHANGE_64;
1846
1847         if (attrs->ia_valid & ATTR_ATIME)
1848                 args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
1849         else
1850                 args->atime = NO_CHANGE_64;
1851
1852         if (attrs->ia_valid & ATTR_MTIME)
1853                 args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
1854         else
1855                 args->mtime = NO_CHANGE_64;
1856
1857         if (attrs->ia_valid & ATTR_CTIME)
1858                 args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
1859         else
1860                 args->ctime = NO_CHANGE_64;
1861
1862         args->device = 0;
1863         open_file = find_writable_file(cifsInode);
1864         if (open_file) {
1865                 u16 nfid = open_file->netfid;
1866                 u32 npid = open_file->pid;
1867                 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
1868                 cifsFileInfo_put(open_file);
1869         } else {
1870                 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
1871                                     cifs_sb->local_nls,
1872                                     cifs_sb->mnt_cifs_flags &
1873                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1874         }
1875
1876         if (!rc) {
1877                 rc = inode_setattr(inode, attrs);
1878
1879                 /* force revalidate when any of these times are set since some
1880                    of the fs types (eg ext3, fat) do not have fine enough
1881                    time granularity to match protocol, and we do not have a
1882                    a way (yet) to query the server fs's time granularity (and
1883                    whether it rounds times down).
1884                 */
1885                 if (!rc && (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME)))
1886                         cifsInode->time = 0;
1887         }
1888 out:
1889         kfree(args);
1890         kfree(full_path);
1891         FreeXid(xid);
1892         return rc;
1893 }
1894
1895 static int
1896 cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
1897 {
1898         int xid;
1899         struct inode *inode = direntry->d_inode;
1900         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1901         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1902         char *full_path = NULL;
1903         int rc = -EACCES;
1904         __u32 dosattr = 0;
1905         __u64 mode = NO_CHANGE_64;
1906
1907         xid = GetXid();
1908
1909         cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
1910                  direntry->d_name.name, attrs->ia_valid);
1911
1912         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1913                 /* check if we have permission to change attrs */
1914                 rc = inode_change_ok(inode, attrs);
1915                 if (rc < 0) {
1916                         FreeXid(xid);
1917                         return rc;
1918                 } else
1919                         rc = 0;
1920         }
1921
1922         full_path = build_path_from_dentry(direntry);
1923         if (full_path == NULL) {
1924                 rc = -ENOMEM;
1925                 FreeXid(xid);
1926                 return rc;
1927         }
1928
1929         /*
1930          * Attempt to flush data before changing attributes. We need to do
1931          * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1932          * ownership or mode then we may also need to do this. Here, we take
1933          * the safe way out and just do the flush on all setattr requests. If
1934          * the flush returns error, store it to report later and continue.
1935          *
1936          * BB: This should be smarter. Why bother flushing pages that
1937          * will be truncated anyway? Also, should we error out here if
1938          * the flush returns error?
1939          */
1940         rc = filemap_write_and_wait(inode->i_mapping);
1941         if (rc != 0) {
1942                 cifsInode->write_behind_rc = rc;
1943                 rc = 0;
1944         }
1945
1946         if (attrs->ia_valid & ATTR_SIZE) {
1947                 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1948                 if (rc != 0)
1949                         goto cifs_setattr_exit;
1950         }
1951
1952         /*
1953          * Without unix extensions we can't send ownership changes to the
1954          * server, so silently ignore them. This is consistent with how
1955          * local DOS/Windows filesystems behave (VFAT, NTFS, etc). With
1956          * CIFSACL support + proper Windows to Unix idmapping, we may be
1957          * able to support this in the future.
1958          */
1959         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
1960                 attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
1961
1962         /* skip mode change if it's just for clearing setuid/setgid */
1963         if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1964                 attrs->ia_valid &= ~ATTR_MODE;
1965
1966         if (attrs->ia_valid & ATTR_MODE) {
1967                 cFYI(1, "Mode changed to 0%o", attrs->ia_mode);
1968                 mode = attrs->ia_mode;
1969         }
1970
1971         if (attrs->ia_valid & ATTR_MODE) {
1972                 rc = 0;
1973 #ifdef CONFIG_CIFS_EXPERIMENTAL
1974                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1975                         rc = mode_to_acl(inode, full_path, mode);
1976                 else
1977 #endif
1978                 if (((mode & S_IWUGO) == 0) &&
1979                     (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1980
1981                         dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
1982
1983                         /* fix up mode if we're not using dynperm */
1984                         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
1985                                 attrs->ia_mode = inode->i_mode & ~S_IWUGO;
1986                 } else if ((mode & S_IWUGO) &&
1987                            (cifsInode->cifsAttrs & ATTR_READONLY)) {
1988
1989                         dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
1990                         /* Attributes of 0 are ignored */
1991                         if (dosattr == 0)
1992                                 dosattr |= ATTR_NORMAL;
1993
1994                         /* reset local inode permissions to normal */
1995                         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1996                                 attrs->ia_mode &= ~(S_IALLUGO);
1997                                 if (S_ISDIR(inode->i_mode))
1998                                         attrs->ia_mode |=
1999                                                 cifs_sb->mnt_dir_mode;
2000                                 else
2001                                         attrs->ia_mode |=
2002                                                 cifs_sb->mnt_file_mode;
2003                         }
2004                 } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
2005                         /* ignore mode change - ATTR_READONLY hasn't changed */
2006                         attrs->ia_valid &= ~ATTR_MODE;
2007                 }
2008         }
2009
2010         if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||
2011             ((attrs->ia_valid & ATTR_MODE) && dosattr)) {
2012                 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
2013                 /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */
2014
2015                 /* Even if error on time set, no sense failing the call if
2016                 the server would set the time to a reasonable value anyway,
2017                 and this check ensures that we are not being called from
2018                 sys_utimes in which case we ought to fail the call back to
2019                 the user when the server rejects the call */
2020                 if ((rc) && (attrs->ia_valid &
2021                                 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
2022                         rc = 0;
2023         }
2024
2025         /* do not need local check to inode_check_ok since the server does
2026            that */
2027         if (!rc)
2028                 rc = inode_setattr(inode, attrs);
2029 cifs_setattr_exit:
2030         kfree(full_path);
2031         FreeXid(xid);
2032         return rc;
2033 }
2034
2035 int
2036 cifs_setattr(struct dentry *direntry, struct iattr *attrs)
2037 {
2038         struct inode *inode = direntry->d_inode;
2039         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2040         struct cifsTconInfo *pTcon = cifs_sb->tcon;
2041
2042         if (pTcon->unix_ext)
2043                 return cifs_setattr_unix(direntry, attrs);
2044
2045         return cifs_setattr_nounix(direntry, attrs);
2046
2047         /* BB: add cifs_setattr_legacy for really old servers */
2048 }
2049
2050 #if 0
2051 void cifs_delete_inode(struct inode *inode)
2052 {
2053         cFYI(1, "In cifs_delete_inode, inode = 0x%p", inode);
2054         /* may have to add back in if and when safe distributed caching of
2055            directories added e.g. via FindNotify */
2056 }
2057 #endif