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