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