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