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