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