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