1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/fs.h>
22#include <linux/stat.h>
23#include <linux/slab.h>
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#include "fscache.h"
33
34
35static void cifs_set_ops(struct inode *inode)
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_STRICT_IO) {
48 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
49 inode->i_fop = &cifs_file_strict_nobrl_ops;
50 else
51 inode->i_fop = &cifs_file_strict_ops;
52 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
53 inode->i_fop = &cifs_file_nobrl_ops;
54 else {
55 inode->i_fop = &cifs_file_ops;
56 }
57
58
59 if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf <
60 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
61 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
62 else
63 inode->i_data.a_ops = &cifs_addr_ops;
64 break;
65 case S_IFDIR:
66#ifdef CONFIG_CIFS_DFS_UPCALL
67 if (IS_AUTOMOUNT(inode)) {
68 inode->i_op = &cifs_dfs_referral_inode_operations;
69 } else {
70#else
71 {
72#endif
73 inode->i_op = &cifs_dir_inode_ops;
74 inode->i_fop = &cifs_dir_ops;
75 }
76 break;
77 case S_IFLNK:
78 inode->i_op = &cifs_symlink_inode_ops;
79 break;
80 default:
81 init_special_inode(inode, inode->i_mode, inode->i_rdev);
82 break;
83 }
84}
85
86
87
88
89static void
90cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
91{
92 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
93
94 cFYI(1, "%s: revalidating inode %llu", __func__, cifs_i->uniqueid);
95
96 if (inode->i_state & I_NEW) {
97 cFYI(1, "%s: inode %llu is new", __func__, cifs_i->uniqueid);
98 return;
99 }
100
101
102 if (cifs_i->clientCanCacheRead) {
103 cFYI(1, "%s: inode %llu is oplocked", __func__,
104 cifs_i->uniqueid);
105 return;
106 }
107
108
109 if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
110 cifs_i->server_eof == fattr->cf_eof) {
111 cFYI(1, "%s: inode %llu is unchanged", __func__,
112 cifs_i->uniqueid);
113 return;
114 }
115
116 cFYI(1, "%s: invalidating inode %llu mapping", __func__,
117 cifs_i->uniqueid);
118 cifs_i->invalid_mapping = true;
119}
120
121
122void
123cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
124{
125 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
126 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
127 unsigned long oldtime = cifs_i->time;
128
129 cifs_revalidate_cache(inode, fattr);
130
131 inode->i_atime = fattr->cf_atime;
132 inode->i_mtime = fattr->cf_mtime;
133 inode->i_ctime = fattr->cf_ctime;
134 inode->i_rdev = fattr->cf_rdev;
135 set_nlink(inode, fattr->cf_nlink);
136 inode->i_uid = fattr->cf_uid;
137 inode->i_gid = fattr->cf_gid;
138
139
140 if (inode->i_state & I_NEW ||
141 !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
142 inode->i_mode = fattr->cf_mode;
143
144 cifs_i->cifsAttrs = fattr->cf_cifsattrs;
145
146 if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
147 cifs_i->time = 0;
148 else
149 cifs_i->time = jiffies;
150
151 cFYI(1, "inode 0x%p old_time=%ld new_time=%ld", inode,
152 oldtime, cifs_i->time);
153
154 cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
155
156 cifs_i->server_eof = fattr->cf_eof;
157
158
159
160
161 spin_lock(&inode->i_lock);
162 if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
163 i_size_write(inode, fattr->cf_eof);
164
165
166
167
168
169
170 inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
171 }
172 spin_unlock(&inode->i_lock);
173
174 if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL)
175 inode->i_flags |= S_AUTOMOUNT;
176 cifs_set_ops(inode);
177}
178
179void
180cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr)
181{
182 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
183
184 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
185 return;
186
187 fattr->cf_uniqueid = iunique(sb, ROOT_I);
188}
189
190
191void
192cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
193 struct cifs_sb_info *cifs_sb)
194{
195 memset(fattr, 0, sizeof(*fattr));
196 fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
197 fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
198 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
199
200 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
201 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
202 fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
203 fattr->cf_mode = le64_to_cpu(info->Permissions);
204
205
206
207
208
209 fattr->cf_mode &= ~S_IFMT;
210 switch (le32_to_cpu(info->Type)) {
211 case UNIX_FILE:
212 fattr->cf_mode |= S_IFREG;
213 fattr->cf_dtype = DT_REG;
214 break;
215 case UNIX_SYMLINK:
216 fattr->cf_mode |= S_IFLNK;
217 fattr->cf_dtype = DT_LNK;
218 break;
219 case UNIX_DIR:
220 fattr->cf_mode |= S_IFDIR;
221 fattr->cf_dtype = DT_DIR;
222 break;
223 case UNIX_CHARDEV:
224 fattr->cf_mode |= S_IFCHR;
225 fattr->cf_dtype = DT_CHR;
226 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
227 le64_to_cpu(info->DevMinor) & MINORMASK);
228 break;
229 case UNIX_BLOCKDEV:
230 fattr->cf_mode |= S_IFBLK;
231 fattr->cf_dtype = DT_BLK;
232 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
233 le64_to_cpu(info->DevMinor) & MINORMASK);
234 break;
235 case UNIX_FIFO:
236 fattr->cf_mode |= S_IFIFO;
237 fattr->cf_dtype = DT_FIFO;
238 break;
239 case UNIX_SOCKET:
240 fattr->cf_mode |= S_IFSOCK;
241 fattr->cf_dtype = DT_SOCK;
242 break;
243 default:
244
245 fattr->cf_mode |= S_IFREG;
246 fattr->cf_dtype = DT_REG;
247 cFYI(1, "unknown type %d", le32_to_cpu(info->Type));
248 break;
249 }
250
251 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
252 fattr->cf_uid = cifs_sb->mnt_uid;
253 else
254 fattr->cf_uid = le64_to_cpu(info->Uid);
255
256 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
257 fattr->cf_gid = cifs_sb->mnt_gid;
258 else
259 fattr->cf_gid = le64_to_cpu(info->Gid);
260
261 fattr->cf_nlink = le64_to_cpu(info->Nlinks);
262}
263
264
265
266
267
268
269
270
271static void
272cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
273{
274 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
275
276 cFYI(1, "creating fake fattr for DFS referral");
277
278 memset(fattr, 0, sizeof(*fattr));
279 fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
280 fattr->cf_uid = cifs_sb->mnt_uid;
281 fattr->cf_gid = cifs_sb->mnt_gid;
282 fattr->cf_atime = CURRENT_TIME;
283 fattr->cf_ctime = CURRENT_TIME;
284 fattr->cf_mtime = CURRENT_TIME;
285 fattr->cf_nlink = 2;
286 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
287}
288
289int cifs_get_file_info_unix(struct file *filp)
290{
291 int rc;
292 int xid;
293 FILE_UNIX_BASIC_INFO find_data;
294 struct cifs_fattr fattr;
295 struct inode *inode = filp->f_path.dentry->d_inode;
296 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
297 struct cifsFileInfo *cfile = filp->private_data;
298 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
299
300 xid = GetXid();
301 rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
302 if (!rc) {
303 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
304 } else if (rc == -EREMOTE) {
305 cifs_create_dfs_fattr(&fattr, inode->i_sb);
306 rc = 0;
307 }
308
309 cifs_fattr_to_inode(inode, &fattr);
310 FreeXid(xid);
311 return rc;
312}
313
314int cifs_get_inode_info_unix(struct inode **pinode,
315 const unsigned char *full_path,
316 struct super_block *sb, int xid)
317{
318 int rc;
319 FILE_UNIX_BASIC_INFO find_data;
320 struct cifs_fattr fattr;
321 struct cifs_tcon *tcon;
322 struct tcon_link *tlink;
323 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
324
325 cFYI(1, "Getting info on %s", full_path);
326
327 tlink = cifs_sb_tlink(cifs_sb);
328 if (IS_ERR(tlink))
329 return PTR_ERR(tlink);
330 tcon = tlink_tcon(tlink);
331
332
333 rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
334 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
335 CIFS_MOUNT_MAP_SPECIAL_CHR);
336 cifs_put_tlink(tlink);
337
338 if (!rc) {
339 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
340 } else if (rc == -EREMOTE) {
341 cifs_create_dfs_fattr(&fattr, sb);
342 rc = 0;
343 } else {
344 return rc;
345 }
346
347
348 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
349 int tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
350 if (tmprc)
351 cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
352 }
353
354 if (*pinode == NULL) {
355
356 cifs_fill_uniqueid(sb, &fattr);
357 *pinode = cifs_iget(sb, &fattr);
358 if (!*pinode)
359 rc = -ENOMEM;
360 } else {
361
362 cifs_fattr_to_inode(*pinode, &fattr);
363 }
364
365 return rc;
366}
367
368static int
369cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
370 struct cifs_sb_info *cifs_sb, int xid)
371{
372 int rc;
373 int oplock = 0;
374 __u16 netfid;
375 struct tcon_link *tlink;
376 struct cifs_tcon *tcon;
377 struct cifs_io_parms io_parms;
378 char buf[24];
379 unsigned int bytes_read;
380 char *pbuf;
381
382 pbuf = buf;
383
384 fattr->cf_mode &= ~S_IFMT;
385
386 if (fattr->cf_eof == 0) {
387 fattr->cf_mode |= S_IFIFO;
388 fattr->cf_dtype = DT_FIFO;
389 return 0;
390 } else if (fattr->cf_eof < 8) {
391 fattr->cf_mode |= S_IFREG;
392 fattr->cf_dtype = DT_REG;
393 return -EINVAL;
394 }
395
396 tlink = cifs_sb_tlink(cifs_sb);
397 if (IS_ERR(tlink))
398 return PTR_ERR(tlink);
399 tcon = tlink_tcon(tlink);
400
401 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, GENERIC_READ,
402 CREATE_NOT_DIR, &netfid, &oplock, NULL,
403 cifs_sb->local_nls,
404 cifs_sb->mnt_cifs_flags &
405 CIFS_MOUNT_MAP_SPECIAL_CHR);
406 if (rc == 0) {
407 int buf_type = CIFS_NO_BUFFER;
408
409 io_parms.netfid = netfid;
410 io_parms.pid = current->tgid;
411 io_parms.tcon = tcon;
412 io_parms.offset = 0;
413 io_parms.length = 24;
414 rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf,
415 &buf_type);
416 if ((rc == 0) && (bytes_read >= 8)) {
417 if (memcmp("IntxBLK", pbuf, 8) == 0) {
418 cFYI(1, "Block device");
419 fattr->cf_mode |= S_IFBLK;
420 fattr->cf_dtype = DT_BLK;
421 if (bytes_read == 24) {
422
423 __u64 mjr;
424 __u64 mnr;
425 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
426 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
427 fattr->cf_rdev = MKDEV(mjr, mnr);
428 }
429 } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
430 cFYI(1, "Char device");
431 fattr->cf_mode |= S_IFCHR;
432 fattr->cf_dtype = DT_CHR;
433 if (bytes_read == 24) {
434
435 __u64 mjr;
436 __u64 mnr;
437 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
438 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
439 fattr->cf_rdev = MKDEV(mjr, mnr);
440 }
441 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
442 cFYI(1, "Symlink");
443 fattr->cf_mode |= S_IFLNK;
444 fattr->cf_dtype = DT_LNK;
445 } else {
446 fattr->cf_mode |= S_IFREG;
447 fattr->cf_dtype = DT_REG;
448 rc = -EOPNOTSUPP;
449 }
450 } else {
451 fattr->cf_mode |= S_IFREG;
452 fattr->cf_dtype = DT_REG;
453 rc = -EOPNOTSUPP;
454 }
455 CIFSSMBClose(xid, tcon, netfid);
456 }
457 cifs_put_tlink(tlink);
458 return rc;
459}
460
461#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID)
462
463
464
465
466
467
468static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
469 struct cifs_sb_info *cifs_sb, int xid)
470{
471#ifdef CONFIG_CIFS_XATTR
472 ssize_t rc;
473 char ea_value[4];
474 __u32 mode;
475 struct tcon_link *tlink;
476 struct cifs_tcon *tcon;
477
478 tlink = cifs_sb_tlink(cifs_sb);
479 if (IS_ERR(tlink))
480 return PTR_ERR(tlink);
481 tcon = tlink_tcon(tlink);
482
483 rc = CIFSSMBQAllEAs(xid, tcon, path, "SETFILEBITS",
484 ea_value, 4 , cifs_sb->local_nls,
485 cifs_sb->mnt_cifs_flags &
486 CIFS_MOUNT_MAP_SPECIAL_CHR);
487 cifs_put_tlink(tlink);
488 if (rc < 0)
489 return (int)rc;
490 else if (rc > 3) {
491 mode = le32_to_cpu(*((__le32 *)ea_value));
492 fattr->cf_mode &= ~SFBITS_MASK;
493 cFYI(1, "special bits 0%o org mode 0%o", mode,
494 fattr->cf_mode);
495 fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
496 cFYI(1, "special mode bits 0%o", mode);
497 }
498
499 return 0;
500#else
501 return -EOPNOTSUPP;
502#endif
503}
504
505
506static void
507cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
508 struct cifs_sb_info *cifs_sb, bool adjust_tz)
509{
510 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
511
512 memset(fattr, 0, sizeof(*fattr));
513 fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
514 if (info->DeletePending)
515 fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;
516
517 if (info->LastAccessTime)
518 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
519 else
520 fattr->cf_atime = CURRENT_TIME;
521
522 fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
523 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
524
525 if (adjust_tz) {
526 fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj;
527 fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj;
528 }
529
530 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
531 fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
532 fattr->cf_createtime = le64_to_cpu(info->CreationTime);
533
534 if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
535 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
536 fattr->cf_dtype = DT_DIR;
537
538
539
540
541 fattr->cf_nlink = 2;
542 } else {
543 fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
544 fattr->cf_dtype = DT_REG;
545
546
547 if (fattr->cf_cifsattrs & ATTR_READONLY)
548 fattr->cf_mode &= ~(S_IWUGO);
549
550 fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
551 }
552
553 fattr->cf_uid = cifs_sb->mnt_uid;
554 fattr->cf_gid = cifs_sb->mnt_gid;
555}
556
557int cifs_get_file_info(struct file *filp)
558{
559 int rc;
560 int xid;
561 FILE_ALL_INFO find_data;
562 struct cifs_fattr fattr;
563 struct inode *inode = filp->f_path.dentry->d_inode;
564 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
565 struct cifsFileInfo *cfile = filp->private_data;
566 struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
567
568 xid = GetXid();
569 rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
570 switch (rc) {
571 case 0:
572 cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
573 break;
574 case -EREMOTE:
575 cifs_create_dfs_fattr(&fattr, inode->i_sb);
576 rc = 0;
577 break;
578 case -EOPNOTSUPP:
579 case -EINVAL:
580
581
582
583
584
585 rc = 0;
586 CIFS_I(inode)->time = 0;
587 default:
588 goto cgfi_exit;
589 }
590
591
592
593
594
595 fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
596 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
597 cifs_fattr_to_inode(inode, &fattr);
598cgfi_exit:
599 FreeXid(xid);
600 return rc;
601}
602
603int cifs_get_inode_info(struct inode **pinode,
604 const unsigned char *full_path, FILE_ALL_INFO *pfindData,
605 struct super_block *sb, int xid, const __u16 *pfid)
606{
607 int rc = 0, tmprc;
608 struct cifs_tcon *pTcon;
609 struct tcon_link *tlink;
610 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
611 char *buf = NULL;
612 bool adjustTZ = false;
613 struct cifs_fattr fattr;
614
615 tlink = cifs_sb_tlink(cifs_sb);
616 if (IS_ERR(tlink))
617 return PTR_ERR(tlink);
618 pTcon = tlink_tcon(tlink);
619
620 cFYI(1, "Getting info on %s", full_path);
621
622 if ((pfindData == NULL) && (*pinode != NULL)) {
623 if (CIFS_I(*pinode)->clientCanCacheRead) {
624 cFYI(1, "No need to revalidate cached inode sizes");
625 goto cgii_exit;
626 }
627 }
628
629
630 if (pfindData == NULL) {
631 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
632 if (buf == NULL) {
633 rc = -ENOMEM;
634 goto cgii_exit;
635 }
636 pfindData = (FILE_ALL_INFO *)buf;
637
638
639 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
640 0 ,
641 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
642 CIFS_MOUNT_MAP_SPECIAL_CHR);
643
644
645
646 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
647 rc = SMBQueryInformation(xid, pTcon, full_path,
648 pfindData, cifs_sb->local_nls,
649 cifs_sb->mnt_cifs_flags &
650 CIFS_MOUNT_MAP_SPECIAL_CHR);
651 adjustTZ = true;
652 }
653 }
654
655 if (!rc) {
656 cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
657 cifs_sb, adjustTZ);
658 } else if (rc == -EREMOTE) {
659 cifs_create_dfs_fattr(&fattr, sb);
660 rc = 0;
661 } else {
662 goto cgii_exit;
663 }
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682 if (*pinode == NULL) {
683 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
684 int rc1 = 0;
685
686 rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
687 full_path, &fattr.cf_uniqueid,
688 cifs_sb->local_nls,
689 cifs_sb->mnt_cifs_flags &
690 CIFS_MOUNT_MAP_SPECIAL_CHR);
691 if (rc1 || !fattr.cf_uniqueid) {
692 cFYI(1, "GetSrvInodeNum rc %d", rc1);
693 fattr.cf_uniqueid = iunique(sb, ROOT_I);
694 cifs_autodisable_serverino(cifs_sb);
695 }
696 } else {
697 fattr.cf_uniqueid = iunique(sb, ROOT_I);
698 }
699 } else {
700 fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
701 }
702
703
704 if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
705 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
706 tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
707 if (tmprc)
708 cFYI(1, "cifs_sfu_type failed: %d", tmprc);
709 }
710
711#ifdef CONFIG_CIFS_ACL
712
713 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
714 rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path,
715 pfid);
716 if (rc) {
717 cFYI(1, "%s: Getting ACL failed with error: %d",
718 __func__, rc);
719 goto cgii_exit;
720 }
721 }
722#endif
723
724
725 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
726 cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
727
728
729 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) {
730 tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid);
731 if (tmprc)
732 cFYI(1, "CIFSCheckMFSymlink: %d", tmprc);
733 }
734
735 if (!*pinode) {
736 *pinode = cifs_iget(sb, &fattr);
737 if (!*pinode)
738 rc = -ENOMEM;
739 } else {
740 cifs_fattr_to_inode(*pinode, &fattr);
741 }
742
743cgii_exit:
744 kfree(buf);
745 cifs_put_tlink(tlink);
746 return rc;
747}
748
749static const struct inode_operations cifs_ipc_inode_ops = {
750 .lookup = cifs_lookup,
751};
752
753char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
754 struct cifs_tcon *tcon)
755{
756 int pplen = vol->prepath ? strlen(vol->prepath) : 0;
757 int dfsplen;
758 char *full_path = NULL;
759
760
761 if (pplen == 0) {
762 full_path = kmalloc(1, GFP_KERNEL);
763 if (full_path)
764 full_path[0] = 0;
765 return full_path;
766 }
767
768 if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
769 dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
770 else
771 dfsplen = 0;
772
773 full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
774 if (full_path == NULL)
775 return full_path;
776
777 if (dfsplen)
778 strncpy(full_path, tcon->treeName, dfsplen);
779 strncpy(full_path + dfsplen, vol->prepath, pplen);
780 convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb));
781 full_path[dfsplen + pplen] = 0;
782 return full_path;
783}
784
785static int
786cifs_find_inode(struct inode *inode, void *opaque)
787{
788 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
789
790
791 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
792 return 0;
793
794
795 if (CIFS_I(inode)->createtime != fattr->cf_createtime)
796 return 0;
797
798
799 if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT))
800 return 0;
801
802
803 if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry))
804 fattr->cf_flags |= CIFS_FATTR_INO_COLLISION;
805
806 return 1;
807}
808
809static int
810cifs_init_inode(struct inode *inode, void *opaque)
811{
812 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
813
814 CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
815 CIFS_I(inode)->createtime = fattr->cf_createtime;
816 return 0;
817}
818
819
820
821
822
823
824static bool
825inode_has_hashed_dentries(struct inode *inode)
826{
827 struct dentry *dentry;
828
829 spin_lock(&inode->i_lock);
830 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
831 if (!d_unhashed(dentry) || IS_ROOT(dentry)) {
832 spin_unlock(&inode->i_lock);
833 return true;
834 }
835 }
836 spin_unlock(&inode->i_lock);
837 return false;
838}
839
840
841struct inode *
842cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
843{
844 unsigned long hash;
845 struct inode *inode;
846
847retry_iget5_locked:
848 cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid);
849
850
851 hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
852
853 inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
854 if (inode) {
855
856 if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) {
857 fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION;
858
859 if (inode_has_hashed_dentries(inode)) {
860 cifs_autodisable_serverino(CIFS_SB(sb));
861 iput(inode);
862 fattr->cf_uniqueid = iunique(sb, ROOT_I);
863 goto retry_iget5_locked;
864 }
865 }
866
867 cifs_fattr_to_inode(inode, fattr);
868 if (sb->s_flags & MS_NOATIME)
869 inode->i_flags |= S_NOATIME | S_NOCMTIME;
870 if (inode->i_state & I_NEW) {
871 inode->i_ino = hash;
872 if (S_ISREG(inode->i_mode))
873 inode->i_data.backing_dev_info = sb->s_bdi;
874#ifdef CONFIG_CIFS_FSCACHE
875
876 CIFS_I(inode)->fscache = NULL;
877#endif
878 unlock_new_inode(inode);
879 }
880 }
881
882 return inode;
883}
884
885
886struct inode *cifs_root_iget(struct super_block *sb)
887{
888 int xid;
889 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
890 struct inode *inode = NULL;
891 long rc;
892 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
893
894 xid = GetXid();
895 if (tcon->unix_ext)
896 rc = cifs_get_inode_info_unix(&inode, "", sb, xid);
897 else
898 rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL);
899
900 if (!inode) {
901 inode = ERR_PTR(rc);
902 goto out;
903 }
904
905#ifdef CONFIG_CIFS_FSCACHE
906
907 tcon->resource_id = CIFS_I(inode)->uniqueid;
908#endif
909
910 if (rc && tcon->ipc) {
911 cFYI(1, "ipc connection - fake read inode");
912 inode->i_mode |= S_IFDIR;
913 set_nlink(inode, 2);
914 inode->i_op = &cifs_ipc_inode_ops;
915 inode->i_fop = &simple_dir_operations;
916 inode->i_uid = cifs_sb->mnt_uid;
917 inode->i_gid = cifs_sb->mnt_gid;
918 } else if (rc) {
919 iget_failed(inode);
920 inode = ERR_PTR(rc);
921 }
922
923out:
924
925
926
927 _FreeXid(xid);
928 return inode;
929}
930
931static int
932cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
933 char *full_path, __u32 dosattr)
934{
935 int rc;
936 int oplock = 0;
937 __u16 netfid;
938 __u32 netpid;
939 bool set_time = false;
940 struct cifsFileInfo *open_file;
941 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
942 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
943 struct tcon_link *tlink = NULL;
944 struct cifs_tcon *pTcon;
945 FILE_BASIC_INFO info_buf;
946
947 if (attrs == NULL)
948 return -EINVAL;
949
950 if (attrs->ia_valid & ATTR_ATIME) {
951 set_time = true;
952 info_buf.LastAccessTime =
953 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
954 } else
955 info_buf.LastAccessTime = 0;
956
957 if (attrs->ia_valid & ATTR_MTIME) {
958 set_time = true;
959 info_buf.LastWriteTime =
960 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
961 } else
962 info_buf.LastWriteTime = 0;
963
964
965
966
967
968
969
970 if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
971 cFYI(1, "CIFS - CTIME changed");
972 info_buf.ChangeTime =
973 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
974 } else
975 info_buf.ChangeTime = 0;
976
977 info_buf.CreationTime = 0;
978 info_buf.Attributes = cpu_to_le32(dosattr);
979
980
981
982
983 open_file = find_writable_file(cifsInode, true);
984 if (open_file) {
985 netfid = open_file->netfid;
986 netpid = open_file->pid;
987 pTcon = tlink_tcon(open_file->tlink);
988 goto set_via_filehandle;
989 }
990
991 tlink = cifs_sb_tlink(cifs_sb);
992 if (IS_ERR(tlink)) {
993 rc = PTR_ERR(tlink);
994 tlink = NULL;
995 goto out;
996 }
997 pTcon = tlink_tcon(tlink);
998
999
1000
1001
1002
1003 if (!(pTcon->ses->flags & CIFS_SES_NT4)) {
1004 rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
1005 &info_buf, cifs_sb->local_nls,
1006 cifs_sb->mnt_cifs_flags &
1007 CIFS_MOUNT_MAP_SPECIAL_CHR);
1008 if (rc == 0) {
1009 cifsInode->cifsAttrs = dosattr;
1010 goto out;
1011 } else if (rc != -EOPNOTSUPP && rc != -EINVAL)
1012 goto out;
1013 }
1014
1015 cFYI(1, "calling SetFileInfo since SetPathInfo for "
1016 "times not supported by this server");
1017 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
1018 SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
1019 CREATE_NOT_DIR, &netfid, &oplock,
1020 NULL, cifs_sb->local_nls,
1021 cifs_sb->mnt_cifs_flags &
1022 CIFS_MOUNT_MAP_SPECIAL_CHR);
1023
1024 if (rc != 0) {
1025 if (rc == -EIO)
1026 rc = -EINVAL;
1027 goto out;
1028 }
1029
1030 netpid = current->tgid;
1031
1032set_via_filehandle:
1033 rc = CIFSSMBSetFileInfo(xid, pTcon, &info_buf, netfid, netpid);
1034 if (!rc)
1035 cifsInode->cifsAttrs = dosattr;
1036
1037 if (open_file == NULL)
1038 CIFSSMBClose(xid, pTcon, netfid);
1039 else
1040 cifsFileInfo_put(open_file);
1041out:
1042 if (tlink != NULL)
1043 cifs_put_tlink(tlink);
1044 return rc;
1045}
1046
1047
1048
1049
1050
1051
1052static int
1053cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
1054{
1055 int oplock = 0;
1056 int rc;
1057 __u16 netfid;
1058 struct inode *inode = dentry->d_inode;
1059 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1060 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1061 struct tcon_link *tlink;
1062 struct cifs_tcon *tcon;
1063 __u32 dosattr, origattr;
1064 FILE_BASIC_INFO *info_buf = NULL;
1065
1066 tlink = cifs_sb_tlink(cifs_sb);
1067 if (IS_ERR(tlink))
1068 return PTR_ERR(tlink);
1069 tcon = tlink_tcon(tlink);
1070
1071 rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
1072 DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
1073 &netfid, &oplock, NULL, cifs_sb->local_nls,
1074 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1075 if (rc != 0)
1076 goto out;
1077
1078 origattr = cifsInode->cifsAttrs;
1079 if (origattr == 0)
1080 origattr |= ATTR_NORMAL;
1081
1082 dosattr = origattr & ~ATTR_READONLY;
1083 if (dosattr == 0)
1084 dosattr |= ATTR_NORMAL;
1085 dosattr |= ATTR_HIDDEN;
1086
1087
1088 if (dosattr != origattr) {
1089 info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
1090 if (info_buf == NULL) {
1091 rc = -ENOMEM;
1092 goto out_close;
1093 }
1094 info_buf->Attributes = cpu_to_le32(dosattr);
1095 rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
1096 current->tgid);
1097
1098
1099 if (rc != 0)
1100 cifsInode->cifsAttrs = dosattr;
1101 else
1102 dosattr = origattr;
1103 }
1104
1105
1106 rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
1107 cifs_sb->mnt_cifs_flags &
1108 CIFS_MOUNT_MAP_SPECIAL_CHR);
1109 if (rc != 0) {
1110 rc = -ETXTBSY;
1111 goto undo_setattr;
1112 }
1113
1114
1115 if (!cifsInode->delete_pending) {
1116 rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid,
1117 current->tgid);
1118
1119
1120
1121
1122
1123
1124
1125
1126 if (rc == -ENOENT)
1127 rc = 0;
1128 else if (rc != 0) {
1129 rc = -ETXTBSY;
1130 goto undo_rename;
1131 }
1132 cifsInode->delete_pending = true;
1133 }
1134
1135out_close:
1136 CIFSSMBClose(xid, tcon, netfid);
1137out:
1138 kfree(info_buf);
1139 cifs_put_tlink(tlink);
1140 return rc;
1141
1142
1143
1144
1145
1146
1147undo_rename:
1148 CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name,
1149 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1150 CIFS_MOUNT_MAP_SPECIAL_CHR);
1151undo_setattr:
1152 if (dosattr != origattr) {
1153 info_buf->Attributes = cpu_to_le32(origattr);
1154 if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
1155 current->tgid))
1156 cifsInode->cifsAttrs = origattr;
1157 }
1158
1159 goto out_close;
1160}
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170int cifs_unlink(struct inode *dir, struct dentry *dentry)
1171{
1172 int rc = 0;
1173 int xid;
1174 char *full_path = NULL;
1175 struct inode *inode = dentry->d_inode;
1176 struct cifsInodeInfo *cifs_inode;
1177 struct super_block *sb = dir->i_sb;
1178 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1179 struct tcon_link *tlink;
1180 struct cifs_tcon *tcon;
1181 struct iattr *attrs = NULL;
1182 __u32 dosattr = 0, origattr = 0;
1183
1184 cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry);
1185
1186 tlink = cifs_sb_tlink(cifs_sb);
1187 if (IS_ERR(tlink))
1188 return PTR_ERR(tlink);
1189 tcon = tlink_tcon(tlink);
1190
1191 xid = GetXid();
1192
1193
1194
1195 full_path = build_path_from_dentry(dentry);
1196 if (full_path == NULL) {
1197 rc = -ENOMEM;
1198 goto unlink_out;
1199 }
1200
1201 if ((tcon->ses->capabilities & CAP_UNIX) &&
1202 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1203 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1204 rc = CIFSPOSIXDelFile(xid, tcon, full_path,
1205 SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
1206 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1207 cFYI(1, "posix del rc %d", rc);
1208 if ((rc == 0) || (rc == -ENOENT))
1209 goto psx_del_no_retry;
1210 }
1211
1212retry_std_delete:
1213 rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls,
1214 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1215
1216psx_del_no_retry:
1217 if (!rc) {
1218 if (inode)
1219 drop_nlink(inode);
1220 } else if (rc == -ENOENT) {
1221 d_drop(dentry);
1222 } else if (rc == -ETXTBSY) {
1223 rc = cifs_rename_pending_delete(full_path, dentry, xid);
1224 if (rc == 0)
1225 drop_nlink(inode);
1226 } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
1227 attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
1228 if (attrs == NULL) {
1229 rc = -ENOMEM;
1230 goto out_reval;
1231 }
1232
1233
1234 cifs_inode = CIFS_I(inode);
1235 origattr = cifs_inode->cifsAttrs;
1236 if (origattr == 0)
1237 origattr |= ATTR_NORMAL;
1238 dosattr = origattr & ~ATTR_READONLY;
1239 if (dosattr == 0)
1240 dosattr |= ATTR_NORMAL;
1241 dosattr |= ATTR_HIDDEN;
1242
1243 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
1244 if (rc != 0)
1245 goto out_reval;
1246
1247 goto retry_std_delete;
1248 }
1249
1250
1251 if (rc != 0 && dosattr != 0)
1252 cifs_set_file_info(inode, attrs, xid, full_path, origattr);
1253
1254out_reval:
1255 if (inode) {
1256 cifs_inode = CIFS_I(inode);
1257 cifs_inode->time = 0;
1258
1259 inode->i_ctime = current_fs_time(sb);
1260 }
1261 dir->i_ctime = dir->i_mtime = current_fs_time(sb);
1262 cifs_inode = CIFS_I(dir);
1263 CIFS_I(dir)->time = 0;
1264unlink_out:
1265 kfree(full_path);
1266 kfree(attrs);
1267 FreeXid(xid);
1268 cifs_put_tlink(tlink);
1269 return rc;
1270}
1271
1272int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode)
1273{
1274 int rc = 0, tmprc;
1275 int xid;
1276 struct cifs_sb_info *cifs_sb;
1277 struct tcon_link *tlink;
1278 struct cifs_tcon *pTcon;
1279 char *full_path = NULL;
1280 struct inode *newinode = NULL;
1281 struct cifs_fattr fattr;
1282
1283 cFYI(1, "In cifs_mkdir, mode = 0x%hx inode = 0x%p", mode, inode);
1284
1285 cifs_sb = CIFS_SB(inode->i_sb);
1286 tlink = cifs_sb_tlink(cifs_sb);
1287 if (IS_ERR(tlink))
1288 return PTR_ERR(tlink);
1289 pTcon = tlink_tcon(tlink);
1290
1291 xid = GetXid();
1292
1293 full_path = build_path_from_dentry(direntry);
1294 if (full_path == NULL) {
1295 rc = -ENOMEM;
1296 goto mkdir_out;
1297 }
1298
1299 if ((pTcon->ses->capabilities & CAP_UNIX) &&
1300 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1301 le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
1302 u32 oplock = 0;
1303 FILE_UNIX_BASIC_INFO *pInfo =
1304 kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1305 if (pInfo == NULL) {
1306 rc = -ENOMEM;
1307 goto mkdir_out;
1308 }
1309
1310 mode &= ~current_umask();
1311 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
1312 mode, NULL , pInfo, &oplock,
1313 full_path, cifs_sb->local_nls,
1314 cifs_sb->mnt_cifs_flags &
1315 CIFS_MOUNT_MAP_SPECIAL_CHR);
1316 if (rc == -EOPNOTSUPP) {
1317 kfree(pInfo);
1318 goto mkdir_retry_old;
1319 } else if (rc) {
1320 cFYI(1, "posix mkdir returned 0x%x", rc);
1321 d_drop(direntry);
1322 } else {
1323 if (pInfo->Type == cpu_to_le32(-1)) {
1324
1325 kfree(pInfo);
1326 goto mkdir_get_info;
1327 }
1328
1329
1330
1331 cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
1332 cifs_fill_uniqueid(inode->i_sb, &fattr);
1333 newinode = cifs_iget(inode->i_sb, &fattr);
1334 if (!newinode) {
1335 kfree(pInfo);
1336 goto mkdir_get_info;
1337 }
1338
1339 d_instantiate(direntry, newinode);
1340
1341#ifdef CONFIG_CIFS_DEBUG2
1342 cFYI(1, "instantiated dentry %p %s to inode %p",
1343 direntry, direntry->d_name.name, newinode);
1344
1345 if (newinode->i_nlink != 2)
1346 cFYI(1, "unexpected number of links %d",
1347 newinode->i_nlink);
1348#endif
1349 }
1350 kfree(pInfo);
1351 goto mkdir_out;
1352 }
1353mkdir_retry_old:
1354
1355 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
1356 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1357 if (rc) {
1358 cFYI(1, "cifs_mkdir returned 0x%x", rc);
1359 d_drop(direntry);
1360 } else {
1361mkdir_get_info:
1362 if (pTcon->unix_ext)
1363 rc = cifs_get_inode_info_unix(&newinode, full_path,
1364 inode->i_sb, xid);
1365 else
1366 rc = cifs_get_inode_info(&newinode, full_path, NULL,
1367 inode->i_sb, xid, NULL);
1368
1369 d_instantiate(direntry, newinode);
1370
1371
1372 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
1373 set_nlink(direntry->d_inode, 2);
1374
1375 mode &= ~current_umask();
1376
1377 if (inode->i_mode & S_ISGID)
1378 mode |= S_ISGID;
1379
1380 if (pTcon->unix_ext) {
1381 struct cifs_unix_set_info_args args = {
1382 .mode = mode,
1383 .ctime = NO_CHANGE_64,
1384 .atime = NO_CHANGE_64,
1385 .mtime = NO_CHANGE_64,
1386 .device = 0,
1387 };
1388 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
1389 args.uid = (__u64)current_fsuid();
1390 if (inode->i_mode & S_ISGID)
1391 args.gid = (__u64)inode->i_gid;
1392 else
1393 args.gid = (__u64)current_fsgid();
1394 } else {
1395 args.uid = NO_CHANGE_64;
1396 args.gid = NO_CHANGE_64;
1397 }
1398 CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
1399 cifs_sb->local_nls,
1400 cifs_sb->mnt_cifs_flags &
1401 CIFS_MOUNT_MAP_SPECIAL_CHR);
1402 } else {
1403 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
1404 (mode & S_IWUGO) == 0) {
1405 FILE_BASIC_INFO pInfo;
1406 struct cifsInodeInfo *cifsInode;
1407 u32 dosattrs;
1408
1409 memset(&pInfo, 0, sizeof(pInfo));
1410 cifsInode = CIFS_I(newinode);
1411 dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
1412 pInfo.Attributes = cpu_to_le32(dosattrs);
1413 tmprc = CIFSSMBSetPathInfo(xid, pTcon,
1414 full_path, &pInfo,
1415 cifs_sb->local_nls,
1416 cifs_sb->mnt_cifs_flags &
1417 CIFS_MOUNT_MAP_SPECIAL_CHR);
1418 if (tmprc == 0)
1419 cifsInode->cifsAttrs = dosattrs;
1420 }
1421 if (direntry->d_inode) {
1422 if (cifs_sb->mnt_cifs_flags &
1423 CIFS_MOUNT_DYNPERM)
1424 direntry->d_inode->i_mode =
1425 (mode | S_IFDIR);
1426
1427 if (cifs_sb->mnt_cifs_flags &
1428 CIFS_MOUNT_SET_UID) {
1429 direntry->d_inode->i_uid =
1430 current_fsuid();
1431 if (inode->i_mode & S_ISGID)
1432 direntry->d_inode->i_gid =
1433 inode->i_gid;
1434 else
1435 direntry->d_inode->i_gid =
1436 current_fsgid();
1437 }
1438 }
1439 }
1440 }
1441mkdir_out:
1442
1443
1444
1445
1446 CIFS_I(inode)->time = 0;
1447 kfree(full_path);
1448 FreeXid(xid);
1449 cifs_put_tlink(tlink);
1450 return rc;
1451}
1452
1453int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1454{
1455 int rc = 0;
1456 int xid;
1457 struct cifs_sb_info *cifs_sb;
1458 struct tcon_link *tlink;
1459 struct cifs_tcon *pTcon;
1460 char *full_path = NULL;
1461 struct cifsInodeInfo *cifsInode;
1462
1463 cFYI(1, "cifs_rmdir, inode = 0x%p", inode);
1464
1465 xid = GetXid();
1466
1467 full_path = build_path_from_dentry(direntry);
1468 if (full_path == NULL) {
1469 rc = -ENOMEM;
1470 goto rmdir_exit;
1471 }
1472
1473 cifs_sb = CIFS_SB(inode->i_sb);
1474 tlink = cifs_sb_tlink(cifs_sb);
1475 if (IS_ERR(tlink)) {
1476 rc = PTR_ERR(tlink);
1477 goto rmdir_exit;
1478 }
1479 pTcon = tlink_tcon(tlink);
1480
1481 rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1482 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1483 cifs_put_tlink(tlink);
1484
1485 if (!rc) {
1486 spin_lock(&direntry->d_inode->i_lock);
1487 i_size_write(direntry->d_inode, 0);
1488 clear_nlink(direntry->d_inode);
1489 spin_unlock(&direntry->d_inode->i_lock);
1490 }
1491
1492 cifsInode = CIFS_I(direntry->d_inode);
1493
1494 cifsInode->time = 0;
1495
1496 cifsInode = CIFS_I(inode);
1497
1498
1499
1500
1501 cifsInode->time = 0;
1502
1503 direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1504 current_fs_time(inode->i_sb);
1505
1506rmdir_exit:
1507 kfree(full_path);
1508 FreeXid(xid);
1509 return rc;
1510}
1511
1512static int
1513cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1514 struct dentry *to_dentry, const char *toPath)
1515{
1516 struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
1517 struct tcon_link *tlink;
1518 struct cifs_tcon *pTcon;
1519 __u16 srcfid;
1520 int oplock, rc;
1521
1522 tlink = cifs_sb_tlink(cifs_sb);
1523 if (IS_ERR(tlink))
1524 return PTR_ERR(tlink);
1525 pTcon = tlink_tcon(tlink);
1526
1527
1528 rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
1529 cifs_sb->mnt_cifs_flags &
1530 CIFS_MOUNT_MAP_SPECIAL_CHR);
1531
1532
1533
1534
1535
1536
1537 if (rc == 0 || rc != -ETXTBSY)
1538 goto do_rename_exit;
1539
1540
1541 if (to_dentry->d_parent != from_dentry->d_parent)
1542 goto do_rename_exit;
1543
1544
1545 rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE,
1546 CREATE_NOT_DIR, &srcfid, &oplock, NULL,
1547 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1548 CIFS_MOUNT_MAP_SPECIAL_CHR);
1549
1550 if (rc == 0) {
1551 rc = CIFSSMBRenameOpenFile(xid, pTcon, srcfid,
1552 (const char *) to_dentry->d_name.name,
1553 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1554 CIFS_MOUNT_MAP_SPECIAL_CHR);
1555
1556 CIFSSMBClose(xid, pTcon, srcfid);
1557 }
1558do_rename_exit:
1559 cifs_put_tlink(tlink);
1560 return rc;
1561}
1562
1563int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1564 struct inode *target_dir, struct dentry *target_dentry)
1565{
1566 char *fromName = NULL;
1567 char *toName = NULL;
1568 struct cifs_sb_info *cifs_sb;
1569 struct tcon_link *tlink;
1570 struct cifs_tcon *tcon;
1571 FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1572 FILE_UNIX_BASIC_INFO *info_buf_target;
1573 int xid, rc, tmprc;
1574
1575 cifs_sb = CIFS_SB(source_dir->i_sb);
1576 tlink = cifs_sb_tlink(cifs_sb);
1577 if (IS_ERR(tlink))
1578 return PTR_ERR(tlink);
1579 tcon = tlink_tcon(tlink);
1580
1581 xid = GetXid();
1582
1583
1584
1585
1586
1587 fromName = build_path_from_dentry(source_dentry);
1588 if (fromName == NULL) {
1589 rc = -ENOMEM;
1590 goto cifs_rename_exit;
1591 }
1592
1593 toName = build_path_from_dentry(target_dentry);
1594 if (toName == NULL) {
1595 rc = -ENOMEM;
1596 goto cifs_rename_exit;
1597 }
1598
1599 rc = cifs_do_rename(xid, source_dentry, fromName,
1600 target_dentry, toName);
1601
1602 if (rc == -EEXIST && tcon->unix_ext) {
1603
1604
1605
1606
1607 info_buf_source =
1608 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
1609 GFP_KERNEL);
1610 if (info_buf_source == NULL) {
1611 rc = -ENOMEM;
1612 goto cifs_rename_exit;
1613 }
1614
1615 info_buf_target = info_buf_source + 1;
1616 tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
1617 info_buf_source,
1618 cifs_sb->local_nls,
1619 cifs_sb->mnt_cifs_flags &
1620 CIFS_MOUNT_MAP_SPECIAL_CHR);
1621 if (tmprc != 0)
1622 goto unlink_target;
1623
1624 tmprc = CIFSSMBUnixQPathInfo(xid, tcon, toName,
1625 info_buf_target,
1626 cifs_sb->local_nls,
1627 cifs_sb->mnt_cifs_flags &
1628 CIFS_MOUNT_MAP_SPECIAL_CHR);
1629
1630 if (tmprc == 0 && (info_buf_source->UniqueId ==
1631 info_buf_target->UniqueId)) {
1632
1633 rc = 0;
1634 goto cifs_rename_exit;
1635 }
1636 }
1637
1638
1639unlink_target:
1640
1641 if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) {
1642 tmprc = cifs_unlink(target_dir, target_dentry);
1643 if (tmprc)
1644 goto cifs_rename_exit;
1645
1646 rc = cifs_do_rename(xid, source_dentry, fromName,
1647 target_dentry, toName);
1648 }
1649
1650cifs_rename_exit:
1651 kfree(info_buf_source);
1652 kfree(fromName);
1653 kfree(toName);
1654 FreeXid(xid);
1655 cifs_put_tlink(tlink);
1656 return rc;
1657}
1658
1659static bool
1660cifs_inode_needs_reval(struct inode *inode)
1661{
1662 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1663 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1664
1665 if (cifs_i->clientCanCacheRead)
1666 return false;
1667
1668 if (!lookupCacheEnabled)
1669 return true;
1670
1671 if (cifs_i->time == 0)
1672 return true;
1673
1674 if (!time_in_range(jiffies, cifs_i->time,
1675 cifs_i->time + cifs_sb->actimeo))
1676 return true;
1677
1678
1679 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) &&
1680 S_ISREG(inode->i_mode) && inode->i_nlink != 1)
1681 return true;
1682
1683 return false;
1684}
1685
1686
1687
1688
1689int
1690cifs_invalidate_mapping(struct inode *inode)
1691{
1692 int rc = 0;
1693 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1694
1695 cifs_i->invalid_mapping = false;
1696
1697 if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
1698 rc = invalidate_inode_pages2(inode->i_mapping);
1699 if (rc) {
1700 cERROR(1, "%s: could not invalidate inode %p", __func__,
1701 inode);
1702 cifs_i->invalid_mapping = true;
1703 }
1704 }
1705
1706 cifs_fscache_reset_inode_cookie(inode);
1707 return rc;
1708}
1709
1710int cifs_revalidate_file_attr(struct file *filp)
1711{
1712 int rc = 0;
1713 struct inode *inode = filp->f_path.dentry->d_inode;
1714 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
1715
1716 if (!cifs_inode_needs_reval(inode))
1717 return rc;
1718
1719 if (tlink_tcon(cfile->tlink)->unix_ext)
1720 rc = cifs_get_file_info_unix(filp);
1721 else
1722 rc = cifs_get_file_info(filp);
1723
1724 return rc;
1725}
1726
1727int cifs_revalidate_dentry_attr(struct dentry *dentry)
1728{
1729 int xid;
1730 int rc = 0;
1731 struct inode *inode = dentry->d_inode;
1732 struct super_block *sb = dentry->d_sb;
1733 char *full_path = NULL;
1734
1735 if (inode == NULL)
1736 return -ENOENT;
1737
1738 if (!cifs_inode_needs_reval(inode))
1739 return rc;
1740
1741 xid = GetXid();
1742
1743
1744
1745 full_path = build_path_from_dentry(dentry);
1746 if (full_path == NULL) {
1747 rc = -ENOMEM;
1748 goto out;
1749 }
1750
1751 cFYI(1, "Update attributes: %s inode 0x%p count %d dentry: 0x%p d_time "
1752 "%ld jiffies %ld", full_path, inode, inode->i_count.counter,
1753 dentry, dentry->d_time, jiffies);
1754
1755 if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext)
1756 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
1757 else
1758 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
1759 xid, NULL);
1760
1761out:
1762 kfree(full_path);
1763 FreeXid(xid);
1764 return rc;
1765}
1766
1767int cifs_revalidate_file(struct file *filp)
1768{
1769 int rc;
1770 struct inode *inode = filp->f_path.dentry->d_inode;
1771
1772 rc = cifs_revalidate_file_attr(filp);
1773 if (rc)
1774 return rc;
1775
1776 if (CIFS_I(inode)->invalid_mapping)
1777 rc = cifs_invalidate_mapping(inode);
1778 return rc;
1779}
1780
1781
1782int cifs_revalidate_dentry(struct dentry *dentry)
1783{
1784 int rc;
1785 struct inode *inode = dentry->d_inode;
1786
1787 rc = cifs_revalidate_dentry_attr(dentry);
1788 if (rc)
1789 return rc;
1790
1791 if (CIFS_I(inode)->invalid_mapping)
1792 rc = cifs_invalidate_mapping(inode);
1793 return rc;
1794}
1795
1796int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1797 struct kstat *stat)
1798{
1799 struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
1800 struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
1801 struct inode *inode = dentry->d_inode;
1802 int rc;
1803
1804
1805
1806
1807
1808 if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping &&
1809 inode->i_mapping->nrpages != 0) {
1810 rc = filemap_fdatawait(inode->i_mapping);
1811 if (rc) {
1812 mapping_set_error(inode->i_mapping, rc);
1813 return rc;
1814 }
1815 }
1816
1817 rc = cifs_revalidate_dentry_attr(dentry);
1818 if (rc)
1819 return rc;
1820
1821 generic_fillattr(inode, stat);
1822 stat->blksize = CIFS_MAX_MSGSIZE;
1823 stat->ino = CIFS_I(inode)->uniqueid;
1824
1825
1826
1827
1828
1829
1830 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) &&
1831 !tcon->unix_ext) {
1832 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID))
1833 stat->uid = current_fsuid();
1834 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID))
1835 stat->gid = current_fsgid();
1836 }
1837 return rc;
1838}
1839
1840static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1841{
1842 pgoff_t index = from >> PAGE_CACHE_SHIFT;
1843 unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1844 struct page *page;
1845 int rc = 0;
1846
1847 page = grab_cache_page(mapping, index);
1848 if (!page)
1849 return -ENOMEM;
1850
1851 zero_user_segment(page, offset, PAGE_CACHE_SIZE);
1852 unlock_page(page);
1853 page_cache_release(page);
1854 return rc;
1855}
1856
1857static void cifs_setsize(struct inode *inode, loff_t offset)
1858{
1859 loff_t oldsize;
1860
1861 spin_lock(&inode->i_lock);
1862 oldsize = inode->i_size;
1863 i_size_write(inode, offset);
1864 spin_unlock(&inode->i_lock);
1865
1866 truncate_pagecache(inode, oldsize, offset);
1867}
1868
1869static int
1870cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1871 int xid, char *full_path)
1872{
1873 int rc;
1874 struct cifsFileInfo *open_file;
1875 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1876 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1877 struct tcon_link *tlink = NULL;
1878 struct cifs_tcon *pTcon = NULL;
1879 struct cifs_io_parms io_parms;
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890 open_file = find_writable_file(cifsInode, true);
1891 if (open_file) {
1892 __u16 nfid = open_file->netfid;
1893 __u32 npid = open_file->pid;
1894 pTcon = tlink_tcon(open_file->tlink);
1895 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1896 npid, false);
1897 cifsFileInfo_put(open_file);
1898 cFYI(1, "SetFSize for attrs rc = %d", rc);
1899 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1900 unsigned int bytes_written;
1901
1902 io_parms.netfid = nfid;
1903 io_parms.pid = npid;
1904 io_parms.tcon = pTcon;
1905 io_parms.offset = 0;
1906 io_parms.length = attrs->ia_size;
1907 rc = CIFSSMBWrite(xid, &io_parms, &bytes_written,
1908 NULL, NULL, 1);
1909 cFYI(1, "Wrt seteof rc %d", rc);
1910 }
1911 } else
1912 rc = -EINVAL;
1913
1914 if (rc != 0) {
1915 if (pTcon == NULL) {
1916 tlink = cifs_sb_tlink(cifs_sb);
1917 if (IS_ERR(tlink))
1918 return PTR_ERR(tlink);
1919 pTcon = tlink_tcon(tlink);
1920 }
1921
1922
1923
1924
1925
1926 rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,
1927 false, cifs_sb->local_nls,
1928 cifs_sb->mnt_cifs_flags &
1929 CIFS_MOUNT_MAP_SPECIAL_CHR);
1930 cFYI(1, "SetEOF by path (setattrs) rc = %d", rc);
1931 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1932 __u16 netfid;
1933 int oplock = 0;
1934
1935 rc = SMBLegacyOpen(xid, pTcon, full_path,
1936 FILE_OPEN, GENERIC_WRITE,
1937 CREATE_NOT_DIR, &netfid, &oplock, NULL,
1938 cifs_sb->local_nls,
1939 cifs_sb->mnt_cifs_flags &
1940 CIFS_MOUNT_MAP_SPECIAL_CHR);
1941 if (rc == 0) {
1942 unsigned int bytes_written;
1943
1944 io_parms.netfid = netfid;
1945 io_parms.pid = current->tgid;
1946 io_parms.tcon = pTcon;
1947 io_parms.offset = 0;
1948 io_parms.length = attrs->ia_size;
1949 rc = CIFSSMBWrite(xid, &io_parms,
1950 &bytes_written,
1951 NULL, NULL, 1);
1952 cFYI(1, "wrt seteof rc %d", rc);
1953 CIFSSMBClose(xid, pTcon, netfid);
1954 }
1955 }
1956 if (tlink)
1957 cifs_put_tlink(tlink);
1958 }
1959
1960 if (rc == 0) {
1961 cifsInode->server_eof = attrs->ia_size;
1962 cifs_setsize(inode, attrs->ia_size);
1963 cifs_truncate_page(inode->i_mapping, inode->i_size);
1964 }
1965
1966 return rc;
1967}
1968
1969static int
1970cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1971{
1972 int rc;
1973 int xid;
1974 char *full_path = NULL;
1975 struct inode *inode = direntry->d_inode;
1976 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1977 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1978 struct tcon_link *tlink;
1979 struct cifs_tcon *pTcon;
1980 struct cifs_unix_set_info_args *args = NULL;
1981 struct cifsFileInfo *open_file;
1982
1983 cFYI(1, "setattr_unix on file %s attrs->ia_valid=0x%x",
1984 direntry->d_name.name, attrs->ia_valid);
1985
1986 xid = GetXid();
1987
1988 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
1989 attrs->ia_valid |= ATTR_FORCE;
1990
1991 rc = inode_change_ok(inode, attrs);
1992 if (rc < 0)
1993 goto out;
1994
1995 full_path = build_path_from_dentry(direntry);
1996 if (full_path == NULL) {
1997 rc = -ENOMEM;
1998 goto out;
1999 }
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012 rc = filemap_write_and_wait(inode->i_mapping);
2013 mapping_set_error(inode->i_mapping, rc);
2014 rc = 0;
2015
2016 if (attrs->ia_valid & ATTR_SIZE) {
2017 rc = cifs_set_file_size(inode, attrs, xid, full_path);
2018 if (rc != 0)
2019 goto out;
2020 }
2021
2022
2023 if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
2024 attrs->ia_valid &= ~ATTR_MODE;
2025
2026 args = kmalloc(sizeof(*args), GFP_KERNEL);
2027 if (args == NULL) {
2028 rc = -ENOMEM;
2029 goto out;
2030 }
2031
2032
2033 if (attrs->ia_valid & ATTR_MODE)
2034 args->mode = attrs->ia_mode;
2035 else
2036 args->mode = NO_CHANGE_64;
2037
2038 if (attrs->ia_valid & ATTR_UID)
2039 args->uid = attrs->ia_uid;
2040 else
2041 args->uid = NO_CHANGE_64;
2042
2043 if (attrs->ia_valid & ATTR_GID)
2044 args->gid = attrs->ia_gid;
2045 else
2046 args->gid = NO_CHANGE_64;
2047
2048 if (attrs->ia_valid & ATTR_ATIME)
2049 args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
2050 else
2051 args->atime = NO_CHANGE_64;
2052
2053 if (attrs->ia_valid & ATTR_MTIME)
2054 args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
2055 else
2056 args->mtime = NO_CHANGE_64;
2057
2058 if (attrs->ia_valid & ATTR_CTIME)
2059 args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
2060 else
2061 args->ctime = NO_CHANGE_64;
2062
2063 args->device = 0;
2064 open_file = find_writable_file(cifsInode, true);
2065 if (open_file) {
2066 u16 nfid = open_file->netfid;
2067 u32 npid = open_file->pid;
2068 pTcon = tlink_tcon(open_file->tlink);
2069 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
2070 cifsFileInfo_put(open_file);
2071 } else {
2072 tlink = cifs_sb_tlink(cifs_sb);
2073 if (IS_ERR(tlink)) {
2074 rc = PTR_ERR(tlink);
2075 goto out;
2076 }
2077 pTcon = tlink_tcon(tlink);
2078 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
2079 cifs_sb->local_nls,
2080 cifs_sb->mnt_cifs_flags &
2081 CIFS_MOUNT_MAP_SPECIAL_CHR);
2082 cifs_put_tlink(tlink);
2083 }
2084
2085 if (rc)
2086 goto out;
2087
2088 if ((attrs->ia_valid & ATTR_SIZE) &&
2089 attrs->ia_size != i_size_read(inode))
2090 truncate_setsize(inode, attrs->ia_size);
2091
2092 setattr_copy(inode, attrs);
2093 mark_inode_dirty(inode);
2094
2095
2096
2097
2098
2099
2100
2101 if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME))
2102 cifsInode->time = 0;
2103out:
2104 kfree(args);
2105 kfree(full_path);
2106 FreeXid(xid);
2107 return rc;
2108}
2109
2110static int
2111cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
2112{
2113 int xid;
2114 uid_t uid = NO_CHANGE_32;
2115 gid_t gid = NO_CHANGE_32;
2116 struct inode *inode = direntry->d_inode;
2117 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2118 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
2119 char *full_path = NULL;
2120 int rc = -EACCES;
2121 __u32 dosattr = 0;
2122 __u64 mode = NO_CHANGE_64;
2123
2124 xid = GetXid();
2125
2126 cFYI(1, "setattr on file %s attrs->iavalid 0x%x",
2127 direntry->d_name.name, attrs->ia_valid);
2128
2129 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM)
2130 attrs->ia_valid |= ATTR_FORCE;
2131
2132 rc = inode_change_ok(inode, attrs);
2133 if (rc < 0) {
2134 FreeXid(xid);
2135 return rc;
2136 }
2137
2138 full_path = build_path_from_dentry(direntry);
2139 if (full_path == NULL) {
2140 rc = -ENOMEM;
2141 FreeXid(xid);
2142 return rc;
2143 }
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156 rc = filemap_write_and_wait(inode->i_mapping);
2157 mapping_set_error(inode->i_mapping, rc);
2158 rc = 0;
2159
2160 if (attrs->ia_valid & ATTR_SIZE) {
2161 rc = cifs_set_file_size(inode, attrs, xid, full_path);
2162 if (rc != 0)
2163 goto cifs_setattr_exit;
2164 }
2165
2166 if (attrs->ia_valid & ATTR_UID)
2167 uid = attrs->ia_uid;
2168
2169 if (attrs->ia_valid & ATTR_GID)
2170 gid = attrs->ia_gid;
2171
2172#ifdef CONFIG_CIFS_ACL
2173 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
2174 if (uid != NO_CHANGE_32 || gid != NO_CHANGE_32) {
2175 rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64,
2176 uid, gid);
2177 if (rc) {
2178 cFYI(1, "%s: Setting id failed with error: %d",
2179 __func__, rc);
2180 goto cifs_setattr_exit;
2181 }
2182 }
2183 } else
2184#endif
2185 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
2186 attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
2187
2188
2189 if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
2190 attrs->ia_valid &= ~ATTR_MODE;
2191
2192 if (attrs->ia_valid & ATTR_MODE) {
2193 mode = attrs->ia_mode;
2194 rc = 0;
2195#ifdef CONFIG_CIFS_ACL
2196 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
2197 rc = id_mode_to_cifs_acl(inode, full_path, mode,
2198 NO_CHANGE_32, NO_CHANGE_32);
2199 if (rc) {
2200 cFYI(1, "%s: Setting ACL failed with error: %d",
2201 __func__, rc);
2202 goto cifs_setattr_exit;
2203 }
2204 } else
2205#endif
2206 if (((mode & S_IWUGO) == 0) &&
2207 (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
2208
2209 dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
2210
2211
2212 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
2213 attrs->ia_mode = inode->i_mode & ~S_IWUGO;
2214 } else if ((mode & S_IWUGO) &&
2215 (cifsInode->cifsAttrs & ATTR_READONLY)) {
2216
2217 dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
2218
2219 if (dosattr == 0)
2220 dosattr |= ATTR_NORMAL;
2221
2222
2223 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
2224 attrs->ia_mode &= ~(S_IALLUGO);
2225 if (S_ISDIR(inode->i_mode))
2226 attrs->ia_mode |=
2227 cifs_sb->mnt_dir_mode;
2228 else
2229 attrs->ia_mode |=
2230 cifs_sb->mnt_file_mode;
2231 }
2232 } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
2233
2234 attrs->ia_valid &= ~ATTR_MODE;
2235 }
2236 }
2237
2238 if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||
2239 ((attrs->ia_valid & ATTR_MODE) && dosattr)) {
2240 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
2241
2242
2243
2244
2245
2246
2247
2248 if ((rc) && (attrs->ia_valid &
2249 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
2250 rc = 0;
2251 }
2252
2253
2254
2255 if (rc)
2256 goto cifs_setattr_exit;
2257
2258 if ((attrs->ia_valid & ATTR_SIZE) &&
2259 attrs->ia_size != i_size_read(inode))
2260 truncate_setsize(inode, attrs->ia_size);
2261
2262 setattr_copy(inode, attrs);
2263 mark_inode_dirty(inode);
2264
2265cifs_setattr_exit:
2266 kfree(full_path);
2267 FreeXid(xid);
2268 return rc;
2269}
2270
2271int
2272cifs_setattr(struct dentry *direntry, struct iattr *attrs)
2273{
2274 struct inode *inode = direntry->d_inode;
2275 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2276 struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
2277
2278 if (pTcon->unix_ext)
2279 return cifs_setattr_unix(direntry, attrs);
2280
2281 return cifs_setattr_nounix(direntry, attrs);
2282
2283
2284}
2285
2286#if 0
2287void cifs_delete_inode(struct inode *inode)
2288{
2289 cFYI(1, "In cifs_delete_inode, inode = 0x%p", inode);
2290
2291
2292}
2293#endif
2294