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