x86, ioapic: Fix io_apic_redir_entries to return the number of entries.
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / cifs / inode.c
blob35ec117162134da1e04e31aa58525d88232e1af3
1 /*
2 * fs/cifs/inode.c
4 * Copyright (C) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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"
34 static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
36 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
38 switch (inode->i_mode & S_IFMT) {
39 case S_IFREG:
40 inode->i_op = &cifs_file_inode_ops;
41 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
42 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
43 inode->i_fop = &cifs_file_direct_nobrl_ops;
44 else
45 inode->i_fop = &cifs_file_direct_ops;
46 } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
47 inode->i_fop = &cifs_file_nobrl_ops;
48 else { /* not direct, send byte range locks */
49 inode->i_fop = &cifs_file_ops;
53 /* check if server can support readpages */
54 if (cifs_sb->tcon->ses->server->maxBuf <
55 PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE)
56 inode->i_data.a_ops = &cifs_addr_ops_smallbuf;
57 else
58 inode->i_data.a_ops = &cifs_addr_ops;
59 break;
60 case S_IFDIR:
61 #ifdef CONFIG_CIFS_DFS_UPCALL
62 if (is_dfs_referral) {
63 inode->i_op = &cifs_dfs_referral_inode_operations;
64 } else {
65 #else /* NO DFS support, treat as a directory */
67 #endif
68 inode->i_op = &cifs_dir_inode_ops;
69 inode->i_fop = &cifs_dir_ops;
71 break;
72 case S_IFLNK:
73 inode->i_op = &cifs_symlink_inode_ops;
74 break;
75 default:
76 init_special_inode(inode, inode->i_mode, inode->i_rdev);
77 break;
81 /* check inode attributes against fattr. If they don't match, tag the
82 * inode for cache invalidation
84 static void
85 cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
87 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
89 cFYI(1, ("%s: revalidating inode %llu", __func__, cifs_i->uniqueid));
91 if (inode->i_state & I_NEW) {
92 cFYI(1, ("%s: inode %llu is new", __func__, cifs_i->uniqueid));
93 return;
96 /* don't bother with revalidation if we have an oplock */
97 if (cifs_i->clientCanCacheRead) {
98 cFYI(1, ("%s: inode %llu is oplocked", __func__,
99 cifs_i->uniqueid));
100 return;
103 /* revalidate if mtime or size have changed */
104 if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
105 cifs_i->server_eof == fattr->cf_eof) {
106 cFYI(1, ("%s: inode %llu is unchanged", __func__,
107 cifs_i->uniqueid));
108 return;
111 cFYI(1, ("%s: invalidating inode %llu mapping", __func__,
112 cifs_i->uniqueid));
113 cifs_i->invalid_mapping = true;
116 /* populate an inode with info from a cifs_fattr struct */
117 void
118 cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
120 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
121 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
122 unsigned long oldtime = cifs_i->time;
124 cifs_revalidate_cache(inode, fattr);
126 inode->i_atime = fattr->cf_atime;
127 inode->i_mtime = fattr->cf_mtime;
128 inode->i_ctime = fattr->cf_ctime;
129 inode->i_rdev = fattr->cf_rdev;
130 inode->i_nlink = fattr->cf_nlink;
131 inode->i_uid = fattr->cf_uid;
132 inode->i_gid = fattr->cf_gid;
134 /* if dynperm is set, don't clobber existing mode */
135 if (inode->i_state & I_NEW ||
136 !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
137 inode->i_mode = fattr->cf_mode;
139 cifs_i->cifsAttrs = fattr->cf_cifsattrs;
140 cifs_i->uniqueid = fattr->cf_uniqueid;
142 if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
143 cifs_i->time = 0;
144 else
145 cifs_i->time = jiffies;
147 cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode,
148 oldtime, cifs_i->time));
150 cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
152 cifs_i->server_eof = fattr->cf_eof;
154 * Can't safely change the file size here if the client is writing to
155 * it due to potential races.
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);
162 * i_blocks is not related to (i_size / i_blksize),
163 * but instead 512 byte (2**9) size is required for
164 * calculating num blocks.
166 inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
168 spin_unlock(&inode->i_lock);
170 cifs_set_ops(inode, fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL);
173 /* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
174 void
175 cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
176 struct cifs_sb_info *cifs_sb)
178 memset(fattr, 0, sizeof(*fattr));
179 fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
180 fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
181 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
183 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
184 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
185 fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
186 fattr->cf_mode = le64_to_cpu(info->Permissions);
189 * Since we set the inode type below we need to mask off
190 * to avoid strange results if bits set above.
192 fattr->cf_mode &= ~S_IFMT;
193 switch (le32_to_cpu(info->Type)) {
194 case UNIX_FILE:
195 fattr->cf_mode |= S_IFREG;
196 fattr->cf_dtype = DT_REG;
197 break;
198 case UNIX_SYMLINK:
199 fattr->cf_mode |= S_IFLNK;
200 fattr->cf_dtype = DT_LNK;
201 break;
202 case UNIX_DIR:
203 fattr->cf_mode |= S_IFDIR;
204 fattr->cf_dtype = DT_DIR;
205 break;
206 case UNIX_CHARDEV:
207 fattr->cf_mode |= S_IFCHR;
208 fattr->cf_dtype = DT_CHR;
209 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
210 le64_to_cpu(info->DevMinor) & MINORMASK);
211 break;
212 case UNIX_BLOCKDEV:
213 fattr->cf_mode |= S_IFBLK;
214 fattr->cf_dtype = DT_BLK;
215 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
216 le64_to_cpu(info->DevMinor) & MINORMASK);
217 break;
218 case UNIX_FIFO:
219 fattr->cf_mode |= S_IFIFO;
220 fattr->cf_dtype = DT_FIFO;
221 break;
222 case UNIX_SOCKET:
223 fattr->cf_mode |= S_IFSOCK;
224 fattr->cf_dtype = DT_SOCK;
225 break;
226 default:
227 /* safest to call it a file if we do not know */
228 fattr->cf_mode |= S_IFREG;
229 fattr->cf_dtype = DT_REG;
230 cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
231 break;
234 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
235 fattr->cf_uid = cifs_sb->mnt_uid;
236 else
237 fattr->cf_uid = le64_to_cpu(info->Uid);
239 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
240 fattr->cf_gid = cifs_sb->mnt_gid;
241 else
242 fattr->cf_gid = le64_to_cpu(info->Gid);
244 fattr->cf_nlink = le64_to_cpu(info->Nlinks);
248 * Fill a cifs_fattr struct with fake inode info.
250 * Needed to setup cifs_fattr data for the directory which is the
251 * junction to the new submount (ie to setup the fake directory
252 * which represents a DFS referral).
254 static void
255 cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
257 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
259 cFYI(1, ("creating fake fattr for DFS referral"));
261 memset(fattr, 0, sizeof(*fattr));
262 fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
263 fattr->cf_uid = cifs_sb->mnt_uid;
264 fattr->cf_gid = cifs_sb->mnt_gid;
265 fattr->cf_atime = CURRENT_TIME;
266 fattr->cf_ctime = CURRENT_TIME;
267 fattr->cf_mtime = CURRENT_TIME;
268 fattr->cf_nlink = 2;
269 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
272 int cifs_get_file_info_unix(struct file *filp)
274 int rc;
275 int xid;
276 FILE_UNIX_BASIC_INFO find_data;
277 struct cifs_fattr fattr;
278 struct inode *inode = filp->f_path.dentry->d_inode;
279 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
280 struct cifsTconInfo *tcon = cifs_sb->tcon;
281 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
283 xid = GetXid();
284 rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
285 if (!rc) {
286 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
287 } else if (rc == -EREMOTE) {
288 cifs_create_dfs_fattr(&fattr, inode->i_sb);
289 rc = 0;
292 cifs_fattr_to_inode(inode, &fattr);
293 FreeXid(xid);
294 return rc;
297 int cifs_get_inode_info_unix(struct inode **pinode,
298 const unsigned char *full_path,
299 struct super_block *sb, int xid)
301 int rc;
302 FILE_UNIX_BASIC_INFO find_data;
303 struct cifs_fattr fattr;
304 struct cifsTconInfo *tcon;
305 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
307 tcon = cifs_sb->tcon;
308 cFYI(1, ("Getting info on %s", full_path));
310 /* could have done a find first instead but this returns more info */
311 rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
312 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
313 CIFS_MOUNT_MAP_SPECIAL_CHR);
315 if (!rc) {
316 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
317 } else if (rc == -EREMOTE) {
318 cifs_create_dfs_fattr(&fattr, sb);
319 rc = 0;
320 } else {
321 return rc;
324 if (*pinode == NULL) {
325 /* get new inode */
326 *pinode = cifs_iget(sb, &fattr);
327 if (!*pinode)
328 rc = -ENOMEM;
329 } else {
330 /* we already have inode, update it */
331 cifs_fattr_to_inode(*pinode, &fattr);
334 return rc;
337 static int
338 cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
339 struct cifs_sb_info *cifs_sb, int xid)
341 int rc;
342 int oplock = 0;
343 __u16 netfid;
344 struct cifsTconInfo *pTcon = cifs_sb->tcon;
345 char buf[24];
346 unsigned int bytes_read;
347 char *pbuf;
349 pbuf = buf;
351 fattr->cf_mode &= ~S_IFMT;
353 if (fattr->cf_eof == 0) {
354 fattr->cf_mode |= S_IFIFO;
355 fattr->cf_dtype = DT_FIFO;
356 return 0;
357 } else if (fattr->cf_eof < 8) {
358 fattr->cf_mode |= S_IFREG;
359 fattr->cf_dtype = DT_REG;
360 return -EINVAL; /* EOPNOTSUPP? */
363 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
364 CREATE_NOT_DIR, &netfid, &oplock, NULL,
365 cifs_sb->local_nls,
366 cifs_sb->mnt_cifs_flags &
367 CIFS_MOUNT_MAP_SPECIAL_CHR);
368 if (rc == 0) {
369 int buf_type = CIFS_NO_BUFFER;
370 /* Read header */
371 rc = CIFSSMBRead(xid, pTcon, netfid,
372 24 /* length */, 0 /* offset */,
373 &bytes_read, &pbuf, &buf_type);
374 if ((rc == 0) && (bytes_read >= 8)) {
375 if (memcmp("IntxBLK", pbuf, 8) == 0) {
376 cFYI(1, ("Block device"));
377 fattr->cf_mode |= S_IFBLK;
378 fattr->cf_dtype = DT_BLK;
379 if (bytes_read == 24) {
380 /* we have enough to decode dev num */
381 __u64 mjr; /* major */
382 __u64 mnr; /* minor */
383 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
384 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
385 fattr->cf_rdev = MKDEV(mjr, mnr);
387 } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
388 cFYI(1, ("Char device"));
389 fattr->cf_mode |= S_IFCHR;
390 fattr->cf_dtype = DT_CHR;
391 if (bytes_read == 24) {
392 /* we have enough to decode dev num */
393 __u64 mjr; /* major */
394 __u64 mnr; /* minor */
395 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
396 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
397 fattr->cf_rdev = MKDEV(mjr, mnr);
399 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
400 cFYI(1, ("Symlink"));
401 fattr->cf_mode |= S_IFLNK;
402 fattr->cf_dtype = DT_LNK;
403 } else {
404 fattr->cf_mode |= S_IFREG; /* file? */
405 fattr->cf_dtype = DT_REG;
406 rc = -EOPNOTSUPP;
408 } else {
409 fattr->cf_mode |= S_IFREG; /* then it is a file */
410 fattr->cf_dtype = DT_REG;
411 rc = -EOPNOTSUPP; /* or some unknown SFU type */
413 CIFSSMBClose(xid, pTcon, netfid);
415 return rc;
418 #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
421 * Fetch mode bits as provided by SFU.
423 * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ?
425 static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
426 struct cifs_sb_info *cifs_sb, int xid)
428 #ifdef CONFIG_CIFS_XATTR
429 ssize_t rc;
430 char ea_value[4];
431 __u32 mode;
433 rc = CIFSSMBQAllEAs(xid, cifs_sb->tcon, path, "SETFILEBITS",
434 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
435 cifs_sb->mnt_cifs_flags &
436 CIFS_MOUNT_MAP_SPECIAL_CHR);
437 if (rc < 0)
438 return (int)rc;
439 else if (rc > 3) {
440 mode = le32_to_cpu(*((__le32 *)ea_value));
441 fattr->cf_mode &= ~SFBITS_MASK;
442 cFYI(1, ("special bits 0%o org mode 0%o", mode,
443 fattr->cf_mode));
444 fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
445 cFYI(1, ("special mode bits 0%o", mode));
448 return 0;
449 #else
450 return -EOPNOTSUPP;
451 #endif
454 /* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
455 static void
456 cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
457 struct cifs_sb_info *cifs_sb, bool adjust_tz)
459 memset(fattr, 0, sizeof(*fattr));
460 fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
461 if (info->DeletePending)
462 fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;
464 if (info->LastAccessTime)
465 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
466 else
467 fattr->cf_atime = CURRENT_TIME;
469 fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
470 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
472 if (adjust_tz) {
473 fattr->cf_ctime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
474 fattr->cf_mtime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
477 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
478 fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
480 if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
481 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
482 fattr->cf_dtype = DT_DIR;
483 } else {
484 fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
485 fattr->cf_dtype = DT_REG;
487 /* clear write bits if ATTR_READONLY is set */
488 if (fattr->cf_cifsattrs & ATTR_READONLY)
489 fattr->cf_mode &= ~(S_IWUGO);
492 fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
494 fattr->cf_uid = cifs_sb->mnt_uid;
495 fattr->cf_gid = cifs_sb->mnt_gid;
498 int cifs_get_file_info(struct file *filp)
500 int rc;
501 int xid;
502 FILE_ALL_INFO find_data;
503 struct cifs_fattr fattr;
504 struct inode *inode = filp->f_path.dentry->d_inode;
505 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
506 struct cifsTconInfo *tcon = cifs_sb->tcon;
507 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
509 xid = GetXid();
510 rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
511 if (rc == -EOPNOTSUPP || rc == -EINVAL) {
513 * FIXME: legacy server -- fall back to path-based call?
514 * for now, just skip revalidating and mark inode for
515 * immediate reval.
517 rc = 0;
518 CIFS_I(inode)->time = 0;
519 goto cgfi_exit;
520 } else if (rc == -EREMOTE) {
521 cifs_create_dfs_fattr(&fattr, inode->i_sb);
522 rc = 0;
523 } else if (rc)
524 goto cgfi_exit;
527 * don't bother with SFU junk here -- just mark inode as needing
528 * revalidation.
530 cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
531 fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
532 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
533 cifs_fattr_to_inode(inode, &fattr);
534 cgfi_exit:
535 FreeXid(xid);
536 return rc;
539 int cifs_get_inode_info(struct inode **pinode,
540 const unsigned char *full_path, FILE_ALL_INFO *pfindData,
541 struct super_block *sb, int xid, const __u16 *pfid)
543 int rc = 0, tmprc;
544 struct cifsTconInfo *pTcon;
545 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
546 char *buf = NULL;
547 bool adjustTZ = false;
548 struct cifs_fattr fattr;
550 pTcon = cifs_sb->tcon;
551 cFYI(1, ("Getting info on %s", full_path));
553 if ((pfindData == NULL) && (*pinode != NULL)) {
554 if (CIFS_I(*pinode)->clientCanCacheRead) {
555 cFYI(1, ("No need to revalidate cached inode sizes"));
556 return rc;
560 /* if file info not passed in then get it from server */
561 if (pfindData == NULL) {
562 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
563 if (buf == NULL)
564 return -ENOMEM;
565 pfindData = (FILE_ALL_INFO *)buf;
567 /* could do find first instead but this returns more info */
568 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
569 0 /* not legacy */,
570 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
571 CIFS_MOUNT_MAP_SPECIAL_CHR);
572 /* BB optimize code so we do not make the above call
573 when server claims no NT SMB support and the above call
574 failed at least once - set flag in tcon or mount */
575 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
576 rc = SMBQueryInformation(xid, pTcon, full_path,
577 pfindData, cifs_sb->local_nls,
578 cifs_sb->mnt_cifs_flags &
579 CIFS_MOUNT_MAP_SPECIAL_CHR);
580 adjustTZ = true;
584 if (!rc) {
585 cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
586 cifs_sb, adjustTZ);
587 } else if (rc == -EREMOTE) {
588 cifs_create_dfs_fattr(&fattr, sb);
589 rc = 0;
590 } else {
591 goto cgii_exit;
595 * If an inode wasn't passed in, then get the inode number
597 * Is an i_ino of zero legal? Can we use that to check if the server
598 * supports returning inode numbers? Are there other sanity checks we
599 * can use to ensure that the server is really filling in that field?
601 * We can not use the IndexNumber field by default from Windows or
602 * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA
603 * CIFS spec claims that this value is unique within the scope of a
604 * share, and the windows docs hint that it's actually unique
605 * per-machine.
607 * There may be higher info levels that work but are there Windows
608 * server or network appliances for which IndexNumber field is not
609 * guaranteed unique?
611 if (*pinode == NULL) {
612 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
613 int rc1 = 0;
615 rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
616 full_path, &fattr.cf_uniqueid,
617 cifs_sb->local_nls,
618 cifs_sb->mnt_cifs_flags &
619 CIFS_MOUNT_MAP_SPECIAL_CHR);
620 if (rc1 || !fattr.cf_uniqueid) {
621 cFYI(1, ("GetSrvInodeNum rc %d", rc1));
622 fattr.cf_uniqueid = iunique(sb, ROOT_I);
623 cifs_autodisable_serverino(cifs_sb);
625 } else {
626 fattr.cf_uniqueid = iunique(sb, ROOT_I);
628 } else {
629 fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
632 /* query for SFU type info if supported and needed */
633 if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
634 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
635 tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
636 if (tmprc)
637 cFYI(1, ("cifs_sfu_type failed: %d", tmprc));
640 #ifdef CONFIG_CIFS_EXPERIMENTAL
641 /* fill in 0777 bits from ACL */
642 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
643 cFYI(1, ("Getting mode bits from ACL"));
644 cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
646 #endif
648 /* fill in remaining high mode bits e.g. SUID, VTX */
649 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
650 cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
652 if (!*pinode) {
653 *pinode = cifs_iget(sb, &fattr);
654 if (!*pinode)
655 rc = -ENOMEM;
656 } else {
657 cifs_fattr_to_inode(*pinode, &fattr);
660 cgii_exit:
661 kfree(buf);
662 return rc;
665 static const struct inode_operations cifs_ipc_inode_ops = {
666 .lookup = cifs_lookup,
669 char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
671 int pplen = cifs_sb->prepathlen;
672 int dfsplen;
673 char *full_path = NULL;
675 /* if no prefix path, simply set path to the root of share to "" */
676 if (pplen == 0) {
677 full_path = kmalloc(1, GFP_KERNEL);
678 if (full_path)
679 full_path[0] = 0;
680 return full_path;
683 if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS))
684 dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1);
685 else
686 dfsplen = 0;
688 full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
689 if (full_path == NULL)
690 return full_path;
692 if (dfsplen) {
693 strncpy(full_path, cifs_sb->tcon->treeName, dfsplen);
694 /* switch slash direction in prepath depending on whether
695 * windows or posix style path names
697 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
698 int i;
699 for (i = 0; i < dfsplen; i++) {
700 if (full_path[i] == '\\')
701 full_path[i] = '/';
705 strncpy(full_path + dfsplen, cifs_sb->prepath, pplen);
706 full_path[dfsplen + pplen] = 0; /* add trailing null */
707 return full_path;
710 static int
711 cifs_find_inode(struct inode *inode, void *opaque)
713 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
715 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
716 return 0;
718 return 1;
721 static int
722 cifs_init_inode(struct inode *inode, void *opaque)
724 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
726 CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
727 return 0;
730 /* Given fattrs, get a corresponding inode */
731 struct inode *
732 cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
734 unsigned long hash;
735 struct inode *inode;
737 cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid));
739 /* hash down to 32-bits on 32-bit arch */
740 hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
742 inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
744 /* we have fattrs in hand, update the inode */
745 if (inode) {
746 cifs_fattr_to_inode(inode, fattr);
747 if (sb->s_flags & MS_NOATIME)
748 inode->i_flags |= S_NOATIME | S_NOCMTIME;
749 if (inode->i_state & I_NEW) {
750 inode->i_ino = hash;
751 unlock_new_inode(inode);
755 return inode;
758 /* gets root inode */
759 struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
761 int xid;
762 struct cifs_sb_info *cifs_sb;
763 struct inode *inode = NULL;
764 long rc;
765 char *full_path;
767 cifs_sb = CIFS_SB(sb);
768 full_path = cifs_build_path_to_root(cifs_sb);
769 if (full_path == NULL)
770 return ERR_PTR(-ENOMEM);
772 xid = GetXid();
773 if (cifs_sb->tcon->unix_ext)
774 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
775 else
776 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
777 xid, NULL);
779 if (!inode)
780 return ERR_PTR(-ENOMEM);
782 if (rc && cifs_sb->tcon->ipc) {
783 cFYI(1, ("ipc connection - fake read inode"));
784 inode->i_mode |= S_IFDIR;
785 inode->i_nlink = 2;
786 inode->i_op = &cifs_ipc_inode_ops;
787 inode->i_fop = &simple_dir_operations;
788 inode->i_uid = cifs_sb->mnt_uid;
789 inode->i_gid = cifs_sb->mnt_gid;
790 } else if (rc) {
791 kfree(full_path);
792 _FreeXid(xid);
793 iget_failed(inode);
794 return ERR_PTR(rc);
798 kfree(full_path);
799 /* can not call macro FreeXid here since in a void func
800 * TODO: This is no longer true
802 _FreeXid(xid);
803 return inode;
806 static int
807 cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
808 char *full_path, __u32 dosattr)
810 int rc;
811 int oplock = 0;
812 __u16 netfid;
813 __u32 netpid;
814 bool set_time = false;
815 struct cifsFileInfo *open_file;
816 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
817 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
818 struct cifsTconInfo *pTcon = cifs_sb->tcon;
819 FILE_BASIC_INFO info_buf;
821 if (attrs == NULL)
822 return -EINVAL;
824 if (attrs->ia_valid & ATTR_ATIME) {
825 set_time = true;
826 info_buf.LastAccessTime =
827 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
828 } else
829 info_buf.LastAccessTime = 0;
831 if (attrs->ia_valid & ATTR_MTIME) {
832 set_time = true;
833 info_buf.LastWriteTime =
834 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
835 } else
836 info_buf.LastWriteTime = 0;
839 * Samba throws this field away, but windows may actually use it.
840 * Do not set ctime unless other time stamps are changed explicitly
841 * (i.e. by utimes()) since we would then have a mix of client and
842 * server times.
844 if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
845 cFYI(1, ("CIFS - CTIME changed"));
846 info_buf.ChangeTime =
847 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
848 } else
849 info_buf.ChangeTime = 0;
851 info_buf.CreationTime = 0; /* don't change */
852 info_buf.Attributes = cpu_to_le32(dosattr);
855 * If the file is already open for write, just use that fileid
857 open_file = find_writable_file(cifsInode);
858 if (open_file) {
859 netfid = open_file->netfid;
860 netpid = open_file->pid;
861 goto set_via_filehandle;
865 * NT4 apparently returns success on this call, but it doesn't
866 * really work.
868 if (!(pTcon->ses->flags & CIFS_SES_NT4)) {
869 rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
870 &info_buf, cifs_sb->local_nls,
871 cifs_sb->mnt_cifs_flags &
872 CIFS_MOUNT_MAP_SPECIAL_CHR);
873 if (rc == 0) {
874 cifsInode->cifsAttrs = dosattr;
875 goto out;
876 } else if (rc != -EOPNOTSUPP && rc != -EINVAL)
877 goto out;
880 cFYI(1, ("calling SetFileInfo since SetPathInfo for "
881 "times not supported by this server"));
882 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
883 SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
884 CREATE_NOT_DIR, &netfid, &oplock,
885 NULL, cifs_sb->local_nls,
886 cifs_sb->mnt_cifs_flags &
887 CIFS_MOUNT_MAP_SPECIAL_CHR);
889 if (rc != 0) {
890 if (rc == -EIO)
891 rc = -EINVAL;
892 goto out;
895 netpid = current->tgid;
897 set_via_filehandle:
898 rc = CIFSSMBSetFileInfo(xid, pTcon, &info_buf, netfid, netpid);
899 if (!rc)
900 cifsInode->cifsAttrs = dosattr;
902 if (open_file == NULL)
903 CIFSSMBClose(xid, pTcon, netfid);
904 else
905 cifsFileInfo_put(open_file);
906 out:
907 return rc;
911 * open the given file (if it isn't already), set the DELETE_ON_CLOSE bit
912 * and rename it to a random name that hopefully won't conflict with
913 * anything else.
915 static int
916 cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
918 int oplock = 0;
919 int rc;
920 __u16 netfid;
921 struct inode *inode = dentry->d_inode;
922 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
923 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
924 struct cifsTconInfo *tcon = cifs_sb->tcon;
925 __u32 dosattr, origattr;
926 FILE_BASIC_INFO *info_buf = NULL;
928 rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
929 DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
930 &netfid, &oplock, NULL, cifs_sb->local_nls,
931 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
932 if (rc != 0)
933 goto out;
935 origattr = cifsInode->cifsAttrs;
936 if (origattr == 0)
937 origattr |= ATTR_NORMAL;
939 dosattr = origattr & ~ATTR_READONLY;
940 if (dosattr == 0)
941 dosattr |= ATTR_NORMAL;
942 dosattr |= ATTR_HIDDEN;
944 /* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */
945 if (dosattr != origattr) {
946 info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
947 if (info_buf == NULL) {
948 rc = -ENOMEM;
949 goto out_close;
951 info_buf->Attributes = cpu_to_le32(dosattr);
952 rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
953 current->tgid);
954 /* although we would like to mark the file hidden
955 if that fails we will still try to rename it */
956 if (rc != 0)
957 cifsInode->cifsAttrs = dosattr;
958 else
959 dosattr = origattr; /* since not able to change them */
962 /* rename the file */
963 rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
964 cifs_sb->mnt_cifs_flags &
965 CIFS_MOUNT_MAP_SPECIAL_CHR);
966 if (rc != 0) {
967 rc = -ETXTBSY;
968 goto undo_setattr;
971 /* try to set DELETE_ON_CLOSE */
972 if (!cifsInode->delete_pending) {
973 rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid,
974 current->tgid);
976 * some samba versions return -ENOENT when we try to set the
977 * file disposition here. Likely a samba bug, but work around
978 * it for now. This means that some cifsXXX files may hang
979 * around after they shouldn't.
981 * BB: remove this hack after more servers have the fix
983 if (rc == -ENOENT)
984 rc = 0;
985 else if (rc != 0) {
986 rc = -ETXTBSY;
987 goto undo_rename;
989 cifsInode->delete_pending = true;
992 out_close:
993 CIFSSMBClose(xid, tcon, netfid);
994 out:
995 kfree(info_buf);
996 return rc;
999 * reset everything back to the original state. Don't bother
1000 * dealing with errors here since we can't do anything about
1001 * them anyway.
1003 undo_rename:
1004 CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name,
1005 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1006 CIFS_MOUNT_MAP_SPECIAL_CHR);
1007 undo_setattr:
1008 if (dosattr != origattr) {
1009 info_buf->Attributes = cpu_to_le32(origattr);
1010 if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
1011 current->tgid))
1012 cifsInode->cifsAttrs = origattr;
1015 goto out_close;
1020 * If dentry->d_inode is null (usually meaning the cached dentry
1021 * is a negative dentry) then we would attempt a standard SMB delete, but
1022 * if that fails we can not attempt the fall back mechanisms on EACCESS
1023 * but will return the EACCESS to the caller. Note that the VFS does not call
1024 * unlink on negative dentries currently.
1026 int cifs_unlink(struct inode *dir, struct dentry *dentry)
1028 int rc = 0;
1029 int xid;
1030 char *full_path = NULL;
1031 struct inode *inode = dentry->d_inode;
1032 struct cifsInodeInfo *cifs_inode;
1033 struct super_block *sb = dir->i_sb;
1034 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1035 struct cifsTconInfo *tcon = cifs_sb->tcon;
1036 struct iattr *attrs = NULL;
1037 __u32 dosattr = 0, origattr = 0;
1039 cFYI(1, ("cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry));
1041 xid = GetXid();
1043 /* Unlink can be called from rename so we can not take the
1044 * sb->s_vfs_rename_mutex here */
1045 full_path = build_path_from_dentry(dentry);
1046 if (full_path == NULL) {
1047 rc = -ENOMEM;
1048 FreeXid(xid);
1049 return rc;
1052 if ((tcon->ses->capabilities & CAP_UNIX) &&
1053 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1054 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1055 rc = CIFSPOSIXDelFile(xid, tcon, full_path,
1056 SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
1057 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1058 cFYI(1, ("posix del rc %d", rc));
1059 if ((rc == 0) || (rc == -ENOENT))
1060 goto psx_del_no_retry;
1063 retry_std_delete:
1064 rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls,
1065 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1067 psx_del_no_retry:
1068 if (!rc) {
1069 if (inode)
1070 drop_nlink(inode);
1071 } else if (rc == -ENOENT) {
1072 d_drop(dentry);
1073 } else if (rc == -ETXTBSY) {
1074 rc = cifs_rename_pending_delete(full_path, dentry, xid);
1075 if (rc == 0)
1076 drop_nlink(inode);
1077 } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
1078 attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
1079 if (attrs == NULL) {
1080 rc = -ENOMEM;
1081 goto out_reval;
1084 /* try to reset dos attributes */
1085 cifs_inode = CIFS_I(inode);
1086 origattr = cifs_inode->cifsAttrs;
1087 if (origattr == 0)
1088 origattr |= ATTR_NORMAL;
1089 dosattr = origattr & ~ATTR_READONLY;
1090 if (dosattr == 0)
1091 dosattr |= ATTR_NORMAL;
1092 dosattr |= ATTR_HIDDEN;
1094 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
1095 if (rc != 0)
1096 goto out_reval;
1098 goto retry_std_delete;
1101 /* undo the setattr if we errored out and it's needed */
1102 if (rc != 0 && dosattr != 0)
1103 cifs_set_file_info(inode, attrs, xid, full_path, origattr);
1105 out_reval:
1106 if (inode) {
1107 cifs_inode = CIFS_I(inode);
1108 cifs_inode->time = 0; /* will force revalidate to get info
1109 when needed */
1110 inode->i_ctime = current_fs_time(sb);
1112 dir->i_ctime = dir->i_mtime = current_fs_time(sb);
1113 cifs_inode = CIFS_I(dir);
1114 CIFS_I(dir)->time = 0; /* force revalidate of dir as well */
1116 kfree(full_path);
1117 kfree(attrs);
1118 FreeXid(xid);
1119 return rc;
1122 int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1124 int rc = 0, tmprc;
1125 int xid;
1126 struct cifs_sb_info *cifs_sb;
1127 struct cifsTconInfo *pTcon;
1128 char *full_path = NULL;
1129 struct inode *newinode = NULL;
1130 struct cifs_fattr fattr;
1132 cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
1134 xid = GetXid();
1136 cifs_sb = CIFS_SB(inode->i_sb);
1137 pTcon = cifs_sb->tcon;
1139 full_path = build_path_from_dentry(direntry);
1140 if (full_path == NULL) {
1141 rc = -ENOMEM;
1142 FreeXid(xid);
1143 return rc;
1146 if ((pTcon->ses->capabilities & CAP_UNIX) &&
1147 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1148 le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
1149 u32 oplock = 0;
1150 FILE_UNIX_BASIC_INFO *pInfo =
1151 kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1152 if (pInfo == NULL) {
1153 rc = -ENOMEM;
1154 goto mkdir_out;
1157 mode &= ~current_umask();
1158 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
1159 mode, NULL /* netfid */, pInfo, &oplock,
1160 full_path, cifs_sb->local_nls,
1161 cifs_sb->mnt_cifs_flags &
1162 CIFS_MOUNT_MAP_SPECIAL_CHR);
1163 if (rc == -EOPNOTSUPP) {
1164 kfree(pInfo);
1165 goto mkdir_retry_old;
1166 } else if (rc) {
1167 cFYI(1, ("posix mkdir returned 0x%x", rc));
1168 d_drop(direntry);
1169 } else {
1170 if (pInfo->Type == cpu_to_le32(-1)) {
1171 /* no return info, go query for it */
1172 kfree(pInfo);
1173 goto mkdir_get_info;
1175 /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
1176 to set uid/gid */
1177 inc_nlink(inode);
1178 if (pTcon->nocase)
1179 direntry->d_op = &cifs_ci_dentry_ops;
1180 else
1181 direntry->d_op = &cifs_dentry_ops;
1183 cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
1184 newinode = cifs_iget(inode->i_sb, &fattr);
1185 if (!newinode) {
1186 kfree(pInfo);
1187 goto mkdir_get_info;
1190 d_instantiate(direntry, newinode);
1192 #ifdef CONFIG_CIFS_DEBUG2
1193 cFYI(1, ("instantiated dentry %p %s to inode %p",
1194 direntry, direntry->d_name.name, newinode));
1196 if (newinode->i_nlink != 2)
1197 cFYI(1, ("unexpected number of links %d",
1198 newinode->i_nlink));
1199 #endif
1201 kfree(pInfo);
1202 goto mkdir_out;
1204 mkdir_retry_old:
1205 /* BB add setting the equivalent of mode via CreateX w/ACLs */
1206 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
1207 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1208 if (rc) {
1209 cFYI(1, ("cifs_mkdir returned 0x%x", rc));
1210 d_drop(direntry);
1211 } else {
1212 mkdir_get_info:
1213 inc_nlink(inode);
1214 if (pTcon->unix_ext)
1215 rc = cifs_get_inode_info_unix(&newinode, full_path,
1216 inode->i_sb, xid);
1217 else
1218 rc = cifs_get_inode_info(&newinode, full_path, NULL,
1219 inode->i_sb, xid, NULL);
1221 if (pTcon->nocase)
1222 direntry->d_op = &cifs_ci_dentry_ops;
1223 else
1224 direntry->d_op = &cifs_dentry_ops;
1225 d_instantiate(direntry, newinode);
1226 /* setting nlink not necessary except in cases where we
1227 * failed to get it from the server or was set bogus */
1228 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
1229 direntry->d_inode->i_nlink = 2;
1231 mode &= ~current_umask();
1232 /* must turn on setgid bit if parent dir has it */
1233 if (inode->i_mode & S_ISGID)
1234 mode |= S_ISGID;
1236 if (pTcon->unix_ext) {
1237 struct cifs_unix_set_info_args args = {
1238 .mode = mode,
1239 .ctime = NO_CHANGE_64,
1240 .atime = NO_CHANGE_64,
1241 .mtime = NO_CHANGE_64,
1242 .device = 0,
1244 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
1245 args.uid = (__u64)current_fsuid();
1246 if (inode->i_mode & S_ISGID)
1247 args.gid = (__u64)inode->i_gid;
1248 else
1249 args.gid = (__u64)current_fsgid();
1250 } else {
1251 args.uid = NO_CHANGE_64;
1252 args.gid = NO_CHANGE_64;
1254 CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
1255 cifs_sb->local_nls,
1256 cifs_sb->mnt_cifs_flags &
1257 CIFS_MOUNT_MAP_SPECIAL_CHR);
1258 } else {
1259 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
1260 (mode & S_IWUGO) == 0) {
1261 FILE_BASIC_INFO pInfo;
1262 struct cifsInodeInfo *cifsInode;
1263 u32 dosattrs;
1265 memset(&pInfo, 0, sizeof(pInfo));
1266 cifsInode = CIFS_I(newinode);
1267 dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
1268 pInfo.Attributes = cpu_to_le32(dosattrs);
1269 tmprc = CIFSSMBSetPathInfo(xid, pTcon,
1270 full_path, &pInfo,
1271 cifs_sb->local_nls,
1272 cifs_sb->mnt_cifs_flags &
1273 CIFS_MOUNT_MAP_SPECIAL_CHR);
1274 if (tmprc == 0)
1275 cifsInode->cifsAttrs = dosattrs;
1277 if (direntry->d_inode) {
1278 if (cifs_sb->mnt_cifs_flags &
1279 CIFS_MOUNT_DYNPERM)
1280 direntry->d_inode->i_mode =
1281 (mode | S_IFDIR);
1283 if (cifs_sb->mnt_cifs_flags &
1284 CIFS_MOUNT_SET_UID) {
1285 direntry->d_inode->i_uid =
1286 current_fsuid();
1287 if (inode->i_mode & S_ISGID)
1288 direntry->d_inode->i_gid =
1289 inode->i_gid;
1290 else
1291 direntry->d_inode->i_gid =
1292 current_fsgid();
1297 mkdir_out:
1298 kfree(full_path);
1299 FreeXid(xid);
1300 return rc;
1303 int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1305 int rc = 0;
1306 int xid;
1307 struct cifs_sb_info *cifs_sb;
1308 struct cifsTconInfo *pTcon;
1309 char *full_path = NULL;
1310 struct cifsInodeInfo *cifsInode;
1312 cFYI(1, ("cifs_rmdir, inode = 0x%p", inode));
1314 xid = GetXid();
1316 cifs_sb = CIFS_SB(inode->i_sb);
1317 pTcon = cifs_sb->tcon;
1319 full_path = build_path_from_dentry(direntry);
1320 if (full_path == NULL) {
1321 rc = -ENOMEM;
1322 FreeXid(xid);
1323 return rc;
1326 rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1327 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1329 if (!rc) {
1330 drop_nlink(inode);
1331 spin_lock(&direntry->d_inode->i_lock);
1332 i_size_write(direntry->d_inode, 0);
1333 clear_nlink(direntry->d_inode);
1334 spin_unlock(&direntry->d_inode->i_lock);
1337 cifsInode = CIFS_I(direntry->d_inode);
1338 cifsInode->time = 0; /* force revalidate to go get info when
1339 needed */
1341 cifsInode = CIFS_I(inode);
1342 cifsInode->time = 0; /* force revalidate to get parent dir info
1343 since cached search results now invalid */
1345 direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1346 current_fs_time(inode->i_sb);
1348 kfree(full_path);
1349 FreeXid(xid);
1350 return rc;
1353 static int
1354 cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1355 struct dentry *to_dentry, const char *toPath)
1357 struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
1358 struct cifsTconInfo *pTcon = cifs_sb->tcon;
1359 __u16 srcfid;
1360 int oplock, rc;
1362 /* try path-based rename first */
1363 rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
1364 cifs_sb->mnt_cifs_flags &
1365 CIFS_MOUNT_MAP_SPECIAL_CHR);
1368 * don't bother with rename by filehandle unless file is busy and
1369 * source Note that cross directory moves do not work with
1370 * rename by filehandle to various Windows servers.
1372 if (rc == 0 || rc != -ETXTBSY)
1373 return rc;
1375 /* open the file to be renamed -- we need DELETE perms */
1376 rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE,
1377 CREATE_NOT_DIR, &srcfid, &oplock, NULL,
1378 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1379 CIFS_MOUNT_MAP_SPECIAL_CHR);
1381 if (rc == 0) {
1382 rc = CIFSSMBRenameOpenFile(xid, pTcon, srcfid,
1383 (const char *) to_dentry->d_name.name,
1384 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1385 CIFS_MOUNT_MAP_SPECIAL_CHR);
1387 CIFSSMBClose(xid, pTcon, srcfid);
1390 return rc;
1393 int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1394 struct inode *target_dir, struct dentry *target_dentry)
1396 char *fromName = NULL;
1397 char *toName = NULL;
1398 struct cifs_sb_info *cifs_sb_source;
1399 struct cifs_sb_info *cifs_sb_target;
1400 struct cifsTconInfo *tcon;
1401 FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1402 FILE_UNIX_BASIC_INFO *info_buf_target;
1403 int xid, rc, tmprc;
1405 cifs_sb_target = CIFS_SB(target_dir->i_sb);
1406 cifs_sb_source = CIFS_SB(source_dir->i_sb);
1407 tcon = cifs_sb_source->tcon;
1409 xid = GetXid();
1412 * BB: this might be allowed if same server, but different share.
1413 * Consider adding support for this
1415 if (tcon != cifs_sb_target->tcon) {
1416 rc = -EXDEV;
1417 goto cifs_rename_exit;
1421 * we already have the rename sem so we do not need to
1422 * grab it again here to protect the path integrity
1424 fromName = build_path_from_dentry(source_dentry);
1425 if (fromName == NULL) {
1426 rc = -ENOMEM;
1427 goto cifs_rename_exit;
1430 toName = build_path_from_dentry(target_dentry);
1431 if (toName == NULL) {
1432 rc = -ENOMEM;
1433 goto cifs_rename_exit;
1436 rc = cifs_do_rename(xid, source_dentry, fromName,
1437 target_dentry, toName);
1439 if (rc == -EEXIST && tcon->unix_ext) {
1441 * Are src and dst hardlinks of same inode? We can
1442 * only tell with unix extensions enabled
1444 info_buf_source =
1445 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
1446 GFP_KERNEL);
1447 if (info_buf_source == NULL) {
1448 rc = -ENOMEM;
1449 goto cifs_rename_exit;
1452 info_buf_target = info_buf_source + 1;
1453 tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
1454 info_buf_source,
1455 cifs_sb_source->local_nls,
1456 cifs_sb_source->mnt_cifs_flags &
1457 CIFS_MOUNT_MAP_SPECIAL_CHR);
1458 if (tmprc != 0)
1459 goto unlink_target;
1461 tmprc = CIFSSMBUnixQPathInfo(xid, tcon,
1462 toName, info_buf_target,
1463 cifs_sb_target->local_nls,
1464 /* remap based on source sb */
1465 cifs_sb_source->mnt_cifs_flags &
1466 CIFS_MOUNT_MAP_SPECIAL_CHR);
1468 if (tmprc == 0 && (info_buf_source->UniqueId ==
1469 info_buf_target->UniqueId)) {
1470 /* same file, POSIX says that this is a noop */
1471 rc = 0;
1472 goto cifs_rename_exit;
1474 } /* else ... BB we could add the same check for Windows by
1475 checking the UniqueId via FILE_INTERNAL_INFO */
1477 unlink_target:
1478 /* Try unlinking the target dentry if it's not negative */
1479 if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) {
1480 tmprc = cifs_unlink(target_dir, target_dentry);
1481 if (tmprc)
1482 goto cifs_rename_exit;
1484 rc = cifs_do_rename(xid, source_dentry, fromName,
1485 target_dentry, toName);
1488 cifs_rename_exit:
1489 kfree(info_buf_source);
1490 kfree(fromName);
1491 kfree(toName);
1492 FreeXid(xid);
1493 return rc;
1496 static bool
1497 cifs_inode_needs_reval(struct inode *inode)
1499 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1501 if (cifs_i->clientCanCacheRead)
1502 return false;
1504 if (!lookupCacheEnabled)
1505 return true;
1507 if (cifs_i->time == 0)
1508 return true;
1510 /* FIXME: the actimeo should be tunable */
1511 if (time_after_eq(jiffies, cifs_i->time + HZ))
1512 return true;
1514 return false;
1517 /* check invalid_mapping flag and zap the cache if it's set */
1518 static void
1519 cifs_invalidate_mapping(struct inode *inode)
1521 int rc;
1522 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1524 cifs_i->invalid_mapping = false;
1526 /* write back any cached data */
1527 if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
1528 rc = filemap_write_and_wait(inode->i_mapping);
1529 if (rc)
1530 cifs_i->write_behind_rc = rc;
1532 invalidate_remote_inode(inode);
1535 int cifs_revalidate_file(struct file *filp)
1537 int rc = 0;
1538 struct inode *inode = filp->f_path.dentry->d_inode;
1540 if (!cifs_inode_needs_reval(inode))
1541 goto check_inval;
1543 if (CIFS_SB(inode->i_sb)->tcon->unix_ext)
1544 rc = cifs_get_file_info_unix(filp);
1545 else
1546 rc = cifs_get_file_info(filp);
1548 check_inval:
1549 if (CIFS_I(inode)->invalid_mapping)
1550 cifs_invalidate_mapping(inode);
1552 return rc;
1555 /* revalidate a dentry's inode attributes */
1556 int cifs_revalidate_dentry(struct dentry *dentry)
1558 int xid;
1559 int rc = 0;
1560 char *full_path = NULL;
1561 struct inode *inode = dentry->d_inode;
1562 struct super_block *sb = dentry->d_sb;
1564 if (inode == NULL)
1565 return -ENOENT;
1567 xid = GetXid();
1569 if (!cifs_inode_needs_reval(inode))
1570 goto check_inval;
1572 /* can not safely grab the rename sem here if rename calls revalidate
1573 since that would deadlock */
1574 full_path = build_path_from_dentry(dentry);
1575 if (full_path == NULL) {
1576 rc = -ENOMEM;
1577 goto check_inval;
1580 cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
1581 "jiffies %ld", full_path, inode, inode->i_count.counter,
1582 dentry, dentry->d_time, jiffies));
1584 if (CIFS_SB(sb)->tcon->unix_ext)
1585 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
1586 else
1587 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
1588 xid, NULL);
1590 check_inval:
1591 if (CIFS_I(inode)->invalid_mapping)
1592 cifs_invalidate_mapping(inode);
1594 kfree(full_path);
1595 FreeXid(xid);
1596 return rc;
1599 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1600 struct kstat *stat)
1602 int err = cifs_revalidate_dentry(dentry);
1603 if (!err) {
1604 generic_fillattr(dentry->d_inode, stat);
1605 stat->blksize = CIFS_MAX_MSGSIZE;
1606 stat->ino = CIFS_I(dentry->d_inode)->uniqueid;
1608 return err;
1611 static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1613 pgoff_t index = from >> PAGE_CACHE_SHIFT;
1614 unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1615 struct page *page;
1616 int rc = 0;
1618 page = grab_cache_page(mapping, index);
1619 if (!page)
1620 return -ENOMEM;
1622 zero_user_segment(page, offset, PAGE_CACHE_SIZE);
1623 unlock_page(page);
1624 page_cache_release(page);
1625 return rc;
1628 static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1630 loff_t oldsize;
1631 int err;
1633 spin_lock(&inode->i_lock);
1634 err = inode_newsize_ok(inode, offset);
1635 if (err) {
1636 spin_unlock(&inode->i_lock);
1637 goto out;
1640 oldsize = inode->i_size;
1641 i_size_write(inode, offset);
1642 spin_unlock(&inode->i_lock);
1643 truncate_pagecache(inode, oldsize, offset);
1644 if (inode->i_op->truncate)
1645 inode->i_op->truncate(inode);
1646 out:
1647 return err;
1650 static int
1651 cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1652 int xid, char *full_path)
1654 int rc;
1655 struct cifsFileInfo *open_file;
1656 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1657 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1658 struct cifsTconInfo *pTcon = cifs_sb->tcon;
1661 * To avoid spurious oplock breaks from server, in the case of
1662 * inodes that we already have open, avoid doing path based
1663 * setting of file size if we can do it by handle.
1664 * This keeps our caching token (oplock) and avoids timeouts
1665 * when the local oplock break takes longer to flush
1666 * writebehind data than the SMB timeout for the SetPathInfo
1667 * request would allow
1669 open_file = find_writable_file(cifsInode);
1670 if (open_file) {
1671 __u16 nfid = open_file->netfid;
1672 __u32 npid = open_file->pid;
1673 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1674 npid, false);
1675 cifsFileInfo_put(open_file);
1676 cFYI(1, ("SetFSize for attrs rc = %d", rc));
1677 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1678 unsigned int bytes_written;
1679 rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
1680 &bytes_written, NULL, NULL, 1);
1681 cFYI(1, ("Wrt seteof rc %d", rc));
1683 } else
1684 rc = -EINVAL;
1686 if (rc != 0) {
1687 /* Set file size by pathname rather than by handle
1688 either because no valid, writeable file handle for
1689 it was found or because there was an error setting
1690 it by handle */
1691 rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,
1692 false, cifs_sb->local_nls,
1693 cifs_sb->mnt_cifs_flags &
1694 CIFS_MOUNT_MAP_SPECIAL_CHR);
1695 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1696 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1697 __u16 netfid;
1698 int oplock = 0;
1700 rc = SMBLegacyOpen(xid, pTcon, full_path,
1701 FILE_OPEN, GENERIC_WRITE,
1702 CREATE_NOT_DIR, &netfid, &oplock, NULL,
1703 cifs_sb->local_nls,
1704 cifs_sb->mnt_cifs_flags &
1705 CIFS_MOUNT_MAP_SPECIAL_CHR);
1706 if (rc == 0) {
1707 unsigned int bytes_written;
1708 rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
1709 attrs->ia_size,
1710 &bytes_written, NULL,
1711 NULL, 1);
1712 cFYI(1, ("wrt seteof rc %d", rc));
1713 CIFSSMBClose(xid, pTcon, netfid);
1718 if (rc == 0) {
1719 cifsInode->server_eof = attrs->ia_size;
1720 rc = cifs_vmtruncate(inode, attrs->ia_size);
1721 cifs_truncate_page(inode->i_mapping, inode->i_size);
1724 return rc;
1727 static int
1728 cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1730 int rc;
1731 int xid;
1732 char *full_path = NULL;
1733 struct inode *inode = direntry->d_inode;
1734 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1735 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1736 struct cifsTconInfo *pTcon = cifs_sb->tcon;
1737 struct cifs_unix_set_info_args *args = NULL;
1738 struct cifsFileInfo *open_file;
1740 cFYI(1, ("setattr_unix on file %s attrs->ia_valid=0x%x",
1741 direntry->d_name.name, attrs->ia_valid));
1743 xid = GetXid();
1745 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1746 /* check if we have permission to change attrs */
1747 rc = inode_change_ok(inode, attrs);
1748 if (rc < 0)
1749 goto out;
1750 else
1751 rc = 0;
1754 full_path = build_path_from_dentry(direntry);
1755 if (full_path == NULL) {
1756 rc = -ENOMEM;
1757 goto out;
1761 * Attempt to flush data before changing attributes. We need to do
1762 * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1763 * ownership or mode then we may also need to do this. Here, we take
1764 * the safe way out and just do the flush on all setattr requests. If
1765 * the flush returns error, store it to report later and continue.
1767 * BB: This should be smarter. Why bother flushing pages that
1768 * will be truncated anyway? Also, should we error out here if
1769 * the flush returns error?
1771 rc = filemap_write_and_wait(inode->i_mapping);
1772 if (rc != 0) {
1773 cifsInode->write_behind_rc = rc;
1774 rc = 0;
1777 if (attrs->ia_valid & ATTR_SIZE) {
1778 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1779 if (rc != 0)
1780 goto out;
1783 /* skip mode change if it's just for clearing setuid/setgid */
1784 if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1785 attrs->ia_valid &= ~ATTR_MODE;
1787 args = kmalloc(sizeof(*args), GFP_KERNEL);
1788 if (args == NULL) {
1789 rc = -ENOMEM;
1790 goto out;
1793 /* set up the struct */
1794 if (attrs->ia_valid & ATTR_MODE)
1795 args->mode = attrs->ia_mode;
1796 else
1797 args->mode = NO_CHANGE_64;
1799 if (attrs->ia_valid & ATTR_UID)
1800 args->uid = attrs->ia_uid;
1801 else
1802 args->uid = NO_CHANGE_64;
1804 if (attrs->ia_valid & ATTR_GID)
1805 args->gid = attrs->ia_gid;
1806 else
1807 args->gid = NO_CHANGE_64;
1809 if (attrs->ia_valid & ATTR_ATIME)
1810 args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
1811 else
1812 args->atime = NO_CHANGE_64;
1814 if (attrs->ia_valid & ATTR_MTIME)
1815 args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
1816 else
1817 args->mtime = NO_CHANGE_64;
1819 if (attrs->ia_valid & ATTR_CTIME)
1820 args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
1821 else
1822 args->ctime = NO_CHANGE_64;
1824 args->device = 0;
1825 open_file = find_writable_file(cifsInode);
1826 if (open_file) {
1827 u16 nfid = open_file->netfid;
1828 u32 npid = open_file->pid;
1829 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
1830 cifsFileInfo_put(open_file);
1831 } else {
1832 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
1833 cifs_sb->local_nls,
1834 cifs_sb->mnt_cifs_flags &
1835 CIFS_MOUNT_MAP_SPECIAL_CHR);
1838 if (!rc) {
1839 rc = inode_setattr(inode, attrs);
1841 /* force revalidate when any of these times are set since some
1842 of the fs types (eg ext3, fat) do not have fine enough
1843 time granularity to match protocol, and we do not have a
1844 a way (yet) to query the server fs's time granularity (and
1845 whether it rounds times down).
1847 if (!rc && (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME)))
1848 cifsInode->time = 0;
1850 out:
1851 kfree(args);
1852 kfree(full_path);
1853 FreeXid(xid);
1854 return rc;
1857 static int
1858 cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
1860 int xid;
1861 struct inode *inode = direntry->d_inode;
1862 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1863 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1864 char *full_path = NULL;
1865 int rc = -EACCES;
1866 __u32 dosattr = 0;
1867 __u64 mode = NO_CHANGE_64;
1869 xid = GetXid();
1871 cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
1872 direntry->d_name.name, attrs->ia_valid));
1874 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1875 /* check if we have permission to change attrs */
1876 rc = inode_change_ok(inode, attrs);
1877 if (rc < 0) {
1878 FreeXid(xid);
1879 return rc;
1880 } else
1881 rc = 0;
1884 full_path = build_path_from_dentry(direntry);
1885 if (full_path == NULL) {
1886 rc = -ENOMEM;
1887 FreeXid(xid);
1888 return rc;
1892 * Attempt to flush data before changing attributes. We need to do
1893 * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1894 * ownership or mode then we may also need to do this. Here, we take
1895 * the safe way out and just do the flush on all setattr requests. If
1896 * the flush returns error, store it to report later and continue.
1898 * BB: This should be smarter. Why bother flushing pages that
1899 * will be truncated anyway? Also, should we error out here if
1900 * the flush returns error?
1902 rc = filemap_write_and_wait(inode->i_mapping);
1903 if (rc != 0) {
1904 cifsInode->write_behind_rc = rc;
1905 rc = 0;
1908 if (attrs->ia_valid & ATTR_SIZE) {
1909 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1910 if (rc != 0)
1911 goto cifs_setattr_exit;
1915 * Without unix extensions we can't send ownership changes to the
1916 * server, so silently ignore them. This is consistent with how
1917 * local DOS/Windows filesystems behave (VFAT, NTFS, etc). With
1918 * CIFSACL support + proper Windows to Unix idmapping, we may be
1919 * able to support this in the future.
1921 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
1922 attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
1924 /* skip mode change if it's just for clearing setuid/setgid */
1925 if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1926 attrs->ia_valid &= ~ATTR_MODE;
1928 if (attrs->ia_valid & ATTR_MODE) {
1929 cFYI(1, ("Mode changed to 0%o", attrs->ia_mode));
1930 mode = attrs->ia_mode;
1933 if (attrs->ia_valid & ATTR_MODE) {
1934 rc = 0;
1935 #ifdef CONFIG_CIFS_EXPERIMENTAL
1936 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1937 rc = mode_to_acl(inode, full_path, mode);
1938 else
1939 #endif
1940 if (((mode & S_IWUGO) == 0) &&
1941 (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1943 dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
1945 /* fix up mode if we're not using dynperm */
1946 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
1947 attrs->ia_mode = inode->i_mode & ~S_IWUGO;
1948 } else if ((mode & S_IWUGO) &&
1949 (cifsInode->cifsAttrs & ATTR_READONLY)) {
1951 dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
1952 /* Attributes of 0 are ignored */
1953 if (dosattr == 0)
1954 dosattr |= ATTR_NORMAL;
1956 /* reset local inode permissions to normal */
1957 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1958 attrs->ia_mode &= ~(S_IALLUGO);
1959 if (S_ISDIR(inode->i_mode))
1960 attrs->ia_mode |=
1961 cifs_sb->mnt_dir_mode;
1962 else
1963 attrs->ia_mode |=
1964 cifs_sb->mnt_file_mode;
1966 } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1967 /* ignore mode change - ATTR_READONLY hasn't changed */
1968 attrs->ia_valid &= ~ATTR_MODE;
1972 if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||
1973 ((attrs->ia_valid & ATTR_MODE) && dosattr)) {
1974 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
1975 /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */
1977 /* Even if error on time set, no sense failing the call if
1978 the server would set the time to a reasonable value anyway,
1979 and this check ensures that we are not being called from
1980 sys_utimes in which case we ought to fail the call back to
1981 the user when the server rejects the call */
1982 if ((rc) && (attrs->ia_valid &
1983 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
1984 rc = 0;
1987 /* do not need local check to inode_check_ok since the server does
1988 that */
1989 if (!rc)
1990 rc = inode_setattr(inode, attrs);
1991 cifs_setattr_exit:
1992 kfree(full_path);
1993 FreeXid(xid);
1994 return rc;
1998 cifs_setattr(struct dentry *direntry, struct iattr *attrs)
2000 struct inode *inode = direntry->d_inode;
2001 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2002 struct cifsTconInfo *pTcon = cifs_sb->tcon;
2004 if (pTcon->unix_ext)
2005 return cifs_setattr_unix(direntry, attrs);
2007 return cifs_setattr_nounix(direntry, attrs);
2009 /* BB: add cifs_setattr_legacy for really old servers */
2012 #if 0
2013 void cifs_delete_inode(struct inode *inode)
2015 cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
2016 /* may have to add back in if and when safe distributed caching of
2017 directories added e.g. via FindNotify */
2019 #endif