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