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