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