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