cf18ee7655902210240ea0c5281e546370b9d22d
[linux-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         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 || !fattr.cf_uniqueid) {
516                                 cFYI(1, ("GetSrvInodeNum rc %d", rc1));
517                                 fattr.cf_uniqueid = iunique(sb, ROOT_I);
518                                 cifs_autodisable_serverino(cifs_sb);
519                         }
520                 } else {
521                         fattr.cf_uniqueid = iunique(sb, ROOT_I);
522                 }
523         } else {
524                 fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
525         }
526
527         /* query for SFU type info if supported and needed */
528         if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
529             cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
530                 tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
531                 if (tmprc)
532                         cFYI(1, ("cifs_sfu_type failed: %d", tmprc));
533         }
534
535 #ifdef CONFIG_CIFS_EXPERIMENTAL
536         /* fill in 0777 bits from ACL */
537         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
538                 cFYI(1, ("Getting mode bits from ACL"));
539                 cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
540         }
541 #endif
542
543         /* fill in remaining high mode bits e.g. SUID, VTX */
544         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
545                 cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
546
547         if (!*pinode) {
548                 *pinode = cifs_iget(sb, &fattr);
549                 if (!*pinode)
550                         rc = -ENOMEM;
551         } else {
552                 cifs_fattr_to_inode(*pinode, &fattr);
553         }
554
555 cgii_exit:
556         kfree(buf);
557         return rc;
558 }
559
560 static const struct inode_operations cifs_ipc_inode_ops = {
561         .lookup = cifs_lookup,
562 };
563
564 char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
565 {
566         int pplen = cifs_sb->prepathlen;
567         int dfsplen;
568         char *full_path = NULL;
569
570         /* if no prefix path, simply set path to the root of share to "" */
571         if (pplen == 0) {
572                 full_path = kmalloc(1, GFP_KERNEL);
573                 if (full_path)
574                         full_path[0] = 0;
575                 return full_path;
576         }
577
578         if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS))
579                 dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1);
580         else
581                 dfsplen = 0;
582
583         full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
584         if (full_path == NULL)
585                 return full_path;
586
587         if (dfsplen) {
588                 strncpy(full_path, cifs_sb->tcon->treeName, dfsplen);
589                 /* switch slash direction in prepath depending on whether
590                  * windows or posix style path names
591                  */
592                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
593                         int i;
594                         for (i = 0; i < dfsplen; i++) {
595                                 if (full_path[i] == '\\')
596                                         full_path[i] = '/';
597                         }
598                 }
599         }
600         strncpy(full_path + dfsplen, cifs_sb->prepath, pplen);
601         full_path[dfsplen + pplen] = 0; /* add trailing null */
602         return full_path;
603 }
604
605 static int
606 cifs_find_inode(struct inode *inode, void *opaque)
607 {
608         struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
609
610         if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
611                 return 0;
612
613         return 1;
614 }
615
616 static int
617 cifs_init_inode(struct inode *inode, void *opaque)
618 {
619         struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
620
621         CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
622         return 0;
623 }
624
625 /* Given fattrs, get a corresponding inode */
626 struct inode *
627 cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
628 {
629         unsigned long hash;
630         struct inode *inode;
631
632         cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid));
633
634         /* hash down to 32-bits on 32-bit arch */
635         hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
636
637         inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
638
639         /* we have fattrs in hand, update the inode */
640         if (inode) {
641                 cifs_fattr_to_inode(inode, fattr);
642                 if (sb->s_flags & MS_NOATIME)
643                         inode->i_flags |= S_NOATIME | S_NOCMTIME;
644                 if (inode->i_state & I_NEW) {
645                         inode->i_ino = hash;
646                         unlock_new_inode(inode);
647                 }
648         }
649
650         return inode;
651 }
652
653 /* gets root inode */
654 struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
655 {
656         int xid;
657         struct cifs_sb_info *cifs_sb;
658         struct inode *inode = NULL;
659         long rc;
660         char *full_path;
661
662         cifs_sb = CIFS_SB(sb);
663         full_path = cifs_build_path_to_root(cifs_sb);
664         if (full_path == NULL)
665                 return ERR_PTR(-ENOMEM);
666
667         xid = GetXid();
668         if (cifs_sb->tcon->unix_ext)
669                 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
670         else
671                 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
672                                                 xid, NULL);
673
674         if (!inode)
675                 return ERR_PTR(-ENOMEM);
676
677         if (rc && cifs_sb->tcon->ipc) {
678                 cFYI(1, ("ipc connection - fake read inode"));
679                 inode->i_mode |= S_IFDIR;
680                 inode->i_nlink = 2;
681                 inode->i_op = &cifs_ipc_inode_ops;
682                 inode->i_fop = &simple_dir_operations;
683                 inode->i_uid = cifs_sb->mnt_uid;
684                 inode->i_gid = cifs_sb->mnt_gid;
685         } else if (rc) {
686                 kfree(full_path);
687                 _FreeXid(xid);
688                 iget_failed(inode);
689                 return ERR_PTR(rc);
690         }
691
692
693         kfree(full_path);
694         /* can not call macro FreeXid here since in a void func
695          * TODO: This is no longer true
696          */
697         _FreeXid(xid);
698         return inode;
699 }
700
701 static int
702 cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
703                     char *full_path, __u32 dosattr)
704 {
705         int rc;
706         int oplock = 0;
707         __u16 netfid;
708         __u32 netpid;
709         bool set_time = false;
710         struct cifsFileInfo *open_file;
711         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
712         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
713         struct cifsTconInfo *pTcon = cifs_sb->tcon;
714         FILE_BASIC_INFO info_buf;
715
716         if (attrs == NULL)
717                 return -EINVAL;
718
719         if (attrs->ia_valid & ATTR_ATIME) {
720                 set_time = true;
721                 info_buf.LastAccessTime =
722                         cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
723         } else
724                 info_buf.LastAccessTime = 0;
725
726         if (attrs->ia_valid & ATTR_MTIME) {
727                 set_time = true;
728                 info_buf.LastWriteTime =
729                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
730         } else
731                 info_buf.LastWriteTime = 0;
732
733         /*
734          * Samba throws this field away, but windows may actually use it.
735          * Do not set ctime unless other time stamps are changed explicitly
736          * (i.e. by utimes()) since we would then have a mix of client and
737          * server times.
738          */
739         if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
740                 cFYI(1, ("CIFS - CTIME changed"));
741                 info_buf.ChangeTime =
742                     cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
743         } else
744                 info_buf.ChangeTime = 0;
745
746         info_buf.CreationTime = 0;      /* don't change */
747         info_buf.Attributes = cpu_to_le32(dosattr);
748
749         /*
750          * If the file is already open for write, just use that fileid
751          */
752         open_file = find_writable_file(cifsInode);
753         if (open_file) {
754                 netfid = open_file->netfid;
755                 netpid = open_file->pid;
756                 goto set_via_filehandle;
757         }
758
759         /*
760          * NT4 apparently returns success on this call, but it doesn't
761          * really work.
762          */
763         if (!(pTcon->ses->flags & CIFS_SES_NT4)) {
764                 rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
765                                      &info_buf, cifs_sb->local_nls,
766                                      cifs_sb->mnt_cifs_flags &
767                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
768                 if (rc == 0) {
769                         cifsInode->cifsAttrs = dosattr;
770                         goto out;
771                 } else if (rc != -EOPNOTSUPP && rc != -EINVAL)
772                         goto out;
773         }
774
775         cFYI(1, ("calling SetFileInfo since SetPathInfo for "
776                  "times not supported by this server"));
777         rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
778                          SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
779                          CREATE_NOT_DIR, &netfid, &oplock,
780                          NULL, cifs_sb->local_nls,
781                          cifs_sb->mnt_cifs_flags &
782                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
783
784         if (rc != 0) {
785                 if (rc == -EIO)
786                         rc = -EINVAL;
787                 goto out;
788         }
789
790         netpid = current->tgid;
791
792 set_via_filehandle:
793         rc = CIFSSMBSetFileInfo(xid, pTcon, &info_buf, netfid, netpid);
794         if (!rc)
795                 cifsInode->cifsAttrs = dosattr;
796
797         if (open_file == NULL)
798                 CIFSSMBClose(xid, pTcon, netfid);
799         else
800                 cifsFileInfo_put(open_file);
801 out:
802         return rc;
803 }
804
805 /*
806  * open the given file (if it isn't already), set the DELETE_ON_CLOSE bit
807  * and rename it to a random name that hopefully won't conflict with
808  * anything else.
809  */
810 static int
811 cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
812 {
813         int oplock = 0;
814         int rc;
815         __u16 netfid;
816         struct inode *inode = dentry->d_inode;
817         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
818         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
819         struct cifsTconInfo *tcon = cifs_sb->tcon;
820         __u32 dosattr, origattr;
821         FILE_BASIC_INFO *info_buf = NULL;
822
823         rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
824                          DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
825                          &netfid, &oplock, NULL, cifs_sb->local_nls,
826                          cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
827         if (rc != 0)
828                 goto out;
829
830         origattr = cifsInode->cifsAttrs;
831         if (origattr == 0)
832                 origattr |= ATTR_NORMAL;
833
834         dosattr = origattr & ~ATTR_READONLY;
835         if (dosattr == 0)
836                 dosattr |= ATTR_NORMAL;
837         dosattr |= ATTR_HIDDEN;
838
839         /* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */
840         if (dosattr != origattr) {
841                 info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
842                 if (info_buf == NULL) {
843                         rc = -ENOMEM;
844                         goto out_close;
845                 }
846                 info_buf->Attributes = cpu_to_le32(dosattr);
847                 rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
848                                         current->tgid);
849                 /* although we would like to mark the file hidden
850                    if that fails we will still try to rename it */
851                 if (rc != 0)
852                         cifsInode->cifsAttrs = dosattr;
853                 else
854                         dosattr = origattr; /* since not able to change them */
855         }
856
857         /* rename the file */
858         rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
859                                    cifs_sb->mnt_cifs_flags &
860                                             CIFS_MOUNT_MAP_SPECIAL_CHR);
861         if (rc != 0) {
862                 rc = -ETXTBSY;
863                 goto undo_setattr;
864         }
865
866         /* try to set DELETE_ON_CLOSE */
867         if (!cifsInode->delete_pending) {
868                 rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid,
869                                                current->tgid);
870                 /*
871                  * some samba versions return -ENOENT when we try to set the
872                  * file disposition here. Likely a samba bug, but work around
873                  * it for now. This means that some cifsXXX files may hang
874                  * around after they shouldn't.
875                  *
876                  * BB: remove this hack after more servers have the fix
877                  */
878                 if (rc == -ENOENT)
879                         rc = 0;
880                 else if (rc != 0) {
881                         rc = -ETXTBSY;
882                         goto undo_rename;
883                 }
884                 cifsInode->delete_pending = true;
885         }
886
887 out_close:
888         CIFSSMBClose(xid, tcon, netfid);
889 out:
890         kfree(info_buf);
891         return rc;
892
893         /*
894          * reset everything back to the original state. Don't bother
895          * dealing with errors here since we can't do anything about
896          * them anyway.
897          */
898 undo_rename:
899         CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name,
900                                 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
901                                             CIFS_MOUNT_MAP_SPECIAL_CHR);
902 undo_setattr:
903         if (dosattr != origattr) {
904                 info_buf->Attributes = cpu_to_le32(origattr);
905                 if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
906                                         current->tgid))
907                         cifsInode->cifsAttrs = origattr;
908         }
909
910         goto out_close;
911 }
912
913
914 /*
915  * If dentry->d_inode is null (usually meaning the cached dentry
916  * is a negative dentry) then we would attempt a standard SMB delete, but
917  * if that fails we can not attempt the fall back mechanisms on EACCESS
918  * but will return the EACCESS to the caller. Note that the VFS does not call
919  * unlink on negative dentries currently.
920  */
921 int cifs_unlink(struct inode *dir, struct dentry *dentry)
922 {
923         int rc = 0;
924         int xid;
925         char *full_path = NULL;
926         struct inode *inode = dentry->d_inode;
927         struct cifsInodeInfo *cifs_inode;
928         struct super_block *sb = dir->i_sb;
929         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
930         struct cifsTconInfo *tcon = cifs_sb->tcon;
931         struct iattr *attrs = NULL;
932         __u32 dosattr = 0, origattr = 0;
933
934         cFYI(1, ("cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry));
935
936         xid = GetXid();
937
938         /* Unlink can be called from rename so we can not take the
939          * sb->s_vfs_rename_mutex here */
940         full_path = build_path_from_dentry(dentry);
941         if (full_path == NULL) {
942                 rc = -ENOMEM;
943                 FreeXid(xid);
944                 return rc;
945         }
946
947         if ((tcon->ses->capabilities & CAP_UNIX) &&
948                 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
949                         le64_to_cpu(tcon->fsUnixInfo.Capability))) {
950                 rc = CIFSPOSIXDelFile(xid, tcon, full_path,
951                         SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
952                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
953                 cFYI(1, ("posix del rc %d", rc));
954                 if ((rc == 0) || (rc == -ENOENT))
955                         goto psx_del_no_retry;
956         }
957
958 retry_std_delete:
959         rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls,
960                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
961
962 psx_del_no_retry:
963         if (!rc) {
964                 if (inode)
965                         drop_nlink(inode);
966         } else if (rc == -ENOENT) {
967                 d_drop(dentry);
968         } else if (rc == -ETXTBSY) {
969                 rc = cifs_rename_pending_delete(full_path, dentry, xid);
970                 if (rc == 0)
971                         drop_nlink(inode);
972         } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
973                 attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
974                 if (attrs == NULL) {
975                         rc = -ENOMEM;
976                         goto out_reval;
977                 }
978
979                 /* try to reset dos attributes */
980                 cifs_inode = CIFS_I(inode);
981                 origattr = cifs_inode->cifsAttrs;
982                 if (origattr == 0)
983                         origattr |= ATTR_NORMAL;
984                 dosattr = origattr & ~ATTR_READONLY;
985                 if (dosattr == 0)
986                         dosattr |= ATTR_NORMAL;
987                 dosattr |= ATTR_HIDDEN;
988
989                 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
990                 if (rc != 0)
991                         goto out_reval;
992
993                 goto retry_std_delete;
994         }
995
996         /* undo the setattr if we errored out and it's needed */
997         if (rc != 0 && dosattr != 0)
998                 cifs_set_file_info(inode, attrs, xid, full_path, origattr);
999
1000 out_reval:
1001         if (inode) {
1002                 cifs_inode = CIFS_I(inode);
1003                 cifs_inode->time = 0;   /* will force revalidate to get info
1004                                            when needed */
1005                 inode->i_ctime = current_fs_time(sb);
1006         }
1007         dir->i_ctime = dir->i_mtime = current_fs_time(sb);
1008         cifs_inode = CIFS_I(dir);
1009         CIFS_I(dir)->time = 0;  /* force revalidate of dir as well */
1010
1011         kfree(full_path);
1012         kfree(attrs);
1013         FreeXid(xid);
1014         return rc;
1015 }
1016
1017 int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1018 {
1019         int rc = 0, tmprc;
1020         int xid;
1021         struct cifs_sb_info *cifs_sb;
1022         struct cifsTconInfo *pTcon;
1023         char *full_path = NULL;
1024         struct inode *newinode = NULL;
1025         struct cifs_fattr fattr;
1026
1027         cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
1028
1029         xid = GetXid();
1030
1031         cifs_sb = CIFS_SB(inode->i_sb);
1032         pTcon = cifs_sb->tcon;
1033
1034         full_path = build_path_from_dentry(direntry);
1035         if (full_path == NULL) {
1036                 rc = -ENOMEM;
1037                 FreeXid(xid);
1038                 return rc;
1039         }
1040
1041         if ((pTcon->ses->capabilities & CAP_UNIX) &&
1042                 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1043                         le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
1044                 u32 oplock = 0;
1045                 FILE_UNIX_BASIC_INFO *pInfo =
1046                         kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1047                 if (pInfo == NULL) {
1048                         rc = -ENOMEM;
1049                         goto mkdir_out;
1050                 }
1051
1052                 mode &= ~current_umask();
1053                 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
1054                                 mode, NULL /* netfid */, pInfo, &oplock,
1055                                 full_path, cifs_sb->local_nls,
1056                                 cifs_sb->mnt_cifs_flags &
1057                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1058                 if (rc == -EOPNOTSUPP) {
1059                         kfree(pInfo);
1060                         goto mkdir_retry_old;
1061                 } else if (rc) {
1062                         cFYI(1, ("posix mkdir returned 0x%x", rc));
1063                         d_drop(direntry);
1064                 } else {
1065                         if (pInfo->Type == cpu_to_le32(-1)) {
1066                                 /* no return info, go query for it */
1067                                 kfree(pInfo);
1068                                 goto mkdir_get_info;
1069                         }
1070 /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
1071         to set uid/gid */
1072                         inc_nlink(inode);
1073                         if (pTcon->nocase)
1074                                 direntry->d_op = &cifs_ci_dentry_ops;
1075                         else
1076                                 direntry->d_op = &cifs_dentry_ops;
1077
1078                         cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
1079                         newinode = cifs_iget(inode->i_sb, &fattr);
1080                         if (!newinode) {
1081                                 kfree(pInfo);
1082                                 goto mkdir_get_info;
1083                         }
1084
1085                         d_instantiate(direntry, newinode);
1086
1087 #ifdef CONFIG_CIFS_DEBUG2
1088                         cFYI(1, ("instantiated dentry %p %s to inode %p",
1089                                 direntry, direntry->d_name.name, newinode));
1090
1091                         if (newinode->i_nlink != 2)
1092                                 cFYI(1, ("unexpected number of links %d",
1093                                         newinode->i_nlink));
1094 #endif
1095                 }
1096                 kfree(pInfo);
1097                 goto mkdir_out;
1098         }
1099 mkdir_retry_old:
1100         /* BB add setting the equivalent of mode via CreateX w/ACLs */
1101         rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
1102                           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1103         if (rc) {
1104                 cFYI(1, ("cifs_mkdir returned 0x%x", rc));
1105                 d_drop(direntry);
1106         } else {
1107 mkdir_get_info:
1108                 inc_nlink(inode);
1109                 if (pTcon->unix_ext)
1110                         rc = cifs_get_inode_info_unix(&newinode, full_path,
1111                                                       inode->i_sb, xid);
1112                 else
1113                         rc = cifs_get_inode_info(&newinode, full_path, NULL,
1114                                                  inode->i_sb, xid, NULL);
1115
1116                 if (pTcon->nocase)
1117                         direntry->d_op = &cifs_ci_dentry_ops;
1118                 else
1119                         direntry->d_op = &cifs_dentry_ops;
1120                 d_instantiate(direntry, newinode);
1121                  /* setting nlink not necessary except in cases where we
1122                   * failed to get it from the server or was set bogus */
1123                 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
1124                                 direntry->d_inode->i_nlink = 2;
1125
1126                 mode &= ~current_umask();
1127                 /* must turn on setgid bit if parent dir has it */
1128                 if (inode->i_mode & S_ISGID)
1129                         mode |= S_ISGID;
1130
1131                 if (pTcon->unix_ext) {
1132                         struct cifs_unix_set_info_args args = {
1133                                 .mode   = mode,
1134                                 .ctime  = NO_CHANGE_64,
1135                                 .atime  = NO_CHANGE_64,
1136                                 .mtime  = NO_CHANGE_64,
1137                                 .device = 0,
1138                         };
1139                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
1140                                 args.uid = (__u64)current_fsuid();
1141                                 if (inode->i_mode & S_ISGID)
1142                                         args.gid = (__u64)inode->i_gid;
1143                                 else
1144                                         args.gid = (__u64)current_fsgid();
1145                         } else {
1146                                 args.uid = NO_CHANGE_64;
1147                                 args.gid = NO_CHANGE_64;
1148                         }
1149                         CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
1150                                                cifs_sb->local_nls,
1151                                                cifs_sb->mnt_cifs_flags &
1152                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1153                 } else {
1154                         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
1155                             (mode & S_IWUGO) == 0) {
1156                                 FILE_BASIC_INFO pInfo;
1157                                 struct cifsInodeInfo *cifsInode;
1158                                 u32 dosattrs;
1159
1160                                 memset(&pInfo, 0, sizeof(pInfo));
1161                                 cifsInode = CIFS_I(newinode);
1162                                 dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
1163                                 pInfo.Attributes = cpu_to_le32(dosattrs);
1164                                 tmprc = CIFSSMBSetPathInfo(xid, pTcon,
1165                                                 full_path, &pInfo,
1166                                                 cifs_sb->local_nls,
1167                                                 cifs_sb->mnt_cifs_flags &
1168                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1169                                 if (tmprc == 0)
1170                                         cifsInode->cifsAttrs = dosattrs;
1171                         }
1172                         if (direntry->d_inode) {
1173                                 if (cifs_sb->mnt_cifs_flags &
1174                                      CIFS_MOUNT_DYNPERM)
1175                                         direntry->d_inode->i_mode =
1176                                                 (mode | S_IFDIR);
1177
1178                                 if (cifs_sb->mnt_cifs_flags &
1179                                      CIFS_MOUNT_SET_UID) {
1180                                         direntry->d_inode->i_uid =
1181                                                 current_fsuid();
1182                                         if (inode->i_mode & S_ISGID)
1183                                                 direntry->d_inode->i_gid =
1184                                                         inode->i_gid;
1185                                         else
1186                                                 direntry->d_inode->i_gid =
1187                                                         current_fsgid();
1188                                 }
1189                         }
1190                 }
1191         }
1192 mkdir_out:
1193         kfree(full_path);
1194         FreeXid(xid);
1195         return rc;
1196 }
1197
1198 int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1199 {
1200         int rc = 0;
1201         int xid;
1202         struct cifs_sb_info *cifs_sb;
1203         struct cifsTconInfo *pTcon;
1204         char *full_path = NULL;
1205         struct cifsInodeInfo *cifsInode;
1206
1207         cFYI(1, ("cifs_rmdir, inode = 0x%p", inode));
1208
1209         xid = GetXid();
1210
1211         cifs_sb = CIFS_SB(inode->i_sb);
1212         pTcon = cifs_sb->tcon;
1213
1214         full_path = build_path_from_dentry(direntry);
1215         if (full_path == NULL) {
1216                 rc = -ENOMEM;
1217                 FreeXid(xid);
1218                 return rc;
1219         }
1220
1221         rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1222                           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1223
1224         if (!rc) {
1225                 drop_nlink(inode);
1226                 spin_lock(&direntry->d_inode->i_lock);
1227                 i_size_write(direntry->d_inode, 0);
1228                 clear_nlink(direntry->d_inode);
1229                 spin_unlock(&direntry->d_inode->i_lock);
1230         }
1231
1232         cifsInode = CIFS_I(direntry->d_inode);
1233         cifsInode->time = 0;    /* force revalidate to go get info when
1234                                    needed */
1235
1236         cifsInode = CIFS_I(inode);
1237         cifsInode->time = 0;    /* force revalidate to get parent dir info
1238                                    since cached search results now invalid */
1239
1240         direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1241                 current_fs_time(inode->i_sb);
1242
1243         kfree(full_path);
1244         FreeXid(xid);
1245         return rc;
1246 }
1247
1248 static int
1249 cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1250                 struct dentry *to_dentry, const char *toPath)
1251 {
1252         struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
1253         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1254         __u16 srcfid;
1255         int oplock, rc;
1256
1257         /* try path-based rename first */
1258         rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
1259                            cifs_sb->mnt_cifs_flags &
1260                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1261
1262         /*
1263          * don't bother with rename by filehandle unless file is busy and
1264          * source Note that cross directory moves do not work with
1265          * rename by filehandle to various Windows servers.
1266          */
1267         if (rc == 0 || rc != -ETXTBSY)
1268                 return rc;
1269
1270         /* open the file to be renamed -- we need DELETE perms */
1271         rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE,
1272                          CREATE_NOT_DIR, &srcfid, &oplock, NULL,
1273                          cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1274                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
1275
1276         if (rc == 0) {
1277                 rc = CIFSSMBRenameOpenFile(xid, pTcon, srcfid,
1278                                 (const char *) to_dentry->d_name.name,
1279                                 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1280                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1281
1282                 CIFSSMBClose(xid, pTcon, srcfid);
1283         }
1284
1285         return rc;
1286 }
1287
1288 int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1289         struct inode *target_dir, struct dentry *target_dentry)
1290 {
1291         char *fromName = NULL;
1292         char *toName = NULL;
1293         struct cifs_sb_info *cifs_sb_source;
1294         struct cifs_sb_info *cifs_sb_target;
1295         struct cifsTconInfo *tcon;
1296         FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1297         FILE_UNIX_BASIC_INFO *info_buf_target;
1298         int xid, rc, tmprc;
1299
1300         cifs_sb_target = CIFS_SB(target_dir->i_sb);
1301         cifs_sb_source = CIFS_SB(source_dir->i_sb);
1302         tcon = cifs_sb_source->tcon;
1303
1304         xid = GetXid();
1305
1306         /*
1307          * BB: this might be allowed if same server, but different share.
1308          * Consider adding support for this
1309          */
1310         if (tcon != cifs_sb_target->tcon) {
1311                 rc = -EXDEV;
1312                 goto cifs_rename_exit;
1313         }
1314
1315         /*
1316          * we already have the rename sem so we do not need to
1317          * grab it again here to protect the path integrity
1318          */
1319         fromName = build_path_from_dentry(source_dentry);
1320         if (fromName == NULL) {
1321                 rc = -ENOMEM;
1322                 goto cifs_rename_exit;
1323         }
1324
1325         toName = build_path_from_dentry(target_dentry);
1326         if (toName == NULL) {
1327                 rc = -ENOMEM;
1328                 goto cifs_rename_exit;
1329         }
1330
1331         rc = cifs_do_rename(xid, source_dentry, fromName,
1332                             target_dentry, toName);
1333
1334         if (rc == -EEXIST && tcon->unix_ext) {
1335                 /*
1336                  * Are src and dst hardlinks of same inode? We can
1337                  * only tell with unix extensions enabled
1338                  */
1339                 info_buf_source =
1340                         kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
1341                                         GFP_KERNEL);
1342                 if (info_buf_source == NULL) {
1343                         rc = -ENOMEM;
1344                         goto cifs_rename_exit;
1345                 }
1346
1347                 info_buf_target = info_buf_source + 1;
1348                 tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
1349                                         info_buf_source,
1350                                         cifs_sb_source->local_nls,
1351                                         cifs_sb_source->mnt_cifs_flags &
1352                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1353                 if (tmprc != 0)
1354                         goto unlink_target;
1355
1356                 tmprc = CIFSSMBUnixQPathInfo(xid, tcon,
1357                                         toName, info_buf_target,
1358                                         cifs_sb_target->local_nls,
1359                                         /* remap based on source sb */
1360                                         cifs_sb_source->mnt_cifs_flags &
1361                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1362
1363                 if (tmprc == 0 && (info_buf_source->UniqueId ==
1364                                    info_buf_target->UniqueId)) {
1365                         /* same file, POSIX says that this is a noop */
1366                         rc = 0;
1367                         goto cifs_rename_exit;
1368                 }
1369         } /* else ... BB we could add the same check for Windows by
1370                      checking the UniqueId via FILE_INTERNAL_INFO */
1371
1372 unlink_target:
1373         /* Try unlinking the target dentry if it's not negative */
1374         if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) {
1375                 tmprc = cifs_unlink(target_dir, target_dentry);
1376                 if (tmprc)
1377                         goto cifs_rename_exit;
1378
1379                 rc = cifs_do_rename(xid, source_dentry, fromName,
1380                                     target_dentry, toName);
1381         }
1382
1383 cifs_rename_exit:
1384         kfree(info_buf_source);
1385         kfree(fromName);
1386         kfree(toName);
1387         FreeXid(xid);
1388         return rc;
1389 }
1390
1391 int cifs_revalidate(struct dentry *direntry)
1392 {
1393         int xid;
1394         int rc = 0, wbrc = 0;
1395         char *full_path;
1396         struct cifs_sb_info *cifs_sb;
1397         struct cifsInodeInfo *cifsInode;
1398         loff_t local_size;
1399         struct timespec local_mtime;
1400         bool invalidate_inode = false;
1401
1402         if (direntry->d_inode == NULL)
1403                 return -ENOENT;
1404
1405         cifsInode = CIFS_I(direntry->d_inode);
1406
1407         if (cifsInode == NULL)
1408                 return -ENOENT;
1409
1410         /* no sense revalidating inode info on file that no one can write */
1411         if (CIFS_I(direntry->d_inode)->clientCanCacheRead)
1412                 return rc;
1413
1414         xid = GetXid();
1415
1416         cifs_sb = CIFS_SB(direntry->d_sb);
1417
1418         /* can not safely grab the rename sem here if rename calls revalidate
1419            since that would deadlock */
1420         full_path = build_path_from_dentry(direntry);
1421         if (full_path == NULL) {
1422                 rc = -ENOMEM;
1423                 FreeXid(xid);
1424                 return rc;
1425         }
1426         cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
1427                  "jiffies %ld", full_path, direntry->d_inode,
1428                  direntry->d_inode->i_count.counter, direntry,
1429                  direntry->d_time, jiffies));
1430
1431         if (cifsInode->time == 0) {
1432                 /* was set to zero previously to force revalidate */
1433         } else if (time_before(jiffies, cifsInode->time + HZ) &&
1434                    lookupCacheEnabled) {
1435                 if ((S_ISREG(direntry->d_inode->i_mode) == 0) ||
1436                     (direntry->d_inode->i_nlink == 1)) {
1437                         kfree(full_path);
1438                         FreeXid(xid);
1439                         return rc;
1440                 } else {
1441                         cFYI(1, ("Have to revalidate file due to hardlinks"));
1442                 }
1443         }
1444
1445         /* save mtime and size */
1446         local_mtime = direntry->d_inode->i_mtime;
1447         local_size = direntry->d_inode->i_size;
1448
1449         if (cifs_sb->tcon->unix_ext) {
1450                 rc = cifs_get_inode_info_unix(&direntry->d_inode, full_path,
1451                                               direntry->d_sb, xid);
1452                 if (rc) {
1453                         cFYI(1, ("error on getting revalidate info %d", rc));
1454 /*                      if (rc != -ENOENT)
1455                                 rc = 0; */      /* BB should we cache info on
1456                                                    certain errors? */
1457                 }
1458         } else {
1459                 rc = cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
1460                                          direntry->d_sb, xid, NULL);
1461                 if (rc) {
1462                         cFYI(1, ("error on getting revalidate info %d", rc));
1463 /*                      if (rc != -ENOENT)
1464                                 rc = 0; */      /* BB should we cache info on
1465                                                    certain errors? */
1466                 }
1467         }
1468         /* should we remap certain errors, access denied?, to zero */
1469
1470         /* if not oplocked, we invalidate inode pages if mtime or file size
1471            had changed on server */
1472
1473         if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
1474             (local_size == direntry->d_inode->i_size)) {
1475                 cFYI(1, ("cifs_revalidate - inode unchanged"));
1476         } else {
1477                 /* file may have changed on server */
1478                 if (cifsInode->clientCanCacheRead) {
1479                         /* no need to invalidate inode pages since we were the
1480                            only ones who could have modified the file and the
1481                            server copy is staler than ours */
1482                 } else {
1483                         invalidate_inode = true;
1484                 }
1485         }
1486
1487         /* can not grab this sem since kernel filesys locking documentation
1488            indicates i_mutex may be taken by the kernel on lookup and rename
1489            which could deadlock if we grab the i_mutex here as well */
1490 /*      mutex_lock(&direntry->d_inode->i_mutex);*/
1491         /* need to write out dirty pages here  */
1492         if (direntry->d_inode->i_mapping) {
1493                 /* do we need to lock inode until after invalidate completes
1494                    below? */
1495                 wbrc = filemap_fdatawrite(direntry->d_inode->i_mapping);
1496                 if (wbrc)
1497                         CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1498         }
1499         if (invalidate_inode) {
1500         /* shrink_dcache not necessary now that cifs dentry ops
1501         are exported for negative dentries */
1502 /*              if (S_ISDIR(direntry->d_inode->i_mode))
1503                         shrink_dcache_parent(direntry); */
1504                 if (S_ISREG(direntry->d_inode->i_mode)) {
1505                         if (direntry->d_inode->i_mapping) {
1506                                 wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
1507                                 if (wbrc)
1508                                         CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
1509                         }
1510                         /* may eventually have to do this for open files too */
1511                         if (list_empty(&(cifsInode->openFileList))) {
1512                                 /* changed on server - flush read ahead pages */
1513                                 cFYI(1, ("Invalidating read ahead data on "
1514                                          "closed file"));
1515                                 invalidate_remote_inode(direntry->d_inode);
1516                         }
1517                 }
1518         }
1519 /*      mutex_unlock(&direntry->d_inode->i_mutex); */
1520
1521         kfree(full_path);
1522         FreeXid(xid);
1523         return rc;
1524 }
1525
1526 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1527         struct kstat *stat)
1528 {
1529         int err = cifs_revalidate(dentry);
1530         if (!err) {
1531                 generic_fillattr(dentry->d_inode, stat);
1532                 stat->blksize = CIFS_MAX_MSGSIZE;
1533                 stat->ino = CIFS_I(dentry->d_inode)->uniqueid;
1534         }
1535         return err;
1536 }
1537
1538 static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1539 {
1540         pgoff_t index = from >> PAGE_CACHE_SHIFT;
1541         unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1542         struct page *page;
1543         int rc = 0;
1544
1545         page = grab_cache_page(mapping, index);
1546         if (!page)
1547                 return -ENOMEM;
1548
1549         zero_user_segment(page, offset, PAGE_CACHE_SIZE);
1550         unlock_page(page);
1551         page_cache_release(page);
1552         return rc;
1553 }
1554
1555 static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1556 {
1557         loff_t oldsize;
1558         int err;
1559
1560         spin_lock(&inode->i_lock);
1561         err = inode_newsize_ok(inode, offset);
1562         if (err) {
1563                 spin_unlock(&inode->i_lock);
1564                 goto out;
1565         }
1566
1567         oldsize = inode->i_size;
1568         i_size_write(inode, offset);
1569         spin_unlock(&inode->i_lock);
1570         truncate_pagecache(inode, oldsize, offset);
1571         if (inode->i_op->truncate)
1572                 inode->i_op->truncate(inode);
1573 out:
1574         return err;
1575 }
1576
1577 static int
1578 cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1579                    int xid, char *full_path)
1580 {
1581         int rc;
1582         struct cifsFileInfo *open_file;
1583         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1584         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1585         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1586
1587         /*
1588          * To avoid spurious oplock breaks from server, in the case of
1589          * inodes that we already have open, avoid doing path based
1590          * setting of file size if we can do it by handle.
1591          * This keeps our caching token (oplock) and avoids timeouts
1592          * when the local oplock break takes longer to flush
1593          * writebehind data than the SMB timeout for the SetPathInfo
1594          * request would allow
1595          */
1596         open_file = find_writable_file(cifsInode);
1597         if (open_file) {
1598                 __u16 nfid = open_file->netfid;
1599                 __u32 npid = open_file->pid;
1600                 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1601                                         npid, false);
1602                 cifsFileInfo_put(open_file);
1603                 cFYI(1, ("SetFSize for attrs rc = %d", rc));
1604                 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1605                         unsigned int bytes_written;
1606                         rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
1607                                           &bytes_written, NULL, NULL, 1);
1608                         cFYI(1, ("Wrt seteof rc %d", rc));
1609                 }
1610         } else
1611                 rc = -EINVAL;
1612
1613         if (rc != 0) {
1614                 /* Set file size by pathname rather than by handle
1615                    either because no valid, writeable file handle for
1616                    it was found or because there was an error setting
1617                    it by handle */
1618                 rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,
1619                                    false, cifs_sb->local_nls,
1620                                    cifs_sb->mnt_cifs_flags &
1621                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1622                 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1623                 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1624                         __u16 netfid;
1625                         int oplock = 0;
1626
1627                         rc = SMBLegacyOpen(xid, pTcon, full_path,
1628                                 FILE_OPEN, GENERIC_WRITE,
1629                                 CREATE_NOT_DIR, &netfid, &oplock, NULL,
1630                                 cifs_sb->local_nls,
1631                                 cifs_sb->mnt_cifs_flags &
1632                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1633                         if (rc == 0) {
1634                                 unsigned int bytes_written;
1635                                 rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
1636                                                   attrs->ia_size,
1637                                                   &bytes_written, NULL,
1638                                                   NULL, 1);
1639                                 cFYI(1, ("wrt seteof rc %d", rc));
1640                                 CIFSSMBClose(xid, pTcon, netfid);
1641                         }
1642                 }
1643         }
1644
1645         if (rc == 0) {
1646                 cifsInode->server_eof = attrs->ia_size;
1647                 rc = cifs_vmtruncate(inode, attrs->ia_size);
1648                 cifs_truncate_page(inode->i_mapping, inode->i_size);
1649         }
1650
1651         return rc;
1652 }
1653
1654 static int
1655 cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1656 {
1657         int rc;
1658         int xid;
1659         char *full_path = NULL;
1660         struct inode *inode = direntry->d_inode;
1661         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1662         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1663         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1664         struct cifs_unix_set_info_args *args = NULL;
1665         struct cifsFileInfo *open_file;
1666
1667         cFYI(1, ("setattr_unix on file %s attrs->ia_valid=0x%x",
1668                  direntry->d_name.name, attrs->ia_valid));
1669
1670         xid = GetXid();
1671
1672         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1673                 /* check if we have permission to change attrs */
1674                 rc = inode_change_ok(inode, attrs);
1675                 if (rc < 0)
1676                         goto out;
1677                 else
1678                         rc = 0;
1679         }
1680
1681         full_path = build_path_from_dentry(direntry);
1682         if (full_path == NULL) {
1683                 rc = -ENOMEM;
1684                 goto out;
1685         }
1686
1687         /*
1688          * Attempt to flush data before changing attributes. We need to do
1689          * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1690          * ownership or mode then we may also need to do this. Here, we take
1691          * the safe way out and just do the flush on all setattr requests. If
1692          * the flush returns error, store it to report later and continue.
1693          *
1694          * BB: This should be smarter. Why bother flushing pages that
1695          * will be truncated anyway? Also, should we error out here if
1696          * the flush returns error?
1697          */
1698         rc = filemap_write_and_wait(inode->i_mapping);
1699         if (rc != 0) {
1700                 cifsInode->write_behind_rc = rc;
1701                 rc = 0;
1702         }
1703
1704         if (attrs->ia_valid & ATTR_SIZE) {
1705                 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1706                 if (rc != 0)
1707                         goto out;
1708         }
1709
1710         /* skip mode change if it's just for clearing setuid/setgid */
1711         if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1712                 attrs->ia_valid &= ~ATTR_MODE;
1713
1714         args = kmalloc(sizeof(*args), GFP_KERNEL);
1715         if (args == NULL) {
1716                 rc = -ENOMEM;
1717                 goto out;
1718         }
1719
1720         /* set up the struct */
1721         if (attrs->ia_valid & ATTR_MODE)
1722                 args->mode = attrs->ia_mode;
1723         else
1724                 args->mode = NO_CHANGE_64;
1725
1726         if (attrs->ia_valid & ATTR_UID)
1727                 args->uid = attrs->ia_uid;
1728         else
1729                 args->uid = NO_CHANGE_64;
1730
1731         if (attrs->ia_valid & ATTR_GID)
1732                 args->gid = attrs->ia_gid;
1733         else
1734                 args->gid = NO_CHANGE_64;
1735
1736         if (attrs->ia_valid & ATTR_ATIME)
1737                 args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
1738         else
1739                 args->atime = NO_CHANGE_64;
1740
1741         if (attrs->ia_valid & ATTR_MTIME)
1742                 args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
1743         else
1744                 args->mtime = NO_CHANGE_64;
1745
1746         if (attrs->ia_valid & ATTR_CTIME)
1747                 args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
1748         else
1749                 args->ctime = NO_CHANGE_64;
1750
1751         args->device = 0;
1752         open_file = find_writable_file(cifsInode);
1753         if (open_file) {
1754                 u16 nfid = open_file->netfid;
1755                 u32 npid = open_file->pid;
1756                 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
1757                 cifsFileInfo_put(open_file);
1758         } else {
1759                 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
1760                                     cifs_sb->local_nls,
1761                                     cifs_sb->mnt_cifs_flags &
1762                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1763         }
1764
1765         if (!rc)
1766                 rc = inode_setattr(inode, attrs);
1767 out:
1768         kfree(args);
1769         kfree(full_path);
1770         FreeXid(xid);
1771         return rc;
1772 }
1773
1774 static int
1775 cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
1776 {
1777         int xid;
1778         struct inode *inode = direntry->d_inode;
1779         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1780         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1781         char *full_path = NULL;
1782         int rc = -EACCES;
1783         __u32 dosattr = 0;
1784         __u64 mode = NO_CHANGE_64;
1785
1786         xid = GetXid();
1787
1788         cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
1789                  direntry->d_name.name, attrs->ia_valid));
1790
1791         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1792                 /* check if we have permission to change attrs */
1793                 rc = inode_change_ok(inode, attrs);
1794                 if (rc < 0) {
1795                         FreeXid(xid);
1796                         return rc;
1797                 } else
1798                         rc = 0;
1799         }
1800
1801         full_path = build_path_from_dentry(direntry);
1802         if (full_path == NULL) {
1803                 rc = -ENOMEM;
1804                 FreeXid(xid);
1805                 return rc;
1806         }
1807
1808         /*
1809          * Attempt to flush data before changing attributes. We need to do
1810          * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1811          * ownership or mode then we may also need to do this. Here, we take
1812          * the safe way out and just do the flush on all setattr requests. If
1813          * the flush returns error, store it to report later and continue.
1814          *
1815          * BB: This should be smarter. Why bother flushing pages that
1816          * will be truncated anyway? Also, should we error out here if
1817          * the flush returns error?
1818          */
1819         rc = filemap_write_and_wait(inode->i_mapping);
1820         if (rc != 0) {
1821                 cifsInode->write_behind_rc = rc;
1822                 rc = 0;
1823         }
1824
1825         if (attrs->ia_valid & ATTR_SIZE) {
1826                 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1827                 if (rc != 0)
1828                         goto cifs_setattr_exit;
1829         }
1830
1831         /*
1832          * Without unix extensions we can't send ownership changes to the
1833          * server, so silently ignore them. This is consistent with how
1834          * local DOS/Windows filesystems behave (VFAT, NTFS, etc). With
1835          * CIFSACL support + proper Windows to Unix idmapping, we may be
1836          * able to support this in the future.
1837          */
1838         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
1839                 attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
1840
1841         /* skip mode change if it's just for clearing setuid/setgid */
1842         if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1843                 attrs->ia_valid &= ~ATTR_MODE;
1844
1845         if (attrs->ia_valid & ATTR_MODE) {
1846                 cFYI(1, ("Mode changed to 0%o", attrs->ia_mode));
1847                 mode = attrs->ia_mode;
1848         }
1849
1850         if (attrs->ia_valid & ATTR_MODE) {
1851                 rc = 0;
1852 #ifdef CONFIG_CIFS_EXPERIMENTAL
1853                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1854                         rc = mode_to_acl(inode, full_path, mode);
1855                 else
1856 #endif
1857                 if (((mode & S_IWUGO) == 0) &&
1858                     (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1859
1860                         dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
1861
1862                         /* fix up mode if we're not using dynperm */
1863                         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
1864                                 attrs->ia_mode = inode->i_mode & ~S_IWUGO;
1865                 } else if ((mode & S_IWUGO) &&
1866                            (cifsInode->cifsAttrs & ATTR_READONLY)) {
1867
1868                         dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
1869                         /* Attributes of 0 are ignored */
1870                         if (dosattr == 0)
1871                                 dosattr |= ATTR_NORMAL;
1872
1873                         /* reset local inode permissions to normal */
1874                         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1875                                 attrs->ia_mode &= ~(S_IALLUGO);
1876                                 if (S_ISDIR(inode->i_mode))
1877                                         attrs->ia_mode |=
1878                                                 cifs_sb->mnt_dir_mode;
1879                                 else
1880                                         attrs->ia_mode |=
1881                                                 cifs_sb->mnt_file_mode;
1882                         }
1883                 } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1884                         /* ignore mode change - ATTR_READONLY hasn't changed */
1885                         attrs->ia_valid &= ~ATTR_MODE;
1886                 }
1887         }
1888
1889         if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||
1890             ((attrs->ia_valid & ATTR_MODE) && dosattr)) {
1891                 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
1892                 /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */
1893
1894                 /* Even if error on time set, no sense failing the call if
1895                 the server would set the time to a reasonable value anyway,
1896                 and this check ensures that we are not being called from
1897                 sys_utimes in which case we ought to fail the call back to
1898                 the user when the server rejects the call */
1899                 if ((rc) && (attrs->ia_valid &
1900                                 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
1901                         rc = 0;
1902         }
1903
1904         /* do not need local check to inode_check_ok since the server does
1905            that */
1906         if (!rc)
1907                 rc = inode_setattr(inode, attrs);
1908 cifs_setattr_exit:
1909         kfree(full_path);
1910         FreeXid(xid);
1911         return rc;
1912 }
1913
1914 int
1915 cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1916 {
1917         struct inode *inode = direntry->d_inode;
1918         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1919         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1920
1921         if (pTcon->unix_ext)
1922                 return cifs_setattr_unix(direntry, attrs);
1923
1924         return cifs_setattr_nounix(direntry, attrs);
1925
1926         /* BB: add cifs_setattr_legacy for really old servers */
1927 }
1928
1929 #if 0
1930 void cifs_delete_inode(struct inode *inode)
1931 {
1932         cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
1933         /* may have to add back in if and when safe distributed caching of
1934            directories added e.g. via FindNotify */
1935 }
1936 #endif