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