[CIFS] when not using unix extensions, check for and set ATTR_READONLY on create...
[pandora-kernel.git] / fs / cifs / inode.c
1 /*
2  *   fs/cifs/inode.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2007
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 static void cifs_unix_info_to_inode(struct inode *inode,
81                 FILE_UNIX_BASIC_INFO *info, int force_uid_gid)
82 {
83         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
84         struct cifsInodeInfo *cifsInfo = CIFS_I(inode);
85         __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes);
86         __u64 end_of_file = le64_to_cpu(info->EndOfFile);
87
88         inode->i_atime = cifs_NTtimeToUnix(le64_to_cpu(info->LastAccessTime));
89         inode->i_mtime =
90                 cifs_NTtimeToUnix(le64_to_cpu(info->LastModificationTime));
91         inode->i_ctime = cifs_NTtimeToUnix(le64_to_cpu(info->LastStatusChange));
92         inode->i_mode = le64_to_cpu(info->Permissions);
93
94         /*
95          * Since we set the inode type below we need to mask off
96          * to avoid strange results if bits set above.
97          */
98         inode->i_mode &= ~S_IFMT;
99         switch (le32_to_cpu(info->Type)) {
100         case UNIX_FILE:
101                 inode->i_mode |= S_IFREG;
102                 break;
103         case UNIX_SYMLINK:
104                 inode->i_mode |= S_IFLNK;
105                 break;
106         case UNIX_DIR:
107                 inode->i_mode |= S_IFDIR;
108                 break;
109         case UNIX_CHARDEV:
110                 inode->i_mode |= S_IFCHR;
111                 inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor),
112                                       le64_to_cpu(info->DevMinor) & MINORMASK);
113                 break;
114         case UNIX_BLOCKDEV:
115                 inode->i_mode |= S_IFBLK;
116                 inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor),
117                                       le64_to_cpu(info->DevMinor) & MINORMASK);
118                 break;
119         case UNIX_FIFO:
120                 inode->i_mode |= S_IFIFO;
121                 break;
122         case UNIX_SOCKET:
123                 inode->i_mode |= S_IFSOCK;
124                 break;
125         default:
126                 /* safest to call it a file if we do not know */
127                 inode->i_mode |= S_IFREG;
128                 cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
129                 break;
130         }
131
132         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) &&
133             !force_uid_gid)
134                 inode->i_uid = cifs_sb->mnt_uid;
135         else
136                 inode->i_uid = le64_to_cpu(info->Uid);
137
138         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) &&
139             !force_uid_gid)
140                 inode->i_gid = cifs_sb->mnt_gid;
141         else
142                 inode->i_gid = le64_to_cpu(info->Gid);
143
144         inode->i_nlink = le64_to_cpu(info->Nlinks);
145
146         spin_lock(&inode->i_lock);
147         if (is_size_safe_to_change(cifsInfo, end_of_file)) {
148                 /*
149                  * We can not safely change the file size here if the client
150                  * is writing to it due to potential races.
151                  */
152                 i_size_write(inode, end_of_file);
153
154                 /*
155                  * i_blocks is not related to (i_size / i_blksize),
156                  * but instead 512 byte (2**9) size is required for
157                  * calculating num blocks.
158                  */
159                 inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
160         }
161         spin_unlock(&inode->i_lock);
162 }
163
164 static const unsigned char *cifs_get_search_path(struct cifs_sb_info *cifs_sb,
165                                                 const char *search_path)
166 {
167         int tree_len;
168         int path_len;
169         int i;
170         char *tmp_path;
171         struct cifsTconInfo *pTcon = cifs_sb->tcon;
172
173         if (!(pTcon->Flags & SMB_SHARE_IS_IN_DFS))
174                 return search_path;
175
176         /* use full path name for working with DFS */
177         tree_len = strnlen(pTcon->treeName, MAX_TREE_SIZE + 1);
178         path_len = strnlen(search_path, MAX_PATHCONF);
179
180         tmp_path = kmalloc(tree_len+path_len+1, GFP_KERNEL);
181         if (tmp_path == NULL)
182                 return search_path;
183
184         strncpy(tmp_path, pTcon->treeName, tree_len);
185         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
186                 for (i = 0; i < tree_len; i++) {
187                         if (tmp_path[i] == '\\')
188                                 tmp_path[i] = '/';
189                 }
190         strncpy(tmp_path+tree_len, search_path, path_len);
191         tmp_path[tree_len+path_len] = 0;
192         return tmp_path;
193 }
194
195 int cifs_get_inode_info_unix(struct inode **pinode,
196         const unsigned char *search_path, struct super_block *sb, int xid)
197 {
198         int rc = 0;
199         FILE_UNIX_BASIC_INFO findData;
200         struct cifsTconInfo *pTcon;
201         struct inode *inode;
202         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
203         const unsigned char *full_path;
204         bool is_dfs_referral = false;
205
206         pTcon = cifs_sb->tcon;
207         cFYI(1, ("Getting info on %s", search_path));
208
209         full_path = cifs_get_search_path(cifs_sb, search_path);
210
211 try_again_CIFSSMBUnixQPathInfo:
212         /* could have done a find first instead but this returns more info */
213         rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &findData,
214                                   cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
215                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
216 /*      dump_mem("\nUnixQPathInfo return data", &findData,
217                  sizeof(findData)); */
218         if (rc) {
219                 if (rc == -EREMOTE && !is_dfs_referral) {
220                         is_dfs_referral = true;
221                         if (full_path != search_path) {
222                                 kfree(full_path);
223                                 full_path = search_path;
224                         }
225                         goto try_again_CIFSSMBUnixQPathInfo;
226                 }
227                 goto cgiiu_exit;
228         } else {
229                 struct cifsInodeInfo *cifsInfo;
230                 __u64 num_of_bytes = le64_to_cpu(findData.NumOfBytes);
231                 __u64 end_of_file = le64_to_cpu(findData.EndOfFile);
232
233                 /* get new inode */
234                 if (*pinode == NULL) {
235                         *pinode = new_inode(sb);
236                         if (*pinode == NULL) {
237                                 rc = -ENOMEM;
238                                 goto cgiiu_exit;
239                         }
240                         /* Is an i_ino of zero legal? */
241                         /* Are there sanity checks we can use to ensure that
242                            the server is really filling in that field? */
243                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
244                                 (*pinode)->i_ino =
245                                         (unsigned long)findData.UniqueId;
246                         } /* note ino incremented to unique num in new_inode */
247                         if (sb->s_flags & MS_NOATIME)
248                                 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
249
250                         insert_inode_hash(*pinode);
251                 }
252
253                 inode = *pinode;
254                 cifsInfo = CIFS_I(inode);
255
256                 cFYI(1, ("Old time %ld", cifsInfo->time));
257                 cifsInfo->time = jiffies;
258                 cFYI(1, ("New time %ld", cifsInfo->time));
259                 /* this is ok to set on every inode revalidate */
260                 atomic_set(&cifsInfo->inUse, 1);
261
262                 cifs_unix_info_to_inode(inode, &findData, 0);
263
264
265                 if (num_of_bytes < end_of_file)
266                         cFYI(1, ("allocation size less than end of file"));
267                 cFYI(1, ("Size %ld and blocks %llu",
268                         (unsigned long) inode->i_size,
269                         (unsigned long long)inode->i_blocks));
270
271                 cifs_set_ops(inode, is_dfs_referral);
272         }
273 cgiiu_exit:
274         if (full_path != search_path)
275                 kfree(full_path);
276         return rc;
277 }
278
279 static int decode_sfu_inode(struct inode *inode, __u64 size,
280                             const unsigned char *path,
281                             struct cifs_sb_info *cifs_sb, int xid)
282 {
283         int rc;
284         int oplock = 0;
285         __u16 netfid;
286         struct cifsTconInfo *pTcon = cifs_sb->tcon;
287         char buf[24];
288         unsigned int bytes_read;
289         char *pbuf;
290
291         pbuf = buf;
292
293         if (size == 0) {
294                 inode->i_mode |= S_IFIFO;
295                 return 0;
296         } else if (size < 8) {
297                 return -EINVAL;  /* EOPNOTSUPP? */
298         }
299
300         rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
301                          CREATE_NOT_DIR, &netfid, &oplock, NULL,
302                          cifs_sb->local_nls,
303                          cifs_sb->mnt_cifs_flags &
304                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
305         if (rc == 0) {
306                 int buf_type = CIFS_NO_BUFFER;
307                         /* Read header */
308                 rc = CIFSSMBRead(xid, pTcon,
309                                  netfid,
310                                  24 /* length */, 0 /* offset */,
311                                  &bytes_read, &pbuf, &buf_type);
312                 if ((rc == 0) && (bytes_read >= 8)) {
313                         if (memcmp("IntxBLK", pbuf, 8) == 0) {
314                                 cFYI(1, ("Block device"));
315                                 inode->i_mode |= S_IFBLK;
316                                 if (bytes_read == 24) {
317                                         /* we have enough to decode dev num */
318                                         __u64 mjr; /* major */
319                                         __u64 mnr; /* minor */
320                                         mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
321                                         mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
322                                         inode->i_rdev = MKDEV(mjr, mnr);
323                                 }
324                         } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
325                                 cFYI(1, ("Char device"));
326                                 inode->i_mode |= S_IFCHR;
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                                         inode->i_rdev = MKDEV(mjr, mnr);
334                                 }
335                         } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
336                                 cFYI(1, ("Symlink"));
337                                 inode->i_mode |= S_IFLNK;
338                         } else {
339                                 inode->i_mode |= S_IFREG; /* file? */
340                                 rc = -EOPNOTSUPP;
341                         }
342                 } else {
343                         inode->i_mode |= S_IFREG; /* then it is a file */
344                         rc = -EOPNOTSUPP; /* or some unknown SFU type */
345                 }
346                 CIFSSMBClose(xid, pTcon, netfid);
347         }
348         return rc;
349 }
350
351 #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID)  /* SETFILEBITS valid bits */
352
353 static int get_sfu_mode(struct inode *inode,
354                         const unsigned char *path,
355                         struct cifs_sb_info *cifs_sb, int xid)
356 {
357 #ifdef CONFIG_CIFS_XATTR
358         ssize_t rc;
359         char ea_value[4];
360         __u32 mode;
361
362         rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
363                         ea_value, 4 /* size of buf */, cifs_sb->local_nls,
364                 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
365         if (rc < 0)
366                 return (int)rc;
367         else if (rc > 3) {
368                 mode = le32_to_cpu(*((__le32 *)ea_value));
369                 inode->i_mode &= ~SFBITS_MASK;
370                 cFYI(1, ("special bits 0%o org mode 0%o", mode, inode->i_mode));
371                 inode->i_mode = (mode &  SFBITS_MASK) | inode->i_mode;
372                 cFYI(1, ("special mode bits 0%o", mode));
373                 return 0;
374         } else {
375                 return 0;
376         }
377 #else
378         return -EOPNOTSUPP;
379 #endif
380 }
381
382 int cifs_get_inode_info(struct inode **pinode,
383         const unsigned char *search_path, FILE_ALL_INFO *pfindData,
384         struct super_block *sb, int xid, const __u16 *pfid)
385 {
386         int rc = 0;
387         struct cifsTconInfo *pTcon;
388         struct inode *inode;
389         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
390         const unsigned char *full_path = NULL;
391         char *buf = NULL;
392         bool adjustTZ = false;
393         bool is_dfs_referral = false;
394
395         pTcon = cifs_sb->tcon;
396         cFYI(1, ("Getting info on %s", search_path));
397
398         if ((pfindData == NULL) && (*pinode != NULL)) {
399                 if (CIFS_I(*pinode)->clientCanCacheRead) {
400                         cFYI(1, ("No need to revalidate cached inode sizes"));
401                         return rc;
402                 }
403         }
404
405         /* if file info not passed in then get it from server */
406         if (pfindData == NULL) {
407                 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
408                 if (buf == NULL)
409                         return -ENOMEM;
410                 pfindData = (FILE_ALL_INFO *)buf;
411
412                 full_path = cifs_get_search_path(cifs_sb, search_path);
413
414 try_again_CIFSSMBQPathInfo:
415                 /* could do find first instead but this returns more info */
416                 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
417                               0 /* not legacy */,
418                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
419                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
420                 /* BB optimize code so we do not make the above call
421                 when server claims no NT SMB support and the above call
422                 failed at least once - set flag in tcon or mount */
423                 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
424                         rc = SMBQueryInformation(xid, pTcon, full_path,
425                                         pfindData, cifs_sb->local_nls,
426                                         cifs_sb->mnt_cifs_flags &
427                                           CIFS_MOUNT_MAP_SPECIAL_CHR);
428                         adjustTZ = true;
429                 }
430         }
431         /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
432         if (rc) {
433                 if (rc == -EREMOTE && !is_dfs_referral) {
434                         is_dfs_referral = true;
435                         if (full_path != search_path) {
436                                 kfree(full_path);
437                                 full_path = search_path;
438                         }
439                         goto try_again_CIFSSMBQPathInfo;
440                 }
441                 goto cgii_exit;
442         } else {
443                 struct cifsInodeInfo *cifsInfo;
444                 __u32 attr = le32_to_cpu(pfindData->Attributes);
445
446                 /* get new inode */
447                 if (*pinode == NULL) {
448                         *pinode = new_inode(sb);
449                         if (*pinode == NULL) {
450                                 rc = -ENOMEM;
451                                 goto cgii_exit;
452                         }
453                         /* Is an i_ino of zero legal? Can we use that to check
454                            if the server supports returning inode numbers?  Are
455                            there other sanity checks we can use to ensure that
456                            the server is really filling in that field? */
457
458                         /* We can not use the IndexNumber field by default from
459                            Windows or Samba (in ALL_INFO buf) but we can request
460                            it explicitly.  It may not be unique presumably if
461                            the server has multiple devices mounted under one
462                            share */
463
464                         /* There may be higher info levels that work but are
465                            there Windows server or network appliances for which
466                            IndexNumber field is not guaranteed unique? */
467
468                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
469                                 int rc1 = 0;
470                                 __u64 inode_num;
471
472                                 rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
473                                         search_path, &inode_num,
474                                         cifs_sb->local_nls,
475                                         cifs_sb->mnt_cifs_flags &
476                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
477                                 if (rc1) {
478                                         cFYI(1, ("GetSrvInodeNum rc %d", rc1));
479                                         /* BB EOPNOSUPP disable SERVER_INUM? */
480                                 } else /* do we need cast or hash to ino? */
481                                         (*pinode)->i_ino = inode_num;
482                         } /* else ino incremented to unique num in new_inode*/
483                         if (sb->s_flags & MS_NOATIME)
484                                 (*pinode)->i_flags |= S_NOATIME | S_NOCMTIME;
485                         insert_inode_hash(*pinode);
486                 }
487                 inode = *pinode;
488                 cifsInfo = CIFS_I(inode);
489                 cifsInfo->cifsAttrs = attr;
490                 cFYI(1, ("Old time %ld", cifsInfo->time));
491                 cifsInfo->time = jiffies;
492                 cFYI(1, ("New time %ld", cifsInfo->time));
493
494                 /* blksize needs to be multiple of two. So safer to default to
495                 blksize and blkbits set in superblock so 2**blkbits and blksize
496                 will match rather than setting to:
497                 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
498
499                 /* Linux can not store file creation time so ignore it */
500                 if (pfindData->LastAccessTime)
501                         inode->i_atime = cifs_NTtimeToUnix
502                                 (le64_to_cpu(pfindData->LastAccessTime));
503                 else /* do not need to use current_fs_time - time not stored */
504                         inode->i_atime = CURRENT_TIME;
505                 inode->i_mtime =
506                     cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
507                 inode->i_ctime =
508                     cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
509                 cFYI(0, ("Attributes came in as 0x%x", attr));
510                 if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
511                         inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
512                         inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
513                 }
514
515                 /* set default mode. will override for dirs below */
516                 if (atomic_read(&cifsInfo->inUse) == 0)
517                         /* new inode, can safely set these fields */
518                         inode->i_mode = cifs_sb->mnt_file_mode;
519                 else /* since we set the inode type below we need to mask off
520                      to avoid strange results if type changes and both
521                      get orred in */
522                         inode->i_mode &= ~S_IFMT;
523 /*              if (attr & ATTR_REPARSE)  */
524                 /* We no longer handle these as symlinks because we could not
525                    follow them due to the absolute path with drive letter */
526                 if (attr & ATTR_DIRECTORY) {
527                 /* override default perms since we do not do byte range locking
528                    on dirs */
529                         inode->i_mode = cifs_sb->mnt_dir_mode;
530                         inode->i_mode |= S_IFDIR;
531                 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
532                            (cifsInfo->cifsAttrs & ATTR_SYSTEM) &&
533                            /* No need to le64 convert size of zero */
534                            (pfindData->EndOfFile == 0)) {
535                         inode->i_mode = cifs_sb->mnt_file_mode;
536                         inode->i_mode |= S_IFIFO;
537 /* BB Finish for SFU style symlinks and devices */
538                 } else if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) &&
539                            (cifsInfo->cifsAttrs & ATTR_SYSTEM)) {
540                         if (decode_sfu_inode(inode,
541                                          le64_to_cpu(pfindData->EndOfFile),
542                                          search_path,
543                                          cifs_sb, xid))
544                                 cFYI(1, ("Unrecognized sfu inode type"));
545
546                         cFYI(1, ("sfu mode 0%o", inode->i_mode));
547                 } else {
548                         inode->i_mode |= S_IFREG;
549                         /* treat the dos attribute of read-only as read-only
550                            mode e.g. 555 */
551                         if (cifsInfo->cifsAttrs & ATTR_READONLY)
552                                 inode->i_mode &= ~(S_IWUGO);
553                         else if ((inode->i_mode & S_IWUGO) == 0)
554                                 /* the ATTR_READONLY flag may have been */
555                                 /* changed on server -- set any w bits  */
556                                 /* allowed by mnt_file_mode             */
557                                 inode->i_mode |= (S_IWUGO &
558                                                   cifs_sb->mnt_file_mode);
559                 /* BB add code here -
560                    validate if device or weird share or device type? */
561                 }
562
563                 spin_lock(&inode->i_lock);
564                 if (is_size_safe_to_change(cifsInfo,
565                                            le64_to_cpu(pfindData->EndOfFile))) {
566                         /* can not safely shrink the file size here if the
567                            client is writing to it due to potential races */
568                         i_size_write(inode, le64_to_cpu(pfindData->EndOfFile));
569
570                         /* 512 bytes (2**9) is the fake blocksize that must be
571                            used for this calculation */
572                         inode->i_blocks = (512 - 1 + le64_to_cpu(
573                                            pfindData->AllocationSize)) >> 9;
574                 }
575                 spin_unlock(&inode->i_lock);
576
577                 inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
578
579                 /* BB fill in uid and gid here? with help from winbind?
580                    or retrieve from NTFS stream extended attribute */
581 #ifdef CONFIG_CIFS_EXPERIMENTAL
582                 /* fill in 0777 bits from ACL */
583                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
584                         cFYI(1, ("Getting mode bits from ACL"));
585                         acl_to_uid_mode(inode, search_path, pfid);
586                 }
587 #endif
588                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
589                         /* fill in remaining high mode bits e.g. SUID, VTX */
590                         get_sfu_mode(inode, search_path, cifs_sb, xid);
591                 } else if (atomic_read(&cifsInfo->inUse) == 0) {
592                         inode->i_uid = cifs_sb->mnt_uid;
593                         inode->i_gid = cifs_sb->mnt_gid;
594                         /* set so we do not keep refreshing these fields with
595                            bad data after user has changed them in memory */
596                         atomic_set(&cifsInfo->inUse, 1);
597                 }
598
599                 cifs_set_ops(inode, is_dfs_referral);
600         }
601 cgii_exit:
602         if (full_path != search_path)
603                 kfree(full_path);
604         kfree(buf);
605         return rc;
606 }
607
608 static const struct inode_operations cifs_ipc_inode_ops = {
609         .lookup = cifs_lookup,
610 };
611
612 /* gets root inode */
613 struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
614 {
615         int xid;
616         struct cifs_sb_info *cifs_sb;
617         struct inode *inode;
618         long rc;
619
620         inode = iget_locked(sb, ino);
621         if (!inode)
622                 return ERR_PTR(-ENOMEM);
623         if (!(inode->i_state & I_NEW))
624                 return inode;
625
626         cifs_sb = CIFS_SB(inode->i_sb);
627         xid = GetXid();
628
629         if (cifs_sb->tcon->unix_ext)
630                 rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid);
631         else
632                 rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid,
633                                          NULL);
634         if (rc && cifs_sb->tcon->ipc) {
635                 cFYI(1, ("ipc connection - fake read inode"));
636                 inode->i_mode |= S_IFDIR;
637                 inode->i_nlink = 2;
638                 inode->i_op = &cifs_ipc_inode_ops;
639                 inode->i_fop = &simple_dir_operations;
640                 inode->i_uid = cifs_sb->mnt_uid;
641                 inode->i_gid = cifs_sb->mnt_gid;
642                 _FreeXid(xid);
643                 iget_failed(inode);
644                 return ERR_PTR(rc);
645         }
646
647         unlock_new_inode(inode);
648
649         /* can not call macro FreeXid here since in a void func
650          * TODO: This is no longer true
651          */
652         _FreeXid(xid);
653         return inode;
654 }
655
656 int cifs_unlink(struct inode *inode, struct dentry *direntry)
657 {
658         int rc = 0;
659         int xid;
660         struct cifs_sb_info *cifs_sb;
661         struct cifsTconInfo *pTcon;
662         char *full_path = NULL;
663         struct cifsInodeInfo *cifsInode;
664         FILE_BASIC_INFO *pinfo_buf;
665
666         cFYI(1, ("cifs_unlink, inode = 0x%p", inode));
667
668         xid = GetXid();
669
670         if (inode)
671                 cifs_sb = CIFS_SB(inode->i_sb);
672         else
673                 cifs_sb = CIFS_SB(direntry->d_sb);
674         pTcon = cifs_sb->tcon;
675
676         /* Unlink can be called from rename so we can not grab the sem here
677            since we deadlock otherwise */
678 /*      mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);*/
679         full_path = build_path_from_dentry(direntry);
680 /*      mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);*/
681         if (full_path == NULL) {
682                 FreeXid(xid);
683                 return -ENOMEM;
684         }
685
686         if ((pTcon->ses->capabilities & CAP_UNIX) &&
687                 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
688                         le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
689                 rc = CIFSPOSIXDelFile(xid, pTcon, full_path,
690                         SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
691                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
692                 cFYI(1, ("posix del rc %d", rc));
693                 if ((rc == 0) || (rc == -ENOENT))
694                         goto psx_del_no_retry;
695         }
696
697         rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls,
698                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
699 psx_del_no_retry:
700         if (!rc) {
701                 if (direntry->d_inode)
702                         drop_nlink(direntry->d_inode);
703         } else if (rc == -ENOENT) {
704                 d_drop(direntry);
705         } else if (rc == -ETXTBSY) {
706                 int oplock = 0;
707                 __u16 netfid;
708
709                 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
710                                  CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
711                                  &netfid, &oplock, NULL, cifs_sb->local_nls,
712                                  cifs_sb->mnt_cifs_flags &
713                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
714                 if (rc == 0) {
715                         CIFSSMBRenameOpenFile(xid, pTcon, netfid, NULL,
716                                               cifs_sb->local_nls,
717                                               cifs_sb->mnt_cifs_flags &
718                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
719                         CIFSSMBClose(xid, pTcon, netfid);
720                         if (direntry->d_inode)
721                                 drop_nlink(direntry->d_inode);
722                 }
723         } else if (rc == -EACCES) {
724                 /* try only if r/o attribute set in local lookup data? */
725                 pinfo_buf = kzalloc(sizeof(FILE_BASIC_INFO), GFP_KERNEL);
726                 if (pinfo_buf) {
727                         /* ATTRS set to normal clears r/o bit */
728                         pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL);
729                         if (!(pTcon->ses->flags & CIFS_SES_NT4))
730                                 rc = CIFSSMBSetTimes(xid, pTcon, full_path,
731                                                      pinfo_buf,
732                                                      cifs_sb->local_nls,
733                                                      cifs_sb->mnt_cifs_flags &
734                                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
735                         else
736                                 rc = -EOPNOTSUPP;
737
738                         if (rc == -EOPNOTSUPP) {
739                                 int oplock = 0;
740                                 __u16 netfid;
741                         /*      rc = CIFSSMBSetAttrLegacy(xid, pTcon,
742                                                           full_path,
743                                                           (__u16)ATTR_NORMAL,
744                                                           cifs_sb->local_nls);
745                            For some strange reason it seems that NT4 eats the
746                            old setattr call without actually setting the
747                            attributes so on to the third attempted workaround
748                            */
749
750                         /* BB could scan to see if we already have it open
751                            and pass in pid of opener to function */
752                                 rc = CIFSSMBOpen(xid, pTcon, full_path,
753                                                  FILE_OPEN, SYNCHRONIZE |
754                                                  FILE_WRITE_ATTRIBUTES, 0,
755                                                  &netfid, &oplock, NULL,
756                                                  cifs_sb->local_nls,
757                                                  cifs_sb->mnt_cifs_flags &
758                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
759                                 if (rc == 0) {
760                                         rc = CIFSSMBSetFileTimes(xid, pTcon,
761                                                                  pinfo_buf,
762                                                                  netfid);
763                                         CIFSSMBClose(xid, pTcon, netfid);
764                                 }
765                         }
766                         kfree(pinfo_buf);
767                 }
768                 if (rc == 0) {
769                         rc = CIFSSMBDelFile(xid, pTcon, full_path,
770                                             cifs_sb->local_nls,
771                                             cifs_sb->mnt_cifs_flags &
772                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
773                         if (!rc) {
774                                 if (direntry->d_inode)
775                                         drop_nlink(direntry->d_inode);
776                         } else if (rc == -ETXTBSY) {
777                                 int oplock = 0;
778                                 __u16 netfid;
779
780                                 rc = CIFSSMBOpen(xid, pTcon, full_path,
781                                                  FILE_OPEN, DELETE,
782                                                  CREATE_NOT_DIR |
783                                                  CREATE_DELETE_ON_CLOSE,
784                                                  &netfid, &oplock, NULL,
785                                                  cifs_sb->local_nls,
786                                                  cifs_sb->mnt_cifs_flags &
787                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
788                                 if (rc == 0) {
789                                         CIFSSMBRenameOpenFile(xid, pTcon,
790                                                 netfid, NULL,
791                                                 cifs_sb->local_nls,
792                                                 cifs_sb->mnt_cifs_flags &
793                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
794                                         CIFSSMBClose(xid, pTcon, netfid);
795                                         if (direntry->d_inode)
796                                                 drop_nlink(direntry->d_inode);
797                                 }
798                         /* BB if rc = -ETXTBUSY goto the rename logic BB */
799                         }
800                 }
801         }
802         if (direntry->d_inode) {
803                 cifsInode = CIFS_I(direntry->d_inode);
804                 cifsInode->time = 0;    /* will force revalidate to get info
805                                            when needed */
806                 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb);
807         }
808         if (inode) {
809                 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
810                 cifsInode = CIFS_I(inode);
811                 cifsInode->time = 0;    /* force revalidate of dir as well */
812         }
813
814         kfree(full_path);
815         FreeXid(xid);
816         return rc;
817 }
818
819 static void posix_fill_in_inode(struct inode *tmp_inode,
820         FILE_UNIX_BASIC_INFO *pData, int isNewInode)
821 {
822         struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
823         loff_t local_size;
824         struct timespec local_mtime;
825
826         cifsInfo->time = jiffies;
827         atomic_inc(&cifsInfo->inUse);
828
829         /* save mtime and size */
830         local_mtime = tmp_inode->i_mtime;
831         local_size  = tmp_inode->i_size;
832
833         cifs_unix_info_to_inode(tmp_inode, pData, 1);
834         cifs_set_ops(tmp_inode, false);
835
836         if (!S_ISREG(tmp_inode->i_mode))
837                 return;
838
839         /*
840          * No sense invalidating pages for new inode
841          * since we we have not started caching
842          * readahead file data yet.
843          */
844         if (isNewInode)
845                 return;
846
847         if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
848                 (local_size == tmp_inode->i_size)) {
849                 cFYI(1, ("inode exists but unchanged"));
850         } else {
851                 /* file may have changed on server */
852                 cFYI(1, ("invalidate inode, readdir detected change"));
853                 invalidate_remote_inode(tmp_inode);
854         }
855 }
856
857 int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
858 {
859         int rc = 0;
860         int xid;
861         struct cifs_sb_info *cifs_sb;
862         struct cifsTconInfo *pTcon;
863         char *full_path = NULL;
864         struct inode *newinode = NULL;
865
866         cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
867
868         xid = GetXid();
869
870         cifs_sb = CIFS_SB(inode->i_sb);
871         pTcon = cifs_sb->tcon;
872
873         full_path = build_path_from_dentry(direntry);
874         if (full_path == NULL) {
875                 FreeXid(xid);
876                 return -ENOMEM;
877         }
878
879         if ((pTcon->ses->capabilities & CAP_UNIX) &&
880                 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
881                         le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
882                 u32 oplock = 0;
883                 FILE_UNIX_BASIC_INFO *pInfo =
884                         kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
885                 if (pInfo == NULL) {
886                         rc = -ENOMEM;
887                         goto mkdir_out;
888                 }
889
890                 mode &= ~current->fs->umask;
891                 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
892                                 mode, NULL /* netfid */, pInfo, &oplock,
893                                 full_path, cifs_sb->local_nls,
894                                 cifs_sb->mnt_cifs_flags &
895                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
896                 if (rc == -EOPNOTSUPP) {
897                         kfree(pInfo);
898                         goto mkdir_retry_old;
899                 } else if (rc) {
900                         cFYI(1, ("posix mkdir returned 0x%x", rc));
901                         d_drop(direntry);
902                 } else {
903                         if (pInfo->Type == cpu_to_le32(-1)) {
904                                 /* no return info, go query for it */
905                                 kfree(pInfo);
906                                 goto mkdir_get_info;
907                         }
908 /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
909         to set uid/gid */
910                         inc_nlink(inode);
911                         if (pTcon->nocase)
912                                 direntry->d_op = &cifs_ci_dentry_ops;
913                         else
914                                 direntry->d_op = &cifs_dentry_ops;
915
916                         newinode = new_inode(inode->i_sb);
917                         if (newinode == NULL) {
918                                 kfree(pInfo);
919                                 goto mkdir_get_info;
920                         }
921                         /* Is an i_ino of zero legal? */
922                         /* Are there sanity checks we can use to ensure that
923                            the server is really filling in that field? */
924                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
925                                 newinode->i_ino =
926                                         (unsigned long)pInfo->UniqueId;
927                         } /* note ino incremented to unique num in new_inode */
928                         if (inode->i_sb->s_flags & MS_NOATIME)
929                                 newinode->i_flags |= S_NOATIME | S_NOCMTIME;
930                         newinode->i_nlink = 2;
931
932                         insert_inode_hash(newinode);
933                         d_instantiate(direntry, newinode);
934
935                         /* we already checked in POSIXCreate whether
936                            frame was long enough */
937                         posix_fill_in_inode(direntry->d_inode,
938                                         pInfo, 1 /* NewInode */);
939 #ifdef CONFIG_CIFS_DEBUG2
940                         cFYI(1, ("instantiated dentry %p %s to inode %p",
941                                 direntry, direntry->d_name.name, newinode));
942
943                         if (newinode->i_nlink != 2)
944                                 cFYI(1, ("unexpected number of links %d",
945                                         newinode->i_nlink));
946 #endif
947                 }
948                 kfree(pInfo);
949                 goto mkdir_out;
950         }
951 mkdir_retry_old:
952         /* BB add setting the equivalent of mode via CreateX w/ACLs */
953         rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
954                           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
955         if (rc) {
956                 cFYI(1, ("cifs_mkdir returned 0x%x", rc));
957                 d_drop(direntry);
958         } else {
959 mkdir_get_info:
960                 inc_nlink(inode);
961                 if (pTcon->unix_ext)
962                         rc = cifs_get_inode_info_unix(&newinode, full_path,
963                                                       inode->i_sb, xid);
964                 else
965                         rc = cifs_get_inode_info(&newinode, full_path, NULL,
966                                                  inode->i_sb, xid, NULL);
967
968                 if (pTcon->nocase)
969                         direntry->d_op = &cifs_ci_dentry_ops;
970                 else
971                         direntry->d_op = &cifs_dentry_ops;
972                 d_instantiate(direntry, newinode);
973                  /* setting nlink not necessary except in cases where we
974                   * failed to get it from the server or was set bogus */
975                 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
976                                 direntry->d_inode->i_nlink = 2;
977                 mode &= ~current->fs->umask;
978                 if (pTcon->unix_ext) {
979                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
980                                 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
981                                                     mode,
982                                                     (__u64)current->fsuid,
983                                                     (__u64)current->fsgid,
984                                                     0 /* dev_t */,
985                                                     cifs_sb->local_nls,
986                                                     cifs_sb->mnt_cifs_flags &
987                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
988                         } else {
989                                 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
990                                                     mode, (__u64)-1,
991                                                     (__u64)-1, 0 /* dev_t */,
992                                                     cifs_sb->local_nls,
993                                                     cifs_sb->mnt_cifs_flags &
994                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
995                         }
996                 } else {
997                         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
998                             (mode & S_IWUGO) == 0) {
999                                 FILE_BASIC_INFO pInfo;
1000                                 memset(&pInfo, 0, sizeof(pInfo));
1001                                 pInfo.Attributes = cpu_to_le32(ATTR_READONLY);
1002                                 CIFSSMBSetTimes(xid, pTcon, full_path,
1003                                                 &pInfo, cifs_sb->local_nls,
1004                                                 cifs_sb->mnt_cifs_flags &
1005                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1006                         }
1007                         if (direntry->d_inode) {
1008                                 direntry->d_inode->i_mode = mode;
1009                                 direntry->d_inode->i_mode |= S_IFDIR;
1010                                 if (cifs_sb->mnt_cifs_flags &
1011                                      CIFS_MOUNT_SET_UID) {
1012                                         direntry->d_inode->i_uid =
1013                                                 current->fsuid;
1014                                         direntry->d_inode->i_gid =
1015                                                 current->fsgid;
1016                                 }
1017                         }
1018                 }
1019         }
1020 mkdir_out:
1021         kfree(full_path);
1022         FreeXid(xid);
1023         return rc;
1024 }
1025
1026 int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1027 {
1028         int rc = 0;
1029         int xid;
1030         struct cifs_sb_info *cifs_sb;
1031         struct cifsTconInfo *pTcon;
1032         char *full_path = NULL;
1033         struct cifsInodeInfo *cifsInode;
1034
1035         cFYI(1, ("cifs_rmdir, inode = 0x%p", inode));
1036
1037         xid = GetXid();
1038
1039         cifs_sb = CIFS_SB(inode->i_sb);
1040         pTcon = cifs_sb->tcon;
1041
1042         full_path = build_path_from_dentry(direntry);
1043         if (full_path == NULL) {
1044                 FreeXid(xid);
1045                 return -ENOMEM;
1046         }
1047
1048         rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1049                           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1050
1051         if (!rc) {
1052                 drop_nlink(inode);
1053                 spin_lock(&direntry->d_inode->i_lock);
1054                 i_size_write(direntry->d_inode, 0);
1055                 clear_nlink(direntry->d_inode);
1056                 spin_unlock(&direntry->d_inode->i_lock);
1057         }
1058
1059         cifsInode = CIFS_I(direntry->d_inode);
1060         cifsInode->time = 0;    /* force revalidate to go get info when
1061                                    needed */
1062         direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1063                 current_fs_time(inode->i_sb);
1064
1065         kfree(full_path);
1066         FreeXid(xid);
1067         return rc;
1068 }
1069
1070 int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
1071         struct inode *target_inode, struct dentry *target_direntry)
1072 {
1073         char *fromName;
1074         char *toName;
1075         struct cifs_sb_info *cifs_sb_source;
1076         struct cifs_sb_info *cifs_sb_target;
1077         struct cifsTconInfo *pTcon;
1078         int xid;
1079         int rc = 0;
1080
1081         xid = GetXid();
1082
1083         cifs_sb_target = CIFS_SB(target_inode->i_sb);
1084         cifs_sb_source = CIFS_SB(source_inode->i_sb);
1085         pTcon = cifs_sb_source->tcon;
1086
1087         if (pTcon != cifs_sb_target->tcon) {
1088                 FreeXid(xid);
1089                 return -EXDEV;  /* BB actually could be allowed if same server,
1090                                    but different share.
1091                                    Might eventually add support for this */
1092         }
1093
1094         /* we already  have the rename sem so we do not need to grab it again
1095            here to protect the path integrity */
1096         fromName = build_path_from_dentry(source_direntry);
1097         toName = build_path_from_dentry(target_direntry);
1098         if ((fromName == NULL) || (toName == NULL)) {
1099                 rc = -ENOMEM;
1100                 goto cifs_rename_exit;
1101         }
1102
1103         rc = CIFSSMBRename(xid, pTcon, fromName, toName,
1104                            cifs_sb_source->local_nls,
1105                            cifs_sb_source->mnt_cifs_flags &
1106                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1107         if (rc == -EEXIST) {
1108                 /* check if they are the same file because rename of hardlinked
1109                    files is a noop */
1110                 FILE_UNIX_BASIC_INFO *info_buf_source;
1111                 FILE_UNIX_BASIC_INFO *info_buf_target;
1112
1113                 info_buf_source =
1114                         kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1115                 if (info_buf_source != NULL) {
1116                         info_buf_target = info_buf_source + 1;
1117                         if (pTcon->unix_ext)
1118                                 rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
1119                                         info_buf_source,
1120                                         cifs_sb_source->local_nls,
1121                                         cifs_sb_source->mnt_cifs_flags &
1122                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1123                         /* else rc is still EEXIST so will fall through to
1124                            unlink the target and retry rename */
1125                         if (rc == 0) {
1126                                 rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName,
1127                                                 info_buf_target,
1128                                                 cifs_sb_target->local_nls,
1129                                                 /* remap based on source sb */
1130                                                 cifs_sb_source->mnt_cifs_flags &
1131                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
1132                         }
1133                         if ((rc == 0) &&
1134                             (info_buf_source->UniqueId ==
1135                              info_buf_target->UniqueId)) {
1136                         /* do not rename since the files are hardlinked which
1137                            is a noop */
1138                         } else {
1139                         /* we either can not tell the files are hardlinked
1140                            (as with Windows servers) or files are not
1141                            hardlinked so delete the target manually before
1142                            renaming to follow POSIX rather than Windows
1143                            semantics */
1144                                 cifs_unlink(target_inode, target_direntry);
1145                                 rc = CIFSSMBRename(xid, pTcon, fromName,
1146                                                    toName,
1147                                                    cifs_sb_source->local_nls,
1148                                                    cifs_sb_source->mnt_cifs_flags
1149                                                    & CIFS_MOUNT_MAP_SPECIAL_CHR);
1150                         }
1151                         kfree(info_buf_source);
1152                 } /* if we can not get memory just leave rc as EEXIST */
1153         }
1154
1155         if (rc)
1156                 cFYI(1, ("rename rc %d", rc));
1157
1158         if ((rc == -EIO) || (rc == -EEXIST)) {
1159                 int oplock = 0;
1160                 __u16 netfid;
1161
1162                 /* BB FIXME Is Generic Read correct for rename? */
1163                 /* if renaming directory - we should not say CREATE_NOT_DIR,
1164                    need to test renaming open directory, also GENERIC_READ
1165                    might not right be right access to request */
1166                 rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ,
1167                                  CREATE_NOT_DIR, &netfid, &oplock, NULL,
1168                                  cifs_sb_source->local_nls,
1169                                  cifs_sb_source->mnt_cifs_flags &
1170                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1171                 if (rc == 0) {
1172                         rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
1173                                               cifs_sb_source->local_nls,
1174                                               cifs_sb_source->mnt_cifs_flags &
1175                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1176                         CIFSSMBClose(xid, pTcon, netfid);
1177                 }
1178         }
1179
1180 cifs_rename_exit:
1181         kfree(fromName);
1182         kfree(toName);
1183         FreeXid(xid);
1184         return rc;
1185 }
1186
1187 int cifs_revalidate(struct dentry *direntry)
1188 {
1189         int xid;
1190         int rc = 0, wbrc = 0;
1191         char *full_path;
1192         struct cifs_sb_info *cifs_sb;
1193         struct cifsInodeInfo *cifsInode;
1194         loff_t local_size;
1195         struct timespec local_mtime;
1196         bool invalidate_inode = false;
1197
1198         if (direntry->d_inode == NULL)
1199                 return -ENOENT;
1200
1201         cifsInode = CIFS_I(direntry->d_inode);
1202
1203         if (cifsInode == NULL)
1204                 return -ENOENT;
1205
1206         /* no sense revalidating inode info on file that no one can write */
1207         if (CIFS_I(direntry->d_inode)->clientCanCacheRead)
1208                 return rc;
1209
1210         xid = GetXid();
1211
1212         cifs_sb = CIFS_SB(direntry->d_sb);
1213
1214         /* can not safely grab the rename sem here if rename calls revalidate
1215            since that would deadlock */
1216         full_path = build_path_from_dentry(direntry);
1217         if (full_path == NULL) {
1218                 FreeXid(xid);
1219                 return -ENOMEM;
1220         }
1221         cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
1222                  "jiffies %ld", full_path, direntry->d_inode,
1223                  direntry->d_inode->i_count.counter, direntry,
1224                  direntry->d_time, jiffies));
1225
1226         if (cifsInode->time == 0) {
1227                 /* was set to zero previously to force revalidate */
1228         } else if (time_before(jiffies, cifsInode->time + HZ) &&
1229                    lookupCacheEnabled) {
1230                 if ((S_ISREG(direntry->d_inode->i_mode) == 0) ||
1231                     (direntry->d_inode->i_nlink == 1)) {
1232                         kfree(full_path);
1233                         FreeXid(xid);
1234                         return rc;
1235                 } else {
1236                         cFYI(1, ("Have to revalidate file due to hardlinks"));
1237                 }
1238         }
1239
1240         /* save mtime and size */
1241         local_mtime = direntry->d_inode->i_mtime;
1242         local_size = direntry->d_inode->i_size;
1243
1244         if (cifs_sb->tcon->unix_ext) {
1245                 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
1246                                               direntry->d_sb, xid);
1247                 if (rc) {
1248                         cFYI(1, ("error on getting revalidate info %d", rc));
1249 /*                      if (rc != -ENOENT)
1250                                 rc = 0; */      /* BB should we cache info on
1251                                                    certain errors? */
1252                 }
1253         } else {
1254                 rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
1255                                          direntry->d_sb, xid, NULL);
1256                 if (rc) {
1257                         cFYI(1, ("error on getting revalidate info %d", rc));
1258 /*                      if (rc != -ENOENT)
1259                                 rc = 0; */      /* BB should we cache info on
1260                                                    certain errors? */
1261                 }
1262         }
1263         /* should we remap certain errors, access denied?, to zero */
1264
1265         /* if not oplocked, we invalidate inode pages if mtime or file size
1266            had changed on server */
1267
1268         if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
1269             (local_size == direntry->d_inode->i_size)) {
1270                 cFYI(1, ("cifs_revalidate - inode unchanged"));
1271         } else {
1272                 /* file may have changed on server */
1273                 if (cifsInode->clientCanCacheRead) {
1274                         /* no need to invalidate inode pages since we were the
1275                            only ones who could have modified the file and the
1276                            server copy is staler than ours */
1277                 } else {
1278                         invalidate_inode = true;
1279                 }
1280         }
1281
1282         /* can not grab this sem since kernel filesys locking documentation
1283            indicates i_mutex may be taken by the kernel on lookup and rename
1284            which could deadlock if we grab the i_mutex here as well */
1285 /*      mutex_lock(&direntry->d_inode->i_mutex);*/
1286         /* need to write out dirty pages here  */
1287         if (direntry->d_inode->i_mapping) {
1288                 /* do we need to lock inode until after invalidate completes
1289                    below? */
1290                 wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping);
1291                 if (wbrc)
1292                         CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1293         }
1294         if (invalidate_inode) {
1295         /* shrink_dcache not necessary now that cifs dentry ops
1296         are exported for negative dentries */
1297 /*              if (S_ISDIR(direntry->d_inode->i_mode))
1298                         shrink_dcache_parent(direntry); */
1299                 if (S_ISREG(direntry->d_inode->i_mode)) {
1300                         if (direntry->d_inode->i_mapping)
1301                                 wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
1302                                 if (wbrc)
1303                                         CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1304                         /* may eventually have to do this for open files too */
1305                         if (list_empty(&(cifsInode->openFileList))) {
1306                                 /* changed on server - flush read ahead pages */
1307                                 cFYI(1, ("Invalidating read ahead data on "
1308                                          "closed file"));
1309                                 invalidate_remote_inode(direntry->d_inode);
1310                         }
1311                 }
1312         }
1313 /*      mutex_unlock(&direntry->d_inode->i_mutex); */
1314
1315         kfree(full_path);
1316         FreeXid(xid);
1317         return rc;
1318 }
1319
1320 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1321         struct kstat *stat)
1322 {
1323         int err = cifs_revalidate(dentry);
1324         if (!err) {
1325                 generic_fillattr(dentry->d_inode, stat);
1326                 stat->blksize = CIFS_MAX_MSGSIZE;
1327         }
1328         return err;
1329 }
1330
1331 static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1332 {
1333         pgoff_t index = from >> PAGE_CACHE_SHIFT;
1334         unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1335         struct page *page;
1336         int rc = 0;
1337
1338         page = grab_cache_page(mapping, index);
1339         if (!page)
1340                 return -ENOMEM;
1341
1342         zero_user_segment(page, offset, PAGE_CACHE_SIZE);
1343         unlock_page(page);
1344         page_cache_release(page);
1345         return rc;
1346 }
1347
1348 static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1349 {
1350         struct address_space *mapping = inode->i_mapping;
1351         unsigned long limit;
1352
1353         spin_lock(&inode->i_lock);
1354         if (inode->i_size < offset)
1355                 goto do_expand;
1356         /*
1357          * truncation of in-use swapfiles is disallowed - it would cause
1358          * subsequent swapout to scribble on the now-freed blocks.
1359          */
1360         if (IS_SWAPFILE(inode)) {
1361                 spin_unlock(&inode->i_lock);
1362                 goto out_busy;
1363         }
1364         i_size_write(inode, offset);
1365         spin_unlock(&inode->i_lock);
1366         /*
1367          * unmap_mapping_range is called twice, first simply for efficiency
1368          * so that truncate_inode_pages does fewer single-page unmaps. However
1369          * after this first call, and before truncate_inode_pages finishes,
1370          * it is possible for private pages to be COWed, which remain after
1371          * truncate_inode_pages finishes, hence the second unmap_mapping_range
1372          * call must be made for correctness.
1373          */
1374         unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1375         truncate_inode_pages(mapping, offset);
1376         unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1377         goto out_truncate;
1378
1379 do_expand:
1380         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
1381         if (limit != RLIM_INFINITY && offset > limit) {
1382                 spin_unlock(&inode->i_lock);
1383                 goto out_sig;
1384         }
1385         if (offset > inode->i_sb->s_maxbytes) {
1386                 spin_unlock(&inode->i_lock);
1387                 goto out_big;
1388         }
1389         i_size_write(inode, offset);
1390         spin_unlock(&inode->i_lock);
1391 out_truncate:
1392         if (inode->i_op && inode->i_op->truncate)
1393                 inode->i_op->truncate(inode);
1394         return 0;
1395 out_sig:
1396         send_sig(SIGXFSZ, current, 0);
1397 out_big:
1398         return -EFBIG;
1399 out_busy:
1400         return -ETXTBSY;
1401 }
1402
1403 int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1404 {
1405         int xid;
1406         struct cifs_sb_info *cifs_sb;
1407         struct cifsTconInfo *pTcon;
1408         char *full_path = NULL;
1409         int rc = -EACCES;
1410         struct cifsFileInfo *open_file = NULL;
1411         FILE_BASIC_INFO time_buf;
1412         bool set_time = false;
1413         bool set_dosattr = false;
1414         __u64 mode = 0xFFFFFFFFFFFFFFFFULL;
1415         __u64 uid = 0xFFFFFFFFFFFFFFFFULL;
1416         __u64 gid = 0xFFFFFFFFFFFFFFFFULL;
1417         struct cifsInodeInfo *cifsInode;
1418         struct inode *inode = direntry->d_inode;
1419
1420         xid = GetXid();
1421
1422         cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
1423                  direntry->d_name.name, attrs->ia_valid));
1424
1425         cifs_sb = CIFS_SB(inode->i_sb);
1426         pTcon = cifs_sb->tcon;
1427
1428         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1429                 /* check if we have permission to change attrs */
1430                 rc = inode_change_ok(inode, attrs);
1431                 if (rc < 0) {
1432                         FreeXid(xid);
1433                         return rc;
1434                 } else
1435                         rc = 0;
1436         }
1437
1438         full_path = build_path_from_dentry(direntry);
1439         if (full_path == NULL) {
1440                 FreeXid(xid);
1441                 return -ENOMEM;
1442         }
1443         cifsInode = CIFS_I(inode);
1444
1445         if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
1446                 /*
1447                    Flush data before changing file size or changing the last
1448                    write time of the file on the server. If the
1449                    flush returns error, store it to report later and continue.
1450                    BB: This should be smarter. Why bother flushing pages that
1451                    will be truncated anyway? Also, should we error out here if
1452                    the flush returns error?
1453                  */
1454                 rc = filemap_write_and_wait(inode->i_mapping);
1455                 if (rc != 0) {
1456                         cifsInode->write_behind_rc = rc;
1457                         rc = 0;
1458                 }
1459         }
1460
1461         if (attrs->ia_valid & ATTR_SIZE) {
1462                 /* To avoid spurious oplock breaks from server, in the case of
1463                    inodes that we already have open, avoid doing path based
1464                    setting of file size if we can do it by handle.
1465                    This keeps our caching token (oplock) and avoids timeouts
1466                    when the local oplock break takes longer to flush
1467                    writebehind data than the SMB timeout for the SetPathInfo
1468                    request would allow */
1469
1470                 open_file = find_writable_file(cifsInode);
1471                 if (open_file) {
1472                         __u16 nfid = open_file->netfid;
1473                         __u32 npid = open_file->pid;
1474                         rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
1475                                                 nfid, npid, false);
1476                         atomic_dec(&open_file->wrtPending);
1477                         cFYI(1, ("SetFSize for attrs rc = %d", rc));
1478                         if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1479                                 unsigned int bytes_written;
1480                                 rc = CIFSSMBWrite(xid, pTcon,
1481                                                   nfid, 0, attrs->ia_size,
1482                                                   &bytes_written, NULL, NULL,
1483                                                   1 /* 45 seconds */);
1484                                 cFYI(1, ("Wrt seteof rc %d", rc));
1485                         }
1486                 } else
1487                         rc = -EINVAL;
1488
1489                 if (rc != 0) {
1490                         /* Set file size by pathname rather than by handle
1491                            either because no valid, writeable file handle for
1492                            it was found or because there was an error setting
1493                            it by handle */
1494                         rc = CIFSSMBSetEOF(xid, pTcon, full_path,
1495                                            attrs->ia_size, false,
1496                                            cifs_sb->local_nls,
1497                                            cifs_sb->mnt_cifs_flags &
1498                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1499                         cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1500                         if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1501                                 __u16 netfid;
1502                                 int oplock = 0;
1503
1504                                 rc = SMBLegacyOpen(xid, pTcon, full_path,
1505                                         FILE_OPEN,
1506                                         SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1507                                         CREATE_NOT_DIR, &netfid, &oplock,
1508                                         NULL, cifs_sb->local_nls,
1509                                         cifs_sb->mnt_cifs_flags &
1510                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1511                                 if (rc == 0) {
1512                                         unsigned int bytes_written;
1513                                         rc = CIFSSMBWrite(xid, pTcon,
1514                                                         netfid, 0,
1515                                                         attrs->ia_size,
1516                                                         &bytes_written, NULL,
1517                                                         NULL, 1 /* 45 sec */);
1518                                         cFYI(1, ("wrt seteof rc %d", rc));
1519                                         CIFSSMBClose(xid, pTcon, netfid);
1520                                 }
1521
1522                         }
1523                 }
1524
1525                 /* Server is ok setting allocation size implicitly - no need
1526                    to call:
1527                 CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, true,
1528                          cifs_sb->local_nls);
1529                    */
1530
1531                 if (rc == 0) {
1532                         rc = cifs_vmtruncate(inode, attrs->ia_size);
1533                         cifs_truncate_page(inode->i_mapping, inode->i_size);
1534                 } else
1535                         goto cifs_setattr_exit;
1536         }
1537         if (attrs->ia_valid & ATTR_UID) {
1538                 cFYI(1, ("UID changed to %d", attrs->ia_uid));
1539                 uid = attrs->ia_uid;
1540         }
1541         if (attrs->ia_valid & ATTR_GID) {
1542                 cFYI(1, ("GID changed to %d", attrs->ia_gid));
1543                 gid = attrs->ia_gid;
1544         }
1545
1546         time_buf.Attributes = 0;
1547
1548         /* skip mode change if it's just for clearing setuid/setgid */
1549         if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1550                 attrs->ia_valid &= ~ATTR_MODE;
1551
1552         if (attrs->ia_valid & ATTR_MODE) {
1553                 cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode));
1554                 mode = attrs->ia_mode;
1555         }
1556
1557         if ((pTcon->unix_ext)
1558             && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
1559                 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
1560                                          0 /* dev_t */, cifs_sb->local_nls,
1561                                          cifs_sb->mnt_cifs_flags &
1562                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1563         else if (attrs->ia_valid & ATTR_MODE) {
1564                 rc = 0;
1565 #ifdef CONFIG_CIFS_EXPERIMENTAL
1566                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1567                         rc = mode_to_acl(inode, full_path, mode);
1568                 else if ((mode & S_IWUGO) == 0) {
1569 #else
1570                 if ((mode & S_IWUGO) == 0) {
1571 #endif
1572                         /* not writeable */
1573                         if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1574                                 set_dosattr = true;
1575                                 time_buf.Attributes =
1576                                         cpu_to_le32(cifsInode->cifsAttrs |
1577                                                     ATTR_READONLY);
1578                         }
1579                 } else if (cifsInode->cifsAttrs & ATTR_READONLY) {
1580                         /* If file is readonly on server, we would
1581                         not be able to write to it - so if any write
1582                         bit is enabled for user or group or other we
1583                         need to at least try to remove r/o dos attr */
1584                         set_dosattr = true;
1585                         time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs &
1586                                             (~ATTR_READONLY));
1587                         /* Windows ignores set to zero */
1588                         if (time_buf.Attributes == 0)
1589                                 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
1590                 }
1591         }
1592
1593         if (attrs->ia_valid & ATTR_ATIME) {
1594                 set_time = true;
1595                 time_buf.LastAccessTime =
1596                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
1597         } else
1598                 time_buf.LastAccessTime = 0;
1599
1600         if (attrs->ia_valid & ATTR_MTIME) {
1601                 set_time = true;
1602                 time_buf.LastWriteTime =
1603                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
1604         } else
1605                 time_buf.LastWriteTime = 0;
1606         /* Do not set ctime explicitly unless other time
1607            stamps are changed explicitly (i.e. by utime()
1608            since we would then have a mix of client and
1609            server times */
1610
1611         if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
1612                 set_time = true;
1613                 /* Although Samba throws this field away
1614                 it may be useful to Windows - but we do
1615                 not want to set ctime unless some other
1616                 timestamp is changing */
1617                 cFYI(1, ("CIFS - CTIME changed"));
1618                 time_buf.ChangeTime =
1619                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
1620         } else
1621                 time_buf.ChangeTime = 0;
1622
1623         if (set_time || set_dosattr) {
1624                 time_buf.CreationTime = 0;      /* do not change */
1625                 /* In the future we should experiment - try setting timestamps
1626                    via Handle (SetFileInfo) instead of by path */
1627                 if (!(pTcon->ses->flags & CIFS_SES_NT4))
1628                         rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf,
1629                                              cifs_sb->local_nls,
1630                                              cifs_sb->mnt_cifs_flags &
1631                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1632                 else
1633                         rc = -EOPNOTSUPP;
1634
1635                 if (rc == -EOPNOTSUPP) {
1636                         int oplock = 0;
1637                         __u16 netfid;
1638
1639                         cFYI(1, ("calling SetFileInfo since SetPathInfo for "
1640                                  "times not supported by this server"));
1641                         /* BB we could scan to see if we already have it open
1642                            and pass in pid of opener to function */
1643                         rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
1644                                          SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1645                                          CREATE_NOT_DIR, &netfid, &oplock,
1646                                          NULL, cifs_sb->local_nls,
1647                                          cifs_sb->mnt_cifs_flags &
1648                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1649                         if (rc == 0) {
1650                                 rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf,
1651                                                          netfid);
1652                                 CIFSSMBClose(xid, pTcon, netfid);
1653                         } else {
1654                         /* BB For even older servers we could convert time_buf
1655                            into old DOS style which uses two second
1656                            granularity */
1657
1658                         /* rc = CIFSSMBSetTimesLegacy(xid, pTcon, full_path,
1659                                         &time_buf, cifs_sb->local_nls); */
1660                         }
1661                 }
1662                 /* Even if error on time set, no sense failing the call if
1663                 the server would set the time to a reasonable value anyway,
1664                 and this check ensures that we are not being called from
1665                 sys_utimes in which case we ought to fail the call back to
1666                 the user when the server rejects the call */
1667                 if ((rc) && (attrs->ia_valid &
1668                          (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
1669                         rc = 0;
1670         }
1671
1672         /* do not need local check to inode_check_ok since the server does
1673            that */
1674         if (!rc)
1675                 rc = inode_setattr(inode, attrs);
1676 cifs_setattr_exit:
1677         kfree(full_path);
1678         FreeXid(xid);
1679         return rc;
1680 }
1681
1682 #if 0
1683 void cifs_delete_inode(struct inode *inode)
1684 {
1685         cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
1686         /* may have to add back in if and when safe distributed caching of
1687            directories added e.g. via FindNotify */
1688 }
1689 #endif