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