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