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