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