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