Merge git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6
[sfrench/cifs-2.6.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 = FALSE;
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         int 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 = FALSE;
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 = FALSE;
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 = FALSE;
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                 if (pTcon->unix_ext) {
978                         mode &= ~current->fs->umask;
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                         /* BB to be implemented via Windows secrty descriptors
998                            eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
999                                                  -1, -1, local_nls); */
1000                         if (direntry->d_inode) {
1001                                 direntry->d_inode->i_mode = mode;
1002                                 direntry->d_inode->i_mode |= S_IFDIR;
1003                                 if (cifs_sb->mnt_cifs_flags &
1004                                      CIFS_MOUNT_SET_UID) {
1005                                         direntry->d_inode->i_uid =
1006                                                 current->fsuid;
1007                                         direntry->d_inode->i_gid =
1008                                                 current->fsgid;
1009                                 }
1010                         }
1011                 }
1012         }
1013 mkdir_out:
1014         kfree(full_path);
1015         FreeXid(xid);
1016         return rc;
1017 }
1018
1019 int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1020 {
1021         int rc = 0;
1022         int xid;
1023         struct cifs_sb_info *cifs_sb;
1024         struct cifsTconInfo *pTcon;
1025         char *full_path = NULL;
1026         struct cifsInodeInfo *cifsInode;
1027
1028         cFYI(1, ("cifs_rmdir, inode = 0x%p", inode));
1029
1030         xid = GetXid();
1031
1032         cifs_sb = CIFS_SB(inode->i_sb);
1033         pTcon = cifs_sb->tcon;
1034
1035         full_path = build_path_from_dentry(direntry);
1036         if (full_path == NULL) {
1037                 FreeXid(xid);
1038                 return -ENOMEM;
1039         }
1040
1041         rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1042                           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1043
1044         if (!rc) {
1045                 drop_nlink(inode);
1046                 spin_lock(&direntry->d_inode->i_lock);
1047                 i_size_write(direntry->d_inode, 0);
1048                 clear_nlink(direntry->d_inode);
1049                 spin_unlock(&direntry->d_inode->i_lock);
1050         }
1051
1052         cifsInode = CIFS_I(direntry->d_inode);
1053         cifsInode->time = 0;    /* force revalidate to go get info when
1054                                    needed */
1055         direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1056                 current_fs_time(inode->i_sb);
1057
1058         kfree(full_path);
1059         FreeXid(xid);
1060         return rc;
1061 }
1062
1063 int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
1064         struct inode *target_inode, struct dentry *target_direntry)
1065 {
1066         char *fromName;
1067         char *toName;
1068         struct cifs_sb_info *cifs_sb_source;
1069         struct cifs_sb_info *cifs_sb_target;
1070         struct cifsTconInfo *pTcon;
1071         int xid;
1072         int rc = 0;
1073
1074         xid = GetXid();
1075
1076         cifs_sb_target = CIFS_SB(target_inode->i_sb);
1077         cifs_sb_source = CIFS_SB(source_inode->i_sb);
1078         pTcon = cifs_sb_source->tcon;
1079
1080         if (pTcon != cifs_sb_target->tcon) {
1081                 FreeXid(xid);
1082                 return -EXDEV;  /* BB actually could be allowed if same server,
1083                                    but different share.
1084                                    Might eventually add support for this */
1085         }
1086
1087         /* we already  have the rename sem so we do not need to grab it again
1088            here to protect the path integrity */
1089         fromName = build_path_from_dentry(source_direntry);
1090         toName = build_path_from_dentry(target_direntry);
1091         if ((fromName == NULL) || (toName == NULL)) {
1092                 rc = -ENOMEM;
1093                 goto cifs_rename_exit;
1094         }
1095
1096         rc = CIFSSMBRename(xid, pTcon, fromName, toName,
1097                            cifs_sb_source->local_nls,
1098                            cifs_sb_source->mnt_cifs_flags &
1099                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1100         if (rc == -EEXIST) {
1101                 /* check if they are the same file because rename of hardlinked
1102                    files is a noop */
1103                 FILE_UNIX_BASIC_INFO *info_buf_source;
1104                 FILE_UNIX_BASIC_INFO *info_buf_target;
1105
1106                 info_buf_source =
1107                         kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1108                 if (info_buf_source != NULL) {
1109                         info_buf_target = info_buf_source + 1;
1110                         if (pTcon->unix_ext)
1111                                 rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
1112                                         info_buf_source,
1113                                         cifs_sb_source->local_nls,
1114                                         cifs_sb_source->mnt_cifs_flags &
1115                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1116                         /* else rc is still EEXIST so will fall through to
1117                            unlink the target and retry rename */
1118                         if (rc == 0) {
1119                                 rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName,
1120                                                 info_buf_target,
1121                                                 cifs_sb_target->local_nls,
1122                                                 /* remap based on source sb */
1123                                                 cifs_sb_source->mnt_cifs_flags &
1124                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
1125                         }
1126                         if ((rc == 0) &&
1127                             (info_buf_source->UniqueId ==
1128                              info_buf_target->UniqueId)) {
1129                         /* do not rename since the files are hardlinked which
1130                            is a noop */
1131                         } else {
1132                         /* we either can not tell the files are hardlinked
1133                            (as with Windows servers) or files are not
1134                            hardlinked so delete the target manually before
1135                            renaming to follow POSIX rather than Windows
1136                            semantics */
1137                                 cifs_unlink(target_inode, target_direntry);
1138                                 rc = CIFSSMBRename(xid, pTcon, fromName,
1139                                                    toName,
1140                                                    cifs_sb_source->local_nls,
1141                                                    cifs_sb_source->mnt_cifs_flags
1142                                                    & CIFS_MOUNT_MAP_SPECIAL_CHR);
1143                         }
1144                         kfree(info_buf_source);
1145                 } /* if we can not get memory just leave rc as EEXIST */
1146         }
1147
1148         if (rc)
1149                 cFYI(1, ("rename rc %d", rc));
1150
1151         if ((rc == -EIO) || (rc == -EEXIST)) {
1152                 int oplock = FALSE;
1153                 __u16 netfid;
1154
1155                 /* BB FIXME Is Generic Read correct for rename? */
1156                 /* if renaming directory - we should not say CREATE_NOT_DIR,
1157                    need to test renaming open directory, also GENERIC_READ
1158                    might not right be right access to request */
1159                 rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ,
1160                                  CREATE_NOT_DIR, &netfid, &oplock, NULL,
1161                                  cifs_sb_source->local_nls,
1162                                  cifs_sb_source->mnt_cifs_flags &
1163                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1164                 if (rc == 0) {
1165                         rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
1166                                               cifs_sb_source->local_nls,
1167                                               cifs_sb_source->mnt_cifs_flags &
1168                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1169                         CIFSSMBClose(xid, pTcon, netfid);
1170                 }
1171         }
1172
1173 cifs_rename_exit:
1174         kfree(fromName);
1175         kfree(toName);
1176         FreeXid(xid);
1177         return rc;
1178 }
1179
1180 int cifs_revalidate(struct dentry *direntry)
1181 {
1182         int xid;
1183         int rc = 0, wbrc = 0;
1184         char *full_path;
1185         struct cifs_sb_info *cifs_sb;
1186         struct cifsInodeInfo *cifsInode;
1187         loff_t local_size;
1188         struct timespec local_mtime;
1189         int invalidate_inode = FALSE;
1190
1191         if (direntry->d_inode == NULL)
1192                 return -ENOENT;
1193
1194         cifsInode = CIFS_I(direntry->d_inode);
1195
1196         if (cifsInode == NULL)
1197                 return -ENOENT;
1198
1199         /* no sense revalidating inode info on file that no one can write */
1200         if (CIFS_I(direntry->d_inode)->clientCanCacheRead)
1201                 return rc;
1202
1203         xid = GetXid();
1204
1205         cifs_sb = CIFS_SB(direntry->d_sb);
1206
1207         /* can not safely grab the rename sem here if rename calls revalidate
1208            since that would deadlock */
1209         full_path = build_path_from_dentry(direntry);
1210         if (full_path == NULL) {
1211                 FreeXid(xid);
1212                 return -ENOMEM;
1213         }
1214         cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
1215                  "jiffies %ld", full_path, direntry->d_inode,
1216                  direntry->d_inode->i_count.counter, direntry,
1217                  direntry->d_time, jiffies));
1218
1219         if (cifsInode->time == 0) {
1220                 /* was set to zero previously to force revalidate */
1221         } else if (time_before(jiffies, cifsInode->time + HZ) &&
1222                    lookupCacheEnabled) {
1223                 if ((S_ISREG(direntry->d_inode->i_mode) == 0) ||
1224                     (direntry->d_inode->i_nlink == 1)) {
1225                         kfree(full_path);
1226                         FreeXid(xid);
1227                         return rc;
1228                 } else {
1229                         cFYI(1, ("Have to revalidate file due to hardlinks"));
1230                 }
1231         }
1232
1233         /* save mtime and size */
1234         local_mtime = direntry->d_inode->i_mtime;
1235         local_size = direntry->d_inode->i_size;
1236
1237         if (cifs_sb->tcon->unix_ext) {
1238                 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
1239                                               direntry->d_sb, xid);
1240                 if (rc) {
1241                         cFYI(1, ("error on getting revalidate info %d", rc));
1242 /*                      if (rc != -ENOENT)
1243                                 rc = 0; */      /* BB should we cache info on
1244                                                    certain errors? */
1245                 }
1246         } else {
1247                 rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
1248                                          direntry->d_sb, xid, NULL);
1249                 if (rc) {
1250                         cFYI(1, ("error on getting revalidate info %d", rc));
1251 /*                      if (rc != -ENOENT)
1252                                 rc = 0; */      /* BB should we cache info on
1253                                                    certain errors? */
1254                 }
1255         }
1256         /* should we remap certain errors, access denied?, to zero */
1257
1258         /* if not oplocked, we invalidate inode pages if mtime or file size
1259            had changed on server */
1260
1261         if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
1262             (local_size == direntry->d_inode->i_size)) {
1263                 cFYI(1, ("cifs_revalidate - inode unchanged"));
1264         } else {
1265                 /* file may have changed on server */
1266                 if (cifsInode->clientCanCacheRead) {
1267                         /* no need to invalidate inode pages since we were the
1268                            only ones who could have modified the file and the
1269                            server copy is staler than ours */
1270                 } else {
1271                         invalidate_inode = TRUE;
1272                 }
1273         }
1274
1275         /* can not grab this sem since kernel filesys locking documentation
1276            indicates i_mutex may be taken by the kernel on lookup and rename
1277            which could deadlock if we grab the i_mutex here as well */
1278 /*      mutex_lock(&direntry->d_inode->i_mutex);*/
1279         /* need to write out dirty pages here  */
1280         if (direntry->d_inode->i_mapping) {
1281                 /* do we need to lock inode until after invalidate completes
1282                    below? */
1283                 wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping);
1284                 if (wbrc)
1285                         CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1286         }
1287         if (invalidate_inode) {
1288         /* shrink_dcache not necessary now that cifs dentry ops
1289         are exported for negative dentries */
1290 /*              if (S_ISDIR(direntry->d_inode->i_mode))
1291                         shrink_dcache_parent(direntry); */
1292                 if (S_ISREG(direntry->d_inode->i_mode)) {
1293                         if (direntry->d_inode->i_mapping)
1294                                 wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
1295                                 if (wbrc)
1296                                         CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1297                         /* may eventually have to do this for open files too */
1298                         if (list_empty(&(cifsInode->openFileList))) {
1299                                 /* changed on server - flush read ahead pages */
1300                                 cFYI(1, ("Invalidating read ahead data on "
1301                                          "closed file"));
1302                                 invalidate_remote_inode(direntry->d_inode);
1303                         }
1304                 }
1305         }
1306 /*      mutex_unlock(&direntry->d_inode->i_mutex); */
1307
1308         kfree(full_path);
1309         FreeXid(xid);
1310         return rc;
1311 }
1312
1313 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1314         struct kstat *stat)
1315 {
1316         int err = cifs_revalidate(dentry);
1317         if (!err) {
1318                 generic_fillattr(dentry->d_inode, stat);
1319                 stat->blksize = CIFS_MAX_MSGSIZE;
1320         }
1321         return err;
1322 }
1323
1324 static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1325 {
1326         pgoff_t index = from >> PAGE_CACHE_SHIFT;
1327         unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1328         struct page *page;
1329         int rc = 0;
1330
1331         page = grab_cache_page(mapping, index);
1332         if (!page)
1333                 return -ENOMEM;
1334
1335         zero_user_segment(page, offset, PAGE_CACHE_SIZE);
1336         unlock_page(page);
1337         page_cache_release(page);
1338         return rc;
1339 }
1340
1341 static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1342 {
1343         struct address_space *mapping = inode->i_mapping;
1344         unsigned long limit;
1345
1346         spin_lock(&inode->i_lock);
1347         if (inode->i_size < offset)
1348                 goto do_expand;
1349         /*
1350          * truncation of in-use swapfiles is disallowed - it would cause
1351          * subsequent swapout to scribble on the now-freed blocks.
1352          */
1353         if (IS_SWAPFILE(inode)) {
1354                 spin_unlock(&inode->i_lock);
1355                 goto out_busy;
1356         }
1357         i_size_write(inode, offset);
1358         spin_unlock(&inode->i_lock);
1359         /*
1360          * unmap_mapping_range is called twice, first simply for efficiency
1361          * so that truncate_inode_pages does fewer single-page unmaps. However
1362          * after this first call, and before truncate_inode_pages finishes,
1363          * it is possible for private pages to be COWed, which remain after
1364          * truncate_inode_pages finishes, hence the second unmap_mapping_range
1365          * call must be made for correctness.
1366          */
1367         unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1368         truncate_inode_pages(mapping, offset);
1369         unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1370         goto out_truncate;
1371
1372 do_expand:
1373         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
1374         if (limit != RLIM_INFINITY && offset > limit) {
1375                 spin_unlock(&inode->i_lock);
1376                 goto out_sig;
1377         }
1378         if (offset > inode->i_sb->s_maxbytes) {
1379                 spin_unlock(&inode->i_lock);
1380                 goto out_big;
1381         }
1382         i_size_write(inode, offset);
1383         spin_unlock(&inode->i_lock);
1384 out_truncate:
1385         if (inode->i_op && inode->i_op->truncate)
1386                 inode->i_op->truncate(inode);
1387         return 0;
1388 out_sig:
1389         send_sig(SIGXFSZ, current, 0);
1390 out_big:
1391         return -EFBIG;
1392 out_busy:
1393         return -ETXTBSY;
1394 }
1395
1396 int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1397 {
1398         int xid;
1399         struct cifs_sb_info *cifs_sb;
1400         struct cifsTconInfo *pTcon;
1401         char *full_path = NULL;
1402         int rc = -EACCES;
1403         struct cifsFileInfo *open_file = NULL;
1404         FILE_BASIC_INFO time_buf;
1405         int set_time = FALSE;
1406         int set_dosattr = FALSE;
1407         __u64 mode = 0xFFFFFFFFFFFFFFFFULL;
1408         __u64 uid = 0xFFFFFFFFFFFFFFFFULL;
1409         __u64 gid = 0xFFFFFFFFFFFFFFFFULL;
1410         struct cifsInodeInfo *cifsInode;
1411
1412         xid = GetXid();
1413
1414         cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
1415                  direntry->d_name.name, attrs->ia_valid));
1416
1417         cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
1418         pTcon = cifs_sb->tcon;
1419
1420         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1421                 /* check if we have permission to change attrs */
1422                 rc = inode_change_ok(direntry->d_inode, attrs);
1423                 if (rc < 0) {
1424                         FreeXid(xid);
1425                         return rc;
1426                 } else
1427                         rc = 0;
1428         }
1429
1430         full_path = build_path_from_dentry(direntry);
1431         if (full_path == NULL) {
1432                 FreeXid(xid);
1433                 return -ENOMEM;
1434         }
1435         cifsInode = CIFS_I(direntry->d_inode);
1436
1437         if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
1438                 /*
1439                    Flush data before changing file size or changing the last
1440                    write time of the file on the server. If the
1441                    flush returns error, store it to report later and continue.
1442                    BB: This should be smarter. Why bother flushing pages that
1443                    will be truncated anyway? Also, should we error out here if
1444                    the flush returns error?
1445                  */
1446                 rc = filemap_write_and_wait(direntry->d_inode->i_mapping);
1447                 if (rc != 0) {
1448                         CIFS_I(direntry->d_inode)->write_behind_rc = rc;
1449                         rc = 0;
1450                 }
1451         }
1452
1453         if (attrs->ia_valid & ATTR_SIZE) {
1454                 /* To avoid spurious oplock breaks from server, in the case of
1455                    inodes that we already have open, avoid doing path based
1456                    setting of file size if we can do it by handle.
1457                    This keeps our caching token (oplock) and avoids timeouts
1458                    when the local oplock break takes longer to flush
1459                    writebehind data than the SMB timeout for the SetPathInfo
1460                    request would allow */
1461
1462                 open_file = find_writable_file(cifsInode);
1463                 if (open_file) {
1464                         __u16 nfid = open_file->netfid;
1465                         __u32 npid = open_file->pid;
1466                         rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
1467                                                 nfid, npid, FALSE);
1468                         atomic_dec(&open_file->wrtPending);
1469                         cFYI(1, ("SetFSize for attrs rc = %d", rc));
1470                         if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1471                                 unsigned int bytes_written;
1472                                 rc = CIFSSMBWrite(xid, pTcon,
1473                                                   nfid, 0, attrs->ia_size,
1474                                                   &bytes_written, NULL, NULL,
1475                                                   1 /* 45 seconds */);
1476                                 cFYI(1, ("Wrt seteof rc %d", rc));
1477                         }
1478                 } else
1479                         rc = -EINVAL;
1480
1481                 if (rc != 0) {
1482                         /* Set file size by pathname rather than by handle
1483                            either because no valid, writeable file handle for
1484                            it was found or because there was an error setting
1485                            it by handle */
1486                         rc = CIFSSMBSetEOF(xid, pTcon, full_path,
1487                                            attrs->ia_size, FALSE,
1488                                            cifs_sb->local_nls,
1489                                            cifs_sb->mnt_cifs_flags &
1490                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1491                         cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1492                         if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1493                                 __u16 netfid;
1494                                 int oplock = FALSE;
1495
1496                                 rc = SMBLegacyOpen(xid, pTcon, full_path,
1497                                         FILE_OPEN,
1498                                         SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1499                                         CREATE_NOT_DIR, &netfid, &oplock,
1500                                         NULL, cifs_sb->local_nls,
1501                                         cifs_sb->mnt_cifs_flags &
1502                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1503                                 if (rc == 0) {
1504                                         unsigned int bytes_written;
1505                                         rc = CIFSSMBWrite(xid, pTcon,
1506                                                         netfid, 0,
1507                                                         attrs->ia_size,
1508                                                         &bytes_written, NULL,
1509                                                         NULL, 1 /* 45 sec */);
1510                                         cFYI(1, ("wrt seteof rc %d", rc));
1511                                         CIFSSMBClose(xid, pTcon, netfid);
1512                                 }
1513
1514                         }
1515                 }
1516
1517                 /* Server is ok setting allocation size implicitly - no need
1518                    to call:
1519                 CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, TRUE,
1520                          cifs_sb->local_nls);
1521                    */
1522
1523                 if (rc == 0) {
1524                         rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size);
1525                         cifs_truncate_page(direntry->d_inode->i_mapping,
1526                                            direntry->d_inode->i_size);
1527                 } else
1528                         goto cifs_setattr_exit;
1529         }
1530         if (attrs->ia_valid & ATTR_UID) {
1531                 cFYI(1, ("UID changed to %d", attrs->ia_uid));
1532                 uid = attrs->ia_uid;
1533         }
1534         if (attrs->ia_valid & ATTR_GID) {
1535                 cFYI(1, ("GID changed to %d", attrs->ia_gid));
1536                 gid = attrs->ia_gid;
1537         }
1538
1539         time_buf.Attributes = 0;
1540
1541         /* skip mode change if it's just for clearing setuid/setgid */
1542         if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1543                 attrs->ia_valid &= ~ATTR_MODE;
1544
1545         if (attrs->ia_valid & ATTR_MODE) {
1546                 cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode));
1547                 mode = attrs->ia_mode;
1548         }
1549
1550         if ((pTcon->unix_ext)
1551             && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
1552                 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
1553                                          0 /* dev_t */, cifs_sb->local_nls,
1554                                          cifs_sb->mnt_cifs_flags &
1555                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1556         else if (attrs->ia_valid & ATTR_MODE) {
1557                 rc = 0;
1558 #ifdef CONFIG_CIFS_EXPERIMENTAL
1559                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1560                         rc = mode_to_acl(direntry->d_inode, full_path, mode);
1561                 else if ((mode & S_IWUGO) == 0) {
1562 #else
1563                 if ((mode & S_IWUGO) == 0) {
1564 #endif
1565                         /* not writeable */
1566                         if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1567                                 set_dosattr = TRUE;
1568                                 time_buf.Attributes =
1569                                         cpu_to_le32(cifsInode->cifsAttrs |
1570                                                     ATTR_READONLY);
1571                         }
1572                 } else if (cifsInode->cifsAttrs & ATTR_READONLY) {
1573                         /* If file is readonly on server, we would
1574                         not be able to write to it - so if any write
1575                         bit is enabled for user or group or other we
1576                         need to at least try to remove r/o dos attr */
1577                         set_dosattr = TRUE;
1578                         time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs &
1579                                             (~ATTR_READONLY));
1580                         /* Windows ignores set to zero */
1581                         if (time_buf.Attributes == 0)
1582                                 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
1583                 }
1584 #ifdef CONFIG_CIFS_EXPERIMENTAL
1585                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1586                         mode_to_acl(direntry->d_inode, full_path, mode);
1587 #endif
1588         }
1589
1590         if (attrs->ia_valid & ATTR_ATIME) {
1591                 set_time = TRUE;
1592                 time_buf.LastAccessTime =
1593                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
1594         } else
1595                 time_buf.LastAccessTime = 0;
1596
1597         if (attrs->ia_valid & ATTR_MTIME) {
1598                 set_time = TRUE;
1599                 time_buf.LastWriteTime =
1600                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
1601         } else
1602                 time_buf.LastWriteTime = 0;
1603         /* Do not set ctime explicitly unless other time
1604            stamps are changed explicitly (i.e. by utime()
1605            since we would then have a mix of client and
1606            server times */
1607
1608         if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
1609                 set_time = TRUE;
1610                 /* Although Samba throws this field away
1611                 it may be useful to Windows - but we do
1612                 not want to set ctime unless some other
1613                 timestamp is changing */
1614                 cFYI(1, ("CIFS - CTIME changed"));
1615                 time_buf.ChangeTime =
1616                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
1617         } else
1618                 time_buf.ChangeTime = 0;
1619
1620         if (set_time || set_dosattr) {
1621                 time_buf.CreationTime = 0;      /* do not change */
1622                 /* In the future we should experiment - try setting timestamps
1623                    via Handle (SetFileInfo) instead of by path */
1624                 if (!(pTcon->ses->flags & CIFS_SES_NT4))
1625                         rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf,
1626                                              cifs_sb->local_nls,
1627                                              cifs_sb->mnt_cifs_flags &
1628                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1629                 else
1630                         rc = -EOPNOTSUPP;
1631
1632                 if (rc == -EOPNOTSUPP) {
1633                         int oplock = FALSE;
1634                         __u16 netfid;
1635
1636                         cFYI(1, ("calling SetFileInfo since SetPathInfo for "
1637                                  "times not supported by this server"));
1638                         /* BB we could scan to see if we already have it open
1639                            and pass in pid of opener to function */
1640                         rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
1641                                          SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1642                                          CREATE_NOT_DIR, &netfid, &oplock,
1643                                          NULL, cifs_sb->local_nls,
1644                                          cifs_sb->mnt_cifs_flags &
1645                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1646                         if (rc == 0) {
1647                                 rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf,
1648                                                          netfid);
1649                                 CIFSSMBClose(xid, pTcon, netfid);
1650                         } else {
1651                         /* BB For even older servers we could convert time_buf
1652                            into old DOS style which uses two second
1653                            granularity */
1654
1655                         /* rc = CIFSSMBSetTimesLegacy(xid, pTcon, full_path,
1656                                         &time_buf, cifs_sb->local_nls); */
1657                         }
1658                 }
1659                 /* Even if error on time set, no sense failing the call if
1660                 the server would set the time to a reasonable value anyway,
1661                 and this check ensures that we are not being called from
1662                 sys_utimes in which case we ought to fail the call back to
1663                 the user when the server rejects the call */
1664                 if ((rc) && (attrs->ia_valid &
1665                          (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
1666                         rc = 0;
1667         }
1668
1669         /* do not need local check to inode_check_ok since the server does
1670            that */
1671         if (!rc)
1672                 rc = inode_setattr(direntry->d_inode, attrs);
1673 cifs_setattr_exit:
1674         kfree(full_path);
1675         FreeXid(xid);
1676         return rc;
1677 }
1678
1679 #if 0
1680 void cifs_delete_inode(struct inode *inode)
1681 {
1682         cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
1683         /* may have to add back in if and when safe distributed caching of
1684            directories added e.g. via FindNotify */
1685 }
1686 #endif