Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[linux-2.6] / fs / cifs / inode.c
1 /*
2  *   fs/cifs/inode.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2008
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         cifsInfo->server_eof = end_of_file;
147         spin_lock(&inode->i_lock);
148         if (is_size_safe_to_change(cifsInfo, end_of_file)) {
149                 /*
150                  * We can not safely change the file size here if the client
151                  * is writing to it due to potential races.
152                  */
153                 i_size_write(inode, end_of_file);
154
155                 /*
156                  * i_blocks is not related to (i_size / i_blksize),
157                  * but instead 512 byte (2**9) size is required for
158                  * calculating num blocks.
159                  */
160                 inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
161         }
162         spin_unlock(&inode->i_lock);
163 }
164
165
166 /*
167  *      Needed to setup inode data for the directory which is the
168  *      junction to the new submount (ie to setup the fake directory
169  *      which represents a DFS referral)
170  */
171 static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat,
172                                struct super_block *sb)
173 {
174         struct inode *pinode = NULL;
175
176         memset(pfnd_dat, 0, sizeof(FILE_UNIX_BASIC_INFO));
177
178 /*      __le64 pfnd_dat->EndOfFile = cpu_to_le64(0);
179         __le64 pfnd_dat->NumOfBytes = cpu_to_le64(0);
180         __u64 UniqueId = 0;  */
181         pfnd_dat->LastStatusChange =
182                 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
183         pfnd_dat->LastAccessTime =
184                 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
185         pfnd_dat->LastModificationTime =
186                 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
187         pfnd_dat->Type = cpu_to_le32(UNIX_DIR);
188         pfnd_dat->Permissions = cpu_to_le64(S_IXUGO | S_IRWXU);
189         pfnd_dat->Nlinks = cpu_to_le64(2);
190         if (sb->s_root)
191                 pinode = sb->s_root->d_inode;
192         if (pinode == NULL)
193                 return;
194
195         /* fill in default values for the remaining based on root
196            inode since we can not query the server for this inode info */
197         pfnd_dat->DevMajor = cpu_to_le64(MAJOR(pinode->i_rdev));
198         pfnd_dat->DevMinor = cpu_to_le64(MINOR(pinode->i_rdev));
199         pfnd_dat->Uid = cpu_to_le64(pinode->i_uid);
200         pfnd_dat->Gid = cpu_to_le64(pinode->i_gid);
201 }
202
203 /**
204  * cifs_new inode - create new inode, initialize, and hash it
205  * @sb - pointer to superblock
206  * @inum - if valid pointer and serverino is enabled, replace i_ino with val
207  *
208  * Create a new inode, initialize it for CIFS and hash it. Returns the new
209  * inode or NULL if one couldn't be allocated.
210  *
211  * If the share isn't mounted with "serverino" or inum is a NULL pointer then
212  * we'll just use the inode number assigned by new_inode(). Note that this can
213  * mean i_ino collisions since the i_ino assigned by new_inode is not
214  * guaranteed to be unique.
215  */
216 struct inode *
217 cifs_new_inode(struct super_block *sb, __u64 *inum)
218 {
219         struct inode *inode;
220
221         inode = new_inode(sb);
222         if (inode == NULL)
223                 return NULL;
224
225         /*
226          * BB: Is i_ino == 0 legal? Here, we assume that it is. If it isn't we
227          *     stop passing inum as ptr. Are there sanity checks we can use to
228          *     ensure that the server is really filling in that field? Also,
229          *     if serverino is disabled, perhaps we should be using iunique()?
230          */
231         if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM))
232                 inode->i_ino = (unsigned long) *inum;
233
234         /*
235          * must set this here instead of cifs_alloc_inode since VFS will
236          * clobber i_flags
237          */
238         if (sb->s_flags & MS_NOATIME)
239                 inode->i_flags |= S_NOATIME | S_NOCMTIME;
240
241         insert_inode_hash(inode);
242
243         return inode;
244 }
245
246 int cifs_get_inode_info_unix(struct inode **pinode,
247         const unsigned char *full_path, struct super_block *sb, int xid)
248 {
249         int rc = 0;
250         FILE_UNIX_BASIC_INFO find_data;
251         struct cifsTconInfo *pTcon;
252         struct inode *inode;
253         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
254         bool is_dfs_referral = false;
255         struct cifsInodeInfo *cifsInfo;
256         __u64 num_of_bytes;
257         __u64 end_of_file;
258
259         pTcon = cifs_sb->tcon;
260         cFYI(1, ("Getting info on %s", full_path));
261
262         /* could have done a find first instead but this returns more info */
263         rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &find_data,
264                                   cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
265                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
266         if (rc == -EREMOTE && !is_dfs_referral) {
267                 is_dfs_referral = true;
268                 cFYI(DBG2, ("DFS ref"));
269                 /* for DFS, server does not give us real inode data */
270                 fill_fake_finddataunix(&find_data, sb);
271                 rc = 0;
272         } else if (rc)
273                 goto cgiiu_exit;
274
275         num_of_bytes = le64_to_cpu(find_data.NumOfBytes);
276         end_of_file = le64_to_cpu(find_data.EndOfFile);
277
278         /* get new inode */
279         if (*pinode == NULL) {
280                 __u64 unique_id = le64_to_cpu(find_data.UniqueId);
281                 *pinode = cifs_new_inode(sb, &unique_id);
282                 if (*pinode == NULL) {
283                         rc = -ENOMEM;
284                         goto cgiiu_exit;
285                 }
286         }
287
288         inode = *pinode;
289         cifsInfo = CIFS_I(inode);
290
291         cFYI(1, ("Old time %ld", cifsInfo->time));
292         cifsInfo->time = jiffies;
293         cFYI(1, ("New time %ld", cifsInfo->time));
294         /* this is ok to set on every inode revalidate */
295         atomic_set(&cifsInfo->inUse, 1);
296
297         cifs_unix_info_to_inode(inode, &find_data, 0);
298
299         if (num_of_bytes < end_of_file)
300                 cFYI(1, ("allocation size less than end of file"));
301         cFYI(1, ("Size %ld and blocks %llu",
302                 (unsigned long) inode->i_size,
303                 (unsigned long long)inode->i_blocks));
304
305         cifs_set_ops(inode, is_dfs_referral);
306 cgiiu_exit:
307         return rc;
308 }
309
310 static int decode_sfu_inode(struct inode *inode, __u64 size,
311                             const unsigned char *path,
312                             struct cifs_sb_info *cifs_sb, int xid)
313 {
314         int rc;
315         int oplock = 0;
316         __u16 netfid;
317         struct cifsTconInfo *pTcon = cifs_sb->tcon;
318         char buf[24];
319         unsigned int bytes_read;
320         char *pbuf;
321
322         pbuf = buf;
323
324         if (size == 0) {
325                 inode->i_mode |= S_IFIFO;
326                 return 0;
327         } else if (size < 8) {
328                 return -EINVAL;  /* EOPNOTSUPP? */
329         }
330
331         rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
332                          CREATE_NOT_DIR, &netfid, &oplock, NULL,
333                          cifs_sb->local_nls,
334                          cifs_sb->mnt_cifs_flags &
335                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
336         if (rc == 0) {
337                 int buf_type = CIFS_NO_BUFFER;
338                         /* Read header */
339                 rc = CIFSSMBRead(xid, pTcon,
340                                  netfid,
341                                  24 /* length */, 0 /* offset */,
342                                  &bytes_read, &pbuf, &buf_type);
343                 if ((rc == 0) && (bytes_read >= 8)) {
344                         if (memcmp("IntxBLK", pbuf, 8) == 0) {
345                                 cFYI(1, ("Block device"));
346                                 inode->i_mode |= S_IFBLK;
347                                 if (bytes_read == 24) {
348                                         /* we have enough to decode dev num */
349                                         __u64 mjr; /* major */
350                                         __u64 mnr; /* minor */
351                                         mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
352                                         mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
353                                         inode->i_rdev = MKDEV(mjr, mnr);
354                                 }
355                         } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
356                                 cFYI(1, ("Char device"));
357                                 inode->i_mode |= S_IFCHR;
358                                 if (bytes_read == 24) {
359                                         /* we have enough to decode dev num */
360                                         __u64 mjr; /* major */
361                                         __u64 mnr; /* minor */
362                                         mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
363                                         mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
364                                         inode->i_rdev = MKDEV(mjr, mnr);
365                                 }
366                         } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
367                                 cFYI(1, ("Symlink"));
368                                 inode->i_mode |= S_IFLNK;
369                         } else {
370                                 inode->i_mode |= S_IFREG; /* file? */
371                                 rc = -EOPNOTSUPP;
372                         }
373                 } else {
374                         inode->i_mode |= S_IFREG; /* then it is a file */
375                         rc = -EOPNOTSUPP; /* or some unknown SFU type */
376                 }
377                 CIFSSMBClose(xid, pTcon, netfid);
378         }
379         return rc;
380 }
381
382 #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID)  /* SETFILEBITS valid bits */
383
384 static int get_sfu_mode(struct inode *inode,
385                         const unsigned char *path,
386                         struct cifs_sb_info *cifs_sb, int xid)
387 {
388 #ifdef CONFIG_CIFS_XATTR
389         ssize_t rc;
390         char ea_value[4];
391         __u32 mode;
392
393         rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
394                         ea_value, 4 /* size of buf */, cifs_sb->local_nls,
395                 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
396         if (rc < 0)
397                 return (int)rc;
398         else if (rc > 3) {
399                 mode = le32_to_cpu(*((__le32 *)ea_value));
400                 inode->i_mode &= ~SFBITS_MASK;
401                 cFYI(1, ("special bits 0%o org mode 0%o", mode, inode->i_mode));
402                 inode->i_mode = (mode &  SFBITS_MASK) | inode->i_mode;
403                 cFYI(1, ("special mode bits 0%o", mode));
404                 return 0;
405         } else {
406                 return 0;
407         }
408 #else
409         return -EOPNOTSUPP;
410 #endif
411 }
412
413 /*
414  *      Needed to setup inode data for the directory which is the
415  *      junction to the new submount (ie to setup the fake directory
416  *      which represents a DFS referral)
417  */
418 static void fill_fake_finddata(FILE_ALL_INFO *pfnd_dat,
419                                struct super_block *sb)
420 {
421         memset(pfnd_dat, 0, sizeof(FILE_ALL_INFO));
422
423 /*      __le64 pfnd_dat->AllocationSize = cpu_to_le64(0);
424         __le64 pfnd_dat->EndOfFile = cpu_to_le64(0);
425         __u8 pfnd_dat->DeletePending = 0;
426         __u8 pfnd_data->Directory = 0;
427         __le32 pfnd_dat->EASize = 0;
428         __u64 pfnd_dat->IndexNumber = 0;
429         __u64 pfnd_dat->IndexNumber1 = 0;  */
430         pfnd_dat->CreationTime =
431                 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
432         pfnd_dat->LastAccessTime =
433                 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
434         pfnd_dat->LastWriteTime =
435                 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
436         pfnd_dat->ChangeTime =
437                 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
438         pfnd_dat->Attributes = cpu_to_le32(ATTR_DIRECTORY);
439         pfnd_dat->NumberOfLinks = cpu_to_le32(2);
440 }
441
442 int cifs_get_inode_info(struct inode **pinode,
443         const unsigned char *full_path, FILE_ALL_INFO *pfindData,
444         struct super_block *sb, int xid, const __u16 *pfid)
445 {
446         int rc = 0;
447         __u32 attr;
448         struct cifsInodeInfo *cifsInfo;
449         struct cifsTconInfo *pTcon;
450         struct inode *inode;
451         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
452         char *buf = NULL;
453         bool adjustTZ = false;
454         bool is_dfs_referral = false;
455         umode_t default_mode;
456
457         pTcon = cifs_sb->tcon;
458         cFYI(1, ("Getting info on %s", full_path));
459
460         if ((pfindData == NULL) && (*pinode != NULL)) {
461                 if (CIFS_I(*pinode)->clientCanCacheRead) {
462                         cFYI(1, ("No need to revalidate cached inode sizes"));
463                         return rc;
464                 }
465         }
466
467         /* if file info not passed in then get it from server */
468         if (pfindData == NULL) {
469                 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
470                 if (buf == NULL)
471                         return -ENOMEM;
472                 pfindData = (FILE_ALL_INFO *)buf;
473
474                 /* could do find first instead but this returns more info */
475                 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
476                               0 /* not legacy */,
477                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
478                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
479                 /* BB optimize code so we do not make the above call
480                 when server claims no NT SMB support and the above call
481                 failed at least once - set flag in tcon or mount */
482                 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
483                         rc = SMBQueryInformation(xid, pTcon, full_path,
484                                         pfindData, cifs_sb->local_nls,
485                                         cifs_sb->mnt_cifs_flags &
486                                           CIFS_MOUNT_MAP_SPECIAL_CHR);
487                         adjustTZ = true;
488                 }
489         }
490         /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
491         if (rc == -EREMOTE) {
492                 is_dfs_referral = true;
493                 fill_fake_finddata(pfindData, sb);
494                 rc = 0;
495         } else if (rc)
496                 goto cgii_exit;
497
498         attr = le32_to_cpu(pfindData->Attributes);
499
500         /* get new inode */
501         if (*pinode == NULL) {
502                 __u64 inode_num;
503                 __u64 *pinum = &inode_num;
504
505                 /* Is an i_ino of zero legal? Can we use that to check
506                    if the server supports returning inode numbers?  Are
507                    there other sanity checks we can use to ensure that
508                    the server is really filling in that field? */
509
510                 /* We can not use the IndexNumber field by default from
511                    Windows or Samba (in ALL_INFO buf) but we can request
512                    it explicitly.  It may not be unique presumably if
513                    the server has multiple devices mounted under one share */
514
515                 /* There may be higher info levels that work but are
516                    there Windows server or network appliances for which
517                    IndexNumber field is not guaranteed unique? */
518
519                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
520                         int rc1 = 0;
521
522                         rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
523                                         full_path, pinum,
524                                         cifs_sb->local_nls,
525                                         cifs_sb->mnt_cifs_flags &
526                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
527                         if (rc1) {
528                                 cFYI(1, ("GetSrvInodeNum rc %d", rc1));
529                                 pinum = NULL;
530                                 /* BB EOPNOSUPP disable SERVER_INUM? */
531                         }
532                 } else {
533                         pinum = NULL;
534                 }
535
536                 *pinode = cifs_new_inode(sb, pinum);
537                 if (*pinode == NULL) {
538                         rc = -ENOMEM;
539                         goto cgii_exit;
540                 }
541         }
542         inode = *pinode;
543         cifsInfo = CIFS_I(inode);
544         cifsInfo->cifsAttrs = attr;
545         cifsInfo->delete_pending = pfindData->DeletePending ? true : false;
546         cFYI(1, ("Old time %ld", cifsInfo->time));
547         cifsInfo->time = jiffies;
548         cFYI(1, ("New time %ld", cifsInfo->time));
549
550         /* blksize needs to be multiple of two. So safer to default to
551         blksize and blkbits set in superblock so 2**blkbits and blksize
552         will match rather than setting to:
553         (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
554
555         /* Linux can not store file creation time so ignore it */
556         if (pfindData->LastAccessTime)
557                 inode->i_atime = cifs_NTtimeToUnix
558                         (le64_to_cpu(pfindData->LastAccessTime));
559         else /* do not need to use current_fs_time - time not stored */
560                 inode->i_atime = CURRENT_TIME;
561         inode->i_mtime =
562                     cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
563         inode->i_ctime =
564             cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
565         cFYI(DBG2, ("Attributes came in as 0x%x", attr));
566         if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
567                 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
568                 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
569         }
570
571         /* get default inode mode */
572         if (attr & ATTR_DIRECTORY)
573                 default_mode = cifs_sb->mnt_dir_mode;
574         else
575                 default_mode = cifs_sb->mnt_file_mode;
576
577         /* set permission bits */
578         if (atomic_read(&cifsInfo->inUse) == 0 ||
579             (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
580                 inode->i_mode = default_mode;
581         else {
582                 /* just reenable write bits if !ATTR_READONLY */
583                 if ((inode->i_mode & S_IWUGO) == 0 &&
584                     (attr & ATTR_READONLY) == 0)
585                         inode->i_mode |= (S_IWUGO & default_mode);
586
587                 inode->i_mode &= ~S_IFMT;
588         }
589         /* clear write bits if ATTR_READONLY is set */
590         if (attr & ATTR_READONLY)
591                 inode->i_mode &= ~S_IWUGO;
592
593         /* set inode type */
594         if ((attr & ATTR_SYSTEM) &&
595             (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {
596                 /* no need to fix endianness on 0 */
597                 if (pfindData->EndOfFile == 0)
598                         inode->i_mode |= S_IFIFO;
599                 else if (decode_sfu_inode(inode,
600                                 le64_to_cpu(pfindData->EndOfFile),
601                                 full_path, cifs_sb, xid))
602                         cFYI(1, ("unknown SFU file type\n"));
603         } else {
604                 if (attr & ATTR_DIRECTORY)
605                         inode->i_mode |= S_IFDIR;
606                 else
607                         inode->i_mode |= S_IFREG;
608         }
609
610         cifsInfo->server_eof = le64_to_cpu(pfindData->EndOfFile);
611         spin_lock(&inode->i_lock);
612         if (is_size_safe_to_change(cifsInfo, cifsInfo->server_eof)) {
613                 /* can not safely shrink the file size here if the
614                    client is writing to it due to potential races */
615                 i_size_write(inode, cifsInfo->server_eof);
616
617                 /* 512 bytes (2**9) is the fake blocksize that must be
618                    used for this calculation */
619                 inode->i_blocks = (512 - 1 + le64_to_cpu(
620                                    pfindData->AllocationSize)) >> 9;
621         }
622         spin_unlock(&inode->i_lock);
623
624         inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
625
626         /* BB fill in uid and gid here? with help from winbind?
627            or retrieve from NTFS stream extended attribute */
628 #ifdef CONFIG_CIFS_EXPERIMENTAL
629         /* fill in 0777 bits from ACL */
630         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
631                 cFYI(1, ("Getting mode bits from ACL"));
632                 acl_to_uid_mode(inode, full_path, pfid);
633         }
634 #endif
635         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
636                 /* fill in remaining high mode bits e.g. SUID, VTX */
637                 get_sfu_mode(inode, full_path, cifs_sb, xid);
638         } else if (atomic_read(&cifsInfo->inUse) == 0) {
639                 inode->i_uid = cifs_sb->mnt_uid;
640                 inode->i_gid = cifs_sb->mnt_gid;
641                 /* set so we do not keep refreshing these fields with
642                    bad data after user has changed them in memory */
643                 atomic_set(&cifsInfo->inUse, 1);
644         }
645
646         cifs_set_ops(inode, is_dfs_referral);
647
648
649
650
651 cgii_exit:
652         kfree(buf);
653         return rc;
654 }
655
656 static const struct inode_operations cifs_ipc_inode_ops = {
657         .lookup = cifs_lookup,
658 };
659
660 char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
661 {
662         int pplen = cifs_sb->prepathlen;
663         int dfsplen;
664         char *full_path = NULL;
665
666         /* if no prefix path, simply set path to the root of share to "" */
667         if (pplen == 0) {
668                 full_path = kmalloc(1, GFP_KERNEL);
669                 if (full_path)
670                         full_path[0] = 0;
671                 return full_path;
672         }
673
674         if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS))
675                 dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1);
676         else
677                 dfsplen = 0;
678
679         full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
680         if (full_path == NULL)
681                 return full_path;
682
683         if (dfsplen) {
684                 strncpy(full_path, cifs_sb->tcon->treeName, dfsplen);
685                 /* switch slash direction in prepath depending on whether
686                  * windows or posix style path names
687                  */
688                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
689                         int i;
690                         for (i = 0; i < dfsplen; i++) {
691                                 if (full_path[i] == '\\')
692                                         full_path[i] = '/';
693                         }
694                 }
695         }
696         strncpy(full_path + dfsplen, cifs_sb->prepath, pplen);
697         full_path[dfsplen + pplen] = 0; /* add trailing null */
698         return full_path;
699 }
700
701 /* gets root inode */
702 struct inode *cifs_iget(struct super_block *sb, unsigned long ino)
703 {
704         int xid;
705         struct cifs_sb_info *cifs_sb;
706         struct inode *inode;
707         long rc;
708         char *full_path;
709
710         inode = iget_locked(sb, ino);
711         if (!inode)
712                 return ERR_PTR(-ENOMEM);
713         if (!(inode->i_state & I_NEW))
714                 return inode;
715
716         cifs_sb = CIFS_SB(inode->i_sb);
717         full_path = cifs_build_path_to_root(cifs_sb);
718         if (full_path == NULL)
719                 return ERR_PTR(-ENOMEM);
720
721         xid = GetXid();
722         if (cifs_sb->tcon->unix_ext)
723                 rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
724                                                 xid);
725         else
726                 rc = cifs_get_inode_info(&inode, full_path, NULL, inode->i_sb,
727                                                 xid, NULL);
728         if (rc && cifs_sb->tcon->ipc) {
729                 cFYI(1, ("ipc connection - fake read inode"));
730                 inode->i_mode |= S_IFDIR;
731                 inode->i_nlink = 2;
732                 inode->i_op = &cifs_ipc_inode_ops;
733                 inode->i_fop = &simple_dir_operations;
734                 inode->i_uid = cifs_sb->mnt_uid;
735                 inode->i_gid = cifs_sb->mnt_gid;
736         } else if (rc) {
737                 kfree(full_path);
738                 _FreeXid(xid);
739                 iget_failed(inode);
740                 return ERR_PTR(rc);
741         }
742
743         unlock_new_inode(inode);
744
745         kfree(full_path);
746         /* can not call macro FreeXid here since in a void func
747          * TODO: This is no longer true
748          */
749         _FreeXid(xid);
750         return inode;
751 }
752
753 static int
754 cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
755                     char *full_path, __u32 dosattr)
756 {
757         int rc;
758         int oplock = 0;
759         __u16 netfid;
760         __u32 netpid;
761         bool set_time = false;
762         struct cifsFileInfo *open_file;
763         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
764         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
765         struct cifsTconInfo *pTcon = cifs_sb->tcon;
766         FILE_BASIC_INFO info_buf;
767
768         if (attrs == NULL)
769                 return -EINVAL;
770
771         if (attrs->ia_valid & ATTR_ATIME) {
772                 set_time = true;
773                 info_buf.LastAccessTime =
774                         cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
775         } else
776                 info_buf.LastAccessTime = 0;
777
778         if (attrs->ia_valid & ATTR_MTIME) {
779                 set_time = true;
780                 info_buf.LastWriteTime =
781                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
782         } else
783                 info_buf.LastWriteTime = 0;
784
785         /*
786          * Samba throws this field away, but windows may actually use it.
787          * Do not set ctime unless other time stamps are changed explicitly
788          * (i.e. by utimes()) since we would then have a mix of client and
789          * server times.
790          */
791         if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
792                 cFYI(1, ("CIFS - CTIME changed"));
793                 info_buf.ChangeTime =
794                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
795         } else
796                 info_buf.ChangeTime = 0;
797
798         info_buf.CreationTime = 0;      /* don't change */
799         info_buf.Attributes = cpu_to_le32(dosattr);
800
801         /*
802          * If the file is already open for write, just use that fileid
803          */
804         open_file = find_writable_file(cifsInode);
805         if (open_file) {
806                 netfid = open_file->netfid;
807                 netpid = open_file->pid;
808                 goto set_via_filehandle;
809         }
810
811         /*
812          * NT4 apparently returns success on this call, but it doesn't
813          * really work.
814          */
815         if (!(pTcon->ses->flags & CIFS_SES_NT4)) {
816                 rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
817                                      &info_buf, cifs_sb->local_nls,
818                                      cifs_sb->mnt_cifs_flags &
819                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
820                 if (rc == 0) {
821                         cifsInode->cifsAttrs = dosattr;
822                         goto out;
823                 } else if (rc != -EOPNOTSUPP && rc != -EINVAL)
824                         goto out;
825         }
826
827         cFYI(1, ("calling SetFileInfo since SetPathInfo for "
828                  "times not supported by this server"));
829         rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
830                          SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
831                          CREATE_NOT_DIR, &netfid, &oplock,
832                          NULL, cifs_sb->local_nls,
833                          cifs_sb->mnt_cifs_flags &
834                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
835
836         if (rc != 0) {
837                 if (rc == -EIO)
838                         rc = -EINVAL;
839                 goto out;
840         }
841
842         netpid = current->tgid;
843
844 set_via_filehandle:
845         rc = CIFSSMBSetFileInfo(xid, pTcon, &info_buf, netfid, netpid);
846         if (!rc)
847                 cifsInode->cifsAttrs = dosattr;
848
849         if (open_file == NULL)
850                 CIFSSMBClose(xid, pTcon, netfid);
851         else
852                 atomic_dec(&open_file->wrtPending);
853 out:
854         return rc;
855 }
856
857 /*
858  * open the given file (if it isn't already), set the DELETE_ON_CLOSE bit
859  * and rename it to a random name that hopefully won't conflict with
860  * anything else.
861  */
862 static int
863 cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
864 {
865         int oplock = 0;
866         int rc;
867         __u16 netfid;
868         struct inode *inode = dentry->d_inode;
869         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
870         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
871         struct cifsTconInfo *tcon = cifs_sb->tcon;
872         __u32 dosattr, origattr;
873         FILE_BASIC_INFO *info_buf = NULL;
874
875         rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
876                          DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
877                          &netfid, &oplock, NULL, cifs_sb->local_nls,
878                          cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
879         if (rc != 0)
880                 goto out;
881
882         origattr = cifsInode->cifsAttrs;
883         if (origattr == 0)
884                 origattr |= ATTR_NORMAL;
885
886         dosattr = origattr & ~ATTR_READONLY;
887         if (dosattr == 0)
888                 dosattr |= ATTR_NORMAL;
889         dosattr |= ATTR_HIDDEN;
890
891         /* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */
892         if (dosattr != origattr) {
893                 info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
894                 if (info_buf == NULL) {
895                         rc = -ENOMEM;
896                         goto out_close;
897                 }
898                 info_buf->Attributes = cpu_to_le32(dosattr);
899                 rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
900                                         current->tgid);
901                 /* although we would like to mark the file hidden
902                    if that fails we will still try to rename it */
903                 if (rc != 0)
904                         cifsInode->cifsAttrs = dosattr;
905                 else
906                         dosattr = origattr; /* since not able to change them */
907         }
908
909         /* rename the file */
910         rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
911                                    cifs_sb->mnt_cifs_flags &
912                                             CIFS_MOUNT_MAP_SPECIAL_CHR);
913         if (rc != 0) {
914                 rc = -ETXTBSY;
915                 goto undo_setattr;
916         }
917
918         /* try to set DELETE_ON_CLOSE */
919         if (!cifsInode->delete_pending) {
920                 rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid,
921                                                current->tgid);
922                 /*
923                  * some samba versions return -ENOENT when we try to set the
924                  * file disposition here. Likely a samba bug, but work around
925                  * it for now. This means that some cifsXXX files may hang
926                  * around after they shouldn't.
927                  *
928                  * BB: remove this hack after more servers have the fix
929                  */
930                 if (rc == -ENOENT)
931                         rc = 0;
932                 else if (rc != 0) {
933                         rc = -ETXTBSY;
934                         goto undo_rename;
935                 }
936                 cifsInode->delete_pending = true;
937         }
938
939 out_close:
940         CIFSSMBClose(xid, tcon, netfid);
941 out:
942         kfree(info_buf);
943         return rc;
944
945         /*
946          * reset everything back to the original state. Don't bother
947          * dealing with errors here since we can't do anything about
948          * them anyway.
949          */
950 undo_rename:
951         CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name,
952                                 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
953                                             CIFS_MOUNT_MAP_SPECIAL_CHR);
954 undo_setattr:
955         if (dosattr != origattr) {
956                 info_buf->Attributes = cpu_to_le32(origattr);
957                 if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
958                                         current->tgid))
959                         cifsInode->cifsAttrs = origattr;
960         }
961
962         goto out_close;
963 }
964
965 int cifs_unlink(struct inode *dir, struct dentry *dentry)
966 {
967         int rc = 0;
968         int xid;
969         char *full_path = NULL;
970         struct inode *inode = dentry->d_inode;
971         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
972         struct super_block *sb = dir->i_sb;
973         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
974         struct cifsTconInfo *tcon = cifs_sb->tcon;
975         struct iattr *attrs = NULL;
976         __u32 dosattr = 0, origattr = 0;
977
978         cFYI(1, ("cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry));
979
980         xid = GetXid();
981
982         /* Unlink can be called from rename so we can not take the
983          * sb->s_vfs_rename_mutex here */
984         full_path = build_path_from_dentry(dentry);
985         if (full_path == NULL) {
986                 FreeXid(xid);
987                 return -ENOMEM;
988         }
989
990         if ((tcon->ses->capabilities & CAP_UNIX) &&
991                 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
992                         le64_to_cpu(tcon->fsUnixInfo.Capability))) {
993                 rc = CIFSPOSIXDelFile(xid, tcon, full_path,
994                         SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
995                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
996                 cFYI(1, ("posix del rc %d", rc));
997                 if ((rc == 0) || (rc == -ENOENT))
998                         goto psx_del_no_retry;
999         }
1000
1001 retry_std_delete:
1002         rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls,
1003                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1004
1005 psx_del_no_retry:
1006         if (!rc) {
1007                 if (inode)
1008                         drop_nlink(inode);
1009         } else if (rc == -ENOENT) {
1010                 d_drop(dentry);
1011         } else if (rc == -ETXTBSY) {
1012                 rc = cifs_rename_pending_delete(full_path, dentry, xid);
1013                 if (rc == 0)
1014                         drop_nlink(inode);
1015         } else if (rc == -EACCES && dosattr == 0) {
1016                 attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
1017                 if (attrs == NULL) {
1018                         rc = -ENOMEM;
1019                         goto out_reval;
1020                 }
1021
1022                 /* try to reset dos attributes */
1023                 origattr = cifsInode->cifsAttrs;
1024                 if (origattr == 0)
1025                         origattr |= ATTR_NORMAL;
1026                 dosattr = origattr & ~ATTR_READONLY;
1027                 if (dosattr == 0)
1028                         dosattr |= ATTR_NORMAL;
1029                 dosattr |= ATTR_HIDDEN;
1030
1031                 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
1032                 if (rc != 0)
1033                         goto out_reval;
1034
1035                 goto retry_std_delete;
1036         }
1037
1038         /* undo the setattr if we errored out and it's needed */
1039         if (rc != 0 && dosattr != 0)
1040                 cifs_set_file_info(inode, attrs, xid, full_path, origattr);
1041
1042 out_reval:
1043         if (inode) {
1044                 cifsInode = CIFS_I(inode);
1045                 cifsInode->time = 0;    /* will force revalidate to get info
1046                                            when needed */
1047                 inode->i_ctime = current_fs_time(sb);
1048         }
1049         dir->i_ctime = dir->i_mtime = current_fs_time(sb);
1050         cifsInode = CIFS_I(dir);
1051         CIFS_I(dir)->time = 0;  /* force revalidate of dir as well */
1052
1053         kfree(full_path);
1054         kfree(attrs);
1055         FreeXid(xid);
1056         return rc;
1057 }
1058
1059 void posix_fill_in_inode(struct inode *tmp_inode,
1060         FILE_UNIX_BASIC_INFO *pData, int isNewInode)
1061 {
1062         struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
1063         loff_t local_size;
1064         struct timespec local_mtime;
1065
1066         cifsInfo->time = jiffies;
1067         atomic_inc(&cifsInfo->inUse);
1068
1069         /* save mtime and size */
1070         local_mtime = tmp_inode->i_mtime;
1071         local_size  = tmp_inode->i_size;
1072
1073         cifs_unix_info_to_inode(tmp_inode, pData, 1);
1074         cifs_set_ops(tmp_inode, false);
1075
1076         if (!S_ISREG(tmp_inode->i_mode))
1077                 return;
1078
1079         /*
1080          * No sense invalidating pages for new inode
1081          * since we we have not started caching
1082          * readahead file data yet.
1083          */
1084         if (isNewInode)
1085                 return;
1086
1087         if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
1088                 (local_size == tmp_inode->i_size)) {
1089                 cFYI(1, ("inode exists but unchanged"));
1090         } else {
1091                 /* file may have changed on server */
1092                 cFYI(1, ("invalidate inode, readdir detected change"));
1093                 invalidate_remote_inode(tmp_inode);
1094         }
1095 }
1096
1097 int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1098 {
1099         int rc = 0, tmprc;
1100         int xid;
1101         struct cifs_sb_info *cifs_sb;
1102         struct cifsTconInfo *pTcon;
1103         char *full_path = NULL;
1104         struct inode *newinode = NULL;
1105
1106         cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
1107
1108         xid = GetXid();
1109
1110         cifs_sb = CIFS_SB(inode->i_sb);
1111         pTcon = cifs_sb->tcon;
1112
1113         full_path = build_path_from_dentry(direntry);
1114         if (full_path == NULL) {
1115                 FreeXid(xid);
1116                 return -ENOMEM;
1117         }
1118
1119         if ((pTcon->ses->capabilities & CAP_UNIX) &&
1120                 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1121                         le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
1122                 u32 oplock = 0;
1123                 FILE_UNIX_BASIC_INFO *pInfo =
1124                         kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1125                 if (pInfo == NULL) {
1126                         rc = -ENOMEM;
1127                         goto mkdir_out;
1128                 }
1129
1130                 mode &= ~current_umask();
1131                 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
1132                                 mode, NULL /* netfid */, pInfo, &oplock,
1133                                 full_path, cifs_sb->local_nls,
1134                                 cifs_sb->mnt_cifs_flags &
1135                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1136                 if (rc == -EOPNOTSUPP) {
1137                         kfree(pInfo);
1138                         goto mkdir_retry_old;
1139                 } else if (rc) {
1140                         cFYI(1, ("posix mkdir returned 0x%x", rc));
1141                         d_drop(direntry);
1142                 } else {
1143                         __u64 unique_id;
1144                         if (pInfo->Type == cpu_to_le32(-1)) {
1145                                 /* no return info, go query for it */
1146                                 kfree(pInfo);
1147                                 goto mkdir_get_info;
1148                         }
1149 /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
1150         to set uid/gid */
1151                         inc_nlink(inode);
1152                         if (pTcon->nocase)
1153                                 direntry->d_op = &cifs_ci_dentry_ops;
1154                         else
1155                                 direntry->d_op = &cifs_dentry_ops;
1156
1157                         unique_id = le64_to_cpu(pInfo->UniqueId);
1158                         newinode = cifs_new_inode(inode->i_sb, &unique_id);
1159                         if (newinode == NULL) {
1160                                 kfree(pInfo);
1161                                 goto mkdir_get_info;
1162                         }
1163
1164                         newinode->i_nlink = 2;
1165                         d_instantiate(direntry, newinode);
1166
1167                         /* we already checked in POSIXCreate whether
1168                            frame was long enough */
1169                         posix_fill_in_inode(direntry->d_inode,
1170                                         pInfo, 1 /* NewInode */);
1171 #ifdef CONFIG_CIFS_DEBUG2
1172                         cFYI(1, ("instantiated dentry %p %s to inode %p",
1173                                 direntry, direntry->d_name.name, newinode));
1174
1175                         if (newinode->i_nlink != 2)
1176                                 cFYI(1, ("unexpected number of links %d",
1177                                         newinode->i_nlink));
1178 #endif
1179                 }
1180                 kfree(pInfo);
1181                 goto mkdir_out;
1182         }
1183 mkdir_retry_old:
1184         /* BB add setting the equivalent of mode via CreateX w/ACLs */
1185         rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
1186                           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1187         if (rc) {
1188                 cFYI(1, ("cifs_mkdir returned 0x%x", rc));
1189                 d_drop(direntry);
1190         } else {
1191 mkdir_get_info:
1192                 inc_nlink(inode);
1193                 if (pTcon->unix_ext)
1194                         rc = cifs_get_inode_info_unix(&newinode, full_path,
1195                                                       inode->i_sb, xid);
1196                 else
1197                         rc = cifs_get_inode_info(&newinode, full_path, NULL,
1198                                                  inode->i_sb, xid, NULL);
1199
1200                 if (pTcon->nocase)
1201                         direntry->d_op = &cifs_ci_dentry_ops;
1202                 else
1203                         direntry->d_op = &cifs_dentry_ops;
1204                 d_instantiate(direntry, newinode);
1205                  /* setting nlink not necessary except in cases where we
1206                   * failed to get it from the server or was set bogus */
1207                 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
1208                                 direntry->d_inode->i_nlink = 2;
1209
1210                 mode &= ~current_umask();
1211                 /* must turn on setgid bit if parent dir has it */
1212                 if (inode->i_mode & S_ISGID)
1213                         mode |= S_ISGID;
1214
1215                 if (pTcon->unix_ext) {
1216                         struct cifs_unix_set_info_args args = {
1217                                 .mode   = mode,
1218                                 .ctime  = NO_CHANGE_64,
1219                                 .atime  = NO_CHANGE_64,
1220                                 .mtime  = NO_CHANGE_64,
1221                                 .device = 0,
1222                         };
1223                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
1224                                 args.uid = (__u64)current_fsuid();
1225                                 if (inode->i_mode & S_ISGID)
1226                                         args.gid = (__u64)inode->i_gid;
1227                                 else
1228                                         args.gid = (__u64)current_fsgid();
1229                         } else {
1230                                 args.uid = NO_CHANGE_64;
1231                                 args.gid = NO_CHANGE_64;
1232                         }
1233                         CIFSSMBUnixSetInfo(xid, pTcon, full_path, &args,
1234                                             cifs_sb->local_nls,
1235                                             cifs_sb->mnt_cifs_flags &
1236                                             CIFS_MOUNT_MAP_SPECIAL_CHR);
1237                 } else {
1238                         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
1239                             (mode & S_IWUGO) == 0) {
1240                                 FILE_BASIC_INFO pInfo;
1241                                 struct cifsInodeInfo *cifsInode;
1242                                 u32 dosattrs;
1243
1244                                 memset(&pInfo, 0, sizeof(pInfo));
1245                                 cifsInode = CIFS_I(newinode);
1246                                 dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
1247                                 pInfo.Attributes = cpu_to_le32(dosattrs);
1248                                 tmprc = CIFSSMBSetPathInfo(xid, pTcon,
1249                                                 full_path, &pInfo,
1250                                                 cifs_sb->local_nls,
1251                                                 cifs_sb->mnt_cifs_flags &
1252                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1253                                 if (tmprc == 0)
1254                                         cifsInode->cifsAttrs = dosattrs;
1255                         }
1256                         if (direntry->d_inode) {
1257                                 if (cifs_sb->mnt_cifs_flags &
1258                                      CIFS_MOUNT_DYNPERM)
1259                                         direntry->d_inode->i_mode =
1260                                                 (mode | S_IFDIR);
1261
1262                                 if (cifs_sb->mnt_cifs_flags &
1263                                      CIFS_MOUNT_SET_UID) {
1264                                         direntry->d_inode->i_uid =
1265                                                 current_fsuid();
1266                                         if (inode->i_mode & S_ISGID)
1267                                                 direntry->d_inode->i_gid =
1268                                                         inode->i_gid;
1269                                         else
1270                                                 direntry->d_inode->i_gid =
1271                                                         current_fsgid();
1272                                 }
1273                         }
1274                 }
1275         }
1276 mkdir_out:
1277         kfree(full_path);
1278         FreeXid(xid);
1279         return rc;
1280 }
1281
1282 int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1283 {
1284         int rc = 0;
1285         int xid;
1286         struct cifs_sb_info *cifs_sb;
1287         struct cifsTconInfo *pTcon;
1288         char *full_path = NULL;
1289         struct cifsInodeInfo *cifsInode;
1290
1291         cFYI(1, ("cifs_rmdir, inode = 0x%p", inode));
1292
1293         xid = GetXid();
1294
1295         cifs_sb = CIFS_SB(inode->i_sb);
1296         pTcon = cifs_sb->tcon;
1297
1298         full_path = build_path_from_dentry(direntry);
1299         if (full_path == NULL) {
1300                 FreeXid(xid);
1301                 return -ENOMEM;
1302         }
1303
1304         rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1305                           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1306
1307         if (!rc) {
1308                 drop_nlink(inode);
1309                 spin_lock(&direntry->d_inode->i_lock);
1310                 i_size_write(direntry->d_inode, 0);
1311                 clear_nlink(direntry->d_inode);
1312                 spin_unlock(&direntry->d_inode->i_lock);
1313         }
1314
1315         cifsInode = CIFS_I(direntry->d_inode);
1316         cifsInode->time = 0;    /* force revalidate to go get info when
1317                                    needed */
1318
1319         cifsInode = CIFS_I(inode);
1320         cifsInode->time = 0;    /* force revalidate to get parent dir info
1321                                    since cached search results now invalid */
1322
1323         direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1324                 current_fs_time(inode->i_sb);
1325
1326         kfree(full_path);
1327         FreeXid(xid);
1328         return rc;
1329 }
1330
1331 static int
1332 cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1333                 struct dentry *to_dentry, const char *toPath)
1334 {
1335         struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
1336         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1337         __u16 srcfid;
1338         int oplock, rc;
1339
1340         /* try path-based rename first */
1341         rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
1342                            cifs_sb->mnt_cifs_flags &
1343                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1344
1345         /*
1346          * don't bother with rename by filehandle unless file is busy and
1347          * source Note that cross directory moves do not work with
1348          * rename by filehandle to various Windows servers.
1349          */
1350         if (rc == 0 || rc != -ETXTBSY)
1351                 return rc;
1352
1353         /* open the file to be renamed -- we need DELETE perms */
1354         rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE,
1355                          CREATE_NOT_DIR, &srcfid, &oplock, NULL,
1356                          cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1357                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1358
1359         if (rc == 0) {
1360                 rc = CIFSSMBRenameOpenFile(xid, pTcon, srcfid,
1361                                 (const char *) to_dentry->d_name.name,
1362                                 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1363                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1364
1365                 CIFSSMBClose(xid, pTcon, srcfid);
1366         }
1367
1368         return rc;
1369 }
1370
1371 int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1372         struct inode *target_dir, struct dentry *target_dentry)
1373 {
1374         char *fromName = NULL;
1375         char *toName = NULL;
1376         struct cifs_sb_info *cifs_sb_source;
1377         struct cifs_sb_info *cifs_sb_target;
1378         struct cifsTconInfo *tcon;
1379         FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1380         FILE_UNIX_BASIC_INFO *info_buf_target;
1381         int xid, rc, tmprc;
1382
1383         cifs_sb_target = CIFS_SB(target_dir->i_sb);
1384         cifs_sb_source = CIFS_SB(source_dir->i_sb);
1385         tcon = cifs_sb_source->tcon;
1386
1387         xid = GetXid();
1388
1389         /*
1390          * BB: this might be allowed if same server, but different share.
1391          * Consider adding support for this
1392          */
1393         if (tcon != cifs_sb_target->tcon) {
1394                 rc = -EXDEV;
1395                 goto cifs_rename_exit;
1396         }
1397
1398         /*
1399          * we already have the rename sem so we do not need to
1400          * grab it again here to protect the path integrity
1401          */
1402         fromName = build_path_from_dentry(source_dentry);
1403         if (fromName == NULL) {
1404                 rc = -ENOMEM;
1405                 goto cifs_rename_exit;
1406         }
1407
1408         toName = build_path_from_dentry(target_dentry);
1409         if (toName == NULL) {
1410                 rc = -ENOMEM;
1411                 goto cifs_rename_exit;
1412         }
1413
1414         rc = cifs_do_rename(xid, source_dentry, fromName,
1415                             target_dentry, toName);
1416
1417         if (rc == -EEXIST && tcon->unix_ext) {
1418                 /*
1419                  * Are src and dst hardlinks of same inode? We can
1420                  * only tell with unix extensions enabled
1421                  */
1422                 info_buf_source =
1423                         kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
1424                                         GFP_KERNEL);
1425                 if (info_buf_source == NULL) {
1426                         rc = -ENOMEM;
1427                         goto cifs_rename_exit;
1428                 }
1429
1430                 info_buf_target = info_buf_source + 1;
1431                 tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
1432                                         info_buf_source,
1433                                         cifs_sb_source->local_nls,
1434                                         cifs_sb_source->mnt_cifs_flags &
1435                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1436                 if (tmprc != 0)
1437                         goto unlink_target;
1438
1439                 tmprc = CIFSSMBUnixQPathInfo(xid, tcon,
1440                                         toName, info_buf_target,
1441                                         cifs_sb_target->local_nls,
1442                                         /* remap based on source sb */
1443                                         cifs_sb_source->mnt_cifs_flags &
1444                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1445
1446                 if (tmprc == 0 && (info_buf_source->UniqueId ==
1447                                    info_buf_target->UniqueId)) {
1448                         /* same file, POSIX says that this is a noop */
1449                         rc = 0;
1450                         goto cifs_rename_exit;
1451                 }
1452         } /* else ... BB we could add the same check for Windows by
1453                      checking the UniqueId via FILE_INTERNAL_INFO */
1454
1455 unlink_target:
1456         /* Try unlinking the target dentry if it's not negative */
1457         if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) {
1458                 tmprc = cifs_unlink(target_dir, target_dentry);
1459                 if (tmprc)
1460                         goto cifs_rename_exit;
1461
1462                 rc = cifs_do_rename(xid, source_dentry, fromName,
1463                                     target_dentry, toName);
1464         }
1465
1466 cifs_rename_exit:
1467         kfree(info_buf_source);
1468         kfree(fromName);
1469         kfree(toName);
1470         FreeXid(xid);
1471         return rc;
1472 }
1473
1474 int cifs_revalidate(struct dentry *direntry)
1475 {
1476         int xid;
1477         int rc = 0, wbrc = 0;
1478         char *full_path;
1479         struct cifs_sb_info *cifs_sb;
1480         struct cifsInodeInfo *cifsInode;
1481         loff_t local_size;
1482         struct timespec local_mtime;
1483         bool invalidate_inode = false;
1484
1485         if (direntry->d_inode == NULL)
1486                 return -ENOENT;
1487
1488         cifsInode = CIFS_I(direntry->d_inode);
1489
1490         if (cifsInode == NULL)
1491                 return -ENOENT;
1492
1493         /* no sense revalidating inode info on file that no one can write */
1494         if (CIFS_I(direntry->d_inode)->clientCanCacheRead)
1495                 return rc;
1496
1497         xid = GetXid();
1498
1499         cifs_sb = CIFS_SB(direntry->d_sb);
1500
1501         /* can not safely grab the rename sem here if rename calls revalidate
1502            since that would deadlock */
1503         full_path = build_path_from_dentry(direntry);
1504         if (full_path == NULL) {
1505                 FreeXid(xid);
1506                 return -ENOMEM;
1507         }
1508         cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
1509                  "jiffies %ld", full_path, direntry->d_inode,
1510                  direntry->d_inode->i_count.counter, direntry,
1511                  direntry->d_time, jiffies));
1512
1513         if (cifsInode->time == 0) {
1514                 /* was set to zero previously to force revalidate */
1515         } else if (time_before(jiffies, cifsInode->time + HZ) &&
1516                    lookupCacheEnabled) {
1517                 if ((S_ISREG(direntry->d_inode->i_mode) == 0) ||
1518                     (direntry->d_inode->i_nlink == 1)) {
1519                         kfree(full_path);
1520                         FreeXid(xid);
1521                         return rc;
1522                 } else {
1523                         cFYI(1, ("Have to revalidate file due to hardlinks"));
1524                 }
1525         }
1526
1527         /* save mtime and size */
1528         local_mtime = direntry->d_inode->i_mtime;
1529         local_size = direntry->d_inode->i_size;
1530
1531         if (cifs_sb->tcon->unix_ext) {
1532                 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
1533                                               direntry->d_sb, xid);
1534                 if (rc) {
1535                         cFYI(1, ("error on getting revalidate info %d", rc));
1536 /*                      if (rc != -ENOENT)
1537                                 rc = 0; */      /* BB should we cache info on
1538                                                    certain errors? */
1539                 }
1540         } else {
1541                 rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
1542                                          direntry->d_sb, xid, NULL);
1543                 if (rc) {
1544                         cFYI(1, ("error on getting revalidate info %d", rc));
1545 /*                      if (rc != -ENOENT)
1546                                 rc = 0; */      /* BB should we cache info on
1547                                                    certain errors? */
1548                 }
1549         }
1550         /* should we remap certain errors, access denied?, to zero */
1551
1552         /* if not oplocked, we invalidate inode pages if mtime or file size
1553            had changed on server */
1554
1555         if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
1556             (local_size == direntry->d_inode->i_size)) {
1557                 cFYI(1, ("cifs_revalidate - inode unchanged"));
1558         } else {
1559                 /* file may have changed on server */
1560                 if (cifsInode->clientCanCacheRead) {
1561                         /* no need to invalidate inode pages since we were the
1562                            only ones who could have modified the file and the
1563                            server copy is staler than ours */
1564                 } else {
1565                         invalidate_inode = true;
1566                 }
1567         }
1568
1569         /* can not grab this sem since kernel filesys locking documentation
1570            indicates i_mutex may be taken by the kernel on lookup and rename
1571            which could deadlock if we grab the i_mutex here as well */
1572 /*      mutex_lock(&direntry->d_inode->i_mutex);*/
1573         /* need to write out dirty pages here  */
1574         if (direntry->d_inode->i_mapping) {
1575                 /* do we need to lock inode until after invalidate completes
1576                    below? */
1577                 wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping);
1578                 if (wbrc)
1579                         CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1580         }
1581         if (invalidate_inode) {
1582         /* shrink_dcache not necessary now that cifs dentry ops
1583         are exported for negative dentries */
1584 /*              if (S_ISDIR(direntry->d_inode->i_mode))
1585                         shrink_dcache_parent(direntry); */
1586                 if (S_ISREG(direntry->d_inode->i_mode)) {
1587                         if (direntry->d_inode->i_mapping) {
1588                                 wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
1589                                 if (wbrc)
1590                                         CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1591                         }
1592                         /* may eventually have to do this for open files too */
1593                         if (list_empty(&(cifsInode->openFileList))) {
1594                                 /* changed on server - flush read ahead pages */
1595                                 cFYI(1, ("Invalidating read ahead data on "
1596                                          "closed file"));
1597                                 invalidate_remote_inode(direntry->d_inode);
1598                         }
1599                 }
1600         }
1601 /*      mutex_unlock(&direntry->d_inode->i_mutex); */
1602
1603         kfree(full_path);
1604         FreeXid(xid);
1605         return rc;
1606 }
1607
1608 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1609         struct kstat *stat)
1610 {
1611         int err = cifs_revalidate(dentry);
1612         if (!err) {
1613                 generic_fillattr(dentry->d_inode, stat);
1614                 stat->blksize = CIFS_MAX_MSGSIZE;
1615         }
1616         return err;
1617 }
1618
1619 static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1620 {
1621         pgoff_t index = from >> PAGE_CACHE_SHIFT;
1622         unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1623         struct page *page;
1624         int rc = 0;
1625
1626         page = grab_cache_page(mapping, index);
1627         if (!page)
1628                 return -ENOMEM;
1629
1630         zero_user_segment(page, offset, PAGE_CACHE_SIZE);
1631         unlock_page(page);
1632         page_cache_release(page);
1633         return rc;
1634 }
1635
1636 static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1637 {
1638         struct address_space *mapping = inode->i_mapping;
1639         unsigned long limit;
1640
1641         spin_lock(&inode->i_lock);
1642         if (inode->i_size < offset)
1643                 goto do_expand;
1644         /*
1645          * truncation of in-use swapfiles is disallowed - it would cause
1646          * subsequent swapout to scribble on the now-freed blocks.
1647          */
1648         if (IS_SWAPFILE(inode)) {
1649                 spin_unlock(&inode->i_lock);
1650                 goto out_busy;
1651         }
1652         i_size_write(inode, offset);
1653         spin_unlock(&inode->i_lock);
1654         /*
1655          * unmap_mapping_range is called twice, first simply for efficiency
1656          * so that truncate_inode_pages does fewer single-page unmaps. However
1657          * after this first call, and before truncate_inode_pages finishes,
1658          * it is possible for private pages to be COWed, which remain after
1659          * truncate_inode_pages finishes, hence the second unmap_mapping_range
1660          * call must be made for correctness.
1661          */
1662         unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1663         truncate_inode_pages(mapping, offset);
1664         unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1665         goto out_truncate;
1666
1667 do_expand:
1668         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
1669         if (limit != RLIM_INFINITY && offset > limit) {
1670                 spin_unlock(&inode->i_lock);
1671                 goto out_sig;
1672         }
1673         if (offset > inode->i_sb->s_maxbytes) {
1674                 spin_unlock(&inode->i_lock);
1675                 goto out_big;
1676         }
1677         i_size_write(inode, offset);
1678         spin_unlock(&inode->i_lock);
1679 out_truncate:
1680         if (inode->i_op->truncate)
1681                 inode->i_op->truncate(inode);
1682         return 0;
1683 out_sig:
1684         send_sig(SIGXFSZ, current, 0);
1685 out_big:
1686         return -EFBIG;
1687 out_busy:
1688         return -ETXTBSY;
1689 }
1690
1691 static int
1692 cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1693                    int xid, char *full_path)
1694 {
1695         int rc;
1696         struct cifsFileInfo *open_file;
1697         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1698         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1699         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1700
1701         /*
1702          * To avoid spurious oplock breaks from server, in the case of
1703          * inodes that we already have open, avoid doing path based
1704          * setting of file size if we can do it by handle.
1705          * This keeps our caching token (oplock) and avoids timeouts
1706          * when the local oplock break takes longer to flush
1707          * writebehind data than the SMB timeout for the SetPathInfo
1708          * request would allow
1709          */
1710         open_file = find_writable_file(cifsInode);
1711         if (open_file) {
1712                 __u16 nfid = open_file->netfid;
1713                 __u32 npid = open_file->pid;
1714                 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1715                                         npid, false);
1716                 atomic_dec(&open_file->wrtPending);
1717                 cFYI(1, ("SetFSize for attrs rc = %d", rc));
1718                 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1719                         unsigned int bytes_written;
1720                         rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
1721                                           &bytes_written, NULL, NULL, 1);
1722                         cFYI(1, ("Wrt seteof rc %d", rc));
1723                 }
1724         } else
1725                 rc = -EINVAL;
1726
1727         if (rc != 0) {
1728                 /* Set file size by pathname rather than by handle
1729                    either because no valid, writeable file handle for
1730                    it was found or because there was an error setting
1731                    it by handle */
1732                 rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,
1733                                    false, cifs_sb->local_nls,
1734                                    cifs_sb->mnt_cifs_flags &
1735                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1736                 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1737                 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1738                         __u16 netfid;
1739                         int oplock = 0;
1740
1741                         rc = SMBLegacyOpen(xid, pTcon, full_path,
1742                                 FILE_OPEN, GENERIC_WRITE,
1743                                 CREATE_NOT_DIR, &netfid, &oplock, NULL,
1744                                 cifs_sb->local_nls,
1745                                 cifs_sb->mnt_cifs_flags &
1746                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1747                         if (rc == 0) {
1748                                 unsigned int bytes_written;
1749                                 rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
1750                                                   attrs->ia_size,
1751                                                   &bytes_written, NULL,
1752                                                   NULL, 1);
1753                                 cFYI(1, ("wrt seteof rc %d", rc));
1754                                 CIFSSMBClose(xid, pTcon, netfid);
1755                         }
1756                 }
1757         }
1758
1759         if (rc == 0) {
1760                 cifsInode->server_eof = attrs->ia_size;
1761                 rc = cifs_vmtruncate(inode, attrs->ia_size);
1762                 cifs_truncate_page(inode->i_mapping, inode->i_size);
1763         }
1764
1765         return rc;
1766 }
1767
1768 static int
1769 cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1770 {
1771         int rc;
1772         int xid;
1773         char *full_path = NULL;
1774         struct inode *inode = direntry->d_inode;
1775         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1776         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1777         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1778         struct cifs_unix_set_info_args *args = NULL;
1779
1780         cFYI(1, ("setattr_unix on file %s attrs->ia_valid=0x%x",
1781                  direntry->d_name.name, attrs->ia_valid));
1782
1783         xid = GetXid();
1784
1785         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1786                 /* check if we have permission to change attrs */
1787                 rc = inode_change_ok(inode, attrs);
1788                 if (rc < 0)
1789                         goto out;
1790                 else
1791                         rc = 0;
1792         }
1793
1794         full_path = build_path_from_dentry(direntry);
1795         if (full_path == NULL) {
1796                 rc = -ENOMEM;
1797                 goto out;
1798         }
1799
1800         /*
1801          * Attempt to flush data before changing attributes. We need to do
1802          * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1803          * ownership or mode then we may also need to do this. Here, we take
1804          * the safe way out and just do the flush on all setattr requests. If
1805          * the flush returns error, store it to report later and continue.
1806          *
1807          * BB: This should be smarter. Why bother flushing pages that
1808          * will be truncated anyway? Also, should we error out here if
1809          * the flush returns error?
1810          */
1811         rc = filemap_write_and_wait(inode->i_mapping);
1812         if (rc != 0) {
1813                 cifsInode->write_behind_rc = rc;
1814                 rc = 0;
1815         }
1816
1817         if (attrs->ia_valid & ATTR_SIZE) {
1818                 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1819                 if (rc != 0)
1820                         goto out;
1821         }
1822
1823         /* skip mode change if it's just for clearing setuid/setgid */
1824         if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1825                 attrs->ia_valid &= ~ATTR_MODE;
1826
1827         args = kmalloc(sizeof(*args), GFP_KERNEL);
1828         if (args == NULL) {
1829                 rc = -ENOMEM;
1830                 goto out;
1831         }
1832
1833         /* set up the struct */
1834         if (attrs->ia_valid & ATTR_MODE)
1835                 args->mode = attrs->ia_mode;
1836         else
1837                 args->mode = NO_CHANGE_64;
1838
1839         if (attrs->ia_valid & ATTR_UID)
1840                 args->uid = attrs->ia_uid;
1841         else
1842                 args->uid = NO_CHANGE_64;
1843
1844         if (attrs->ia_valid & ATTR_GID)
1845                 args->gid = attrs->ia_gid;
1846         else
1847                 args->gid = NO_CHANGE_64;
1848
1849         if (attrs->ia_valid & ATTR_ATIME)
1850                 args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
1851         else
1852                 args->atime = NO_CHANGE_64;
1853
1854         if (attrs->ia_valid & ATTR_MTIME)
1855                 args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
1856         else
1857                 args->mtime = NO_CHANGE_64;
1858
1859         if (attrs->ia_valid & ATTR_CTIME)
1860                 args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
1861         else
1862                 args->ctime = NO_CHANGE_64;
1863
1864         args->device = 0;
1865         rc = CIFSSMBUnixSetInfo(xid, pTcon, full_path, args,
1866                                 cifs_sb->local_nls,
1867                                 cifs_sb->mnt_cifs_flags &
1868                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1869
1870         if (!rc)
1871                 rc = inode_setattr(inode, attrs);
1872 out:
1873         kfree(args);
1874         kfree(full_path);
1875         FreeXid(xid);
1876         return rc;
1877 }
1878
1879 static int
1880 cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
1881 {
1882         int xid;
1883         struct inode *inode = direntry->d_inode;
1884         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1885         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1886         char *full_path = NULL;
1887         int rc = -EACCES;
1888         __u32 dosattr = 0;
1889         __u64 mode = NO_CHANGE_64;
1890
1891         xid = GetXid();
1892
1893         cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
1894                  direntry->d_name.name, attrs->ia_valid));
1895
1896         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1897                 /* check if we have permission to change attrs */
1898                 rc = inode_change_ok(inode, attrs);
1899                 if (rc < 0) {
1900                         FreeXid(xid);
1901                         return rc;
1902                 } else
1903                         rc = 0;
1904         }
1905
1906         full_path = build_path_from_dentry(direntry);
1907         if (full_path == NULL) {
1908                 FreeXid(xid);
1909                 return -ENOMEM;
1910         }
1911
1912         /*
1913          * Attempt to flush data before changing attributes. We need to do
1914          * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1915          * ownership or mode then we may also need to do this. Here, we take
1916          * the safe way out and just do the flush on all setattr requests. If
1917          * the flush returns error, store it to report later and continue.
1918          *
1919          * BB: This should be smarter. Why bother flushing pages that
1920          * will be truncated anyway? Also, should we error out here if
1921          * the flush returns error?
1922          */
1923         rc = filemap_write_and_wait(inode->i_mapping);
1924         if (rc != 0) {
1925                 cifsInode->write_behind_rc = rc;
1926                 rc = 0;
1927         }
1928
1929         if (attrs->ia_valid & ATTR_SIZE) {
1930                 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1931                 if (rc != 0)
1932                         goto cifs_setattr_exit;
1933         }
1934
1935         /*
1936          * Without unix extensions we can't send ownership changes to the
1937          * server, so silently ignore them. This is consistent with how
1938          * local DOS/Windows filesystems behave (VFAT, NTFS, etc). With
1939          * CIFSACL support + proper Windows to Unix idmapping, we may be
1940          * able to support this in the future.
1941          */
1942         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
1943                 attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
1944
1945         /* skip mode change if it's just for clearing setuid/setgid */
1946         if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1947                 attrs->ia_valid &= ~ATTR_MODE;
1948
1949         if (attrs->ia_valid & ATTR_MODE) {
1950                 cFYI(1, ("Mode changed to 0%o", attrs->ia_mode));
1951                 mode = attrs->ia_mode;
1952         }
1953
1954         if (attrs->ia_valid & ATTR_MODE) {
1955                 rc = 0;
1956 #ifdef CONFIG_CIFS_EXPERIMENTAL
1957                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1958                         rc = mode_to_acl(inode, full_path, mode);
1959                 else
1960 #endif
1961                 if (((mode & S_IWUGO) == 0) &&
1962                     (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1963
1964                         dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
1965
1966                         /* fix up mode if we're not using dynperm */
1967                         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
1968                                 attrs->ia_mode = inode->i_mode & ~S_IWUGO;
1969                 } else if ((mode & S_IWUGO) &&
1970                            (cifsInode->cifsAttrs & ATTR_READONLY)) {
1971
1972                         dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
1973                         /* Attributes of 0 are ignored */
1974                         if (dosattr == 0)
1975                                 dosattr |= ATTR_NORMAL;
1976
1977                         /* reset local inode permissions to normal */
1978                         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1979                                 attrs->ia_mode &= ~(S_IALLUGO);
1980                                 if (S_ISDIR(inode->i_mode))
1981                                         attrs->ia_mode |=
1982                                                 cifs_sb->mnt_dir_mode;
1983                                 else
1984                                         attrs->ia_mode |=
1985                                                 cifs_sb->mnt_file_mode;
1986                         }
1987                 } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1988                         /* ignore mode change - ATTR_READONLY hasn't changed */
1989                         attrs->ia_valid &= ~ATTR_MODE;
1990                 }
1991         }
1992
1993         if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||
1994             ((attrs->ia_valid & ATTR_MODE) && dosattr)) {
1995                 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
1996                 /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */
1997
1998                 /* Even if error on time set, no sense failing the call if
1999                 the server would set the time to a reasonable value anyway,
2000                 and this check ensures that we are not being called from
2001                 sys_utimes in which case we ought to fail the call back to
2002                 the user when the server rejects the call */
2003                 if ((rc) && (attrs->ia_valid &
2004                                 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
2005                         rc = 0;
2006         }
2007
2008         /* do not need local check to inode_check_ok since the server does
2009            that */
2010         if (!rc)
2011                 rc = inode_setattr(inode, attrs);
2012 cifs_setattr_exit:
2013         kfree(full_path);
2014         FreeXid(xid);
2015         return rc;
2016 }
2017
2018 int
2019 cifs_setattr(struct dentry *direntry, struct iattr *attrs)
2020 {
2021         struct inode *inode = direntry->d_inode;
2022         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2023         struct cifsTconInfo *pTcon = cifs_sb->tcon;
2024
2025         if (pTcon->unix_ext)
2026                 return cifs_setattr_unix(direntry, attrs);
2027
2028         return cifs_setattr_nounix(direntry, attrs);
2029
2030         /* BB: add cifs_setattr_legacy for really old servers */
2031 }
2032
2033 #if 0
2034 void cifs_delete_inode(struct inode *inode)
2035 {
2036         cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
2037         /* may have to add back in if and when safe distributed caching of
2038            directories added e.g. via FindNotify */
2039 }
2040 #endif