dm table: pass correct dev area size to device_area_is_valid
[pandora-kernel.git] / fs / cifs / inode.c
1 /*
2  *   fs/cifs/inode.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2008
5  *   Author(s): Steve French (sfrench@us.ibm.com)
6  *
7  *   This library is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU Lesser General Public License as published
9  *   by the Free Software Foundation; either version 2.1 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This library is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
15  *   the GNU Lesser General Public License for more details.
16  *
17  *   You should have received a copy of the GNU Lesser General Public License
18  *   along with this library; if not, write to the Free Software
19  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 #include <linux/fs.h>
22 #include <linux/stat.h>
23 #include <linux/pagemap.h>
24 #include <asm/div64.h>
25 #include "cifsfs.h"
26 #include "cifspdu.h"
27 #include "cifsglob.h"
28 #include "cifsproto.h"
29 #include "cifs_debug.h"
30 #include "cifs_fs_sb.h"
31
32
33 static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
34 {
35         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
36
37         switch (inode->i_mode & S_IFMT) {
38         case S_IFREG:
39                 inode->i_op = &cifs_file_inode_ops;
40                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
41                         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
42                                 inode->i_fop = &cifs_file_direct_nobrl_ops;
43                         else
44                                 inode->i_fop = &cifs_file_direct_ops;
45                 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
46                         inode->i_fop = &cifs_file_nobrl_ops;
47                 else { /* not direct, send byte range locks */
48                         inode->i_fop = &cifs_file_ops;
49                 }
50
51
52                 /* check if server can support readpages */
53                 if (cifs_sb->tcon->ses->server->maxBuf <
54                                 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
55                         inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
56                 else
57                         inode->i_data.a_ops = &cifs_addr_ops;
58                 break;
59         case S_IFDIR:
60 #ifdef CONFIG_CIFS_DFS_UPCALL
61                 if (is_dfs_referral) {
62                         inode->i_op = &cifs_dfs_referral_inode_operations;
63                 } else {
64 #else /* NO DFS support, treat as a directory */
65                 {
66 #endif
67                         inode->i_op = &cifs_dir_inode_ops;
68                         inode->i_fop = &cifs_dir_ops;
69                 }
70                 break;
71         case S_IFLNK:
72                 inode->i_op = &cifs_symlink_inode_ops;
73                 break;
74         default:
75                 init_special_inode(inode, inode->i_mode, inode->i_rdev);
76                 break;
77         }
78 }
79
80 /* populate an inode with info from a cifs_fattr struct */
81 void
82 cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
83 {
84         struct cifsInodeInfo *cifs_i = CIFS_I(inode);
85         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
86         unsigned long oldtime = cifs_i->time;
87
88         inode->i_atime = fattr->cf_atime;
89         inode->i_mtime = fattr->cf_mtime;
90         inode->i_ctime = fattr->cf_ctime;
91         inode->i_rdev = fattr->cf_rdev;
92         inode->i_nlink = fattr->cf_nlink;
93         inode->i_uid = fattr->cf_uid;
94         inode->i_gid = fattr->cf_gid;
95
96         /* if dynperm is set, don't clobber existing mode */
97         if (inode->i_state & I_NEW ||
98             !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
99                 inode->i_mode = fattr->cf_mode;
100
101         cifs_i->cifsAttrs = fattr->cf_cifsattrs;
102         cifs_i->uniqueid = fattr->cf_uniqueid;
103
104         if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
105                 cifs_i->time = 0;
106         else
107                 cifs_i->time = jiffies;
108
109         cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode,
110                  oldtime, cifs_i->time));
111
112         cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
113
114         /*
115          * Can't safely change the file size here if the client is writing to
116          * it due to potential races.
117          */
118         spin_lock(&inode->i_lock);
119         if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
120                 i_size_write(inode, fattr->cf_eof);
121
122                 /*
123                  * i_blocks is not related to (i_size / i_blksize),
124                  * but instead 512 byte (2**9) size is required for
125                  * calculating num blocks.
126                  */
127                 inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
128         }
129         spin_unlock(&inode->i_lock);
130
131         cifs_set_ops(inode, fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL);
132 }
133
134 /* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
135 void
136 cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
137                          struct cifs_sb_info *cifs_sb)
138 {
139         memset(fattr, 0, sizeof(*fattr));
140         fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
141         fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
142         fattr->cf_eof = le64_to_cpu(info->EndOfFile);
143
144         fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
145         fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
146         fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
147         fattr->cf_mode = le64_to_cpu(info->Permissions);
148
149         /*
150          * Since we set the inode type below we need to mask off
151          * to avoid strange results if bits set above.
152          */
153         fattr->cf_mode &= ~S_IFMT;
154         switch (le32_to_cpu(info->Type)) {
155         case UNIX_FILE:
156                 fattr->cf_mode |= S_IFREG;
157                 fattr->cf_dtype = DT_REG;
158                 break;
159         case UNIX_SYMLINK:
160                 fattr->cf_mode |= S_IFLNK;
161                 fattr->cf_dtype = DT_LNK;
162                 break;
163         case UNIX_DIR:
164                 fattr->cf_mode |= S_IFDIR;
165                 fattr->cf_dtype = DT_DIR;
166                 break;
167         case UNIX_CHARDEV:
168                 fattr->cf_mode |= S_IFCHR;
169                 fattr->cf_dtype = DT_CHR;
170                 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
171                                        le64_to_cpu(info->DevMinor) & MINORMASK);
172                 break;
173         case UNIX_BLOCKDEV:
174                 fattr->cf_mode |= S_IFBLK;
175                 fattr->cf_dtype = DT_BLK;
176                 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
177                                        le64_to_cpu(info->DevMinor) & MINORMASK);
178                 break;
179         case UNIX_FIFO:
180                 fattr->cf_mode |= S_IFIFO;
181                 fattr->cf_dtype = DT_FIFO;
182                 break;
183         case UNIX_SOCKET:
184                 fattr->cf_mode |= S_IFSOCK;
185                 fattr->cf_dtype = DT_SOCK;
186                 break;
187         default:
188                 /* safest to call it a file if we do not know */
189                 fattr->cf_mode |= S_IFREG;
190                 fattr->cf_dtype = DT_REG;
191                 cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
192                 break;
193         }
194
195         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
196                 fattr->cf_uid = cifs_sb->mnt_uid;
197         else
198                 fattr->cf_uid = le64_to_cpu(info->Uid);
199
200         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
201                 fattr->cf_gid = cifs_sb->mnt_gid;
202         else
203                 fattr->cf_gid = le64_to_cpu(info->Gid);
204
205         fattr->cf_nlink = le64_to_cpu(info->Nlinks);
206 }
207
208 /*
209  * Fill a cifs_fattr struct with fake inode info.
210  *
211  * Needed to setup cifs_fattr data for the directory which is the
212  * junction to the new submount (ie to setup the fake directory
213  * which represents a DFS referral).
214  */
215 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 void
392 cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
393                        struct cifs_sb_info *cifs_sb, bool adjust_tz)
394 {
395         memset(fattr, 0, sizeof(*fattr));
396         fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
397         if (info->DeletePending)
398                 fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;
399
400         if (info->LastAccessTime)
401                 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
402         else
403                 fattr->cf_atime = CURRENT_TIME;
404
405         fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
406         fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
407
408         if (adjust_tz) {
409                 fattr->cf_ctime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
410                 fattr->cf_mtime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
411         }
412
413         fattr->cf_eof = le64_to_cpu(info->EndOfFile);
414         fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
415
416         if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
417                 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
418                 fattr->cf_dtype = DT_DIR;
419         } else {
420                 fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
421                 fattr->cf_dtype = DT_REG;
422
423                 /* clear write bits if ATTR_READONLY is set */
424                 if (fattr->cf_cifsattrs & ATTR_READONLY)
425                         fattr->cf_mode &= ~(S_IWUGO);
426         }
427
428         fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
429
430         fattr->cf_uid = cifs_sb->mnt_uid;
431         fattr->cf_gid = cifs_sb->mnt_gid;
432 }
433
434 int cifs_get_inode_info(struct inode **pinode,
435         const unsigned char *full_path, FILE_ALL_INFO *pfindData,
436         struct super_block *sb, int xid, const __u16 *pfid)
437 {
438         int rc = 0, tmprc;
439         struct cifsTconInfo *pTcon;
440         struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
441         char *buf = NULL;
442         bool adjustTZ = false;
443         struct cifs_fattr fattr;
444
445         pTcon = cifs_sb->tcon;
446         cFYI(1, ("Getting info on %s", full_path));
447
448         if ((pfindData == NULL) && (*pinode != NULL)) {
449                 if (CIFS_I(*pinode)->clientCanCacheRead) {
450                         cFYI(1, ("No need to revalidate cached inode sizes"));
451                         return rc;
452                 }
453         }
454
455         /* if file info not passed in then get it from server */
456         if (pfindData == NULL) {
457                 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
458                 if (buf == NULL)
459                         return -ENOMEM;
460                 pfindData = (FILE_ALL_INFO *)buf;
461
462                 /* could do find first instead but this returns more info */
463                 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
464                               0 /* not legacy */,
465                               cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
466                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
467                 /* BB optimize code so we do not make the above call
468                 when server claims no NT SMB support and the above call
469                 failed at least once - set flag in tcon or mount */
470                 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
471                         rc = SMBQueryInformation(xid, pTcon, full_path,
472                                         pfindData, cifs_sb->local_nls,
473                                         cifs_sb->mnt_cifs_flags &
474                                           CIFS_MOUNT_MAP_SPECIAL_CHR);
475                         adjustTZ = true;
476                 }
477         }
478
479         if (!rc) {
480                 cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
481                                        cifs_sb, adjustTZ);
482         } else if (rc == -EREMOTE) {
483                 cifs_create_dfs_fattr(&fattr, sb);
484                 rc = 0;
485         } else {
486                 goto cgii_exit;
487         }
488
489         /*
490          * If an inode wasn't passed in, then get the inode number
491          *
492          * Is an i_ino of zero legal? Can we use that to check if the server
493          * supports returning inode numbers?  Are there other sanity checks we
494          * can use to ensure that the server is really filling in that field?
495          *
496          * We can not use the IndexNumber field by default from Windows or
497          * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA
498          * CIFS spec claims that this value is unique within the scope of a
499          * share, and the windows docs hint that it's actually unique
500          * per-machine.
501          *
502          * There may be higher info levels that work but are there Windows
503          * server or network appliances for which IndexNumber field is not
504          * guaranteed unique?
505          */
506         if (*pinode == NULL) {
507                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
508                         int rc1 = 0;
509
510                         rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
511                                         full_path, &fattr.cf_uniqueid,
512                                         cifs_sb->local_nls,
513                                         cifs_sb->mnt_cifs_flags &
514                                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
515                         if (rc1) {
516                                 /* BB EOPNOSUPP disable SERVER_INUM? */
517                                 cFYI(1, ("GetSrvInodeNum rc %d", rc1));
518                                 fattr.cf_uniqueid = iunique(sb, ROOT_I);
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                 atomic_dec(&open_file->wrtPending);
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 EACESS
918  * but will return the EACESS 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         struct address_space *mapping = inode->i_mapping;
1558         unsigned long limit;
1559
1560         spin_lock(&inode->i_lock);
1561         if (inode->i_size < offset)
1562                 goto do_expand;
1563         /*
1564          * truncation of in-use swapfiles is disallowed - it would cause
1565          * subsequent swapout to scribble on the now-freed blocks.
1566          */
1567         if (IS_SWAPFILE(inode)) {
1568                 spin_unlock(&inode->i_lock);
1569                 goto out_busy;
1570         }
1571         i_size_write(inode, offset);
1572         spin_unlock(&inode->i_lock);
1573         /*
1574          * unmap_mapping_range is called twice, first simply for efficiency
1575          * so that truncate_inode_pages does fewer single-page unmaps. However
1576          * after this first call, and before truncate_inode_pages finishes,
1577          * it is possible for private pages to be COWed, which remain after
1578          * truncate_inode_pages finishes, hence the second unmap_mapping_range
1579          * call must be made for correctness.
1580          */
1581         unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1582         truncate_inode_pages(mapping, offset);
1583         unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
1584         goto out_truncate;
1585
1586 do_expand:
1587         limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
1588         if (limit != RLIM_INFINITY && offset > limit) {
1589                 spin_unlock(&inode->i_lock);
1590                 goto out_sig;
1591         }
1592         if (offset > inode->i_sb->s_maxbytes) {
1593                 spin_unlock(&inode->i_lock);
1594                 goto out_big;
1595         }
1596         i_size_write(inode, offset);
1597         spin_unlock(&inode->i_lock);
1598 out_truncate:
1599         if (inode->i_op->truncate)
1600                 inode->i_op->truncate(inode);
1601         return 0;
1602 out_sig:
1603         send_sig(SIGXFSZ, current, 0);
1604 out_big:
1605         return -EFBIG;
1606 out_busy:
1607         return -ETXTBSY;
1608 }
1609
1610 static int
1611 cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1612                    int xid, char *full_path)
1613 {
1614         int rc;
1615         struct cifsFileInfo *open_file;
1616         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1617         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1618         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1619
1620         /*
1621          * To avoid spurious oplock breaks from server, in the case of
1622          * inodes that we already have open, avoid doing path based
1623          * setting of file size if we can do it by handle.
1624          * This keeps our caching token (oplock) and avoids timeouts
1625          * when the local oplock break takes longer to flush
1626          * writebehind data than the SMB timeout for the SetPathInfo
1627          * request would allow
1628          */
1629         open_file = find_writable_file(cifsInode);
1630         if (open_file) {
1631                 __u16 nfid = open_file->netfid;
1632                 __u32 npid = open_file->pid;
1633                 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1634                                         npid, false);
1635                 atomic_dec(&open_file->wrtPending);
1636                 cFYI(1, ("SetFSize for attrs rc = %d", rc));
1637                 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1638                         unsigned int bytes_written;
1639                         rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
1640                                           &bytes_written, NULL, NULL, 1);
1641                         cFYI(1, ("Wrt seteof rc %d", rc));
1642                 }
1643         } else
1644                 rc = -EINVAL;
1645
1646         if (rc != 0) {
1647                 /* Set file size by pathname rather than by handle
1648                    either because no valid, writeable file handle for
1649                    it was found or because there was an error setting
1650                    it by handle */
1651                 rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,
1652                                    false, cifs_sb->local_nls,
1653                                    cifs_sb->mnt_cifs_flags &
1654                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1655                 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1656                 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1657                         __u16 netfid;
1658                         int oplock = 0;
1659
1660                         rc = SMBLegacyOpen(xid, pTcon, full_path,
1661                                 FILE_OPEN, GENERIC_WRITE,
1662                                 CREATE_NOT_DIR, &netfid, &oplock, NULL,
1663                                 cifs_sb->local_nls,
1664                                 cifs_sb->mnt_cifs_flags &
1665                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1666                         if (rc == 0) {
1667                                 unsigned int bytes_written;
1668                                 rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
1669                                                   attrs->ia_size,
1670                                                   &bytes_written, NULL,
1671                                                   NULL, 1);
1672                                 cFYI(1, ("wrt seteof rc %d", rc));
1673                                 CIFSSMBClose(xid, pTcon, netfid);
1674                         }
1675                 }
1676         }
1677
1678         if (rc == 0) {
1679                 cifsInode->server_eof = attrs->ia_size;
1680                 rc = cifs_vmtruncate(inode, attrs->ia_size);
1681                 cifs_truncate_page(inode->i_mapping, inode->i_size);
1682         }
1683
1684         return rc;
1685 }
1686
1687 static int
1688 cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1689 {
1690         int rc;
1691         int xid;
1692         char *full_path = NULL;
1693         struct inode *inode = direntry->d_inode;
1694         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1695         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1696         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1697         struct cifs_unix_set_info_args *args = NULL;
1698         struct cifsFileInfo *open_file;
1699
1700         cFYI(1, ("setattr_unix on file %s attrs->ia_valid=0x%x",
1701                  direntry->d_name.name, attrs->ia_valid));
1702
1703         xid = GetXid();
1704
1705         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1706                 /* check if we have permission to change attrs */
1707                 rc = inode_change_ok(inode, attrs);
1708                 if (rc < 0)
1709                         goto out;
1710                 else
1711                         rc = 0;
1712         }
1713
1714         full_path = build_path_from_dentry(direntry);
1715         if (full_path == NULL) {
1716                 rc = -ENOMEM;
1717                 goto out;
1718         }
1719
1720         /*
1721          * Attempt to flush data before changing attributes. We need to do
1722          * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1723          * ownership or mode then we may also need to do this. Here, we take
1724          * the safe way out and just do the flush on all setattr requests. If
1725          * the flush returns error, store it to report later and continue.
1726          *
1727          * BB: This should be smarter. Why bother flushing pages that
1728          * will be truncated anyway? Also, should we error out here if
1729          * the flush returns error?
1730          */
1731         rc = filemap_write_and_wait(inode->i_mapping);
1732         if (rc != 0) {
1733                 cifsInode->write_behind_rc = rc;
1734                 rc = 0;
1735         }
1736
1737         if (attrs->ia_valid & ATTR_SIZE) {
1738                 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1739                 if (rc != 0)
1740                         goto out;
1741         }
1742
1743         /* skip mode change if it's just for clearing setuid/setgid */
1744         if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1745                 attrs->ia_valid &= ~ATTR_MODE;
1746
1747         args = kmalloc(sizeof(*args), GFP_KERNEL);
1748         if (args == NULL) {
1749                 rc = -ENOMEM;
1750                 goto out;
1751         }
1752
1753         /* set up the struct */
1754         if (attrs->ia_valid & ATTR_MODE)
1755                 args->mode = attrs->ia_mode;
1756         else
1757                 args->mode = NO_CHANGE_64;
1758
1759         if (attrs->ia_valid & ATTR_UID)
1760                 args->uid = attrs->ia_uid;
1761         else
1762                 args->uid = NO_CHANGE_64;
1763
1764         if (attrs->ia_valid & ATTR_GID)
1765                 args->gid = attrs->ia_gid;
1766         else
1767                 args->gid = NO_CHANGE_64;
1768
1769         if (attrs->ia_valid & ATTR_ATIME)
1770                 args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
1771         else
1772                 args->atime = NO_CHANGE_64;
1773
1774         if (attrs->ia_valid & ATTR_MTIME)
1775                 args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
1776         else
1777                 args->mtime = NO_CHANGE_64;
1778
1779         if (attrs->ia_valid & ATTR_CTIME)
1780                 args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
1781         else
1782                 args->ctime = NO_CHANGE_64;
1783
1784         args->device = 0;
1785         open_file = find_writable_file(cifsInode);
1786         if (open_file) {
1787                 u16 nfid = open_file->netfid;
1788                 u32 npid = open_file->pid;
1789                 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
1790                 atomic_dec(&open_file->wrtPending);
1791         } else {
1792                 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
1793                                     cifs_sb->local_nls,
1794                                     cifs_sb->mnt_cifs_flags &
1795                                         CIFS_MOUNT_MAP_SPECIAL_CHR);
1796         }
1797
1798         if (!rc)
1799                 rc = inode_setattr(inode, attrs);
1800 out:
1801         kfree(args);
1802         kfree(full_path);
1803         FreeXid(xid);
1804         return rc;
1805 }
1806
1807 static int
1808 cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
1809 {
1810         int xid;
1811         struct inode *inode = direntry->d_inode;
1812         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1813         struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1814         char *full_path = NULL;
1815         int rc = -EACCES;
1816         __u32 dosattr = 0;
1817         __u64 mode = NO_CHANGE_64;
1818
1819         xid = GetXid();
1820
1821         cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
1822                  direntry->d_name.name, attrs->ia_valid));
1823
1824         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1825                 /* check if we have permission to change attrs */
1826                 rc = inode_change_ok(inode, attrs);
1827                 if (rc < 0) {
1828                         FreeXid(xid);
1829                         return rc;
1830                 } else
1831                         rc = 0;
1832         }
1833
1834         full_path = build_path_from_dentry(direntry);
1835         if (full_path == NULL) {
1836                 rc = -ENOMEM;
1837                 FreeXid(xid);
1838                 return rc;
1839         }
1840
1841         /*
1842          * Attempt to flush data before changing attributes. We need to do
1843          * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1844          * ownership or mode then we may also need to do this. Here, we take
1845          * the safe way out and just do the flush on all setattr requests. If
1846          * the flush returns error, store it to report later and continue.
1847          *
1848          * BB: This should be smarter. Why bother flushing pages that
1849          * will be truncated anyway? Also, should we error out here if
1850          * the flush returns error?
1851          */
1852         rc = filemap_write_and_wait(inode->i_mapping);
1853         if (rc != 0) {
1854                 cifsInode->write_behind_rc = rc;
1855                 rc = 0;
1856         }
1857
1858         if (attrs->ia_valid & ATTR_SIZE) {
1859                 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1860                 if (rc != 0)
1861                         goto cifs_setattr_exit;
1862         }
1863
1864         /*
1865          * Without unix extensions we can't send ownership changes to the
1866          * server, so silently ignore them. This is consistent with how
1867          * local DOS/Windows filesystems behave (VFAT, NTFS, etc). With
1868          * CIFSACL support + proper Windows to Unix idmapping, we may be
1869          * able to support this in the future.
1870          */
1871         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
1872                 attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
1873
1874         /* skip mode change if it's just for clearing setuid/setgid */
1875         if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1876                 attrs->ia_valid &= ~ATTR_MODE;
1877
1878         if (attrs->ia_valid & ATTR_MODE) {
1879                 cFYI(1, ("Mode changed to 0%o", attrs->ia_mode));
1880                 mode = attrs->ia_mode;
1881         }
1882
1883         if (attrs->ia_valid & ATTR_MODE) {
1884                 rc = 0;
1885 #ifdef CONFIG_CIFS_EXPERIMENTAL
1886                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1887                         rc = mode_to_acl(inode, full_path, mode);
1888                 else
1889 #endif
1890                 if (((mode & S_IWUGO) == 0) &&
1891                     (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1892
1893                         dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
1894
1895                         /* fix up mode if we're not using dynperm */
1896                         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
1897                                 attrs->ia_mode = inode->i_mode & ~S_IWUGO;
1898                 } else if ((mode & S_IWUGO) &&
1899                            (cifsInode->cifsAttrs & ATTR_READONLY)) {
1900
1901                         dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
1902                         /* Attributes of 0 are ignored */
1903                         if (dosattr == 0)
1904                                 dosattr |= ATTR_NORMAL;
1905
1906                         /* reset local inode permissions to normal */
1907                         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1908                                 attrs->ia_mode &= ~(S_IALLUGO);
1909                                 if (S_ISDIR(inode->i_mode))
1910                                         attrs->ia_mode |=
1911                                                 cifs_sb->mnt_dir_mode;
1912                                 else
1913                                         attrs->ia_mode |=
1914                                                 cifs_sb->mnt_file_mode;
1915                         }
1916                 } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1917                         /* ignore mode change - ATTR_READONLY hasn't changed */
1918                         attrs->ia_valid &= ~ATTR_MODE;
1919                 }
1920         }
1921
1922         if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||
1923             ((attrs->ia_valid & ATTR_MODE) && dosattr)) {
1924                 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
1925                 /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */
1926
1927                 /* Even if error on time set, no sense failing the call if
1928                 the server would set the time to a reasonable value anyway,
1929                 and this check ensures that we are not being called from
1930                 sys_utimes in which case we ought to fail the call back to
1931                 the user when the server rejects the call */
1932                 if ((rc) && (attrs->ia_valid &
1933                                 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
1934                         rc = 0;
1935         }
1936
1937         /* do not need local check to inode_check_ok since the server does
1938            that */
1939         if (!rc)
1940                 rc = inode_setattr(inode, attrs);
1941 cifs_setattr_exit:
1942         kfree(full_path);
1943         FreeXid(xid);
1944         return rc;
1945 }
1946
1947 int
1948 cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1949 {
1950         struct inode *inode = direntry->d_inode;
1951         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1952         struct cifsTconInfo *pTcon = cifs_sb->tcon;
1953
1954         if (pTcon->unix_ext)
1955                 return cifs_setattr_unix(direntry, attrs);
1956
1957         return cifs_setattr_nounix(direntry, attrs);
1958
1959         /* BB: add cifs_setattr_legacy for really old servers */
1960 }
1961
1962 #if 0
1963 void cifs_delete_inode(struct inode *inode)
1964 {
1965         cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
1966         /* may have to add back in if and when safe distributed caching of
1967            directories added e.g. via FindNotify */
1968 }
1969 #endif