]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - fs/cifs/inode.c
CIFS: Fix error handling in cifs_readv_complete
[mirror_ubuntu-artful-kernel.git] / fs / cifs / inode.c
CommitLineData
1da177e4
LT
1/*
2 * fs/cifs/inode.c
3 *
f19159dc 4 * Copyright (C) International Business Machines Corp., 2002,2010
1da177e4
LT
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>
1da177e4 22#include <linux/stat.h>
5a0e3ad6 23#include <linux/slab.h>
1da177e4
LT
24#include <linux/pagemap.h>
25#include <asm/div64.h>
26#include "cifsfs.h"
27#include "cifspdu.h"
28#include "cifsglob.h"
29#include "cifsproto.h"
30#include "cifs_debug.h"
31#include "cifs_fs_sb.h"
9451a9a5 32#include "fscache.h"
1da177e4 33
70eff55d 34
01c64fea 35static void cifs_set_ops(struct inode *inode)
70eff55d
CH
36{
37 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
38
39 switch (inode->i_mode & S_IFMT) {
40 case S_IFREG:
41 inode->i_op = &cifs_file_inode_ops;
42 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
43 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
44 inode->i_fop = &cifs_file_direct_nobrl_ops;
45 else
46 inode->i_fop = &cifs_file_direct_ops;
8be7e6ba
PS
47 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
48 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
49 inode->i_fop = &cifs_file_strict_nobrl_ops;
50 else
51 inode->i_fop = &cifs_file_strict_ops;
70eff55d
CH
52 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
53 inode->i_fop = &cifs_file_nobrl_ops;
54 else { /* not direct, send byte range locks */
55 inode->i_fop = &cifs_file_ops;
56 }
57
70eff55d 58 /* check if server can support readpages */
0d424ad0 59 if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <
70eff55d
CH
60 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
61 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
62 else
63 inode->i_data.a_ops = &cifs_addr_ops;
64 break;
65 case S_IFDIR:
bc5b6e24 66#ifdef CONFIG_CIFS_DFS_UPCALL
01c64fea 67 if (IS_AUTOMOUNT(inode)) {
7962670e
IM
68 inode->i_op = &cifs_dfs_referral_inode_operations;
69 } else {
bc5b6e24
SF
70#else /* NO DFS support, treat as a directory */
71 {
72#endif
7962670e
IM
73 inode->i_op = &cifs_dir_inode_ops;
74 inode->i_fop = &cifs_dir_ops;
75 }
70eff55d
CH
76 break;
77 case S_IFLNK:
78 inode->i_op = &cifs_symlink_inode_ops;
79 break;
80 default:
81 init_special_inode(inode, inode->i_mode, inode->i_rdev);
82 break;
83 }
84}
85
df2cf170
JL
86/* check inode attributes against fattr. If they don't match, tag the
87 * inode for cache invalidation
88 */
89static void
90cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
91{
92 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
93
f19159dc 94 cFYI(1, "%s: revalidating inode %llu", __func__, cifs_i->uniqueid);
df2cf170
JL
95
96 if (inode->i_state & I_NEW) {
f19159dc 97 cFYI(1, "%s: inode %llu is new", __func__, cifs_i->uniqueid);
df2cf170
JL
98 return;
99 }
100
101 /* don't bother with revalidation if we have an oplock */
102 if (cifs_i->clientCanCacheRead) {
f19159dc
SF
103 cFYI(1, "%s: inode %llu is oplocked", __func__,
104 cifs_i->uniqueid);
df2cf170
JL
105 return;
106 }
107
108 /* revalidate if mtime or size have changed */
109 if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
110 cifs_i->server_eof == fattr->cf_eof) {
f19159dc
SF
111 cFYI(1, "%s: inode %llu is unchanged", __func__,
112 cifs_i->uniqueid);
df2cf170
JL
113 return;
114 }
115
f19159dc
SF
116 cFYI(1, "%s: invalidating inode %llu mapping", __func__,
117 cifs_i->uniqueid);
df2cf170
JL
118 cifs_i->invalid_mapping = true;
119}
120
cc0bad75
JL
121/* populate an inode with info from a cifs_fattr struct */
122void
123cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
75f12983 124{
cc0bad75 125 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
0b8f18e3
JL
126 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
127 unsigned long oldtime = cifs_i->time;
cc0bad75 128
df2cf170
JL
129 cifs_revalidate_cache(inode, fattr);
130
cc0bad75
JL
131 inode->i_atime = fattr->cf_atime;
132 inode->i_mtime = fattr->cf_mtime;
133 inode->i_ctime = fattr->cf_ctime;
cc0bad75
JL
134 inode->i_rdev = fattr->cf_rdev;
135 inode->i_nlink = fattr->cf_nlink;
136 inode->i_uid = fattr->cf_uid;
137 inode->i_gid = fattr->cf_gid;
138
0b8f18e3
JL
139 /* if dynperm is set, don't clobber existing mode */
140 if (inode->i_state & I_NEW ||
141 !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
142 inode->i_mode = fattr->cf_mode;
143
cc0bad75 144 cifs_i->cifsAttrs = fattr->cf_cifsattrs;
75f12983 145
0b8f18e3
JL
146 if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
147 cifs_i->time = 0;
148 else
149 cifs_i->time = jiffies;
150
b6b38f70
JP
151 cFYI(1, "inode 0x%p old_time=%ld new_time=%ld", inode,
152 oldtime, cifs_i->time);
0b8f18e3
JL
153
154 cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
cc0bad75 155
835a36ca 156 cifs_i->server_eof = fattr->cf_eof;
cc0bad75
JL
157 /*
158 * Can't safely change the file size here if the client is writing to
159 * it due to potential races.
160 */
161 spin_lock(&inode->i_lock);
162 if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
163 i_size_write(inode, fattr->cf_eof);
164
165 /*
166 * i_blocks is not related to (i_size / i_blksize),
167 * but instead 512 byte (2**9) size is required for
168 * calculating num blocks.
169 */
170 inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
171 }
172 spin_unlock(&inode->i_lock);
173
01c64fea
DH
174 if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL)
175 inode->i_flags |= S_AUTOMOUNT;
176 cifs_set_ops(inode);
cc0bad75
JL
177}
178
4065c802
JL
179void
180cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr)
181{
182 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
183
184 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
185 return;
186
187 fattr->cf_uniqueid = iunique(sb, ROOT_I);
188}
189
cc0bad75
JL
190/* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
191void
192cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
193 struct cifs_sb_info *cifs_sb)
194{
195 memset(fattr, 0, sizeof(*fattr));
196 fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
197 fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
198 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
199
200 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
201 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
202 fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
203 fattr->cf_mode = le64_to_cpu(info->Permissions);
75f12983
CH
204
205 /*
206 * Since we set the inode type below we need to mask off
207 * to avoid strange results if bits set above.
208 */
cc0bad75 209 fattr->cf_mode &= ~S_IFMT;
75f12983
CH
210 switch (le32_to_cpu(info->Type)) {
211 case UNIX_FILE:
cc0bad75
JL
212 fattr->cf_mode |= S_IFREG;
213 fattr->cf_dtype = DT_REG;
75f12983
CH
214 break;
215 case UNIX_SYMLINK:
cc0bad75
JL
216 fattr->cf_mode |= S_IFLNK;
217 fattr->cf_dtype = DT_LNK;
75f12983
CH
218 break;
219 case UNIX_DIR:
cc0bad75
JL
220 fattr->cf_mode |= S_IFDIR;
221 fattr->cf_dtype = DT_DIR;
75f12983
CH
222 break;
223 case UNIX_CHARDEV:
cc0bad75
JL
224 fattr->cf_mode |= S_IFCHR;
225 fattr->cf_dtype = DT_CHR;
226 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
227 le64_to_cpu(info->DevMinor) & MINORMASK);
75f12983
CH
228 break;
229 case UNIX_BLOCKDEV:
cc0bad75
JL
230 fattr->cf_mode |= S_IFBLK;
231 fattr->cf_dtype = DT_BLK;
232 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
233 le64_to_cpu(info->DevMinor) & MINORMASK);
75f12983
CH
234 break;
235 case UNIX_FIFO:
cc0bad75
JL
236 fattr->cf_mode |= S_IFIFO;
237 fattr->cf_dtype = DT_FIFO;
75f12983
CH
238 break;
239 case UNIX_SOCKET:
cc0bad75
JL
240 fattr->cf_mode |= S_IFSOCK;
241 fattr->cf_dtype = DT_SOCK;
75f12983
CH
242 break;
243 default:
244 /* safest to call it a file if we do not know */
cc0bad75
JL
245 fattr->cf_mode |= S_IFREG;
246 fattr->cf_dtype = DT_REG;
b6b38f70 247 cFYI(1, "unknown type %d", le32_to_cpu(info->Type));
75f12983
CH
248 break;
249 }
250
cc0bad75
JL
251 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
252 fattr->cf_uid = cifs_sb->mnt_uid;
75f12983 253 else
cc0bad75 254 fattr->cf_uid = le64_to_cpu(info->Uid);
75f12983 255
cc0bad75
JL
256 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
257 fattr->cf_gid = cifs_sb->mnt_gid;
75f12983 258 else
cc0bad75 259 fattr->cf_gid = le64_to_cpu(info->Gid);
75f12983 260
cc0bad75 261 fattr->cf_nlink = le64_to_cpu(info->Nlinks);
75f12983
CH
262}
263
b9a3260f 264/*
cc0bad75
JL
265 * Fill a cifs_fattr struct with fake inode info.
266 *
267 * Needed to setup cifs_fattr data for the directory which is the
268 * junction to the new submount (ie to setup the fake directory
269 * which represents a DFS referral).
b9a3260f 270 */
f1230c97 271static void
cc0bad75 272cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
0e4bbde9 273{
cc0bad75 274 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
0e4bbde9 275
b6b38f70 276 cFYI(1, "creating fake fattr for DFS referral");
cc0bad75
JL
277
278 memset(fattr, 0, sizeof(*fattr));
279 fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
280 fattr->cf_uid = cifs_sb->mnt_uid;
281 fattr->cf_gid = cifs_sb->mnt_gid;
282 fattr->cf_atime = CURRENT_TIME;
283 fattr->cf_ctime = CURRENT_TIME;
284 fattr->cf_mtime = CURRENT_TIME;
285 fattr->cf_nlink = 2;
286 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
0e4bbde9
SF
287}
288
abab095d
JL
289int cifs_get_file_info_unix(struct file *filp)
290{
291 int rc;
292 int xid;
293 FILE_UNIX_BASIC_INFO find_data;
294 struct cifs_fattr fattr;
295 struct inode *inode = filp->f_path.dentry->d_inode;
296 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
c21dfb69 297 struct cifsFileInfo *cfile = filp->private_data;
96daf2b0 298 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
abab095d
JL
299
300 xid = GetXid();
301 rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
302 if (!rc) {
303 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
304 } else if (rc == -EREMOTE) {
305 cifs_create_dfs_fattr(&fattr, inode->i_sb);
306 rc = 0;
307 }
308
309 cifs_fattr_to_inode(inode, &fattr);
310 FreeXid(xid);
311 return rc;
312}
313
1da177e4 314int cifs_get_inode_info_unix(struct inode **pinode,
cc0bad75
JL
315 const unsigned char *full_path,
316 struct super_block *sb, int xid)
1da177e4 317{
cc0bad75 318 int rc;
0e4bbde9 319 FILE_UNIX_BASIC_INFO find_data;
cc0bad75 320 struct cifs_fattr fattr;
96daf2b0 321 struct cifs_tcon *tcon;
7ffec372 322 struct tcon_link *tlink;
1da177e4 323 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1da177e4 324
b6b38f70 325 cFYI(1, "Getting info on %s", full_path);
7962670e 326
7ffec372
JL
327 tlink = cifs_sb_tlink(cifs_sb);
328 if (IS_ERR(tlink))
329 return PTR_ERR(tlink);
330 tcon = tlink_tcon(tlink);
331
1da177e4 332 /* could have done a find first instead but this returns more info */
cc0bad75 333 rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
737b758c
SF
334 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
335 CIFS_MOUNT_MAP_SPECIAL_CHR);
7ffec372 336 cifs_put_tlink(tlink);
e911d0cc 337
cc0bad75
JL
338 if (!rc) {
339 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
340 } else if (rc == -EREMOTE) {
341 cifs_create_dfs_fattr(&fattr, sb);
342 rc = 0;
343 } else {
344 return rc;
345 }
1da177e4 346
1b12b9c1
SM
347 /* check for Minshall+French symlinks */
348 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
349 int tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
350 if (tmprc)
351 cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
352 }
353
0e4bbde9 354 if (*pinode == NULL) {
cc0bad75 355 /* get new inode */
4065c802 356 cifs_fill_uniqueid(sb, &fattr);
cc0bad75
JL
357 *pinode = cifs_iget(sb, &fattr);
358 if (!*pinode)
0e4bbde9 359 rc = -ENOMEM;
cc0bad75
JL
360 } else {
361 /* we already have inode, update it */
362 cifs_fattr_to_inode(*pinode, &fattr);
0e4bbde9 363 }
1da177e4 364
1da177e4
LT
365 return rc;
366}
367
0b8f18e3
JL
368static int
369cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
370 struct cifs_sb_info *cifs_sb, int xid)
d6e2f2a4
SF
371{
372 int rc;
4b18f2a9 373 int oplock = 0;
d6e2f2a4 374 __u16 netfid;
7ffec372 375 struct tcon_link *tlink;
96daf2b0 376 struct cifs_tcon *tcon;
d4ffff1f 377 struct cifs_io_parms io_parms;
86c96b4b 378 char buf[24];
d6e2f2a4 379 unsigned int bytes_read;
fb8c4b14 380 char *pbuf;
d6e2f2a4
SF
381
382 pbuf = buf;
383
0b8f18e3
JL
384 fattr->cf_mode &= ~S_IFMT;
385
386 if (fattr->cf_eof == 0) {
387 fattr->cf_mode |= S_IFIFO;
388 fattr->cf_dtype = DT_FIFO;
d6e2f2a4 389 return 0;
0b8f18e3
JL
390 } else if (fattr->cf_eof < 8) {
391 fattr->cf_mode |= S_IFREG;
392 fattr->cf_dtype = DT_REG;
d6e2f2a4
SF
393 return -EINVAL; /* EOPNOTSUPP? */
394 }
50c2f753 395
7ffec372
JL
396 tlink = cifs_sb_tlink(cifs_sb);
397 if (IS_ERR(tlink))
398 return PTR_ERR(tlink);
399 tcon = tlink_tcon(tlink);
400
401 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, GENERIC_READ,
d6e2f2a4
SF
402 CREATE_NOT_DIR, &netfid, &oplock, NULL,
403 cifs_sb->local_nls,
404 cifs_sb->mnt_cifs_flags &
405 CIFS_MOUNT_MAP_SPECIAL_CHR);
fb8c4b14 406 if (rc == 0) {
ec637e3f 407 int buf_type = CIFS_NO_BUFFER;
d6e2f2a4 408 /* Read header */
d4ffff1f
PS
409 io_parms.netfid = netfid;
410 io_parms.pid = current->tgid;
411 io_parms.tcon = tcon;
412 io_parms.offset = 0;
413 io_parms.length = 24;
414 rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf,
415 &buf_type);
4523cc30
SF
416 if ((rc == 0) && (bytes_read >= 8)) {
417 if (memcmp("IntxBLK", pbuf, 8) == 0) {
b6b38f70 418 cFYI(1, "Block device");
0b8f18e3
JL
419 fattr->cf_mode |= S_IFBLK;
420 fattr->cf_dtype = DT_BLK;
4523cc30 421 if (bytes_read == 24) {
86c96b4b
SF
422 /* we have enough to decode dev num */
423 __u64 mjr; /* major */
424 __u64 mnr; /* minor */
425 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
426 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
0b8f18e3 427 fattr->cf_rdev = MKDEV(mjr, mnr);
86c96b4b 428 }
4523cc30 429 } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
b6b38f70 430 cFYI(1, "Char device");
0b8f18e3
JL
431 fattr->cf_mode |= S_IFCHR;
432 fattr->cf_dtype = DT_CHR;
4523cc30 433 if (bytes_read == 24) {
86c96b4b
SF
434 /* we have enough to decode dev num */
435 __u64 mjr; /* major */
436 __u64 mnr; /* minor */
437 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
438 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
0b8f18e3 439 fattr->cf_rdev = MKDEV(mjr, mnr);
fb8c4b14 440 }
4523cc30 441 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
b6b38f70 442 cFYI(1, "Symlink");
0b8f18e3
JL
443 fattr->cf_mode |= S_IFLNK;
444 fattr->cf_dtype = DT_LNK;
86c96b4b 445 } else {
0b8f18e3
JL
446 fattr->cf_mode |= S_IFREG; /* file? */
447 fattr->cf_dtype = DT_REG;
fb8c4b14 448 rc = -EOPNOTSUPP;
86c96b4b 449 }
3020a1f5 450 } else {
0b8f18e3
JL
451 fattr->cf_mode |= S_IFREG; /* then it is a file */
452 fattr->cf_dtype = DT_REG;
fb8c4b14
SF
453 rc = -EOPNOTSUPP; /* or some unknown SFU type */
454 }
7ffec372 455 CIFSSMBClose(xid, tcon, netfid);
d6e2f2a4 456 }
7ffec372 457 cifs_put_tlink(tlink);
d6e2f2a4 458 return rc;
d6e2f2a4
SF
459}
460
9e294f1c
SF
461#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
462
0b8f18e3
JL
463/*
464 * Fetch mode bits as provided by SFU.
465 *
466 * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ?
467 */
468static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
469 struct cifs_sb_info *cifs_sb, int xid)
9e294f1c 470{
3020a1f5 471#ifdef CONFIG_CIFS_XATTR
9e294f1c
SF
472 ssize_t rc;
473 char ea_value[4];
474 __u32 mode;
7ffec372 475 struct tcon_link *tlink;
96daf2b0 476 struct cifs_tcon *tcon;
7ffec372
JL
477
478 tlink = cifs_sb_tlink(cifs_sb);
479 if (IS_ERR(tlink))
480 return PTR_ERR(tlink);
481 tcon = tlink_tcon(tlink);
9e294f1c 482
7ffec372 483 rc = CIFSSMBQAllEAs(xid, tcon, path, "SETFILEBITS",
0b8f18e3
JL
484 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
485 cifs_sb->mnt_cifs_flags &
486 CIFS_MOUNT_MAP_SPECIAL_CHR);
7ffec372 487 cifs_put_tlink(tlink);
4523cc30 488 if (rc < 0)
9e294f1c
SF
489 return (int)rc;
490 else if (rc > 3) {
491 mode = le32_to_cpu(*((__le32 *)ea_value));
0b8f18e3 492 fattr->cf_mode &= ~SFBITS_MASK;
b6b38f70
JP
493 cFYI(1, "special bits 0%o org mode 0%o", mode,
494 fattr->cf_mode);
0b8f18e3 495 fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
b6b38f70 496 cFYI(1, "special mode bits 0%o", mode);
9e294f1c 497 }
0b8f18e3
JL
498
499 return 0;
3020a1f5
SF
500#else
501 return -EOPNOTSUPP;
502#endif
9e294f1c
SF
503}
504
0b8f18e3 505/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
f1230c97 506static void
0b8f18e3
JL
507cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
508 struct cifs_sb_info *cifs_sb, bool adjust_tz)
b9a3260f 509{
96daf2b0 510 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
0d424ad0 511
0b8f18e3
JL
512 memset(fattr, 0, sizeof(*fattr));
513 fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
514 if (info->DeletePending)
515 fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;
516
517 if (info->LastAccessTime)
518 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
519 else
520 fattr->cf_atime = CURRENT_TIME;
521
522 fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
523 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
524
525 if (adjust_tz) {
0d424ad0
JL
526 fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj;
527 fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj;
0b8f18e3
JL
528 }
529
530 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
531 fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
20054bd6 532 fattr->cf_createtime = le64_to_cpu(info->CreationTime);
0b8f18e3
JL
533
534 if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
535 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
536 fattr->cf_dtype = DT_DIR;
537 } else {
538 fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
539 fattr->cf_dtype = DT_REG;
0b8f18e3 540
d0c280d2
JL
541 /* clear write bits if ATTR_READONLY is set */
542 if (fattr->cf_cifsattrs & ATTR_READONLY)
543 fattr->cf_mode &= ~(S_IWUGO);
544 }
0b8f18e3
JL
545
546 fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
547
548 fattr->cf_uid = cifs_sb->mnt_uid;
549 fattr->cf_gid = cifs_sb->mnt_gid;
b9a3260f
SF
550}
551
abab095d
JL
552int cifs_get_file_info(struct file *filp)
553{
554 int rc;
555 int xid;
556 FILE_ALL_INFO find_data;
557 struct cifs_fattr fattr;
558 struct inode *inode = filp->f_path.dentry->d_inode;
559 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
c21dfb69 560 struct cifsFileInfo *cfile = filp->private_data;
96daf2b0 561 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
abab095d
JL
562
563 xid = GetXid();
564 rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
565 if (rc == -EOPNOTSUPP || rc == -EINVAL) {
566 /*
567 * FIXME: legacy server -- fall back to path-based call?
ff215713
SF
568 * for now, just skip revalidating and mark inode for
569 * immediate reval.
570 */
abab095d
JL
571 rc = 0;
572 CIFS_I(inode)->time = 0;
573 goto cgfi_exit;
574 } else if (rc == -EREMOTE) {
575 cifs_create_dfs_fattr(&fattr, inode->i_sb);
576 rc = 0;
577 } else if (rc)
578 goto cgfi_exit;
579
580 /*
581 * don't bother with SFU junk here -- just mark inode as needing
582 * revalidation.
583 */
584 cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
585 fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
586 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
587 cifs_fattr_to_inode(inode, &fattr);
588cgfi_exit:
589 FreeXid(xid);
590 return rc;
591}
592
1da177e4 593int cifs_get_inode_info(struct inode **pinode,
646dd539 594 const unsigned char *full_path, FILE_ALL_INFO *pfindData,
8b1327f6 595 struct super_block *sb, int xid, const __u16 *pfid)
1da177e4 596{
0b8f18e3 597 int rc = 0, tmprc;
96daf2b0 598 struct cifs_tcon *pTcon;
7ffec372 599 struct tcon_link *tlink;
1da177e4 600 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1da177e4 601 char *buf = NULL;
5ade9dea 602 bool adjustTZ = false;
0b8f18e3 603 struct cifs_fattr fattr;
1da177e4 604
7ffec372
JL
605 tlink = cifs_sb_tlink(cifs_sb);
606 if (IS_ERR(tlink))
607 return PTR_ERR(tlink);
608 pTcon = tlink_tcon(tlink);
609
b6b38f70 610 cFYI(1, "Getting info on %s", full_path);
1da177e4 611
d0d2f2df
SF
612 if ((pfindData == NULL) && (*pinode != NULL)) {
613 if (CIFS_I(*pinode)->clientCanCacheRead) {
b6b38f70 614 cFYI(1, "No need to revalidate cached inode sizes");
7ffec372 615 goto cgii_exit;
1da177e4
LT
616 }
617 }
618
619 /* if file info not passed in then get it from server */
d0d2f2df 620 if (pfindData == NULL) {
1da177e4 621 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
7ffec372
JL
622 if (buf == NULL) {
623 rc = -ENOMEM;
624 goto cgii_exit;
625 }
1da177e4 626 pfindData = (FILE_ALL_INFO *)buf;
7962670e 627
1da177e4 628 /* could do find first instead but this returns more info */
7962670e 629 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
acf1a1b1 630 0 /* not legacy */,
6b8edfe0 631 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
737b758c 632 CIFS_MOUNT_MAP_SPECIAL_CHR);
6b8edfe0
SF
633 /* BB optimize code so we do not make the above call
634 when server claims no NT SMB support and the above call
635 failed at least once - set flag in tcon or mount */
4523cc30 636 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
7962670e 637 rc = SMBQueryInformation(xid, pTcon, full_path,
fb8c4b14 638 pfindData, cifs_sb->local_nls,
6b8edfe0
SF
639 cifs_sb->mnt_cifs_flags &
640 CIFS_MOUNT_MAP_SPECIAL_CHR);
4b18f2a9 641 adjustTZ = true;
6b8edfe0 642 }
1da177e4 643 }
0b8f18e3
JL
644
645 if (!rc) {
646 cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
647 cifs_sb, adjustTZ);
648 } else if (rc == -EREMOTE) {
649 cifs_create_dfs_fattr(&fattr, sb);
b9a3260f 650 rc = 0;
0b8f18e3 651 } else {
7962670e 652 goto cgii_exit;
0b8f18e3 653 }
1da177e4 654
0b8f18e3
JL
655 /*
656 * If an inode wasn't passed in, then get the inode number
657 *
658 * Is an i_ino of zero legal? Can we use that to check if the server
659 * supports returning inode numbers? Are there other sanity checks we
660 * can use to ensure that the server is really filling in that field?
661 *
662 * We can not use the IndexNumber field by default from Windows or
663 * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA
664 * CIFS spec claims that this value is unique within the scope of a
665 * share, and the windows docs hint that it's actually unique
666 * per-machine.
667 *
668 * There may be higher info levels that work but are there Windows
669 * server or network appliances for which IndexNumber field is not
670 * guaranteed unique?
671 */
b9a3260f 672 if (*pinode == NULL) {
b9a3260f
SF
673 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
674 int rc1 = 0;
b9a3260f
SF
675
676 rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
0b8f18e3 677 full_path, &fattr.cf_uniqueid,
737b758c
SF
678 cifs_sb->local_nls,
679 cifs_sb->mnt_cifs_flags &
680 CIFS_MOUNT_MAP_SPECIAL_CHR);
ec06aedd 681 if (rc1 || !fattr.cf_uniqueid) {
b6b38f70 682 cFYI(1, "GetSrvInodeNum rc %d", rc1);
0b8f18e3 683 fattr.cf_uniqueid = iunique(sb, ROOT_I);
ec06aedd 684 cifs_autodisable_serverino(cifs_sb);
132ac7b7 685 }
132ac7b7 686 } else {
0b8f18e3 687 fattr.cf_uniqueid = iunique(sb, ROOT_I);
132ac7b7 688 }
b9a3260f 689 } else {
0b8f18e3 690 fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
b9a3260f
SF
691 }
692
0b8f18e3
JL
693 /* query for SFU type info if supported and needed */
694 if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
695 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
696 tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
697 if (tmprc)
b6b38f70 698 cFYI(1, "cifs_sfu_type failed: %d", tmprc);
b9a3260f 699 }
1da177e4 700
79df1bae 701#ifdef CONFIG_CIFS_ACL
b9a3260f
SF
702 /* fill in 0777 bits from ACL */
703 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
78415d2d
SP
704 rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
705 pfid);
706 if (rc) {
707 cFYI(1, "%s: Getting ACL failed with error: %d",
708 __func__, rc);
709 goto cgii_exit;
710 }
b9a3260f 711 }
79df1bae 712#endif /* CONFIG_CIFS_ACL */
b9a3260f 713
0b8f18e3
JL
714 /* fill in remaining high mode bits e.g. SUID, VTX */
715 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
716 cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
b9a3260f 717
1b12b9c1
SM
718 /* check for Minshall+French symlinks */
719 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
720 tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
721 if (tmprc)
722 cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
723 }
724
0b8f18e3
JL
725 if (!*pinode) {
726 *pinode = cifs_iget(sb, &fattr);
727 if (!*pinode)
728 rc = -ENOMEM;
729 } else {
730 cifs_fattr_to_inode(*pinode, &fattr);
731 }
b9a3260f 732
7962670e 733cgii_exit:
1da177e4 734 kfree(buf);
7ffec372 735 cifs_put_tlink(tlink);
1da177e4
LT
736 return rc;
737}
738
7f8ed420
SF
739static const struct inode_operations cifs_ipc_inode_ops = {
740 .lookup = cifs_lookup,
741};
742
f87d39d9 743char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
96daf2b0 744 struct cifs_tcon *tcon)
8be0ed44 745{
f87d39d9 746 int pplen = vol->prepath ? strlen(vol->prepath) : 0;
8be0ed44
SF
747 int dfsplen;
748 char *full_path = NULL;
749
750 /* if no prefix path, simply set path to the root of share to "" */
751 if (pplen == 0) {
752 full_path = kmalloc(1, GFP_KERNEL);
753 if (full_path)
754 full_path[0] = 0;
755 return full_path;
756 }
757
0d424ad0
JL
758 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
759 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
8be0ed44
SF
760 else
761 dfsplen = 0;
762
763 full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
764 if (full_path == NULL)
765 return full_path;
766
f9e8c450 767 if (dfsplen)
0d424ad0 768 strncpy(full_path, tcon->treeName, dfsplen);
f87d39d9 769 strncpy(full_path + dfsplen, vol->prepath, pplen);
f9e8c450 770 convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
8be0ed44
SF
771 full_path[dfsplen + pplen] = 0; /* add trailing null */
772 return full_path;
773}
774
cc0bad75
JL
775static int
776cifs_find_inode(struct inode *inode, void *opaque)
777{
778 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
779
f30b9c11 780 /* don't match inode with different uniqueid */
cc0bad75
JL
781 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
782 return 0;
783
20054bd6
JL
784 /* use createtime like an i_generation field */
785 if (CIFS_I(inode)->createtime != fattr->cf_createtime)
786 return 0;
787
f30b9c11
JL
788 /* don't match inode of different type */
789 if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT))
790 return 0;
791
5acfec25
JL
792 /* if it's not a directory or has no dentries, then flag it */
793 if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry))
3d694380 794 fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
3d694380 795
cc0bad75
JL
796 return 1;
797}
798
799static int
800cifs_init_inode(struct inode *inode, void *opaque)
801{
802 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
803
804 CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
20054bd6 805 CIFS_I(inode)->createtime = fattr->cf_createtime;
cc0bad75
JL
806 return 0;
807}
808
5acfec25
JL
809/*
810 * walk dentry list for an inode and report whether it has aliases that
811 * are hashed. We use this to determine if a directory inode can actually
812 * be used.
813 */
814static bool
815inode_has_hashed_dentries(struct inode *inode)
816{
817 struct dentry *dentry;
818
873feea0 819 spin_lock(&inode->i_lock);
5acfec25
JL
820 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
821 if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
873feea0 822 spin_unlock(&inode->i_lock);
5acfec25
JL
823 return true;
824 }
825 }
873feea0 826 spin_unlock(&inode->i_lock);
5acfec25
JL
827 return false;
828}
829
cc0bad75
JL
830/* Given fattrs, get a corresponding inode */
831struct inode *
832cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
833{
834 unsigned long hash;
835 struct inode *inode;
836
3d694380 837retry_iget5_locked:
b6b38f70 838 cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid);
cc0bad75
JL
839
840 /* hash down to 32-bits on 32-bit arch */
841 hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
842
843 inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
cc0bad75 844 if (inode) {
5acfec25 845 /* was there a potentially problematic inode collision? */
3d694380 846 if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {
3d694380 847 fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;
5acfec25
JL
848
849 if (inode_has_hashed_dentries(inode)) {
850 cifs_autodisable_serverino(CIFS_SB(sb));
851 iput(inode);
852 fattr->cf_uniqueid = iunique(sb, ROOT_I);
853 goto retry_iget5_locked;
854 }
3d694380
JL
855 }
856
cc0bad75
JL
857 cifs_fattr_to_inode(inode, fattr);
858 if (sb->s_flags & MS_NOATIME)
859 inode->i_flags |= S_NOATIME | S_NOCMTIME;
860 if (inode->i_state & I_NEW) {
861 inode->i_ino = hash;
522440ed
JL
862 if (S_ISREG(inode->i_mode))
863 inode->i_data.backing_dev_info = sb->s_bdi;
0ccd4802 864#ifdef CONFIG_CIFS_FSCACHE
9451a9a5
SJ
865 /* initialize per-inode cache cookie pointer */
866 CIFS_I(inode)->fscache = NULL;
0ccd4802 867#endif
cc0bad75
JL
868 unlock_new_inode(inode);
869 }
870 }
871
872 return inode;
873}
874
1da177e4 875/* gets root inode */
9b6763e0 876struct inode *cifs_root_iget(struct super_block *sb)
1da177e4 877{
ce634ab2 878 int xid;
0d424ad0 879 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
cc0bad75 880 struct inode *inode = NULL;
ce634ab2 881 long rc;
96daf2b0 882 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
ce634ab2 883
8be0ed44 884 xid = GetXid();
0d424ad0 885 if (tcon->unix_ext)
f87d39d9 886 rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
0b8f18e3 887 else
f87d39d9 888 rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
0b8f18e3 889
a7851ce7
OS
890 if (!inode) {
891 inode = ERR_PTR(rc);
892 goto out;
893 }
cc0bad75 894
0ccd4802 895#ifdef CONFIG_CIFS_FSCACHE
d03382ce 896 /* populate tcon->resource_id */
0d424ad0 897 tcon->resource_id = CIFS_I(inode)->uniqueid;
0ccd4802 898#endif
d03382ce 899
0d424ad0 900 if (rc && tcon->ipc) {
b6b38f70 901 cFYI(1, "ipc connection - fake read inode");
7f8ed420
SF
902 inode->i_mode |= S_IFDIR;
903 inode->i_nlink = 2;
904 inode->i_op = &cifs_ipc_inode_ops;
905 inode->i_fop = &simple_dir_operations;
906 inode->i_uid = cifs_sb->mnt_uid;
907 inode->i_gid = cifs_sb->mnt_gid;
ad661334 908 } else if (rc) {
ce634ab2 909 iget_failed(inode);
a7851ce7 910 inode = ERR_PTR(rc);
7f8ed420
SF
911 }
912
a7851ce7 913out:
ce634ab2
DH
914 /* can not call macro FreeXid here since in a void func
915 * TODO: This is no longer true
916 */
1da177e4 917 _FreeXid(xid);
ce634ab2 918 return inode;
1da177e4
LT
919}
920
388e57b2
SF
921static int
922cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
923 char *full_path, __u32 dosattr)
924{
925 int rc;
926 int oplock = 0;
927 __u16 netfid;
928 __u32 netpid;
929 bool set_time = false;
930 struct cifsFileInfo *open_file;
931 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
932 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
7ffec372 933 struct tcon_link *tlink = NULL;
96daf2b0 934 struct cifs_tcon *pTcon;
388e57b2
SF
935 FILE_BASIC_INFO info_buf;
936
1adcb710
SF
937 if (attrs == NULL)
938 return -EINVAL;
939
388e57b2
SF
940 if (attrs->ia_valid & ATTR_ATIME) {
941 set_time = true;
942 info_buf.LastAccessTime =
943 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
944 } else
945 info_buf.LastAccessTime = 0;
946
947 if (attrs->ia_valid & ATTR_MTIME) {
948 set_time = true;
949 info_buf.LastWriteTime =
950 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
951 } else
952 info_buf.LastWriteTime = 0;
953
954 /*
955 * Samba throws this field away, but windows may actually use it.
956 * Do not set ctime unless other time stamps are changed explicitly
957 * (i.e. by utimes()) since we would then have a mix of client and
958 * server times.
959 */
960 if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
b6b38f70 961 cFYI(1, "CIFS - CTIME changed");
388e57b2
SF
962 info_buf.ChangeTime =
963 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
964 } else
965 info_buf.ChangeTime = 0;
966
967 info_buf.CreationTime = 0; /* don't change */
968 info_buf.Attributes = cpu_to_le32(dosattr);
969
970 /*
971 * If the file is already open for write, just use that fileid
972 */
6508d904 973 open_file = find_writable_file(cifsInode, true);
388e57b2
SF
974 if (open_file) {
975 netfid = open_file->netfid;
976 netpid = open_file->pid;
13cfb733 977 pTcon = tlink_tcon(open_file->tlink);
388e57b2
SF
978 goto set_via_filehandle;
979 }
980
7ffec372
JL
981 tlink = cifs_sb_tlink(cifs_sb);
982 if (IS_ERR(tlink)) {
983 rc = PTR_ERR(tlink);
984 tlink = NULL;
985 goto out;
986 }
987 pTcon = tlink_tcon(tlink);
ba00ba64 988
388e57b2
SF
989 /*
990 * NT4 apparently returns success on this call, but it doesn't
991 * really work.
992 */
993 if (!(pTcon->ses->flags & CIFS_SES_NT4)) {
994 rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
995 &info_buf, cifs_sb->local_nls,
996 cifs_sb->mnt_cifs_flags &
997 CIFS_MOUNT_MAP_SPECIAL_CHR);
6b37faa1
JL
998 if (rc == 0) {
999 cifsInode->cifsAttrs = dosattr;
1000 goto out;
1001 } else if (rc != -EOPNOTSUPP && rc != -EINVAL)
388e57b2
SF
1002 goto out;
1003 }
1004
b6b38f70
JP
1005 cFYI(1, "calling SetFileInfo since SetPathInfo for "
1006 "times not supported by this server");
388e57b2
SF
1007 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
1008 SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1009 CREATE_NOT_DIR, &netfid, &oplock,
1010 NULL, cifs_sb->local_nls,
1011 cifs_sb->mnt_cifs_flags &
1012 CIFS_MOUNT_MAP_SPECIAL_CHR);
1013
1014 if (rc != 0) {
1015 if (rc == -EIO)
1016 rc = -EINVAL;
1017 goto out;
1018 }
1019
1020 netpid = current->tgid;
1021
1022set_via_filehandle:
1023 rc = CIFSSMBSetFileInfo(xid, pTcon, &info_buf, netfid, netpid);
d388908e
SF
1024 if (!rc)
1025 cifsInode->cifsAttrs = dosattr;
1026
388e57b2
SF
1027 if (open_file == NULL)
1028 CIFSSMBClose(xid, pTcon, netfid);
1029 else
6ab409b5 1030 cifsFileInfo_put(open_file);
388e57b2 1031out:
7ffec372
JL
1032 if (tlink != NULL)
1033 cifs_put_tlink(tlink);
388e57b2
SF
1034 return rc;
1035}
1036
a12a1ac7
JL
1037/*
1038 * open the given file (if it isn't already), set the DELETE_ON_CLOSE bit
1039 * and rename it to a random name that hopefully won't conflict with
1040 * anything else.
1041 */
1042static int
3270958b 1043cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
a12a1ac7
JL
1044{
1045 int oplock = 0;
1046 int rc;
1047 __u16 netfid;
3270958b 1048 struct inode *inode = dentry->d_inode;
a12a1ac7
JL
1049 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1050 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
7ffec372 1051 struct tcon_link *tlink;
96daf2b0 1052 struct cifs_tcon *tcon;
3270958b
SF
1053 __u32 dosattr, origattr;
1054 FILE_BASIC_INFO *info_buf = NULL;
a12a1ac7 1055
7ffec372
JL
1056 tlink = cifs_sb_tlink(cifs_sb);
1057 if (IS_ERR(tlink))
1058 return PTR_ERR(tlink);
1059 tcon = tlink_tcon(tlink);
1060
a12a1ac7 1061 rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
dd1db2de 1062 DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
a12a1ac7
JL
1063 &netfid, &oplock, NULL, cifs_sb->local_nls,
1064 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1065 if (rc != 0)
1066 goto out;
1067
3270958b
SF
1068 origattr = cifsInode->cifsAttrs;
1069 if (origattr == 0)
1070 origattr |= ATTR_NORMAL;
1071
1072 dosattr = origattr & ~ATTR_READONLY;
a12a1ac7
JL
1073 if (dosattr == 0)
1074 dosattr |= ATTR_NORMAL;
1075 dosattr |= ATTR_HIDDEN;
1076
3270958b
SF
1077 /* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */
1078 if (dosattr != origattr) {
1079 info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
1080 if (info_buf == NULL) {
1081 rc = -ENOMEM;
1082 goto out_close;
1083 }
1084 info_buf->Attributes = cpu_to_le32(dosattr);
1085 rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
1086 current->tgid);
1087 /* although we would like to mark the file hidden
1088 if that fails we will still try to rename it */
41346098 1089 if (rc != 0)
3270958b
SF
1090 cifsInode->cifsAttrs = dosattr;
1091 else
1092 dosattr = origattr; /* since not able to change them */
a12a1ac7 1093 }
a12a1ac7 1094
dd1db2de
JL
1095 /* rename the file */
1096 rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
a12a1ac7
JL
1097 cifs_sb->mnt_cifs_flags &
1098 CIFS_MOUNT_MAP_SPECIAL_CHR);
3270958b
SF
1099 if (rc != 0) {
1100 rc = -ETXTBSY;
1101 goto undo_setattr;
1102 }
6d22f098 1103
3270958b
SF
1104 /* try to set DELETE_ON_CLOSE */
1105 if (!cifsInode->delete_pending) {
1106 rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid,
1107 current->tgid);
1108 /*
1109 * some samba versions return -ENOENT when we try to set the
1110 * file disposition here. Likely a samba bug, but work around
1111 * it for now. This means that some cifsXXX files may hang
1112 * around after they shouldn't.
1113 *
1114 * BB: remove this hack after more servers have the fix
1115 */
1116 if (rc == -ENOENT)
1117 rc = 0;
1118 else if (rc != 0) {
1119 rc = -ETXTBSY;
1120 goto undo_rename;
1121 }
1122 cifsInode->delete_pending = true;
1123 }
7ce86d5a 1124
a12a1ac7
JL
1125out_close:
1126 CIFSSMBClose(xid, tcon, netfid);
1127out:
3270958b 1128 kfree(info_buf);
7ffec372 1129 cifs_put_tlink(tlink);
a12a1ac7 1130 return rc;
3270958b
SF
1131
1132 /*
1133 * reset everything back to the original state. Don't bother
1134 * dealing with errors here since we can't do anything about
1135 * them anyway.
1136 */
1137undo_rename:
1138 CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name,
1139 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1140 CIFS_MOUNT_MAP_SPECIAL_CHR);
1141undo_setattr:
1142 if (dosattr != origattr) {
1143 info_buf->Attributes = cpu_to_le32(origattr);
1144 if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
1145 current->tgid))
1146 cifsInode->cifsAttrs = origattr;
1147 }
1148
1149 goto out_close;
a12a1ac7
JL
1150}
1151
ff694527
SF
1152
1153/*
1154 * If dentry->d_inode is null (usually meaning the cached dentry
1155 * is a negative dentry) then we would attempt a standard SMB delete, but
af901ca1
AGR
1156 * if that fails we can not attempt the fall back mechanisms on EACCESS
1157 * but will return the EACCESS to the caller. Note that the VFS does not call
ff694527
SF
1158 * unlink on negative dentries currently.
1159 */
5f0319a7 1160int cifs_unlink(struct inode *dir, struct dentry *dentry)
1da177e4
LT
1161{
1162 int rc = 0;
1163 int xid;
1da177e4 1164 char *full_path = NULL;
5f0319a7 1165 struct inode *inode = dentry->d_inode;
ff694527 1166 struct cifsInodeInfo *cifs_inode;
5f0319a7
JL
1167 struct super_block *sb = dir->i_sb;
1168 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
7ffec372 1169 struct tcon_link *tlink;
96daf2b0 1170 struct cifs_tcon *tcon;
6050247d
SF
1171 struct iattr *attrs = NULL;
1172 __u32 dosattr = 0, origattr = 0;
1da177e4 1173
b6b38f70 1174 cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry);
1da177e4 1175
7ffec372
JL
1176 tlink = cifs_sb_tlink(cifs_sb);
1177 if (IS_ERR(tlink))
1178 return PTR_ERR(tlink);
1179 tcon = tlink_tcon(tlink);
1180
1da177e4
LT
1181 xid = GetXid();
1182
5f0319a7
JL
1183 /* Unlink can be called from rename so we can not take the
1184 * sb->s_vfs_rename_mutex here */
1185 full_path = build_path_from_dentry(dentry);
1da177e4 1186 if (full_path == NULL) {
0f3bc09e 1187 rc = -ENOMEM;
7ffec372 1188 goto unlink_out;
1da177e4 1189 }
2d785a50 1190
5f0319a7 1191 if ((tcon->ses->capabilities & CAP_UNIX) &&
2d785a50 1192 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
5f0319a7
JL
1193 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1194 rc = CIFSPOSIXDelFile(xid, tcon, full_path,
2d785a50 1195 SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
737b758c 1196 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
b6b38f70 1197 cFYI(1, "posix del rc %d", rc);
2d785a50
SF
1198 if ((rc == 0) || (rc == -ENOENT))
1199 goto psx_del_no_retry;
1200 }
1da177e4 1201
6050247d 1202retry_std_delete:
5f0319a7 1203 rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls,
2d785a50 1204 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
6050247d 1205
2d785a50 1206psx_del_no_retry:
1da177e4 1207 if (!rc) {
5f0319a7
JL
1208 if (inode)
1209 drop_nlink(inode);
1da177e4 1210 } else if (rc == -ENOENT) {
5f0319a7 1211 d_drop(dentry);
1da177e4 1212 } else if (rc == -ETXTBSY) {
3270958b 1213 rc = cifs_rename_pending_delete(full_path, dentry, xid);
a12a1ac7
JL
1214 if (rc == 0)
1215 drop_nlink(inode);
ff694527 1216 } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
388e57b2
SF
1217 attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
1218 if (attrs == NULL) {
1219 rc = -ENOMEM;
1220 goto out_reval;
1da177e4 1221 }
388e57b2
SF
1222
1223 /* try to reset dos attributes */
ff694527
SF
1224 cifs_inode = CIFS_I(inode);
1225 origattr = cifs_inode->cifsAttrs;
6050247d
SF
1226 if (origattr == 0)
1227 origattr |= ATTR_NORMAL;
1228 dosattr = origattr & ~ATTR_READONLY;
388e57b2
SF
1229 if (dosattr == 0)
1230 dosattr |= ATTR_NORMAL;
1231 dosattr |= ATTR_HIDDEN;
1232
1233 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
388e57b2
SF
1234 if (rc != 0)
1235 goto out_reval;
6050247d
SF
1236
1237 goto retry_std_delete;
1da177e4 1238 }
6050247d
SF
1239
1240 /* undo the setattr if we errored out and it's needed */
1241 if (rc != 0 && dosattr != 0)
1242 cifs_set_file_info(inode, attrs, xid, full_path, origattr);
1243
388e57b2 1244out_reval:
4523cc30 1245 if (inode) {
ff694527
SF
1246 cifs_inode = CIFS_I(inode);
1247 cifs_inode->time = 0; /* will force revalidate to get info
5f0319a7
JL
1248 when needed */
1249 inode->i_ctime = current_fs_time(sb);
06bcfedd 1250 }
5f0319a7 1251 dir->i_ctime = dir->i_mtime = current_fs_time(sb);
ff694527 1252 cifs_inode = CIFS_I(dir);
6050247d 1253 CIFS_I(dir)->time = 0; /* force revalidate of dir as well */
7ffec372 1254unlink_out:
1da177e4 1255 kfree(full_path);
6050247d 1256 kfree(attrs);
1da177e4 1257 FreeXid(xid);
7ffec372 1258 cifs_put_tlink(tlink);
1da177e4
LT
1259 return rc;
1260}
1261
1262int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1263{
6b37faa1 1264 int rc = 0, tmprc;
1da177e4
LT
1265 int xid;
1266 struct cifs_sb_info *cifs_sb;
7ffec372 1267 struct tcon_link *tlink;
96daf2b0 1268 struct cifs_tcon *pTcon;
1da177e4
LT
1269 char *full_path = NULL;
1270 struct inode *newinode = NULL;
cc0bad75 1271 struct cifs_fattr fattr;
1da177e4 1272
b6b38f70 1273 cFYI(1, "In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode);
1da177e4 1274
1da177e4 1275 cifs_sb = CIFS_SB(inode->i_sb);
7ffec372
JL
1276 tlink = cifs_sb_tlink(cifs_sb);
1277 if (IS_ERR(tlink))
1278 return PTR_ERR(tlink);
1279 pTcon = tlink_tcon(tlink);
1280
1281 xid = GetXid();
1da177e4 1282
7f57356b 1283 full_path = build_path_from_dentry(direntry);
1da177e4 1284 if (full_path == NULL) {
0f3bc09e 1285 rc = -ENOMEM;
7ffec372 1286 goto mkdir_out;
1da177e4 1287 }
50c2f753 1288
fb8c4b14
SF
1289 if ((pTcon->ses->capabilities & CAP_UNIX) &&
1290 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
2dd29d31
SF
1291 le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
1292 u32 oplock = 0;
f6d09982 1293 FILE_UNIX_BASIC_INFO *pInfo =
2dd29d31 1294 kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
fb8c4b14 1295 if (pInfo == NULL) {
2dd29d31
SF
1296 rc = -ENOMEM;
1297 goto mkdir_out;
1298 }
50c2f753 1299
ce3b0f8d 1300 mode &= ~current_umask();
2dd29d31
SF
1301 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
1302 mode, NULL /* netfid */, pInfo, &oplock,
fb8c4b14
SF
1303 full_path, cifs_sb->local_nls,
1304 cifs_sb->mnt_cifs_flags &
2dd29d31 1305 CIFS_MOUNT_MAP_SPECIAL_CHR);
c45d707f
SF
1306 if (rc == -EOPNOTSUPP) {
1307 kfree(pInfo);
1308 goto mkdir_retry_old;
1309 } else if (rc) {
b6b38f70 1310 cFYI(1, "posix mkdir returned 0x%x", rc);
2dd29d31
SF
1311 d_drop(direntry);
1312 } else {
8f2376ad
CG
1313 if (pInfo->Type == cpu_to_le32(-1)) {
1314 /* no return info, go query for it */
5a07cdf8 1315 kfree(pInfo);
fb8c4b14 1316 goto mkdir_get_info;
5a07cdf8 1317 }
fb8c4b14
SF
1318/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
1319 to set uid/gid */
2dd29d31 1320 inc_nlink(inode);
cbac3cba 1321
cc0bad75 1322 cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
4065c802 1323 cifs_fill_uniqueid(inode->i_sb, &fattr);
cc0bad75
JL
1324 newinode = cifs_iget(inode->i_sb, &fattr);
1325 if (!newinode) {
5a07cdf8 1326 kfree(pInfo);
cbac3cba 1327 goto mkdir_get_info;
5a07cdf8 1328 }
6b37faa1 1329
2dd29d31 1330 d_instantiate(direntry, newinode);
cbac3cba 1331
cbac3cba 1332#ifdef CONFIG_CIFS_DEBUG2
b6b38f70
JP
1333 cFYI(1, "instantiated dentry %p %s to inode %p",
1334 direntry, direntry->d_name.name, newinode);
cbac3cba 1335
fb8c4b14 1336 if (newinode->i_nlink != 2)
b6b38f70
JP
1337 cFYI(1, "unexpected number of links %d",
1338 newinode->i_nlink);
cbac3cba 1339#endif
2dd29d31
SF
1340 }
1341 kfree(pInfo);
1342 goto mkdir_out;
fb8c4b14 1343 }
c45d707f 1344mkdir_retry_old:
1da177e4 1345 /* BB add setting the equivalent of mode via CreateX w/ACLs */
737b758c
SF
1346 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
1347 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1da177e4 1348 if (rc) {
b6b38f70 1349 cFYI(1, "cifs_mkdir returned 0x%x", rc);
1da177e4
LT
1350 d_drop(direntry);
1351 } else {
fb8c4b14 1352mkdir_get_info:
d8c76e6f 1353 inc_nlink(inode);
c18c842b 1354 if (pTcon->unix_ext)
1da177e4 1355 rc = cifs_get_inode_info_unix(&newinode, full_path,
fb8c4b14 1356 inode->i_sb, xid);
1da177e4
LT
1357 else
1358 rc = cifs_get_inode_info(&newinode, full_path, NULL,
8b1327f6 1359 inode->i_sb, xid, NULL);
1da177e4 1360
1da177e4 1361 d_instantiate(direntry, newinode);
2dd29d31 1362 /* setting nlink not necessary except in cases where we
fb8c4b14 1363 * failed to get it from the server or was set bogus */
2dd29d31 1364 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
fb8c4b14 1365 direntry->d_inode->i_nlink = 2;
95089910 1366
ce3b0f8d 1367 mode &= ~current_umask();
95089910
JL
1368 /* must turn on setgid bit if parent dir has it */
1369 if (inode->i_mode & S_ISGID)
1370 mode |= S_ISGID;
1371
c18c842b 1372 if (pTcon->unix_ext) {
4e1e7fb9
JL
1373 struct cifs_unix_set_info_args args = {
1374 .mode = mode,
1375 .ctime = NO_CHANGE_64,
1376 .atime = NO_CHANGE_64,
1377 .mtime = NO_CHANGE_64,
1378 .device = 0,
1379 };
d0d2f2df 1380 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
a001e5b5 1381 args.uid = (__u64)current_fsuid();
95089910
JL
1382 if (inode->i_mode & S_ISGID)
1383 args.gid = (__u64)inode->i_gid;
1384 else
a001e5b5 1385 args.gid = (__u64)current_fsgid();
1da177e4 1386 } else {
4e1e7fb9
JL
1387 args.uid = NO_CHANGE_64;
1388 args.gid = NO_CHANGE_64;
1da177e4 1389 }
01ea95e3
JL
1390 CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
1391 cifs_sb->local_nls,
1392 cifs_sb->mnt_cifs_flags &
1393 CIFS_MOUNT_MAP_SPECIAL_CHR);
3ce53fc4 1394 } else {
67750fb9
JL
1395 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
1396 (mode & S_IWUGO) == 0) {
1397 FILE_BASIC_INFO pInfo;
6b37faa1
JL
1398 struct cifsInodeInfo *cifsInode;
1399 u32 dosattrs;
1400
67750fb9 1401 memset(&pInfo, 0, sizeof(pInfo));
6b37faa1
JL
1402 cifsInode = CIFS_I(newinode);
1403 dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
1404 pInfo.Attributes = cpu_to_le32(dosattrs);
1405 tmprc = CIFSSMBSetPathInfo(xid, pTcon,
1406 full_path, &pInfo,
1407 cifs_sb->local_nls,
67750fb9
JL
1408 cifs_sb->mnt_cifs_flags &
1409 CIFS_MOUNT_MAP_SPECIAL_CHR);
6b37faa1
JL
1410 if (tmprc == 0)
1411 cifsInode->cifsAttrs = dosattrs;
67750fb9 1412 }
fb8c4b14 1413 if (direntry->d_inode) {
b0fd30d3
JL
1414 if (cifs_sb->mnt_cifs_flags &
1415 CIFS_MOUNT_DYNPERM)
1416 direntry->d_inode->i_mode =
1417 (mode | S_IFDIR);
4e94a105 1418
fb8c4b14 1419 if (cifs_sb->mnt_cifs_flags &
6473a559 1420 CIFS_MOUNT_SET_UID) {
fb8c4b14 1421 direntry->d_inode->i_uid =
a001e5b5 1422 current_fsuid();
95089910
JL
1423 if (inode->i_mode & S_ISGID)
1424 direntry->d_inode->i_gid =
1425 inode->i_gid;
1426 else
1427 direntry->d_inode->i_gid =
a001e5b5 1428 current_fsgid();
6473a559
SF
1429 }
1430 }
2a138ebb 1431 }
1da177e4 1432 }
fb8c4b14 1433mkdir_out:
1da177e4
LT
1434 kfree(full_path);
1435 FreeXid(xid);
7ffec372 1436 cifs_put_tlink(tlink);
1da177e4
LT
1437 return rc;
1438}
1439
1440int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1441{
1442 int rc = 0;
1443 int xid;
1444 struct cifs_sb_info *cifs_sb;
7ffec372 1445 struct tcon_link *tlink;
96daf2b0 1446 struct cifs_tcon *pTcon;
1da177e4
LT
1447 char *full_path = NULL;
1448 struct cifsInodeInfo *cifsInode;
1449
b6b38f70 1450 cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
1da177e4
LT
1451
1452 xid = GetXid();
1453
7f57356b 1454 full_path = build_path_from_dentry(direntry);
1da177e4 1455 if (full_path == NULL) {
0f3bc09e 1456 rc = -ENOMEM;
7ffec372 1457 goto rmdir_exit;
1da177e4
LT
1458 }
1459
7ffec372
JL
1460 cifs_sb = CIFS_SB(inode->i_sb);
1461 tlink = cifs_sb_tlink(cifs_sb);
1462 if (IS_ERR(tlink)) {
1463 rc = PTR_ERR(tlink);
1464 goto rmdir_exit;
1465 }
1466 pTcon = tlink_tcon(tlink);
1467
737b758c
SF
1468 rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1469 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
7ffec372 1470 cifs_put_tlink(tlink);
1da177e4
LT
1471
1472 if (!rc) {
9a53c3a7 1473 drop_nlink(inode);
3677db10 1474 spin_lock(&direntry->d_inode->i_lock);
fb8c4b14 1475 i_size_write(direntry->d_inode, 0);
ce71ec36 1476 clear_nlink(direntry->d_inode);
3677db10 1477 spin_unlock(&direntry->d_inode->i_lock);
1da177e4
LT
1478 }
1479
1480 cifsInode = CIFS_I(direntry->d_inode);
1481 cifsInode->time = 0; /* force revalidate to go get info when
1482 needed */
42c24544
SF
1483
1484 cifsInode = CIFS_I(inode);
1485 cifsInode->time = 0; /* force revalidate to get parent dir info
1486 since cached search results now invalid */
1487
1da177e4
LT
1488 direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1489 current_fs_time(inode->i_sb);
1490
7ffec372 1491rmdir_exit:
1da177e4
LT
1492 kfree(full_path);
1493 FreeXid(xid);
1494 return rc;
1495}
1496
ee2fd967
SF
1497static int
1498cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1499 struct dentry *to_dentry, const char *toPath)
1500{
1501 struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
7ffec372 1502 struct tcon_link *tlink;
96daf2b0 1503 struct cifs_tcon *pTcon;
ee2fd967
SF
1504 __u16 srcfid;
1505 int oplock, rc;
1506
7ffec372
JL
1507 tlink = cifs_sb_tlink(cifs_sb);
1508 if (IS_ERR(tlink))
1509 return PTR_ERR(tlink);
1510 pTcon = tlink_tcon(tlink);
1511
ee2fd967
SF
1512 /* try path-based rename first */
1513 rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
1514 cifs_sb->mnt_cifs_flags &
1515 CIFS_MOUNT_MAP_SPECIAL_CHR);
1516
1517 /*
1518 * don't bother with rename by filehandle unless file is busy and
1519 * source Note that cross directory moves do not work with
1520 * rename by filehandle to various Windows servers.
1521 */
1522 if (rc == 0 || rc != -ETXTBSY)
7ffec372 1523 goto do_rename_exit;
ee2fd967 1524
ed0e3ace
JL
1525 /* open-file renames don't work across directories */
1526 if (to_dentry->d_parent != from_dentry->d_parent)
7ffec372 1527 goto do_rename_exit;
ed0e3ace 1528
ee2fd967
SF
1529 /* open the file to be renamed -- we need DELETE perms */
1530 rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE,
1531 CREATE_NOT_DIR, &srcfid, &oplock, NULL,
1532 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1533 CIFS_MOUNT_MAP_SPECIAL_CHR);
1534
1535 if (rc == 0) {
1536 rc = CIFSSMBRenameOpenFile(xid, pTcon, srcfid,
1537 (const char *) to_dentry->d_name.name,
1538 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1539 CIFS_MOUNT_MAP_SPECIAL_CHR);
1540
1541 CIFSSMBClose(xid, pTcon, srcfid);
1542 }
7ffec372
JL
1543do_rename_exit:
1544 cifs_put_tlink(tlink);
ee2fd967
SF
1545 return rc;
1546}
1547
14121bdc
JL
1548int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1549 struct inode *target_dir, struct dentry *target_dentry)
1da177e4 1550{
ee2fd967
SF
1551 char *fromName = NULL;
1552 char *toName = NULL;
639e7a91 1553 struct cifs_sb_info *cifs_sb;
7ffec372 1554 struct tcon_link *tlink;
96daf2b0 1555 struct cifs_tcon *tcon;
ee2fd967
SF
1556 FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1557 FILE_UNIX_BASIC_INFO *info_buf_target;
8d281efb 1558 int xid, rc, tmprc;
1da177e4 1559
639e7a91 1560 cifs_sb = CIFS_SB(source_dir->i_sb);
7ffec372
JL
1561 tlink = cifs_sb_tlink(cifs_sb);
1562 if (IS_ERR(tlink))
1563 return PTR_ERR(tlink);
1564 tcon = tlink_tcon(tlink);
1da177e4 1565
ee2fd967
SF
1566 xid = GetXid();
1567
ee2fd967
SF
1568 /*
1569 * we already have the rename sem so we do not need to
1570 * grab it again here to protect the path integrity
1571 */
14121bdc 1572 fromName = build_path_from_dentry(source_dentry);
ee2fd967
SF
1573 if (fromName == NULL) {
1574 rc = -ENOMEM;
1575 goto cifs_rename_exit;
1576 }
1577
14121bdc 1578 toName = build_path_from_dentry(target_dentry);
ee2fd967 1579 if (toName == NULL) {
1da177e4
LT
1580 rc = -ENOMEM;
1581 goto cifs_rename_exit;
1582 }
1583
14121bdc
JL
1584 rc = cifs_do_rename(xid, source_dentry, fromName,
1585 target_dentry, toName);
ee2fd967 1586
14121bdc
JL
1587 if (rc == -EEXIST && tcon->unix_ext) {
1588 /*
1589 * Are src and dst hardlinks of same inode? We can
1590 * only tell with unix extensions enabled
1591 */
1592 info_buf_source =
1593 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
1594 GFP_KERNEL);
1595 if (info_buf_source == NULL) {
1596 rc = -ENOMEM;
1597 goto cifs_rename_exit;
1598 }
1599
1600 info_buf_target = info_buf_source + 1;
8d281efb 1601 tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
14121bdc 1602 info_buf_source,
639e7a91
JL
1603 cifs_sb->local_nls,
1604 cifs_sb->mnt_cifs_flags &
14121bdc 1605 CIFS_MOUNT_MAP_SPECIAL_CHR);
8d281efb 1606 if (tmprc != 0)
14121bdc 1607 goto unlink_target;
ee2fd967 1608
639e7a91
JL
1609 tmprc = CIFSSMBUnixQPathInfo(xid, tcon, toName,
1610 info_buf_target,
1611 cifs_sb->local_nls,
1612 cifs_sb->mnt_cifs_flags &
14121bdc
JL
1613 CIFS_MOUNT_MAP_SPECIAL_CHR);
1614
8d281efb 1615 if (tmprc == 0 && (info_buf_source->UniqueId ==
ae6884a9 1616 info_buf_target->UniqueId)) {
14121bdc 1617 /* same file, POSIX says that this is a noop */
ae6884a9 1618 rc = 0;
14121bdc 1619 goto cifs_rename_exit;
ae6884a9 1620 }
14121bdc 1621 } /* else ... BB we could add the same check for Windows by
ee2fd967 1622 checking the UniqueId via FILE_INTERNAL_INFO */
14121bdc 1623
ee2fd967 1624unlink_target:
fc6f3943
JL
1625 /* Try unlinking the target dentry if it's not negative */
1626 if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) {
8d281efb 1627 tmprc = cifs_unlink(target_dir, target_dentry);
14121bdc
JL
1628 if (tmprc)
1629 goto cifs_rename_exit;
1630
14121bdc
JL
1631 rc = cifs_do_rename(xid, source_dentry, fromName,
1632 target_dentry, toName);
1da177e4
LT
1633 }
1634
1635cifs_rename_exit:
ee2fd967 1636 kfree(info_buf_source);
1da177e4
LT
1637 kfree(fromName);
1638 kfree(toName);
1639 FreeXid(xid);
7ffec372 1640 cifs_put_tlink(tlink);
1da177e4
LT
1641 return rc;
1642}
1643
df2cf170
JL
1644static bool
1645cifs_inode_needs_reval(struct inode *inode)
1da177e4 1646{
df2cf170 1647 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
6d20e840 1648 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1da177e4 1649
df2cf170
JL
1650 if (cifs_i->clientCanCacheRead)
1651 return false;
1da177e4 1652
df2cf170
JL
1653 if (!lookupCacheEnabled)
1654 return true;
1da177e4 1655
df2cf170
JL
1656 if (cifs_i->time == 0)
1657 return true;
1da177e4 1658
6d20e840
SJ
1659 if (!time_in_range(jiffies, cifs_i->time,
1660 cifs_i->time + cifs_sb->actimeo))
df2cf170
JL
1661 return true;
1662
db19272e 1663 /* hardlinked files w/ noserverino get "special" treatment */
6d20e840 1664 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
db19272e
JL
1665 S_ISREG(inode->i_mode) && inode->i_nlink != 1)
1666 return true;
1667
df2cf170
JL
1668 return false;
1669}
1670
523fb8c8
SJ
1671/*
1672 * Zap the cache. Called when invalid_mapping flag is set.
1673 */
6feb9891 1674int
df2cf170
JL
1675cifs_invalidate_mapping(struct inode *inode)
1676{
6feb9891 1677 int rc = 0;
df2cf170
JL
1678 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1679
1680 cifs_i->invalid_mapping = false;
1681
df2cf170 1682 if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
257fb1f1
PS
1683 rc = invalidate_inode_pages2(inode->i_mapping);
1684 if (rc) {
1685 cERROR(1, "%s: could not invalidate inode %p", __func__,
1686 inode);
1687 cifs_i->invalid_mapping = true;
1688 }
df2cf170 1689 }
257fb1f1 1690
9451a9a5 1691 cifs_fscache_reset_inode_cookie(inode);
6feb9891 1692 return rc;
df2cf170
JL
1693}
1694
6feb9891 1695int cifs_revalidate_file_attr(struct file *filp)
abab095d
JL
1696{
1697 int rc = 0;
1698 struct inode *inode = filp->f_path.dentry->d_inode;
ba00ba64 1699 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
abab095d
JL
1700
1701 if (!cifs_inode_needs_reval(inode))
6feb9891 1702 return rc;
abab095d 1703
13cfb733 1704 if (tlink_tcon(cfile->tlink)->unix_ext)
abab095d
JL
1705 rc = cifs_get_file_info_unix(filp);
1706 else
1707 rc = cifs_get_file_info(filp);
1708
abab095d
JL
1709 return rc;
1710}
1711
6feb9891 1712int cifs_revalidate_dentry_attr(struct dentry *dentry)
df2cf170
JL
1713{
1714 int xid;
1715 int rc = 0;
df2cf170
JL
1716 struct inode *inode = dentry->d_inode;
1717 struct super_block *sb = dentry->d_sb;
6feb9891 1718 char *full_path = NULL;
df2cf170
JL
1719
1720 if (inode == NULL)
1721 return -ENOENT;
1da177e4 1722
df2cf170 1723 if (!cifs_inode_needs_reval(inode))
6feb9891
PS
1724 return rc;
1725
1726 xid = GetXid();
1da177e4
LT
1727
1728 /* can not safely grab the rename sem here if rename calls revalidate
1729 since that would deadlock */
df2cf170 1730 full_path = build_path_from_dentry(dentry);
1da177e4 1731 if (full_path == NULL) {
0f3bc09e 1732 rc = -ENOMEM;
6feb9891 1733 goto out;
1da177e4
LT
1734 }
1735
6feb9891
PS
1736 cFYI(1, "Update attributes: %s inode 0x%p count %d dentry: 0x%p d_time "
1737 "%ld jiffies %ld", full_path, inode, inode->i_count.counter,
f19159dc 1738 dentry, dentry->d_time, jiffies);
1da177e4 1739
0d424ad0 1740 if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
df2cf170
JL
1741 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
1742 else
1743 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
1744 xid, NULL);
1da177e4 1745
6feb9891 1746out:
1da177e4
LT
1747 kfree(full_path);
1748 FreeXid(xid);
1749 return rc;
1750}
1751
6feb9891
PS
1752int cifs_revalidate_file(struct file *filp)
1753{
1754 int rc;
1755 struct inode *inode = filp->f_path.dentry->d_inode;
1756
1757 rc = cifs_revalidate_file_attr(filp);
1758 if (rc)
1759 return rc;
1760
1761 if (CIFS_I(inode)->invalid_mapping)
1762 rc = cifs_invalidate_mapping(inode);
1763 return rc;
1764}
1765
1766/* revalidate a dentry's inode attributes */
1767int cifs_revalidate_dentry(struct dentry *dentry)
1768{
1769 int rc;
1770 struct inode *inode = dentry->d_inode;
1771
1772 rc = cifs_revalidate_dentry_attr(dentry);
1773 if (rc)
1774 return rc;
1775
1776 if (CIFS_I(inode)->invalid_mapping)
1777 rc = cifs_invalidate_mapping(inode);
1778 return rc;
1779}
1780
1da177e4 1781int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1c456013 1782 struct kstat *stat)
1da177e4 1783{
3aa1c8c2 1784 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
96daf2b0 1785 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
6feb9891
PS
1786 struct inode *inode = dentry->d_inode;
1787 int rc;
3aa1c8c2 1788
6feb9891
PS
1789 /*
1790 * We need to be sure that all dirty pages are written and the server
1791 * has actual ctime, mtime and file length.
1792 */
1793 if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping &&
1794 inode->i_mapping->nrpages != 0) {
1795 rc = filemap_fdatawait(inode->i_mapping);
156ecb2d
SF
1796 if (rc) {
1797 mapping_set_error(inode->i_mapping, rc);
1798 return rc;
1799 }
6feb9891 1800 }
1c456013 1801
6feb9891
PS
1802 rc = cifs_revalidate_dentry_attr(dentry);
1803 if (rc)
1804 return rc;
1805
1806 generic_fillattr(inode, stat);
1807 stat->blksize = CIFS_MAX_MSGSIZE;
1808 stat->ino = CIFS_I(inode)->uniqueid;
1809
1810 /*
1811 * If on a multiuser mount without unix extensions, and the admin hasn't
1812 * overridden them, set the ownership to the fsuid/fsgid of the current
1813 * process.
1814 */
1815 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
1816 !tcon->unix_ext) {
1817 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))
1818 stat->uid = current_fsuid();
1819 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID))
1820 stat->gid = current_fsgid();
5fe14c85 1821 }
6feb9891 1822 return rc;
1da177e4
LT
1823}
1824
1825static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1826{
1827 pgoff_t index = from >> PAGE_CACHE_SHIFT;
1828 unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1829 struct page *page;
1da177e4
LT
1830 int rc = 0;
1831
1832 page = grab_cache_page(mapping, index);
1833 if (!page)
1834 return -ENOMEM;
1835
eebd2aa3 1836 zero_user_segment(page, offset, PAGE_CACHE_SIZE);
1da177e4
LT
1837 unlock_page(page);
1838 page_cache_release(page);
1839 return rc;
1840}
1841
1b947463 1842static void cifs_setsize(struct inode *inode, loff_t offset)
3677db10 1843{
c08d3b0e 1844 loff_t oldsize;
3677db10 1845
ba6a46a0 1846 spin_lock(&inode->i_lock);
c08d3b0e 1847 oldsize = inode->i_size;
3677db10 1848 i_size_write(inode, offset);
ba6a46a0 1849 spin_unlock(&inode->i_lock);
1b947463 1850
c08d3b0e 1851 truncate_pagecache(inode, oldsize, offset);
3677db10
SF
1852}
1853
8efdbde6
JL
1854static int
1855cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1856 int xid, char *full_path)
1857{
1858 int rc;
1859 struct cifsFileInfo *open_file;
1860 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1861 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
7ffec372 1862 struct tcon_link *tlink = NULL;
96daf2b0 1863 struct cifs_tcon *pTcon = NULL;
fa2989f4 1864 struct cifs_io_parms io_parms;
8efdbde6
JL
1865
1866 /*
1867 * To avoid spurious oplock breaks from server, in the case of
1868 * inodes that we already have open, avoid doing path based
1869 * setting of file size if we can do it by handle.
1870 * This keeps our caching token (oplock) and avoids timeouts
1871 * when the local oplock break takes longer to flush
1872 * writebehind data than the SMB timeout for the SetPathInfo
1873 * request would allow
1874 */
6508d904 1875 open_file = find_writable_file(cifsInode, true);
8efdbde6
JL
1876 if (open_file) {
1877 __u16 nfid = open_file->netfid;
1878 __u32 npid = open_file->pid;
13cfb733 1879 pTcon = tlink_tcon(open_file->tlink);
8efdbde6
JL
1880 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1881 npid, false);
6ab409b5 1882 cifsFileInfo_put(open_file);
b6b38f70 1883 cFYI(1, "SetFSize for attrs rc = %d", rc);
8efdbde6
JL
1884 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1885 unsigned int bytes_written;
fa2989f4
PS
1886
1887 io_parms.netfid = nfid;
1888 io_parms.pid = npid;
1889 io_parms.tcon = pTcon;
1890 io_parms.offset = 0;
1891 io_parms.length = attrs->ia_size;
1892 rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
1893 NULL, NULL, 1);
b6b38f70 1894 cFYI(1, "Wrt seteof rc %d", rc);
8efdbde6
JL
1895 }
1896 } else
1897 rc = -EINVAL;
1898
1899 if (rc != 0) {
7ffec372
JL
1900 if (pTcon == NULL) {
1901 tlink = cifs_sb_tlink(cifs_sb);
1902 if (IS_ERR(tlink))
1903 return PTR_ERR(tlink);
1904 pTcon = tlink_tcon(tlink);
1905 }
ba00ba64 1906
8efdbde6
JL
1907 /* Set file size by pathname rather than by handle
1908 either because no valid, writeable file handle for
1909 it was found or because there was an error setting
1910 it by handle */
1911 rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,
1912 false, cifs_sb->local_nls,
1913 cifs_sb->mnt_cifs_flags &
1914 CIFS_MOUNT_MAP_SPECIAL_CHR);
b6b38f70 1915 cFYI(1, "SetEOF by path (setattrs) rc = %d", rc);
8efdbde6
JL
1916 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1917 __u16 netfid;
1918 int oplock = 0;
1919
1920 rc = SMBLegacyOpen(xid, pTcon, full_path,
1921 FILE_OPEN, GENERIC_WRITE,
1922 CREATE_NOT_DIR, &netfid, &oplock, NULL,
1923 cifs_sb->local_nls,
1924 cifs_sb->mnt_cifs_flags &
1925 CIFS_MOUNT_MAP_SPECIAL_CHR);
1926 if (rc == 0) {
1927 unsigned int bytes_written;
fa2989f4
PS
1928
1929 io_parms.netfid = netfid;
1930 io_parms.pid = current->tgid;
1931 io_parms.tcon = pTcon;
1932 io_parms.offset = 0;
1933 io_parms.length = attrs->ia_size;
1934 rc = CIFSSMBWrite(xid, &io_parms,
1935 &bytes_written,
1936 NULL, NULL, 1);
b6b38f70 1937 cFYI(1, "wrt seteof rc %d", rc);
8efdbde6
JL
1938 CIFSSMBClose(xid, pTcon, netfid);
1939 }
1940 }
7ffec372
JL
1941 if (tlink)
1942 cifs_put_tlink(tlink);
8efdbde6
JL
1943 }
1944
1945 if (rc == 0) {
fbec9ab9 1946 cifsInode->server_eof = attrs->ia_size;
1b947463 1947 cifs_setsize(inode, attrs->ia_size);
8efdbde6
JL
1948 cifs_truncate_page(inode->i_mapping, inode->i_size);
1949 }
1950
1951 return rc;
1952}
1953
3fe5c1dd
JL
1954static int
1955cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1956{
1957 int rc;
1958 int xid;
1959 char *full_path = NULL;
1960 struct inode *inode = direntry->d_inode;
1961 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1962 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
7ffec372 1963 struct tcon_link *tlink;
96daf2b0 1964 struct cifs_tcon *pTcon;
3fe5c1dd 1965 struct cifs_unix_set_info_args *args = NULL;
3bbeeb3c 1966 struct cifsFileInfo *open_file;
3fe5c1dd 1967
b6b38f70
JP
1968 cFYI(1, "setattr_unix on file %s attrs->ia_valid=0x%x",
1969 direntry->d_name.name, attrs->ia_valid);
3fe5c1dd
JL
1970
1971 xid = GetXid();
1972
db78b877
CH
1973 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
1974 attrs->ia_valid |= ATTR_FORCE;
1975
1976 rc = inode_change_ok(inode, attrs);
1977 if (rc < 0)
1978 goto out;
3fe5c1dd
JL
1979
1980 full_path = build_path_from_dentry(direntry);
1981 if (full_path == NULL) {
1982 rc = -ENOMEM;
1983 goto out;
1984 }
1985
0f4d634c
JL
1986 /*
1987 * Attempt to flush data before changing attributes. We need to do
1988 * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1989 * ownership or mode then we may also need to do this. Here, we take
1990 * the safe way out and just do the flush on all setattr requests. If
1991 * the flush returns error, store it to report later and continue.
1992 *
1993 * BB: This should be smarter. Why bother flushing pages that
1994 * will be truncated anyway? Also, should we error out here if
1995 * the flush returns error?
1996 */
1997 rc = filemap_write_and_wait(inode->i_mapping);
eb4b756b
JL
1998 mapping_set_error(inode->i_mapping, rc);
1999 rc = 0;
3fe5c1dd
JL
2000
2001 if (attrs->ia_valid & ATTR_SIZE) {
2002 rc = cifs_set_file_size(inode, attrs, xid, full_path);
2003 if (rc != 0)
2004 goto out;
2005 }
2006
2007 /* skip mode change if it's just for clearing setuid/setgid */
2008 if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
2009 attrs->ia_valid &= ~ATTR_MODE;
2010
2011 args = kmalloc(sizeof(*args), GFP_KERNEL);
2012 if (args == NULL) {
2013 rc = -ENOMEM;
2014 goto out;
2015 }
2016
2017 /* set up the struct */
2018 if (attrs->ia_valid & ATTR_MODE)
2019 args->mode = attrs->ia_mode;
2020 else
2021 args->mode = NO_CHANGE_64;
2022
2023 if (attrs->ia_valid & ATTR_UID)
2024 args->uid = attrs->ia_uid;
2025 else
2026 args->uid = NO_CHANGE_64;
2027
2028 if (attrs->ia_valid & ATTR_GID)
2029 args->gid = attrs->ia_gid;
2030 else
2031 args->gid = NO_CHANGE_64;
2032
2033 if (attrs->ia_valid & ATTR_ATIME)
2034 args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
2035 else
2036 args->atime = NO_CHANGE_64;
2037
2038 if (attrs->ia_valid & ATTR_MTIME)
2039 args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
2040 else
2041 args->mtime = NO_CHANGE_64;
2042
2043 if (attrs->ia_valid & ATTR_CTIME)
2044 args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
2045 else
2046 args->ctime = NO_CHANGE_64;
2047
2048 args->device = 0;
6508d904 2049 open_file = find_writable_file(cifsInode, true);
3bbeeb3c
JL
2050 if (open_file) {
2051 u16 nfid = open_file->netfid;
2052 u32 npid = open_file->pid;
13cfb733 2053 pTcon = tlink_tcon(open_file->tlink);
3bbeeb3c 2054 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
6ab409b5 2055 cifsFileInfo_put(open_file);
3bbeeb3c 2056 } else {
7ffec372
JL
2057 tlink = cifs_sb_tlink(cifs_sb);
2058 if (IS_ERR(tlink)) {
2059 rc = PTR_ERR(tlink);
2060 goto out;
2061 }
2062 pTcon = tlink_tcon(tlink);
3bbeeb3c 2063 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
01ea95e3
JL
2064 cifs_sb->local_nls,
2065 cifs_sb->mnt_cifs_flags &
2066 CIFS_MOUNT_MAP_SPECIAL_CHR);
7ffec372 2067 cifs_put_tlink(tlink);
3bbeeb3c 2068 }
3fe5c1dd 2069
1025774c
CH
2070 if (rc)
2071 goto out;
ccd4bb1b 2072
1025774c 2073 if ((attrs->ia_valid & ATTR_SIZE) &&
1b947463
CH
2074 attrs->ia_size != i_size_read(inode))
2075 truncate_setsize(inode, attrs->ia_size);
1025774c
CH
2076
2077 setattr_copy(inode, attrs);
2078 mark_inode_dirty(inode);
2079
2080 /* force revalidate when any of these times are set since some
2081 of the fs types (eg ext3, fat) do not have fine enough
2082 time granularity to match protocol, and we do not have a
2083 a way (yet) to query the server fs's time granularity (and
2084 whether it rounds times down).
2085 */
2086 if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))
2087 cifsInode->time = 0;
3fe5c1dd
JL
2088out:
2089 kfree(args);
2090 kfree(full_path);
2091 FreeXid(xid);
2092 return rc;
2093}
2094
0510eeb7
JL
2095static int
2096cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
1da177e4
LT
2097{
2098 int xid;
a5ff3769
SP
2099 uid_t uid = NO_CHANGE_32;
2100 gid_t gid = NO_CHANGE_32;
3fe5c1dd
JL
2101 struct inode *inode = direntry->d_inode;
2102 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
3fe5c1dd 2103 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1da177e4
LT
2104 char *full_path = NULL;
2105 int rc = -EACCES;
feb3e20c 2106 __u32 dosattr = 0;
4e1e7fb9 2107 __u64 mode = NO_CHANGE_64;
3fe5c1dd 2108
1da177e4
LT
2109 xid = GetXid();
2110
b6b38f70
JP
2111 cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
2112 direntry->d_name.name, attrs->ia_valid);
6473a559 2113
db78b877
CH
2114 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
2115 attrs->ia_valid |= ATTR_FORCE;
2116
2117 rc = inode_change_ok(inode, attrs);
2118 if (rc < 0) {
2119 FreeXid(xid);
2120 return rc;
6473a559 2121 }
50c2f753 2122
7f57356b 2123 full_path = build_path_from_dentry(direntry);
1da177e4 2124 if (full_path == NULL) {
0f3bc09e 2125 rc = -ENOMEM;
1da177e4 2126 FreeXid(xid);
0f3bc09e 2127 return rc;
1da177e4 2128 }
1da177e4 2129
0f4d634c
JL
2130 /*
2131 * Attempt to flush data before changing attributes. We need to do
2132 * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
2133 * ownership or mode then we may also need to do this. Here, we take
2134 * the safe way out and just do the flush on all setattr requests. If
2135 * the flush returns error, store it to report later and continue.
2136 *
2137 * BB: This should be smarter. Why bother flushing pages that
2138 * will be truncated anyway? Also, should we error out here if
2139 * the flush returns error?
2140 */
2141 rc = filemap_write_and_wait(inode->i_mapping);
eb4b756b
JL
2142 mapping_set_error(inode->i_mapping, rc);
2143 rc = 0;
cea21805 2144
50531444 2145 if (attrs->ia_valid & ATTR_SIZE) {
8efdbde6
JL
2146 rc = cifs_set_file_size(inode, attrs, xid, full_path);
2147 if (rc != 0)
e30dcf3a 2148 goto cifs_setattr_exit;
1da177e4 2149 }
4ca691a8 2150
a5ff3769
SP
2151 if (attrs->ia_valid & ATTR_UID)
2152 uid = attrs->ia_uid;
2153
2154 if (attrs->ia_valid & ATTR_GID)
2155 gid = attrs->ia_gid;
2156
2157#ifdef CONFIG_CIFS_ACL
2158 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
2159 if (uid != NO_CHANGE_32 || gid != NO_CHANGE_32) {
2160 rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64,
2161 uid, gid);
2162 if (rc) {
2163 cFYI(1, "%s: Setting id failed with error: %d",
2164 __func__, rc);
2165 goto cifs_setattr_exit;
2166 }
2167 }
2168 } else
2169#endif /* CONFIG_CIFS_ACL */
3fe5c1dd 2170 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
4ca691a8 2171 attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
1da177e4 2172
d32c4f26
JL
2173 /* skip mode change if it's just for clearing setuid/setgid */
2174 if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
2175 attrs->ia_valid &= ~ATTR_MODE;
2176
1da177e4 2177 if (attrs->ia_valid & ATTR_MODE) {
1da177e4 2178 mode = attrs->ia_mode;
cdbce9c8 2179 rc = 0;
79df1bae 2180#ifdef CONFIG_CIFS_ACL
78415d2d 2181 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
a5ff3769
SP
2182 rc = id_mode_to_cifs_acl(inode, full_path, mode,
2183 NO_CHANGE_32, NO_CHANGE_32);
78415d2d
SP
2184 if (rc) {
2185 cFYI(1, "%s: Setting ACL failed with error: %d",
2186 __func__, rc);
2187 goto cifs_setattr_exit;
2188 }
2189 } else
79df1bae 2190#endif /* CONFIG_CIFS_ACL */
5132861a
JL
2191 if (((mode & S_IWUGO) == 0) &&
2192 (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
feb3e20c
JL
2193
2194 dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
2195
5132861a
JL
2196 /* fix up mode if we're not using dynperm */
2197 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
2198 attrs->ia_mode = inode->i_mode & ~S_IWUGO;
2199 } else if ((mode & S_IWUGO) &&
2200 (cifsInode->cifsAttrs & ATTR_READONLY)) {
feb3e20c
JL
2201
2202 dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
2203 /* Attributes of 0 are ignored */
2204 if (dosattr == 0)
2205 dosattr |= ATTR_NORMAL;
5132861a
JL
2206
2207 /* reset local inode permissions to normal */
2208 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
2209 attrs->ia_mode &= ~(S_IALLUGO);
2210 if (S_ISDIR(inode->i_mode))
2211 attrs->ia_mode |=
2212 cifs_sb->mnt_dir_mode;
2213 else
2214 attrs->ia_mode |=
2215 cifs_sb->mnt_file_mode;
2216 }
2217 } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
2218 /* ignore mode change - ATTR_READONLY hasn't changed */
2219 attrs->ia_valid &= ~ATTR_MODE;
1da177e4 2220 }
1da177e4
LT
2221 }
2222
feb3e20c
JL
2223 if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||
2224 ((attrs->ia_valid & ATTR_MODE) && dosattr)) {
2225 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
2226 /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */
1da177e4 2227
e30dcf3a
SF
2228 /* Even if error on time set, no sense failing the call if
2229 the server would set the time to a reasonable value anyway,
2230 and this check ensures that we are not being called from
2231 sys_utimes in which case we ought to fail the call back to
2232 the user when the server rejects the call */
fb8c4b14 2233 if ((rc) && (attrs->ia_valid &
feb3e20c 2234 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
e30dcf3a 2235 rc = 0;
1da177e4
LT
2236 }
2237
2238 /* do not need local check to inode_check_ok since the server does
2239 that */
1025774c
CH
2240 if (rc)
2241 goto cifs_setattr_exit;
2242
2243 if ((attrs->ia_valid & ATTR_SIZE) &&
1b947463
CH
2244 attrs->ia_size != i_size_read(inode))
2245 truncate_setsize(inode, attrs->ia_size);
1025774c
CH
2246
2247 setattr_copy(inode, attrs);
2248 mark_inode_dirty(inode);
1025774c 2249
e30dcf3a 2250cifs_setattr_exit:
1da177e4
LT
2251 kfree(full_path);
2252 FreeXid(xid);
2253 return rc;
2254}
2255
0510eeb7
JL
2256int
2257cifs_setattr(struct dentry *direntry, struct iattr *attrs)
2258{
2259 struct inode *inode = direntry->d_inode;
2260 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
96daf2b0 2261 struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
0510eeb7
JL
2262
2263 if (pTcon->unix_ext)
2264 return cifs_setattr_unix(direntry, attrs);
2265
2266 return cifs_setattr_nounix(direntry, attrs);
2267
2268 /* BB: add cifs_setattr_legacy for really old servers */
2269}
2270
99ee4dbd 2271#if 0
1da177e4
LT
2272void cifs_delete_inode(struct inode *inode)
2273{
b6b38f70 2274 cFYI(1, "In cifs_delete_inode, inode = 0x%p", inode);
1da177e4
LT
2275 /* may have to add back in if and when safe distributed caching of
2276 directories added e.g. via FindNotify */
2277}
99ee4dbd 2278#endif