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