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