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