]> err.no Git - linux-2.6/blob - fs/cifs/inode.c
7e4c24491729017803a81113316c9f9a1bf9d9c2
[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                         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, const __u16 *pfid)
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, pfid);
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                                          NULL);
621         if (rc && cifs_sb->tcon->ipc) {
622                 cFYI(1, ("ipc connection - fake read inode"));
623                 inode->i_mode |= S_IFDIR;
624                 inode->i_nlink = 2;
625                 inode->i_op = &cifs_ipc_inode_ops;
626                 inode->i_fop = &simple_dir_operations;
627                 inode->i_uid = cifs_sb->mnt_uid;
628                 inode->i_gid = cifs_sb->mnt_gid;
629                 _FreeXid(xid);
630                 iget_failed(inode);
631                 return ERR_PTR(rc);
632         }
633
634         unlock_new_inode(inode);
635
636         /* can not call macro FreeXid here since in a void func
637          * TODO: This is no longer true
638          */
639         _FreeXid(xid);
640         return inode;
641 }
642
643 int cifs_unlink(struct inode *inode, struct dentry *direntry)
644 {
645         int rc = 0;
646         int xid;
647         struct cifs_sb_info *cifs_sb;
648         struct cifsTconInfo *pTcon;
649         char *full_path = NULL;
650         struct cifsInodeInfo *cifsInode;
651         FILE_BASIC_INFO *pinfo_buf;
652
653         cFYI(1, ("cifs_unlink, inode = 0x%p", inode));
654
655         xid = GetXid();
656
657         if (inode)
658                 cifs_sb = CIFS_SB(inode->i_sb);
659         else
660                 cifs_sb = CIFS_SB(direntry->d_sb);
661         pTcon = cifs_sb->tcon;
662
663         /* Unlink can be called from rename so we can not grab the sem here
664            since we deadlock otherwise */
665 /*      mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);*/
666         full_path = build_path_from_dentry(direntry);
667 /*      mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);*/
668         if (full_path == NULL) {
669                 FreeXid(xid);
670                 return -ENOMEM;
671         }
672
673         if ((pTcon->ses->capabilities & CAP_UNIX) &&
674                 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
675                         le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
676                 rc = CIFSPOSIXDelFile(xid, pTcon, full_path,
677                         SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
678                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
679                 cFYI(1, ("posix del rc %d", rc));
680                 if ((rc == 0) || (rc == -ENOENT))
681                         goto psx_del_no_retry;
682         }
683
684         rc = CIFSSMBDelFile(xid, pTcon, full_path, cifs_sb->local_nls,
685                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
686 psx_del_no_retry:
687         if (!rc) {
688                 if (direntry->d_inode)
689                         drop_nlink(direntry->d_inode);
690         } else if (rc == -ENOENT) {
691                 d_drop(direntry);
692         } else if (rc == -ETXTBSY) {
693                 int oplock = FALSE;
694                 __u16 netfid;
695
696                 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
697                                  CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
698                                  &netfid, &oplock, NULL, cifs_sb->local_nls,
699                                  cifs_sb->mnt_cifs_flags &
700                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
701                 if (rc == 0) {
702                         CIFSSMBRenameOpenFile(xid, pTcon, netfid, NULL,
703                                               cifs_sb->local_nls,
704                                               cifs_sb->mnt_cifs_flags &
705                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
706                         CIFSSMBClose(xid, pTcon, netfid);
707                         if (direntry->d_inode)
708                                 drop_nlink(direntry->d_inode);
709                 }
710         } else if (rc == -EACCES) {
711                 /* try only if r/o attribute set in local lookup data? */
712                 pinfo_buf = kzalloc(sizeof(FILE_BASIC_INFO), GFP_KERNEL);
713                 if (pinfo_buf) {
714                         /* ATTRS set to normal clears r/o bit */
715                         pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL);
716                         if (!(pTcon->ses->flags & CIFS_SES_NT4))
717                                 rc = CIFSSMBSetTimes(xid, pTcon, full_path,
718                                                      pinfo_buf,
719                                                      cifs_sb->local_nls,
720                                                      cifs_sb->mnt_cifs_flags &
721                                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
722                         else
723                                 rc = -EOPNOTSUPP;
724
725                         if (rc == -EOPNOTSUPP) {
726                                 int oplock = FALSE;
727                                 __u16 netfid;
728                         /*      rc = CIFSSMBSetAttrLegacy(xid, pTcon,
729                                                           full_path,
730                                                           (__u16)ATTR_NORMAL,
731                                                           cifs_sb->local_nls);
732                            For some strange reason it seems that NT4 eats the
733                            old setattr call without actually setting the
734                            attributes so on to the third attempted workaround
735                            */
736
737                         /* BB could scan to see if we already have it open
738                            and pass in pid of opener to function */
739                                 rc = CIFSSMBOpen(xid, pTcon, full_path,
740                                                  FILE_OPEN, SYNCHRONIZE |
741                                                  FILE_WRITE_ATTRIBUTES, 0,
742                                                  &netfid, &oplock, NULL,
743                                                  cifs_sb->local_nls,
744                                                  cifs_sb->mnt_cifs_flags &
745                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
746                                 if (rc == 0) {
747                                         rc = CIFSSMBSetFileTimes(xid, pTcon,
748                                                                  pinfo_buf,
749                                                                  netfid);
750                                         CIFSSMBClose(xid, pTcon, netfid);
751                                 }
752                         }
753                         kfree(pinfo_buf);
754                 }
755                 if (rc == 0) {
756                         rc = CIFSSMBDelFile(xid, pTcon, full_path,
757                                             cifs_sb->local_nls,
758                                             cifs_sb->mnt_cifs_flags &
759                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
760                         if (!rc) {
761                                 if (direntry->d_inode)
762                                         drop_nlink(direntry->d_inode);
763                         } else if (rc == -ETXTBSY) {
764                                 int oplock = FALSE;
765                                 __u16 netfid;
766
767                                 rc = CIFSSMBOpen(xid, pTcon, full_path,
768                                                  FILE_OPEN, DELETE,
769                                                  CREATE_NOT_DIR |
770                                                  CREATE_DELETE_ON_CLOSE,
771                                                  &netfid, &oplock, NULL,
772                                                  cifs_sb->local_nls,
773                                                  cifs_sb->mnt_cifs_flags &
774                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
775                                 if (rc == 0) {
776                                         CIFSSMBRenameOpenFile(xid, pTcon,
777                                                 netfid, NULL,
778                                                 cifs_sb->local_nls,
779                                                 cifs_sb->mnt_cifs_flags &
780                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
781                                         CIFSSMBClose(xid, pTcon, netfid);
782                                         if (direntry->d_inode)
783                                                 drop_nlink(direntry->d_inode);
784                                 }
785                         /* BB if rc = -ETXTBUSY goto the rename logic BB */
786                         }
787                 }
788         }
789         if (direntry->d_inode) {
790                 cifsInode = CIFS_I(direntry->d_inode);
791                 cifsInode->time = 0;    /* will force revalidate to get info
792                                            when needed */
793                 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb);
794         }
795         if (inode) {
796                 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
797                 cifsInode = CIFS_I(inode);
798                 cifsInode->time = 0;    /* force revalidate of dir as well */
799         }
800
801         kfree(full_path);
802         FreeXid(xid);
803         return rc;
804 }
805
806 static void posix_fill_in_inode(struct inode *tmp_inode,
807         FILE_UNIX_BASIC_INFO *pData, int isNewInode)
808 {
809         struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
810         loff_t local_size;
811         struct timespec local_mtime;
812
813         cifsInfo->time = jiffies;
814         atomic_inc(&cifsInfo->inUse);
815
816         /* save mtime and size */
817         local_mtime = tmp_inode->i_mtime;
818         local_size  = tmp_inode->i_size;
819
820         cifs_unix_info_to_inode(tmp_inode, pData, 1);
821         cifs_set_ops(tmp_inode, false);
822
823         if (!S_ISREG(tmp_inode->i_mode))
824                 return;
825
826         /*
827          * No sense invalidating pages for new inode
828          * since we we have not started caching
829          * readahead file data yet.
830          */
831         if (isNewInode)
832                 return;
833
834         if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
835                 (local_size == tmp_inode->i_size)) {
836                 cFYI(1, ("inode exists but unchanged"));
837         } else {
838                 /* file may have changed on server */
839                 cFYI(1, ("invalidate inode, readdir detected change"));
840                 invalidate_remote_inode(tmp_inode);
841         }
842 }
843
844 int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
845 {
846         int rc = 0;
847         int xid;
848         struct cifs_sb_info *cifs_sb;
849         struct cifsTconInfo *pTcon;
850         char *full_path = NULL;
851         struct inode *newinode = NULL;
852
853         cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
854
855         xid = GetXid();
856
857         cifs_sb = CIFS_SB(inode->i_sb);
858         pTcon = cifs_sb->tcon;
859
860         full_path = build_path_from_dentry(direntry);
861         if (full_path == NULL) {
862                 FreeXid(xid);
863                 return -ENOMEM;
864         }
865
866         if ((pTcon->ses->capabilities & CAP_UNIX) &&
867                 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
868                         le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
869                 u32 oplock = 0;
870                 FILE_UNIX_BASIC_INFO *pInfo =
871                         kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
872                 if (pInfo == NULL) {
873                         rc = -ENOMEM;
874                         goto mkdir_out;
875                 }
876
877                 mode &= ~current->fs->umask;
878                 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
879                                 mode, NULL /* netfid */, pInfo, &oplock,
880                                 full_path, cifs_sb->local_nls,
881                                 cifs_sb->mnt_cifs_flags &
882                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
883                 if (rc == -EOPNOTSUPP) {
884                         kfree(pInfo);
885                         goto mkdir_retry_old;
886                 } else if (rc) {
887                         cFYI(1, ("posix mkdir returned 0x%x", rc));
888                         d_drop(direntry);
889                 } else {
890                         if (pInfo->Type == cpu_to_le32(-1)) {
891                                 /* no return info, go query for it */
892                                 kfree(pInfo);
893                                 goto mkdir_get_info;
894                         }
895 /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
896         to set uid/gid */
897                         inc_nlink(inode);
898                         if (pTcon->nocase)
899                                 direntry->d_op = &cifs_ci_dentry_ops;
900                         else
901                                 direntry->d_op = &cifs_dentry_ops;
902
903                         newinode = new_inode(inode->i_sb);
904                         if (newinode == NULL) {
905                                 kfree(pInfo);
906                                 goto mkdir_get_info;
907                         }
908                         /* Is an i_ino of zero legal? */
909                         /* Are there sanity checks we can use to ensure that
910                            the server is really filling in that field? */
911                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
912                                 newinode->i_ino =
913                                         (unsigned long)pInfo->UniqueId;
914                         } /* note ino incremented to unique num in new_inode */
915                         if (inode->i_sb->s_flags & MS_NOATIME)
916                                 newinode->i_flags |= S_NOATIME | S_NOCMTIME;
917                         newinode->i_nlink = 2;
918
919                         insert_inode_hash(newinode);
920                         d_instantiate(direntry, newinode);
921
922                         /* we already checked in POSIXCreate whether
923                            frame was long enough */
924                         posix_fill_in_inode(direntry->d_inode,
925                                         pInfo, 1 /* NewInode */);
926 #ifdef CONFIG_CIFS_DEBUG2
927                         cFYI(1, ("instantiated dentry %p %s to inode %p",
928                                 direntry, direntry->d_name.name, newinode));
929
930                         if (newinode->i_nlink != 2)
931                                 cFYI(1, ("unexpected number of links %d",
932                                         newinode->i_nlink));
933 #endif
934                 }
935                 kfree(pInfo);
936                 goto mkdir_out;
937         }
938 mkdir_retry_old:
939         /* BB add setting the equivalent of mode via CreateX w/ACLs */
940         rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
941                           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
942         if (rc) {
943                 cFYI(1, ("cifs_mkdir returned 0x%x", rc));
944                 d_drop(direntry);
945         } else {
946 mkdir_get_info:
947                 inc_nlink(inode);
948                 if (pTcon->unix_ext)
949                         rc = cifs_get_inode_info_unix(&newinode, full_path,
950                                                       inode->i_sb, xid);
951                 else
952                         rc = cifs_get_inode_info(&newinode, full_path, NULL,
953                                                  inode->i_sb, xid, NULL);
954
955                 if (pTcon->nocase)
956                         direntry->d_op = &cifs_ci_dentry_ops;
957                 else
958                         direntry->d_op = &cifs_dentry_ops;
959                 d_instantiate(direntry, newinode);
960                  /* setting nlink not necessary except in cases where we
961                   * failed to get it from the server or was set bogus */
962                 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
963                                 direntry->d_inode->i_nlink = 2;
964                 if (pTcon->unix_ext) {
965                         mode &= ~current->fs->umask;
966                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
967                                 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
968                                                     mode,
969                                                     (__u64)current->fsuid,
970                                                     (__u64)current->fsgid,
971                                                     0 /* dev_t */,
972                                                     cifs_sb->local_nls,
973                                                     cifs_sb->mnt_cifs_flags &
974                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
975                         } else {
976                                 CIFSSMBUnixSetPerms(xid, pTcon, full_path,
977                                                     mode, (__u64)-1,
978                                                     (__u64)-1, 0 /* dev_t */,
979                                                     cifs_sb->local_nls,
980                                                     cifs_sb->mnt_cifs_flags &
981                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
982                         }
983                 } else {
984                         /* BB to be implemented via Windows secrty descriptors
985                            eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode,
986                                                  -1, -1, local_nls); */
987                         if (direntry->d_inode) {
988                                 direntry->d_inode->i_mode = mode;
989                                 direntry->d_inode->i_mode |= S_IFDIR;
990                                 if (cifs_sb->mnt_cifs_flags &
991                                      CIFS_MOUNT_SET_UID) {
992                                         direntry->d_inode->i_uid =
993                                                 current->fsuid;
994                                         direntry->d_inode->i_gid =
995                                                 current->fsgid;
996                                 }
997                         }
998                 }
999         }
1000 mkdir_out:
1001         kfree(full_path);
1002         FreeXid(xid);
1003         return rc;
1004 }
1005
1006 int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1007 {
1008         int rc = 0;
1009         int xid;
1010         struct cifs_sb_info *cifs_sb;
1011         struct cifsTconInfo *pTcon;
1012         char *full_path = NULL;
1013         struct cifsInodeInfo *cifsInode;
1014
1015         cFYI(1, ("cifs_rmdir, inode = 0x%p", inode));
1016
1017         xid = GetXid();
1018
1019         cifs_sb = CIFS_SB(inode->i_sb);
1020         pTcon = cifs_sb->tcon;
1021
1022         full_path = build_path_from_dentry(direntry);
1023         if (full_path == NULL) {
1024                 FreeXid(xid);
1025                 return -ENOMEM;
1026         }
1027
1028         rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1029                           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1030
1031         if (!rc) {
1032                 drop_nlink(inode);
1033                 spin_lock(&direntry->d_inode->i_lock);
1034                 i_size_write(direntry->d_inode, 0);
1035                 clear_nlink(direntry->d_inode);
1036                 spin_unlock(&direntry->d_inode->i_lock);
1037         }
1038
1039         cifsInode = CIFS_I(direntry->d_inode);
1040         cifsInode->time = 0;    /* force revalidate to go get info when
1041                                    needed */
1042         direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1043                 current_fs_time(inode->i_sb);
1044
1045         kfree(full_path);
1046         FreeXid(xid);
1047         return rc;
1048 }
1049
1050 int cifs_rename(struct inode *source_inode, struct dentry *source_direntry,
1051         struct inode *target_inode, struct dentry *target_direntry)
1052 {
1053         char *fromName;
1054         char *toName;
1055         struct cifs_sb_info *cifs_sb_source;
1056         struct cifs_sb_info *cifs_sb_target;
1057         struct cifsTconInfo *pTcon;
1058         int xid;
1059         int rc = 0;
1060
1061         xid = GetXid();
1062
1063         cifs_sb_target = CIFS_SB(target_inode->i_sb);
1064         cifs_sb_source = CIFS_SB(source_inode->i_sb);
1065         pTcon = cifs_sb_source->tcon;
1066
1067         if (pTcon != cifs_sb_target->tcon) {
1068                 FreeXid(xid);
1069                 return -EXDEV;  /* BB actually could be allowed if same server,
1070                                    but different share.
1071                                    Might eventually add support for this */
1072         }
1073
1074         /* we already  have the rename sem so we do not need to grab it again
1075            here to protect the path integrity */
1076         fromName = build_path_from_dentry(source_direntry);
1077         toName = build_path_from_dentry(target_direntry);
1078         if ((fromName == NULL) || (toName == NULL)) {
1079                 rc = -ENOMEM;
1080                 goto cifs_rename_exit;
1081         }
1082
1083         rc = CIFSSMBRename(xid, pTcon, fromName, toName,
1084                            cifs_sb_source->local_nls,
1085                            cifs_sb_source->mnt_cifs_flags &
1086                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1087         if (rc == -EEXIST) {
1088                 /* check if they are the same file because rename of hardlinked
1089                    files is a noop */
1090                 FILE_UNIX_BASIC_INFO *info_buf_source;
1091                 FILE_UNIX_BASIC_INFO *info_buf_target;
1092
1093                 info_buf_source =
1094                         kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1095                 if (info_buf_source != NULL) {
1096                         info_buf_target = info_buf_source + 1;
1097                         if (pTcon->unix_ext)
1098                                 rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
1099                                         info_buf_source,
1100                                         cifs_sb_source->local_nls,
1101                                         cifs_sb_source->mnt_cifs_flags &
1102                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1103                         /* else rc is still EEXIST so will fall through to
1104                            unlink the target and retry rename */
1105                         if (rc == 0) {
1106                                 rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName,
1107                                                 info_buf_target,
1108                                                 cifs_sb_target->local_nls,
1109                                                 /* remap based on source sb */
1110                                                 cifs_sb_source->mnt_cifs_flags &
1111                                                     CIFS_MOUNT_MAP_SPECIAL_CHR);
1112                         }
1113                         if ((rc == 0) &&
1114                             (info_buf_source->UniqueId ==
1115                              info_buf_target->UniqueId)) {
1116                         /* do not rename since the files are hardlinked which
1117                            is a noop */
1118                         } else {
1119                         /* we either can not tell the files are hardlinked
1120                            (as with Windows servers) or files are not
1121                            hardlinked so delete the target manually before
1122                            renaming to follow POSIX rather than Windows
1123                            semantics */
1124                                 cifs_unlink(target_inode, target_direntry);
1125                                 rc = CIFSSMBRename(xid, pTcon, fromName,
1126                                                    toName,
1127                                                    cifs_sb_source->local_nls,
1128                                                    cifs_sb_source->mnt_cifs_flags
1129                                                    & CIFS_MOUNT_MAP_SPECIAL_CHR);
1130                         }
1131                         kfree(info_buf_source);
1132                 } /* if we can not get memory just leave rc as EEXIST */
1133         }
1134
1135         if (rc)
1136                 cFYI(1, ("rename rc %d", rc));
1137
1138         if ((rc == -EIO) || (rc == -EEXIST)) {
1139                 int oplock = FALSE;
1140                 __u16 netfid;
1141
1142                 /* BB FIXME Is Generic Read correct for rename? */
1143                 /* if renaming directory - we should not say CREATE_NOT_DIR,
1144                    need to test renaming open directory, also GENERIC_READ
1145                    might not right be right access to request */
1146                 rc = CIFSSMBOpen(xid, pTcon, fromName, FILE_OPEN, GENERIC_READ,
1147                                  CREATE_NOT_DIR, &netfid, &oplock, NULL,
1148                                  cifs_sb_source->local_nls,
1149                                  cifs_sb_source->mnt_cifs_flags &
1150                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1151                 if (rc == 0) {
1152                         rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
1153                                               cifs_sb_source->local_nls,
1154                                               cifs_sb_source->mnt_cifs_flags &
1155                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1156                         CIFSSMBClose(xid, pTcon, netfid);
1157                 }
1158         }
1159
1160 cifs_rename_exit:
1161         kfree(fromName);
1162         kfree(toName);
1163         FreeXid(xid);
1164         return rc;
1165 }
1166
1167 int cifs_revalidate(struct dentry *direntry)
1168 {
1169         int xid;
1170         int rc = 0, wbrc = 0;
1171         char *full_path;
1172         struct cifs_sb_info *cifs_sb;
1173         struct cifsInodeInfo *cifsInode;
1174         loff_t local_size;
1175         struct timespec local_mtime;
1176         int invalidate_inode = FALSE;
1177
1178         if (direntry->d_inode == NULL)
1179                 return -ENOENT;
1180
1181         cifsInode = CIFS_I(direntry->d_inode);
1182
1183         if (cifsInode == NULL)
1184                 return -ENOENT;
1185
1186         /* no sense revalidating inode info on file that no one can write */
1187         if (CIFS_I(direntry->d_inode)->clientCanCacheRead)
1188                 return rc;
1189
1190         xid = GetXid();
1191
1192         cifs_sb = CIFS_SB(direntry->d_sb);
1193
1194         /* can not safely grab the rename sem here if rename calls revalidate
1195            since that would deadlock */
1196         full_path = build_path_from_dentry(direntry);
1197         if (full_path == NULL) {
1198                 FreeXid(xid);
1199                 return -ENOMEM;
1200         }
1201         cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
1202                  "jiffies %ld", full_path, direntry->d_inode,
1203                  direntry->d_inode->i_count.counter, direntry,
1204                  direntry->d_time, jiffies));
1205
1206         if (cifsInode->time == 0) {
1207                 /* was set to zero previously to force revalidate */
1208         } else if (time_before(jiffies, cifsInode->time + HZ) &&
1209                    lookupCacheEnabled) {
1210                 if ((S_ISREG(direntry->d_inode->i_mode) == 0) ||
1211                     (direntry->d_inode->i_nlink == 1)) {
1212                         kfree(full_path);
1213                         FreeXid(xid);
1214                         return rc;
1215                 } else {
1216                         cFYI(1, ("Have to revalidate file due to hardlinks"));
1217                 }
1218         }
1219
1220         /* save mtime and size */
1221         local_mtime = direntry->d_inode->i_mtime;
1222         local_size = direntry->d_inode->i_size;
1223
1224         if (cifs_sb->tcon->unix_ext) {
1225                 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
1226                                               direntry->d_sb, xid);
1227                 if (rc) {
1228                         cFYI(1, ("error on getting revalidate info %d", rc));
1229 /*                      if (rc != -ENOENT)
1230                                 rc = 0; */      /* BB should we cache info on
1231                                                    certain errors? */
1232                 }
1233         } else {
1234                 rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
1235                                          direntry->d_sb, xid, NULL);
1236                 if (rc) {
1237                         cFYI(1, ("error on getting revalidate info %d", rc));
1238 /*                      if (rc != -ENOENT)
1239                                 rc = 0; */      /* BB should we cache info on
1240                                                    certain errors? */
1241                 }
1242         }
1243         /* should we remap certain errors, access denied?, to zero */
1244
1245         /* if not oplocked, we invalidate inode pages if mtime or file size
1246            had changed on server */
1247
1248         if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
1249             (local_size == direntry->d_inode->i_size)) {
1250                 cFYI(1, ("cifs_revalidate - inode unchanged"));
1251         } else {
1252                 /* file may have changed on server */
1253                 if (cifsInode->clientCanCacheRead) {
1254                         /* no need to invalidate inode pages since we were the
1255                            only ones who could have modified the file and the
1256                            server copy is staler than ours */
1257                 } else {
1258                         invalidate_inode = TRUE;
1259                 }
1260         }
1261
1262         /* can not grab this sem since kernel filesys locking documentation
1263            indicates i_mutex may be taken by the kernel on lookup and rename
1264            which could deadlock if we grab the i_mutex here as well */
1265 /*      mutex_lock(&direntry->d_inode->i_mutex);*/
1266         /* need to write out dirty pages here  */
1267         if (direntry->d_inode->i_mapping) {
1268                 /* do we need to lock inode until after invalidate completes
1269                    below? */
1270                 wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping);
1271                 if (wbrc)
1272                         CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1273         }
1274         if (invalidate_inode) {
1275         /* shrink_dcache not necessary now that cifs dentry ops
1276         are exported for negative dentries */
1277 /*              if (S_ISDIR(direntry->d_inode->i_mode))
1278                         shrink_dcache_parent(direntry); */
1279                 if (S_ISREG(direntry->d_inode->i_mode)) {
1280                         if (direntry->d_inode->i_mapping)
1281                                 wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
1282                                 if (wbrc)
1283                                         CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1284                         /* may eventually have to do this for open files too */
1285                         if (list_empty(&(cifsInode->openFileList))) {
1286                                 /* changed on server - flush read ahead pages */
1287                                 cFYI(1, ("Invalidating read ahead data on "
1288                                          "closed file"));
1289                                 invalidate_remote_inode(direntry->d_inode);
1290                         }
1291                 }
1292         }
1293 /*      mutex_unlock(&direntry->d_inode->i_mutex); */
1294
1295         kfree(full_path);
1296         FreeXid(xid);
1297         return rc;
1298 }
1299
1300 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1301         struct kstat *stat)
1302 {
1303         int err = cifs_revalidate(dentry);
1304         if (!err) {
1305                 generic_fillattr(dentry->d_inode, stat);
1306                 stat->blksize = CIFS_MAX_MSGSIZE;
1307         }
1308         return err;
1309 }
1310
1311 static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1312 {
1313         pgoff_t index = from >> PAGE_CACHE_SHIFT;
1314         unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1315         struct page *page;
1316         int rc = 0;
1317
1318         page = grab_cache_page(mapping, index);
1319         if (!page)
1320                 return -ENOMEM;
1321
1322         zero_user_segment(page, offset, PAGE_CACHE_SIZE);
1323         unlock_page(page);
1324         page_cache_release(page);
1325         return rc;
1326 }
1327
1328 static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1329 {
1330         struct address_space *mapping = inode->i_mapping;
1331         unsigned long limit;
1332
1333         spin_lock(&inode->i_lock);
1334         if (inode->i_size < offset)
1335                 goto do_expand;
1336         /*
1337          * truncation of in-use swapfiles is disallowed - it would cause
1338          * subsequent swapout to scribble on the now-freed blocks.
1339          */
1340         if (IS_SWAPFILE(inode)) {
1341                 spin_unlock(&inode->i_lock);
1342                 goto out_busy;
1343         }
1344         i_size_write(inode, offset);
1345         spin_unlock(&inode->i_lock);
1346         /*
1347          * unmap_mapping_range is called twice, first simply for efficiency
1348          * so that truncate_inode_pages does fewer single-page unmaps. However
1349          * after this first call, and before truncate_inode_pages finishes,
1350          * it is possible for private pages to be COWed, which remain after
1351          * truncate_inode_pages finishes, hence the second unmap_mapping_range
1352          * call must be made for correctness.
1353          */
1354         unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1355         truncate_inode_pages(mapping, offset);
1356         unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1357         goto out_truncate;
1358
1359 do_expand:
1360         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
1361         if (limit != RLIM_INFINITY && offset > limit) {
1362                 spin_unlock(&inode->i_lock);
1363                 goto out_sig;
1364         }
1365         if (offset > inode->i_sb->s_maxbytes) {
1366                 spin_unlock(&inode->i_lock);
1367                 goto out_big;
1368         }
1369         i_size_write(inode, offset);
1370         spin_unlock(&inode->i_lock);
1371 out_truncate:
1372         if (inode->i_op && inode->i_op->truncate)
1373                 inode->i_op->truncate(inode);
1374         return 0;
1375 out_sig:
1376         send_sig(SIGXFSZ, current, 0);
1377 out_big:
1378         return -EFBIG;
1379 out_busy:
1380         return -ETXTBSY;
1381 }
1382
1383 int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1384 {
1385         int xid;
1386         struct cifs_sb_info *cifs_sb;
1387         struct cifsTconInfo *pTcon;
1388         char *full_path = NULL;
1389         int rc = -EACCES;
1390         struct cifsFileInfo *open_file = NULL;
1391         FILE_BASIC_INFO time_buf;
1392         int set_time = FALSE;
1393         int set_dosattr = FALSE;
1394         __u64 mode = 0xFFFFFFFFFFFFFFFFULL;
1395         __u64 uid = 0xFFFFFFFFFFFFFFFFULL;
1396         __u64 gid = 0xFFFFFFFFFFFFFFFFULL;
1397         struct cifsInodeInfo *cifsInode;
1398
1399         xid = GetXid();
1400
1401         cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
1402                  direntry->d_name.name, attrs->ia_valid));
1403
1404         cifs_sb = CIFS_SB(direntry->d_inode->i_sb);
1405         pTcon = cifs_sb->tcon;
1406
1407         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1408                 /* check if we have permission to change attrs */
1409                 rc = inode_change_ok(direntry->d_inode, attrs);
1410                 if (rc < 0) {
1411                         FreeXid(xid);
1412                         return rc;
1413                 } else
1414                         rc = 0;
1415         }
1416
1417         full_path = build_path_from_dentry(direntry);
1418         if (full_path == NULL) {
1419                 FreeXid(xid);
1420                 return -ENOMEM;
1421         }
1422         cifsInode = CIFS_I(direntry->d_inode);
1423
1424         if ((attrs->ia_valid & ATTR_MTIME) || (attrs->ia_valid & ATTR_SIZE)) {
1425                 /*
1426                    Flush data before changing file size or changing the last
1427                    write time of the file on the server. If the
1428                    flush returns error, store it to report later and continue.
1429                    BB: This should be smarter. Why bother flushing pages that
1430                    will be truncated anyway? Also, should we error out here if
1431                    the flush returns error?
1432                  */
1433                 rc = filemap_write_and_wait(direntry->d_inode->i_mapping);
1434                 if (rc != 0) {
1435                         CIFS_I(direntry->d_inode)->write_behind_rc = rc;
1436                         rc = 0;
1437                 }
1438         }
1439
1440         if (attrs->ia_valid & ATTR_SIZE) {
1441                 /* To avoid spurious oplock breaks from server, in the case of
1442                    inodes that we already have open, avoid doing path based
1443                    setting of file size if we can do it by handle.
1444                    This keeps our caching token (oplock) and avoids timeouts
1445                    when the local oplock break takes longer to flush
1446                    writebehind data than the SMB timeout for the SetPathInfo
1447                    request would allow */
1448
1449                 open_file = find_writable_file(cifsInode);
1450                 if (open_file) {
1451                         __u16 nfid = open_file->netfid;
1452                         __u32 npid = open_file->pid;
1453                         rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size,
1454                                                 nfid, npid, FALSE);
1455                         atomic_dec(&open_file->wrtPending);
1456                         cFYI(1, ("SetFSize for attrs rc = %d", rc));
1457                         if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1458                                 unsigned int bytes_written;
1459                                 rc = CIFSSMBWrite(xid, pTcon,
1460                                                   nfid, 0, attrs->ia_size,
1461                                                   &bytes_written, NULL, NULL,
1462                                                   1 /* 45 seconds */);
1463                                 cFYI(1, ("Wrt seteof rc %d", rc));
1464                         }
1465                 } else
1466                         rc = -EINVAL;
1467
1468                 if (rc != 0) {
1469                         /* Set file size by pathname rather than by handle
1470                            either because no valid, writeable file handle for
1471                            it was found or because there was an error setting
1472                            it by handle */
1473                         rc = CIFSSMBSetEOF(xid, pTcon, full_path,
1474                                            attrs->ia_size, FALSE,
1475                                            cifs_sb->local_nls,
1476                                            cifs_sb->mnt_cifs_flags &
1477                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1478                         cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1479                         if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1480                                 __u16 netfid;
1481                                 int oplock = FALSE;
1482
1483                                 rc = SMBLegacyOpen(xid, pTcon, full_path,
1484                                         FILE_OPEN,
1485                                         SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1486                                         CREATE_NOT_DIR, &netfid, &oplock,
1487                                         NULL, cifs_sb->local_nls,
1488                                         cifs_sb->mnt_cifs_flags &
1489                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1490                                 if (rc == 0) {
1491                                         unsigned int bytes_written;
1492                                         rc = CIFSSMBWrite(xid, pTcon,
1493                                                         netfid, 0,
1494                                                         attrs->ia_size,
1495                                                         &bytes_written, NULL,
1496                                                         NULL, 1 /* 45 sec */);
1497                                         cFYI(1, ("wrt seteof rc %d", rc));
1498                                         CIFSSMBClose(xid, pTcon, netfid);
1499                                 }
1500
1501                         }
1502                 }
1503
1504                 /* Server is ok setting allocation size implicitly - no need
1505                    to call:
1506                 CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, TRUE,
1507                          cifs_sb->local_nls);
1508                    */
1509
1510                 if (rc == 0) {
1511                         rc = cifs_vmtruncate(direntry->d_inode, attrs->ia_size);
1512                         cifs_truncate_page(direntry->d_inode->i_mapping,
1513                                            direntry->d_inode->i_size);
1514                 } else
1515                         goto cifs_setattr_exit;
1516         }
1517         if (attrs->ia_valid & ATTR_UID) {
1518                 cFYI(1, ("UID changed to %d", attrs->ia_uid));
1519                 uid = attrs->ia_uid;
1520         }
1521         if (attrs->ia_valid & ATTR_GID) {
1522                 cFYI(1, ("GID changed to %d", attrs->ia_gid));
1523                 gid = attrs->ia_gid;
1524         }
1525
1526         time_buf.Attributes = 0;
1527
1528         /* skip mode change if it's just for clearing setuid/setgid */
1529         if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1530                 attrs->ia_valid &= ~ATTR_MODE;
1531
1532         if (attrs->ia_valid & ATTR_MODE) {
1533                 cFYI(1, ("Mode changed to 0x%x", attrs->ia_mode));
1534                 mode = attrs->ia_mode;
1535         }
1536
1537         if ((pTcon->unix_ext)
1538             && (attrs->ia_valid & (ATTR_MODE | ATTR_GID | ATTR_UID)))
1539                 rc = CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, uid, gid,
1540                                          0 /* dev_t */, cifs_sb->local_nls,
1541                                          cifs_sb->mnt_cifs_flags &
1542                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1543         else if (attrs->ia_valid & ATTR_MODE) {
1544                 rc = 0;
1545 #ifdef CONFIG_CIFS_EXPERIMENTAL
1546                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1547                         rc = mode_to_acl(direntry->d_inode, full_path, mode);
1548                 else if ((mode & S_IWUGO) == 0) {
1549 #else
1550                 if ((mode & S_IWUGO) == 0) {
1551 #endif
1552                         /* not writeable */
1553                         if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1554                                 set_dosattr = TRUE;
1555                                 time_buf.Attributes =
1556                                         cpu_to_le32(cifsInode->cifsAttrs |
1557                                                     ATTR_READONLY);
1558                         }
1559                 } else if (cifsInode->cifsAttrs & ATTR_READONLY) {
1560                         /* If file is readonly on server, we would
1561                         not be able to write to it - so if any write
1562                         bit is enabled for user or group or other we
1563                         need to at least try to remove r/o dos attr */
1564                         set_dosattr = TRUE;
1565                         time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs &
1566                                             (~ATTR_READONLY));
1567                         /* Windows ignores set to zero */
1568                         if (time_buf.Attributes == 0)
1569                                 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
1570                 }
1571 #ifdef CONFIG_CIFS_EXPERIMENTAL
1572                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1573                         mode_to_acl(direntry->d_inode, full_path, mode);
1574 #endif
1575         }
1576
1577         if (attrs->ia_valid & ATTR_ATIME) {
1578                 set_time = TRUE;
1579                 time_buf.LastAccessTime =
1580                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
1581         } else
1582                 time_buf.LastAccessTime = 0;
1583
1584         if (attrs->ia_valid & ATTR_MTIME) {
1585                 set_time = TRUE;
1586                 time_buf.LastWriteTime =
1587                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
1588         } else
1589                 time_buf.LastWriteTime = 0;
1590         /* Do not set ctime explicitly unless other time
1591            stamps are changed explicitly (i.e. by utime()
1592            since we would then have a mix of client and
1593            server times */
1594
1595         if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
1596                 set_time = TRUE;
1597                 /* Although Samba throws this field away
1598                 it may be useful to Windows - but we do
1599                 not want to set ctime unless some other
1600                 timestamp is changing */
1601                 cFYI(1, ("CIFS - CTIME changed"));
1602                 time_buf.ChangeTime =
1603                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
1604         } else
1605                 time_buf.ChangeTime = 0;
1606
1607         if (set_time || set_dosattr) {
1608                 time_buf.CreationTime = 0;      /* do not change */
1609                 /* In the future we should experiment - try setting timestamps
1610                    via Handle (SetFileInfo) instead of by path */
1611                 if (!(pTcon->ses->flags & CIFS_SES_NT4))
1612                         rc = CIFSSMBSetTimes(xid, pTcon, full_path, &time_buf,
1613                                              cifs_sb->local_nls,
1614                                              cifs_sb->mnt_cifs_flags &
1615                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1616                 else
1617                         rc = -EOPNOTSUPP;
1618
1619                 if (rc == -EOPNOTSUPP) {
1620                         int oplock = FALSE;
1621                         __u16 netfid;
1622
1623                         cFYI(1, ("calling SetFileInfo since SetPathInfo for "
1624                                  "times not supported by this server"));
1625                         /* BB we could scan to see if we already have it open
1626                            and pass in pid of opener to function */
1627                         rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
1628                                          SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1629                                          CREATE_NOT_DIR, &netfid, &oplock,
1630                                          NULL, cifs_sb->local_nls,
1631                                          cifs_sb->mnt_cifs_flags &
1632                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1633                         if (rc == 0) {
1634                                 rc = CIFSSMBSetFileTimes(xid, pTcon, &time_buf,
1635                                                          netfid);
1636                                 CIFSSMBClose(xid, pTcon, netfid);
1637                         } else {
1638                         /* BB For even older servers we could convert time_buf
1639                            into old DOS style which uses two second
1640                            granularity */
1641
1642                         /* rc = CIFSSMBSetTimesLegacy(xid, pTcon, full_path,
1643                                         &time_buf, cifs_sb->local_nls); */
1644                         }
1645                 }
1646                 /* Even if error on time set, no sense failing the call if
1647                 the server would set the time to a reasonable value anyway,
1648                 and this check ensures that we are not being called from
1649                 sys_utimes in which case we ought to fail the call back to
1650                 the user when the server rejects the call */
1651                 if ((rc) && (attrs->ia_valid &
1652                          (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
1653                         rc = 0;
1654         }
1655
1656         /* do not need local check to inode_check_ok since the server does
1657            that */
1658         if (!rc)
1659                 rc = inode_setattr(direntry->d_inode, attrs);
1660 cifs_setattr_exit:
1661         kfree(full_path);
1662         FreeXid(xid);
1663         return rc;
1664 }
1665
1666 #if 0
1667 void cifs_delete_inode(struct inode *inode)
1668 {
1669         cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
1670         /* may have to add back in if and when safe distributed caching of
1671            directories added e.g. via FindNotify */
1672 }
1673 #endif