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