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