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