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