[CIFS] checkpatch cleanup
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / cifs / inode.c
blob723daaccbd0e75b87e10169485de124f504d5fd2
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/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"
33 static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
35 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
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 { /* not direct, send byte range locks */
48 inode->i_fop = &cifs_file_ops;
52 /* check if server can support readpages */
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 /* NO DFS support, treat as a directory */
66 #endif
67 inode->i_op = &cifs_dir_inode_ops;
68 inode->i_fop = &cifs_dir_ops;
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;
80 /* check inode attributes against fattr. If they don't match, tag the
81 * inode for cache invalidation
83 static void
84 cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
86 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
88 cFYI(1, ("%s: revalidating inode %llu", __func__, cifs_i->uniqueid));
90 if (inode->i_state & I_NEW) {
91 cFYI(1, ("%s: inode %llu is new", __func__, cifs_i->uniqueid));
92 return;
95 /* don't bother with revalidation if we have an oplock */
96 if (cifs_i->clientCanCacheRead) {
97 cFYI(1, ("%s: inode %llu is oplocked", __func__,
98 cifs_i->uniqueid));
99 return;
102 /* revalidate if mtime or size have changed */
103 if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) &&
104 cifs_i->server_eof == fattr->cf_eof) {
105 cFYI(1, ("%s: inode %llu is unchanged", __func__,
106 cifs_i->uniqueid));
107 return;
110 cFYI(1, ("%s: invalidating inode %llu mapping", __func__,
111 cifs_i->uniqueid));
112 cifs_i->invalid_mapping = true;
115 /* populate an inode with info from a cifs_fattr struct */
116 void
117 cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
119 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
120 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
121 unsigned long oldtime = cifs_i->time;
123 cifs_revalidate_cache(inode, fattr);
125 inode->i_atime = fattr->cf_atime;
126 inode->i_mtime = fattr->cf_mtime;
127 inode->i_ctime = fattr->cf_ctime;
128 inode->i_rdev = fattr->cf_rdev;
129 inode->i_nlink = fattr->cf_nlink;
130 inode->i_uid = fattr->cf_uid;
131 inode->i_gid = fattr->cf_gid;
133 /* if dynperm is set, don't clobber existing mode */
134 if (inode->i_state & I_NEW ||
135 !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
136 inode->i_mode = fattr->cf_mode;
138 cifs_i->cifsAttrs = fattr->cf_cifsattrs;
139 cifs_i->uniqueid = fattr->cf_uniqueid;
141 if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
142 cifs_i->time = 0;
143 else
144 cifs_i->time = jiffies;
146 cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode,
147 oldtime, cifs_i->time));
149 cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
151 cifs_i->server_eof = fattr->cf_eof;
153 * Can't safely change the file size here if the client is writing to
154 * it due to potential races.
156 spin_lock(&inode->i_lock);
157 if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
158 i_size_write(inode, fattr->cf_eof);
161 * i_blocks is not related to (i_size / i_blksize),
162 * but instead 512 byte (2**9) size is required for
163 * calculating num blocks.
165 inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
167 spin_unlock(&inode->i_lock);
169 cifs_set_ops(inode, fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL);
172 /* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
173 void
174 cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
175 struct cifs_sb_info *cifs_sb)
177 memset(fattr, 0, sizeof(*fattr));
178 fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
179 fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
180 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
182 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
183 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
184 fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
185 fattr->cf_mode = le64_to_cpu(info->Permissions);
188 * Since we set the inode type below we need to mask off
189 * to avoid strange results if bits set above.
191 fattr->cf_mode &= ~S_IFMT;
192 switch (le32_to_cpu(info->Type)) {
193 case UNIX_FILE:
194 fattr->cf_mode |= S_IFREG;
195 fattr->cf_dtype = DT_REG;
196 break;
197 case UNIX_SYMLINK:
198 fattr->cf_mode |= S_IFLNK;
199 fattr->cf_dtype = DT_LNK;
200 break;
201 case UNIX_DIR:
202 fattr->cf_mode |= S_IFDIR;
203 fattr->cf_dtype = DT_DIR;
204 break;
205 case UNIX_CHARDEV:
206 fattr->cf_mode |= S_IFCHR;
207 fattr->cf_dtype = DT_CHR;
208 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
209 le64_to_cpu(info->DevMinor) & MINORMASK);
210 break;
211 case UNIX_BLOCKDEV:
212 fattr->cf_mode |= S_IFBLK;
213 fattr->cf_dtype = DT_BLK;
214 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
215 le64_to_cpu(info->DevMinor) & MINORMASK);
216 break;
217 case UNIX_FIFO:
218 fattr->cf_mode |= S_IFIFO;
219 fattr->cf_dtype = DT_FIFO;
220 break;
221 case UNIX_SOCKET:
222 fattr->cf_mode |= S_IFSOCK;
223 fattr->cf_dtype = DT_SOCK;
224 break;
225 default:
226 /* safest to call it a file if we do not know */
227 fattr->cf_mode |= S_IFREG;
228 fattr->cf_dtype = DT_REG;
229 cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
230 break;
233 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
234 fattr->cf_uid = cifs_sb->mnt_uid;
235 else
236 fattr->cf_uid = le64_to_cpu(info->Uid);
238 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
239 fattr->cf_gid = cifs_sb->mnt_gid;
240 else
241 fattr->cf_gid = le64_to_cpu(info->Gid);
243 fattr->cf_nlink = le64_to_cpu(info->Nlinks);
247 * Fill a cifs_fattr struct with fake inode info.
249 * Needed to setup cifs_fattr data for the directory which is the
250 * junction to the new submount (ie to setup the fake directory
251 * which represents a DFS referral).
253 static void
254 cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
256 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
258 cFYI(1, ("creating fake fattr for DFS referral"));
260 memset(fattr, 0, sizeof(*fattr));
261 fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
262 fattr->cf_uid = cifs_sb->mnt_uid;
263 fattr->cf_gid = cifs_sb->mnt_gid;
264 fattr->cf_atime = CURRENT_TIME;
265 fattr->cf_ctime = CURRENT_TIME;
266 fattr->cf_mtime = CURRENT_TIME;
267 fattr->cf_nlink = 2;
268 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
271 int cifs_get_file_info_unix(struct file *filp)
273 int rc;
274 int xid;
275 FILE_UNIX_BASIC_INFO find_data;
276 struct cifs_fattr fattr;
277 struct inode *inode = filp->f_path.dentry->d_inode;
278 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
279 struct cifsTconInfo *tcon = cifs_sb->tcon;
280 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
282 xid = GetXid();
283 rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
284 if (!rc) {
285 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
286 } else if (rc == -EREMOTE) {
287 cifs_create_dfs_fattr(&fattr, inode->i_sb);
288 rc = 0;
291 cifs_fattr_to_inode(inode, &fattr);
292 FreeXid(xid);
293 return rc;
296 int cifs_get_inode_info_unix(struct inode **pinode,
297 const unsigned char *full_path,
298 struct super_block *sb, int xid)
300 int rc;
301 FILE_UNIX_BASIC_INFO find_data;
302 struct cifs_fattr fattr;
303 struct cifsTconInfo *tcon;
304 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
306 tcon = cifs_sb->tcon;
307 cFYI(1, ("Getting info on %s", full_path));
309 /* could have done a find first instead but this returns more info */
310 rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
311 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
312 CIFS_MOUNT_MAP_SPECIAL_CHR);
314 if (!rc) {
315 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
316 } else if (rc == -EREMOTE) {
317 cifs_create_dfs_fattr(&fattr, sb);
318 rc = 0;
319 } else {
320 return rc;
323 if (*pinode == NULL) {
324 /* get new inode */
325 *pinode = cifs_iget(sb, &fattr);
326 if (!*pinode)
327 rc = -ENOMEM;
328 } else {
329 /* we already have inode, update it */
330 cifs_fattr_to_inode(*pinode, &fattr);
333 return rc;
336 static int
337 cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
338 struct cifs_sb_info *cifs_sb, int xid)
340 int rc;
341 int oplock = 0;
342 __u16 netfid;
343 struct cifsTconInfo *pTcon = cifs_sb->tcon;
344 char buf[24];
345 unsigned int bytes_read;
346 char *pbuf;
348 pbuf = buf;
350 fattr->cf_mode &= ~S_IFMT;
352 if (fattr->cf_eof == 0) {
353 fattr->cf_mode |= S_IFIFO;
354 fattr->cf_dtype = DT_FIFO;
355 return 0;
356 } else if (fattr->cf_eof < 8) {
357 fattr->cf_mode |= S_IFREG;
358 fattr->cf_dtype = DT_REG;
359 return -EINVAL; /* EOPNOTSUPP? */
362 rc = CIFSSMBOpen(xid, pTcon, path, FILE_OPEN, GENERIC_READ,
363 CREATE_NOT_DIR, &netfid, &oplock, NULL,
364 cifs_sb->local_nls,
365 cifs_sb->mnt_cifs_flags &
366 CIFS_MOUNT_MAP_SPECIAL_CHR);
367 if (rc == 0) {
368 int buf_type = CIFS_NO_BUFFER;
369 /* Read header */
370 rc = CIFSSMBRead(xid, pTcon, netfid,
371 24 /* length */, 0 /* offset */,
372 &bytes_read, &pbuf, &buf_type);
373 if ((rc == 0) && (bytes_read >= 8)) {
374 if (memcmp("IntxBLK", pbuf, 8) == 0) {
375 cFYI(1, ("Block device"));
376 fattr->cf_mode |= S_IFBLK;
377 fattr->cf_dtype = DT_BLK;
378 if (bytes_read == 24) {
379 /* we have enough to decode dev num */
380 __u64 mjr; /* major */
381 __u64 mnr; /* minor */
382 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
383 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
384 fattr->cf_rdev = MKDEV(mjr, mnr);
386 } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
387 cFYI(1, ("Char device"));
388 fattr->cf_mode |= S_IFCHR;
389 fattr->cf_dtype = DT_CHR;
390 if (bytes_read == 24) {
391 /* we have enough to decode dev num */
392 __u64 mjr; /* major */
393 __u64 mnr; /* minor */
394 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
395 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
396 fattr->cf_rdev = MKDEV(mjr, mnr);
398 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
399 cFYI(1, ("Symlink"));
400 fattr->cf_mode |= S_IFLNK;
401 fattr->cf_dtype = DT_LNK;
402 } else {
403 fattr->cf_mode |= S_IFREG; /* file? */
404 fattr->cf_dtype = DT_REG;
405 rc = -EOPNOTSUPP;
407 } else {
408 fattr->cf_mode |= S_IFREG; /* then it is a file */
409 fattr->cf_dtype = DT_REG;
410 rc = -EOPNOTSUPP; /* or some unknown SFU type */
412 CIFSSMBClose(xid, pTcon, netfid);
414 return rc;
417 #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
420 * Fetch mode bits as provided by SFU.
422 * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ?
424 static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
425 struct cifs_sb_info *cifs_sb, int xid)
427 #ifdef CONFIG_CIFS_XATTR
428 ssize_t rc;
429 char ea_value[4];
430 __u32 mode;
432 rc = CIFSSMBQAllEAs(xid, cifs_sb->tcon, path, "SETFILEBITS",
433 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
434 cifs_sb->mnt_cifs_flags &
435 CIFS_MOUNT_MAP_SPECIAL_CHR);
436 if (rc < 0)
437 return (int)rc;
438 else if (rc > 3) {
439 mode = le32_to_cpu(*((__le32 *)ea_value));
440 fattr->cf_mode &= ~SFBITS_MASK;
441 cFYI(1, ("special bits 0%o org mode 0%o", mode,
442 fattr->cf_mode));
443 fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
444 cFYI(1, ("special mode bits 0%o", mode));
447 return 0;
448 #else
449 return -EOPNOTSUPP;
450 #endif
453 /* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
454 static void
455 cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
456 struct cifs_sb_info *cifs_sb, bool adjust_tz)
458 memset(fattr, 0, sizeof(*fattr));
459 fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
460 if (info->DeletePending)
461 fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;
463 if (info->LastAccessTime)
464 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
465 else
466 fattr->cf_atime = CURRENT_TIME;
468 fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
469 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
471 if (adjust_tz) {
472 fattr->cf_ctime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
473 fattr->cf_mtime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
476 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
477 fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
479 if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
480 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
481 fattr->cf_dtype = DT_DIR;
482 } else {
483 fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
484 fattr->cf_dtype = DT_REG;
486 /* clear write bits if ATTR_READONLY is set */
487 if (fattr->cf_cifsattrs & ATTR_READONLY)
488 fattr->cf_mode &= ~(S_IWUGO);
491 fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
493 fattr->cf_uid = cifs_sb->mnt_uid;
494 fattr->cf_gid = cifs_sb->mnt_gid;
497 int cifs_get_file_info(struct file *filp)
499 int rc;
500 int xid;
501 FILE_ALL_INFO find_data;
502 struct cifs_fattr fattr;
503 struct inode *inode = filp->f_path.dentry->d_inode;
504 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
505 struct cifsTconInfo *tcon = cifs_sb->tcon;
506 struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data;
508 xid = GetXid();
509 rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
510 if (rc == -EOPNOTSUPP || rc == -EINVAL) {
512 * FIXME: legacy server -- fall back to path-based call?
513 * for now, just skip revalidating and mark inode for
514 * immediate reval.
516 rc = 0;
517 CIFS_I(inode)->time = 0;
518 goto cgfi_exit;
519 } else if (rc == -EREMOTE) {
520 cifs_create_dfs_fattr(&fattr, inode->i_sb);
521 rc = 0;
522 } else if (rc)
523 goto cgfi_exit;
526 * don't bother with SFU junk here -- just mark inode as needing
527 * revalidation.
529 cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false);
530 fattr.cf_uniqueid = CIFS_I(inode)->uniqueid;
531 fattr.cf_flags |= CIFS_FATTR_NEED_REVAL;
532 cifs_fattr_to_inode(inode, &fattr);
533 cgfi_exit:
534 FreeXid(xid);
535 return rc;
538 int cifs_get_inode_info(struct inode **pinode,
539 const unsigned char *full_path, FILE_ALL_INFO *pfindData,
540 struct super_block *sb, int xid, const __u16 *pfid)
542 int rc = 0, tmprc;
543 struct cifsTconInfo *pTcon;
544 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
545 char *buf = NULL;
546 bool adjustTZ = false;
547 struct cifs_fattr fattr;
549 pTcon = cifs_sb->tcon;
550 cFYI(1, ("Getting info on %s", full_path));
552 if ((pfindData == NULL) && (*pinode != NULL)) {
553 if (CIFS_I(*pinode)->clientCanCacheRead) {
554 cFYI(1, ("No need to revalidate cached inode sizes"));
555 return rc;
559 /* if file info not passed in then get it from server */
560 if (pfindData == NULL) {
561 buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
562 if (buf == NULL)
563 return -ENOMEM;
564 pfindData = (FILE_ALL_INFO *)buf;
566 /* could do find first instead but this returns more info */
567 rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData,
568 0 /* not legacy */,
569 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
570 CIFS_MOUNT_MAP_SPECIAL_CHR);
571 /* BB optimize code so we do not make the above call
572 when server claims no NT SMB support and the above call
573 failed at least once - set flag in tcon or mount */
574 if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
575 rc = SMBQueryInformation(xid, pTcon, full_path,
576 pfindData, cifs_sb->local_nls,
577 cifs_sb->mnt_cifs_flags &
578 CIFS_MOUNT_MAP_SPECIAL_CHR);
579 adjustTZ = true;
583 if (!rc) {
584 cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
585 cifs_sb, adjustTZ);
586 } else if (rc == -EREMOTE) {
587 cifs_create_dfs_fattr(&fattr, sb);
588 rc = 0;
589 } else {
590 goto cgii_exit;
594 * If an inode wasn't passed in, then get the inode number
596 * Is an i_ino of zero legal? Can we use that to check if the server
597 * supports returning inode numbers? Are there other sanity checks we
598 * can use to ensure that the server is really filling in that field?
600 * We can not use the IndexNumber field by default from Windows or
601 * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA
602 * CIFS spec claims that this value is unique within the scope of a
603 * share, and the windows docs hint that it's actually unique
604 * per-machine.
606 * There may be higher info levels that work but are there Windows
607 * server or network appliances for which IndexNumber field is not
608 * guaranteed unique?
610 if (*pinode == NULL) {
611 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
612 int rc1 = 0;
614 rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
615 full_path, &fattr.cf_uniqueid,
616 cifs_sb->local_nls,
617 cifs_sb->mnt_cifs_flags &
618 CIFS_MOUNT_MAP_SPECIAL_CHR);
619 if (rc1 || !fattr.cf_uniqueid) {
620 cFYI(1, ("GetSrvInodeNum rc %d", rc1));
621 fattr.cf_uniqueid = iunique(sb, ROOT_I);
622 cifs_autodisable_serverino(cifs_sb);
624 } else {
625 fattr.cf_uniqueid = iunique(sb, ROOT_I);
627 } else {
628 fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
631 /* query for SFU type info if supported and needed */
632 if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
633 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
634 tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
635 if (tmprc)
636 cFYI(1, ("cifs_sfu_type failed: %d", tmprc));
639 #ifdef CONFIG_CIFS_EXPERIMENTAL
640 /* fill in 0777 bits from ACL */
641 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
642 cFYI(1, ("Getting mode bits from ACL"));
643 cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
645 #endif
647 /* fill in remaining high mode bits e.g. SUID, VTX */
648 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
649 cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
651 if (!*pinode) {
652 *pinode = cifs_iget(sb, &fattr);
653 if (!*pinode)
654 rc = -ENOMEM;
655 } else {
656 cifs_fattr_to_inode(*pinode, &fattr);
659 cgii_exit:
660 kfree(buf);
661 return rc;
664 static const struct inode_operations cifs_ipc_inode_ops = {
665 .lookup = cifs_lookup,
668 char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
670 int pplen = cifs_sb->prepathlen;
671 int dfsplen;
672 char *full_path = NULL;
674 /* if no prefix path, simply set path to the root of share to "" */
675 if (pplen == 0) {
676 full_path = kmalloc(1, GFP_KERNEL);
677 if (full_path)
678 full_path[0] = 0;
679 return full_path;
682 if (cifs_sb->tcon && (cifs_sb->tcon->Flags & SMB_SHARE_IS_IN_DFS))
683 dfsplen = strnlen(cifs_sb->tcon->treeName, MAX_TREE_SIZE + 1);
684 else
685 dfsplen = 0;
687 full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL);
688 if (full_path == NULL)
689 return full_path;
691 if (dfsplen) {
692 strncpy(full_path, cifs_sb->tcon->treeName, dfsplen);
693 /* switch slash direction in prepath depending on whether
694 * windows or posix style path names
696 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
697 int i;
698 for (i = 0; i < dfsplen; i++) {
699 if (full_path[i] == '\\')
700 full_path[i] = '/';
704 strncpy(full_path + dfsplen, cifs_sb->prepath, pplen);
705 full_path[dfsplen + pplen] = 0; /* add trailing null */
706 return full_path;
709 static int
710 cifs_find_inode(struct inode *inode, void *opaque)
712 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
714 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
715 return 0;
717 return 1;
720 static int
721 cifs_init_inode(struct inode *inode, void *opaque)
723 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
725 CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
726 return 0;
729 /* Given fattrs, get a corresponding inode */
730 struct inode *
731 cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
733 unsigned long hash;
734 struct inode *inode;
736 cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid));
738 /* hash down to 32-bits on 32-bit arch */
739 hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
741 inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
743 /* we have fattrs in hand, update the inode */
744 if (inode) {
745 cifs_fattr_to_inode(inode, fattr);
746 if (sb->s_flags & MS_NOATIME)
747 inode->i_flags |= S_NOATIME | S_NOCMTIME;
748 if (inode->i_state & I_NEW) {
749 inode->i_ino = hash;
750 unlock_new_inode(inode);
754 return inode;
757 /* gets root inode */
758 struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
760 int xid;
761 struct cifs_sb_info *cifs_sb;
762 struct inode *inode = NULL;
763 long rc;
764 char *full_path;
766 cifs_sb = CIFS_SB(sb);
767 full_path = cifs_build_path_to_root(cifs_sb);
768 if (full_path == NULL)
769 return ERR_PTR(-ENOMEM);
771 xid = GetXid();
772 if (cifs_sb->tcon->unix_ext)
773 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
774 else
775 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
776 xid, NULL);
778 if (!inode)
779 return ERR_PTR(-ENOMEM);
781 if (rc && cifs_sb->tcon->ipc) {
782 cFYI(1, ("ipc connection - fake read inode"));
783 inode->i_mode |= S_IFDIR;
784 inode->i_nlink = 2;
785 inode->i_op = &cifs_ipc_inode_ops;
786 inode->i_fop = &simple_dir_operations;
787 inode->i_uid = cifs_sb->mnt_uid;
788 inode->i_gid = cifs_sb->mnt_gid;
789 } else if (rc) {
790 kfree(full_path);
791 _FreeXid(xid);
792 iget_failed(inode);
793 return ERR_PTR(rc);
797 kfree(full_path);
798 /* can not call macro FreeXid here since in a void func
799 * TODO: This is no longer true
801 _FreeXid(xid);
802 return inode;
805 static int
806 cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
807 char *full_path, __u32 dosattr)
809 int rc;
810 int oplock = 0;
811 __u16 netfid;
812 __u32 netpid;
813 bool set_time = false;
814 struct cifsFileInfo *open_file;
815 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
816 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
817 struct cifsTconInfo *pTcon = cifs_sb->tcon;
818 FILE_BASIC_INFO info_buf;
820 if (attrs == NULL)
821 return -EINVAL;
823 if (attrs->ia_valid & ATTR_ATIME) {
824 set_time = true;
825 info_buf.LastAccessTime =
826 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime));
827 } else
828 info_buf.LastAccessTime = 0;
830 if (attrs->ia_valid & ATTR_MTIME) {
831 set_time = true;
832 info_buf.LastWriteTime =
833 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime));
834 } else
835 info_buf.LastWriteTime = 0;
838 * Samba throws this field away, but windows may actually use it.
839 * Do not set ctime unless other time stamps are changed explicitly
840 * (i.e. by utimes()) since we would then have a mix of client and
841 * server times.
843 if (set_time && (attrs->ia_valid & ATTR_CTIME)) {
844 cFYI(1, ("CIFS - CTIME changed"));
845 info_buf.ChangeTime =
846 cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime));
847 } else
848 info_buf.ChangeTime = 0;
850 info_buf.CreationTime = 0; /* don't change */
851 info_buf.Attributes = cpu_to_le32(dosattr);
854 * If the file is already open for write, just use that fileid
856 open_file = find_writable_file(cifsInode);
857 if (open_file) {
858 netfid = open_file->netfid;
859 netpid = open_file->pid;
860 goto set_via_filehandle;
864 * NT4 apparently returns success on this call, but it doesn't
865 * really work.
867 if (!(pTcon->ses->flags & CIFS_SES_NT4)) {
868 rc = CIFSSMBSetPathInfo(xid, pTcon, full_path,
869 &info_buf, cifs_sb->local_nls,
870 cifs_sb->mnt_cifs_flags &
871 CIFS_MOUNT_MAP_SPECIAL_CHR);
872 if (rc == 0) {
873 cifsInode->cifsAttrs = dosattr;
874 goto out;
875 } else if (rc != -EOPNOTSUPP && rc != -EINVAL)
876 goto out;
879 cFYI(1, ("calling SetFileInfo since SetPathInfo for "
880 "times not supported by this server"));
881 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN,
882 SYNCHRONIZE | FILE_WRITE_ATTRIBUTES,
883 CREATE_NOT_DIR, &netfid, &oplock,
884 NULL, cifs_sb->local_nls,
885 cifs_sb->mnt_cifs_flags &
886 CIFS_MOUNT_MAP_SPECIAL_CHR);
888 if (rc != 0) {
889 if (rc == -EIO)
890 rc = -EINVAL;
891 goto out;
894 netpid = current->tgid;
896 set_via_filehandle:
897 rc = CIFSSMBSetFileInfo(xid, pTcon, &info_buf, netfid, netpid);
898 if (!rc)
899 cifsInode->cifsAttrs = dosattr;
901 if (open_file == NULL)
902 CIFSSMBClose(xid, pTcon, netfid);
903 else
904 cifsFileInfo_put(open_file);
905 out:
906 return rc;
910 * open the given file (if it isn't already), set the DELETE_ON_CLOSE bit
911 * and rename it to a random name that hopefully won't conflict with
912 * anything else.
914 static int
915 cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
917 int oplock = 0;
918 int rc;
919 __u16 netfid;
920 struct inode *inode = dentry->d_inode;
921 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
922 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
923 struct cifsTconInfo *tcon = cifs_sb->tcon;
924 __u32 dosattr, origattr;
925 FILE_BASIC_INFO *info_buf = NULL;
927 rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN,
928 DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR,
929 &netfid, &oplock, NULL, cifs_sb->local_nls,
930 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
931 if (rc != 0)
932 goto out;
934 origattr = cifsInode->cifsAttrs;
935 if (origattr == 0)
936 origattr |= ATTR_NORMAL;
938 dosattr = origattr & ~ATTR_READONLY;
939 if (dosattr == 0)
940 dosattr |= ATTR_NORMAL;
941 dosattr |= ATTR_HIDDEN;
943 /* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */
944 if (dosattr != origattr) {
945 info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL);
946 if (info_buf == NULL) {
947 rc = -ENOMEM;
948 goto out_close;
950 info_buf->Attributes = cpu_to_le32(dosattr);
951 rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
952 current->tgid);
953 /* although we would like to mark the file hidden
954 if that fails we will still try to rename it */
955 if (rc != 0)
956 cifsInode->cifsAttrs = dosattr;
957 else
958 dosattr = origattr; /* since not able to change them */
961 /* rename the file */
962 rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls,
963 cifs_sb->mnt_cifs_flags &
964 CIFS_MOUNT_MAP_SPECIAL_CHR);
965 if (rc != 0) {
966 rc = -ETXTBSY;
967 goto undo_setattr;
970 /* try to set DELETE_ON_CLOSE */
971 if (!cifsInode->delete_pending) {
972 rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid,
973 current->tgid);
975 * some samba versions return -ENOENT when we try to set the
976 * file disposition here. Likely a samba bug, but work around
977 * it for now. This means that some cifsXXX files may hang
978 * around after they shouldn't.
980 * BB: remove this hack after more servers have the fix
982 if (rc == -ENOENT)
983 rc = 0;
984 else if (rc != 0) {
985 rc = -ETXTBSY;
986 goto undo_rename;
988 cifsInode->delete_pending = true;
991 out_close:
992 CIFSSMBClose(xid, tcon, netfid);
993 out:
994 kfree(info_buf);
995 return rc;
998 * reset everything back to the original state. Don't bother
999 * dealing with errors here since we can't do anything about
1000 * them anyway.
1002 undo_rename:
1003 CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name,
1004 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1005 CIFS_MOUNT_MAP_SPECIAL_CHR);
1006 undo_setattr:
1007 if (dosattr != origattr) {
1008 info_buf->Attributes = cpu_to_le32(origattr);
1009 if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid,
1010 current->tgid))
1011 cifsInode->cifsAttrs = origattr;
1014 goto out_close;
1019 * If dentry->d_inode is null (usually meaning the cached dentry
1020 * is a negative dentry) then we would attempt a standard SMB delete, but
1021 * if that fails we can not attempt the fall back mechanisms on EACCESS
1022 * but will return the EACCESS to the caller. Note that the VFS does not call
1023 * unlink on negative dentries currently.
1025 int cifs_unlink(struct inode *dir, struct dentry *dentry)
1027 int rc = 0;
1028 int xid;
1029 char *full_path = NULL;
1030 struct inode *inode = dentry->d_inode;
1031 struct cifsInodeInfo *cifs_inode;
1032 struct super_block *sb = dir->i_sb;
1033 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
1034 struct cifsTconInfo *tcon = cifs_sb->tcon;
1035 struct iattr *attrs = NULL;
1036 __u32 dosattr = 0, origattr = 0;
1038 cFYI(1, ("cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry));
1040 xid = GetXid();
1042 /* Unlink can be called from rename so we can not take the
1043 * sb->s_vfs_rename_mutex here */
1044 full_path = build_path_from_dentry(dentry);
1045 if (full_path == NULL) {
1046 rc = -ENOMEM;
1047 FreeXid(xid);
1048 return rc;
1051 if ((tcon->ses->capabilities & CAP_UNIX) &&
1052 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1053 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1054 rc = CIFSPOSIXDelFile(xid, tcon, full_path,
1055 SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls,
1056 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1057 cFYI(1, ("posix del rc %d", rc));
1058 if ((rc == 0) || (rc == -ENOENT))
1059 goto psx_del_no_retry;
1062 retry_std_delete:
1063 rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls,
1064 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1066 psx_del_no_retry:
1067 if (!rc) {
1068 if (inode)
1069 drop_nlink(inode);
1070 } else if (rc == -ENOENT) {
1071 d_drop(dentry);
1072 } else if (rc == -ETXTBSY) {
1073 rc = cifs_rename_pending_delete(full_path, dentry, xid);
1074 if (rc == 0)
1075 drop_nlink(inode);
1076 } else if ((rc == -EACCES) && (dosattr == 0) && inode) {
1077 attrs = kzalloc(sizeof(*attrs), GFP_KERNEL);
1078 if (attrs == NULL) {
1079 rc = -ENOMEM;
1080 goto out_reval;
1083 /* try to reset dos attributes */
1084 cifs_inode = CIFS_I(inode);
1085 origattr = cifs_inode->cifsAttrs;
1086 if (origattr == 0)
1087 origattr |= ATTR_NORMAL;
1088 dosattr = origattr & ~ATTR_READONLY;
1089 if (dosattr == 0)
1090 dosattr |= ATTR_NORMAL;
1091 dosattr |= ATTR_HIDDEN;
1093 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
1094 if (rc != 0)
1095 goto out_reval;
1097 goto retry_std_delete;
1100 /* undo the setattr if we errored out and it's needed */
1101 if (rc != 0 && dosattr != 0)
1102 cifs_set_file_info(inode, attrs, xid, full_path, origattr);
1104 out_reval:
1105 if (inode) {
1106 cifs_inode = CIFS_I(inode);
1107 cifs_inode->time = 0; /* will force revalidate to get info
1108 when needed */
1109 inode->i_ctime = current_fs_time(sb);
1111 dir->i_ctime = dir->i_mtime = current_fs_time(sb);
1112 cifs_inode = CIFS_I(dir);
1113 CIFS_I(dir)->time = 0; /* force revalidate of dir as well */
1115 kfree(full_path);
1116 kfree(attrs);
1117 FreeXid(xid);
1118 return rc;
1121 int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1123 int rc = 0, tmprc;
1124 int xid;
1125 struct cifs_sb_info *cifs_sb;
1126 struct cifsTconInfo *pTcon;
1127 char *full_path = NULL;
1128 struct inode *newinode = NULL;
1129 struct cifs_fattr fattr;
1131 cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
1133 xid = GetXid();
1135 cifs_sb = CIFS_SB(inode->i_sb);
1136 pTcon = cifs_sb->tcon;
1138 full_path = build_path_from_dentry(direntry);
1139 if (full_path == NULL) {
1140 rc = -ENOMEM;
1141 FreeXid(xid);
1142 return rc;
1145 if ((pTcon->ses->capabilities & CAP_UNIX) &&
1146 (CIFS_UNIX_POSIX_PATH_OPS_CAP &
1147 le64_to_cpu(pTcon->fsUnixInfo.Capability))) {
1148 u32 oplock = 0;
1149 FILE_UNIX_BASIC_INFO *pInfo =
1150 kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
1151 if (pInfo == NULL) {
1152 rc = -ENOMEM;
1153 goto mkdir_out;
1156 mode &= ~current_umask();
1157 rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT,
1158 mode, NULL /* netfid */, pInfo, &oplock,
1159 full_path, cifs_sb->local_nls,
1160 cifs_sb->mnt_cifs_flags &
1161 CIFS_MOUNT_MAP_SPECIAL_CHR);
1162 if (rc == -EOPNOTSUPP) {
1163 kfree(pInfo);
1164 goto mkdir_retry_old;
1165 } else if (rc) {
1166 cFYI(1, ("posix mkdir returned 0x%x", rc));
1167 d_drop(direntry);
1168 } else {
1169 if (pInfo->Type == cpu_to_le32(-1)) {
1170 /* no return info, go query for it */
1171 kfree(pInfo);
1172 goto mkdir_get_info;
1174 /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need
1175 to set uid/gid */
1176 inc_nlink(inode);
1177 if (pTcon->nocase)
1178 direntry->d_op = &cifs_ci_dentry_ops;
1179 else
1180 direntry->d_op = &cifs_dentry_ops;
1182 cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
1183 newinode = cifs_iget(inode->i_sb, &fattr);
1184 if (!newinode) {
1185 kfree(pInfo);
1186 goto mkdir_get_info;
1189 d_instantiate(direntry, newinode);
1191 #ifdef CONFIG_CIFS_DEBUG2
1192 cFYI(1, ("instantiated dentry %p %s to inode %p",
1193 direntry, direntry->d_name.name, newinode));
1195 if (newinode->i_nlink != 2)
1196 cFYI(1, ("unexpected number of links %d",
1197 newinode->i_nlink));
1198 #endif
1200 kfree(pInfo);
1201 goto mkdir_out;
1203 mkdir_retry_old:
1204 /* BB add setting the equivalent of mode via CreateX w/ACLs */
1205 rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls,
1206 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1207 if (rc) {
1208 cFYI(1, ("cifs_mkdir returned 0x%x", rc));
1209 d_drop(direntry);
1210 } else {
1211 mkdir_get_info:
1212 inc_nlink(inode);
1213 if (pTcon->unix_ext)
1214 rc = cifs_get_inode_info_unix(&newinode, full_path,
1215 inode->i_sb, xid);
1216 else
1217 rc = cifs_get_inode_info(&newinode, full_path, NULL,
1218 inode->i_sb, xid, NULL);
1220 if (pTcon->nocase)
1221 direntry->d_op = &cifs_ci_dentry_ops;
1222 else
1223 direntry->d_op = &cifs_dentry_ops;
1224 d_instantiate(direntry, newinode);
1225 /* setting nlink not necessary except in cases where we
1226 * failed to get it from the server or was set bogus */
1227 if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2))
1228 direntry->d_inode->i_nlink = 2;
1230 mode &= ~current_umask();
1231 /* must turn on setgid bit if parent dir has it */
1232 if (inode->i_mode & S_ISGID)
1233 mode |= S_ISGID;
1235 if (pTcon->unix_ext) {
1236 struct cifs_unix_set_info_args args = {
1237 .mode = mode,
1238 .ctime = NO_CHANGE_64,
1239 .atime = NO_CHANGE_64,
1240 .mtime = NO_CHANGE_64,
1241 .device = 0,
1243 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
1244 args.uid = (__u64)current_fsuid();
1245 if (inode->i_mode & S_ISGID)
1246 args.gid = (__u64)inode->i_gid;
1247 else
1248 args.gid = (__u64)current_fsgid();
1249 } else {
1250 args.uid = NO_CHANGE_64;
1251 args.gid = NO_CHANGE_64;
1253 CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args,
1254 cifs_sb->local_nls,
1255 cifs_sb->mnt_cifs_flags &
1256 CIFS_MOUNT_MAP_SPECIAL_CHR);
1257 } else {
1258 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
1259 (mode & S_IWUGO) == 0) {
1260 FILE_BASIC_INFO pInfo;
1261 struct cifsInodeInfo *cifsInode;
1262 u32 dosattrs;
1264 memset(&pInfo, 0, sizeof(pInfo));
1265 cifsInode = CIFS_I(newinode);
1266 dosattrs = cifsInode->cifsAttrs|ATTR_READONLY;
1267 pInfo.Attributes = cpu_to_le32(dosattrs);
1268 tmprc = CIFSSMBSetPathInfo(xid, pTcon,
1269 full_path, &pInfo,
1270 cifs_sb->local_nls,
1271 cifs_sb->mnt_cifs_flags &
1272 CIFS_MOUNT_MAP_SPECIAL_CHR);
1273 if (tmprc == 0)
1274 cifsInode->cifsAttrs = dosattrs;
1276 if (direntry->d_inode) {
1277 if (cifs_sb->mnt_cifs_flags &
1278 CIFS_MOUNT_DYNPERM)
1279 direntry->d_inode->i_mode =
1280 (mode | S_IFDIR);
1282 if (cifs_sb->mnt_cifs_flags &
1283 CIFS_MOUNT_SET_UID) {
1284 direntry->d_inode->i_uid =
1285 current_fsuid();
1286 if (inode->i_mode & S_ISGID)
1287 direntry->d_inode->i_gid =
1288 inode->i_gid;
1289 else
1290 direntry->d_inode->i_gid =
1291 current_fsgid();
1296 mkdir_out:
1297 kfree(full_path);
1298 FreeXid(xid);
1299 return rc;
1302 int cifs_rmdir(struct inode *inode, struct dentry *direntry)
1304 int rc = 0;
1305 int xid;
1306 struct cifs_sb_info *cifs_sb;
1307 struct cifsTconInfo *pTcon;
1308 char *full_path = NULL;
1309 struct cifsInodeInfo *cifsInode;
1311 cFYI(1, ("cifs_rmdir, inode = 0x%p", inode));
1313 xid = GetXid();
1315 cifs_sb = CIFS_SB(inode->i_sb);
1316 pTcon = cifs_sb->tcon;
1318 full_path = build_path_from_dentry(direntry);
1319 if (full_path == NULL) {
1320 rc = -ENOMEM;
1321 FreeXid(xid);
1322 return rc;
1325 rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls,
1326 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1328 if (!rc) {
1329 drop_nlink(inode);
1330 spin_lock(&direntry->d_inode->i_lock);
1331 i_size_write(direntry->d_inode, 0);
1332 clear_nlink(direntry->d_inode);
1333 spin_unlock(&direntry->d_inode->i_lock);
1336 cifsInode = CIFS_I(direntry->d_inode);
1337 cifsInode->time = 0; /* force revalidate to go get info when
1338 needed */
1340 cifsInode = CIFS_I(inode);
1341 cifsInode->time = 0; /* force revalidate to get parent dir info
1342 since cached search results now invalid */
1344 direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
1345 current_fs_time(inode->i_sb);
1347 kfree(full_path);
1348 FreeXid(xid);
1349 return rc;
1352 static int
1353 cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
1354 struct dentry *to_dentry, const char *toPath)
1356 struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
1357 struct cifsTconInfo *pTcon = cifs_sb->tcon;
1358 __u16 srcfid;
1359 int oplock, rc;
1361 /* try path-based rename first */
1362 rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls,
1363 cifs_sb->mnt_cifs_flags &
1364 CIFS_MOUNT_MAP_SPECIAL_CHR);
1367 * don't bother with rename by filehandle unless file is busy and
1368 * source Note that cross directory moves do not work with
1369 * rename by filehandle to various Windows servers.
1371 if (rc == 0 || rc != -ETXTBSY)
1372 return rc;
1374 /* open the file to be renamed -- we need DELETE perms */
1375 rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE,
1376 CREATE_NOT_DIR, &srcfid, &oplock, NULL,
1377 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1378 CIFS_MOUNT_MAP_SPECIAL_CHR);
1380 if (rc == 0) {
1381 rc = CIFSSMBRenameOpenFile(xid, pTcon, srcfid,
1382 (const char *) to_dentry->d_name.name,
1383 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
1384 CIFS_MOUNT_MAP_SPECIAL_CHR);
1386 CIFSSMBClose(xid, pTcon, srcfid);
1389 return rc;
1392 int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
1393 struct inode *target_dir, struct dentry *target_dentry)
1395 char *fromName = NULL;
1396 char *toName = NULL;
1397 struct cifs_sb_info *cifs_sb_source;
1398 struct cifs_sb_info *cifs_sb_target;
1399 struct cifsTconInfo *tcon;
1400 FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
1401 FILE_UNIX_BASIC_INFO *info_buf_target;
1402 int xid, rc, tmprc;
1404 cifs_sb_target = CIFS_SB(target_dir->i_sb);
1405 cifs_sb_source = CIFS_SB(source_dir->i_sb);
1406 tcon = cifs_sb_source->tcon;
1408 xid = GetXid();
1411 * BB: this might be allowed if same server, but different share.
1412 * Consider adding support for this
1414 if (tcon != cifs_sb_target->tcon) {
1415 rc = -EXDEV;
1416 goto cifs_rename_exit;
1420 * we already have the rename sem so we do not need to
1421 * grab it again here to protect the path integrity
1423 fromName = build_path_from_dentry(source_dentry);
1424 if (fromName == NULL) {
1425 rc = -ENOMEM;
1426 goto cifs_rename_exit;
1429 toName = build_path_from_dentry(target_dentry);
1430 if (toName == NULL) {
1431 rc = -ENOMEM;
1432 goto cifs_rename_exit;
1435 rc = cifs_do_rename(xid, source_dentry, fromName,
1436 target_dentry, toName);
1438 if (rc == -EEXIST && tcon->unix_ext) {
1440 * Are src and dst hardlinks of same inode? We can
1441 * only tell with unix extensions enabled
1443 info_buf_source =
1444 kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO),
1445 GFP_KERNEL);
1446 if (info_buf_source == NULL) {
1447 rc = -ENOMEM;
1448 goto cifs_rename_exit;
1451 info_buf_target = info_buf_source + 1;
1452 tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName,
1453 info_buf_source,
1454 cifs_sb_source->local_nls,
1455 cifs_sb_source->mnt_cifs_flags &
1456 CIFS_MOUNT_MAP_SPECIAL_CHR);
1457 if (tmprc != 0)
1458 goto unlink_target;
1460 tmprc = CIFSSMBUnixQPathInfo(xid, tcon,
1461 toName, info_buf_target,
1462 cifs_sb_target->local_nls,
1463 /* remap based on source sb */
1464 cifs_sb_source->mnt_cifs_flags &
1465 CIFS_MOUNT_MAP_SPECIAL_CHR);
1467 if (tmprc == 0 && (info_buf_source->UniqueId ==
1468 info_buf_target->UniqueId)) {
1469 /* same file, POSIX says that this is a noop */
1470 rc = 0;
1471 goto cifs_rename_exit;
1473 } /* else ... BB we could add the same check for Windows by
1474 checking the UniqueId via FILE_INTERNAL_INFO */
1476 unlink_target:
1477 /* Try unlinking the target dentry if it's not negative */
1478 if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) {
1479 tmprc = cifs_unlink(target_dir, target_dentry);
1480 if (tmprc)
1481 goto cifs_rename_exit;
1483 rc = cifs_do_rename(xid, source_dentry, fromName,
1484 target_dentry, toName);
1487 cifs_rename_exit:
1488 kfree(info_buf_source);
1489 kfree(fromName);
1490 kfree(toName);
1491 FreeXid(xid);
1492 return rc;
1495 static bool
1496 cifs_inode_needs_reval(struct inode *inode)
1498 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1500 if (cifs_i->clientCanCacheRead)
1501 return false;
1503 if (!lookupCacheEnabled)
1504 return true;
1506 if (cifs_i->time == 0)
1507 return true;
1509 /* FIXME: the actimeo should be tunable */
1510 if (time_after_eq(jiffies, cifs_i->time + HZ))
1511 return true;
1513 return false;
1516 /* check invalid_mapping flag and zap the cache if it's set */
1517 static void
1518 cifs_invalidate_mapping(struct inode *inode)
1520 int rc;
1521 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
1523 cifs_i->invalid_mapping = false;
1525 /* write back any cached data */
1526 if (inode->i_mapping && inode->i_mapping->nrpages != 0) {
1527 rc = filemap_write_and_wait(inode->i_mapping);
1528 if (rc)
1529 cifs_i->write_behind_rc = rc;
1531 invalidate_remote_inode(inode);
1534 int cifs_revalidate_file(struct file *filp)
1536 int rc = 0;
1537 struct inode *inode = filp->f_path.dentry->d_inode;
1539 if (!cifs_inode_needs_reval(inode))
1540 goto check_inval;
1542 if (CIFS_SB(inode->i_sb)->tcon->unix_ext)
1543 rc = cifs_get_file_info_unix(filp);
1544 else
1545 rc = cifs_get_file_info(filp);
1547 check_inval:
1548 if (CIFS_I(inode)->invalid_mapping)
1549 cifs_invalidate_mapping(inode);
1551 return rc;
1554 /* revalidate a dentry's inode attributes */
1555 int cifs_revalidate_dentry(struct dentry *dentry)
1557 int xid;
1558 int rc = 0;
1559 char *full_path = NULL;
1560 struct inode *inode = dentry->d_inode;
1561 struct super_block *sb = dentry->d_sb;
1563 if (inode == NULL)
1564 return -ENOENT;
1566 xid = GetXid();
1568 if (!cifs_inode_needs_reval(inode))
1569 goto check_inval;
1571 /* can not safely grab the rename sem here if rename calls revalidate
1572 since that would deadlock */
1573 full_path = build_path_from_dentry(dentry);
1574 if (full_path == NULL) {
1575 rc = -ENOMEM;
1576 goto check_inval;
1579 cFYI(1, ("Revalidate: %s inode 0x%p count %d dentry: 0x%p d_time %ld "
1580 "jiffies %ld", full_path, inode, inode->i_count.counter,
1581 dentry, dentry->d_time, jiffies));
1583 if (CIFS_SB(sb)->tcon->unix_ext)
1584 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
1585 else
1586 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
1587 xid, NULL);
1589 check_inval:
1590 if (CIFS_I(inode)->invalid_mapping)
1591 cifs_invalidate_mapping(inode);
1593 kfree(full_path);
1594 FreeXid(xid);
1595 return rc;
1598 int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1599 struct kstat *stat)
1601 int err = cifs_revalidate_dentry(dentry);
1602 if (!err) {
1603 generic_fillattr(dentry->d_inode, stat);
1604 stat->blksize = CIFS_MAX_MSGSIZE;
1605 stat->ino = CIFS_I(dentry->d_inode)->uniqueid;
1607 return err;
1610 static int cifs_truncate_page(struct address_space *mapping, loff_t from)
1612 pgoff_t index = from >> PAGE_CACHE_SHIFT;
1613 unsigned offset = from & (PAGE_CACHE_SIZE - 1);
1614 struct page *page;
1615 int rc = 0;
1617 page = grab_cache_page(mapping, index);
1618 if (!page)
1619 return -ENOMEM;
1621 zero_user_segment(page, offset, PAGE_CACHE_SIZE);
1622 unlock_page(page);
1623 page_cache_release(page);
1624 return rc;
1627 static int cifs_vmtruncate(struct inode *inode, loff_t offset)
1629 loff_t oldsize;
1630 int err;
1632 spin_lock(&inode->i_lock);
1633 err = inode_newsize_ok(inode, offset);
1634 if (err) {
1635 spin_unlock(&inode->i_lock);
1636 goto out;
1639 oldsize = inode->i_size;
1640 i_size_write(inode, offset);
1641 spin_unlock(&inode->i_lock);
1642 truncate_pagecache(inode, oldsize, offset);
1643 if (inode->i_op->truncate)
1644 inode->i_op->truncate(inode);
1645 out:
1646 return err;
1649 static int
1650 cifs_set_file_size(struct inode *inode, struct iattr *attrs,
1651 int xid, char *full_path)
1653 int rc;
1654 struct cifsFileInfo *open_file;
1655 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1656 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1657 struct cifsTconInfo *pTcon = cifs_sb->tcon;
1660 * To avoid spurious oplock breaks from server, in the case of
1661 * inodes that we already have open, avoid doing path based
1662 * setting of file size if we can do it by handle.
1663 * This keeps our caching token (oplock) and avoids timeouts
1664 * when the local oplock break takes longer to flush
1665 * writebehind data than the SMB timeout for the SetPathInfo
1666 * request would allow
1668 open_file = find_writable_file(cifsInode);
1669 if (open_file) {
1670 __u16 nfid = open_file->netfid;
1671 __u32 npid = open_file->pid;
1672 rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid,
1673 npid, false);
1674 cifsFileInfo_put(open_file);
1675 cFYI(1, ("SetFSize for attrs rc = %d", rc));
1676 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1677 unsigned int bytes_written;
1678 rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
1679 &bytes_written, NULL, NULL, 1);
1680 cFYI(1, ("Wrt seteof rc %d", rc));
1682 } else
1683 rc = -EINVAL;
1685 if (rc != 0) {
1686 /* Set file size by pathname rather than by handle
1687 either because no valid, writeable file handle for
1688 it was found or because there was an error setting
1689 it by handle */
1690 rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size,
1691 false, cifs_sb->local_nls,
1692 cifs_sb->mnt_cifs_flags &
1693 CIFS_MOUNT_MAP_SPECIAL_CHR);
1694 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1695 if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1696 __u16 netfid;
1697 int oplock = 0;
1699 rc = SMBLegacyOpen(xid, pTcon, full_path,
1700 FILE_OPEN, GENERIC_WRITE,
1701 CREATE_NOT_DIR, &netfid, &oplock, NULL,
1702 cifs_sb->local_nls,
1703 cifs_sb->mnt_cifs_flags &
1704 CIFS_MOUNT_MAP_SPECIAL_CHR);
1705 if (rc == 0) {
1706 unsigned int bytes_written;
1707 rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
1708 attrs->ia_size,
1709 &bytes_written, NULL,
1710 NULL, 1);
1711 cFYI(1, ("wrt seteof rc %d", rc));
1712 CIFSSMBClose(xid, pTcon, netfid);
1717 if (rc == 0) {
1718 cifsInode->server_eof = attrs->ia_size;
1719 rc = cifs_vmtruncate(inode, attrs->ia_size);
1720 cifs_truncate_page(inode->i_mapping, inode->i_size);
1723 return rc;
1726 static int
1727 cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
1729 int rc;
1730 int xid;
1731 char *full_path = NULL;
1732 struct inode *inode = direntry->d_inode;
1733 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1734 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1735 struct cifsTconInfo *pTcon = cifs_sb->tcon;
1736 struct cifs_unix_set_info_args *args = NULL;
1737 struct cifsFileInfo *open_file;
1739 cFYI(1, ("setattr_unix on file %s attrs->ia_valid=0x%x",
1740 direntry->d_name.name, attrs->ia_valid));
1742 xid = GetXid();
1744 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1745 /* check if we have permission to change attrs */
1746 rc = inode_change_ok(inode, attrs);
1747 if (rc < 0)
1748 goto out;
1749 else
1750 rc = 0;
1753 full_path = build_path_from_dentry(direntry);
1754 if (full_path == NULL) {
1755 rc = -ENOMEM;
1756 goto out;
1760 * Attempt to flush data before changing attributes. We need to do
1761 * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1762 * ownership or mode then we may also need to do this. Here, we take
1763 * the safe way out and just do the flush on all setattr requests. If
1764 * the flush returns error, store it to report later and continue.
1766 * BB: This should be smarter. Why bother flushing pages that
1767 * will be truncated anyway? Also, should we error out here if
1768 * the flush returns error?
1770 rc = filemap_write_and_wait(inode->i_mapping);
1771 if (rc != 0) {
1772 cifsInode->write_behind_rc = rc;
1773 rc = 0;
1776 if (attrs->ia_valid & ATTR_SIZE) {
1777 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1778 if (rc != 0)
1779 goto out;
1782 /* skip mode change if it's just for clearing setuid/setgid */
1783 if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1784 attrs->ia_valid &= ~ATTR_MODE;
1786 args = kmalloc(sizeof(*args), GFP_KERNEL);
1787 if (args == NULL) {
1788 rc = -ENOMEM;
1789 goto out;
1792 /* set up the struct */
1793 if (attrs->ia_valid & ATTR_MODE)
1794 args->mode = attrs->ia_mode;
1795 else
1796 args->mode = NO_CHANGE_64;
1798 if (attrs->ia_valid & ATTR_UID)
1799 args->uid = attrs->ia_uid;
1800 else
1801 args->uid = NO_CHANGE_64;
1803 if (attrs->ia_valid & ATTR_GID)
1804 args->gid = attrs->ia_gid;
1805 else
1806 args->gid = NO_CHANGE_64;
1808 if (attrs->ia_valid & ATTR_ATIME)
1809 args->atime = cifs_UnixTimeToNT(attrs->ia_atime);
1810 else
1811 args->atime = NO_CHANGE_64;
1813 if (attrs->ia_valid & ATTR_MTIME)
1814 args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime);
1815 else
1816 args->mtime = NO_CHANGE_64;
1818 if (attrs->ia_valid & ATTR_CTIME)
1819 args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime);
1820 else
1821 args->ctime = NO_CHANGE_64;
1823 args->device = 0;
1824 open_file = find_writable_file(cifsInode);
1825 if (open_file) {
1826 u16 nfid = open_file->netfid;
1827 u32 npid = open_file->pid;
1828 rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid);
1829 cifsFileInfo_put(open_file);
1830 } else {
1831 rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args,
1832 cifs_sb->local_nls,
1833 cifs_sb->mnt_cifs_flags &
1834 CIFS_MOUNT_MAP_SPECIAL_CHR);
1837 if (!rc) {
1838 rc = inode_setattr(inode, attrs);
1840 /* force revalidate when any of these times are set since some
1841 of the fs types (eg ext3, fat) do not have fine enough
1842 time granularity to match protocol, and we do not have a
1843 a way (yet) to query the server fs's time granularity (and
1844 whether it rounds times down).
1846 if (!rc && (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME)))
1847 cifsInode->time = 0;
1849 out:
1850 kfree(args);
1851 kfree(full_path);
1852 FreeXid(xid);
1853 return rc;
1856 static int
1857 cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
1859 int xid;
1860 struct inode *inode = direntry->d_inode;
1861 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
1862 struct cifsInodeInfo *cifsInode = CIFS_I(inode);
1863 char *full_path = NULL;
1864 int rc = -EACCES;
1865 __u32 dosattr = 0;
1866 __u64 mode = NO_CHANGE_64;
1868 xid = GetXid();
1870 cFYI(1, ("setattr on file %s attrs->iavalid 0x%x",
1871 direntry->d_name.name, attrs->ia_valid));
1873 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) == 0) {
1874 /* check if we have permission to change attrs */
1875 rc = inode_change_ok(inode, attrs);
1876 if (rc < 0) {
1877 FreeXid(xid);
1878 return rc;
1879 } else
1880 rc = 0;
1883 full_path = build_path_from_dentry(direntry);
1884 if (full_path == NULL) {
1885 rc = -ENOMEM;
1886 FreeXid(xid);
1887 return rc;
1891 * Attempt to flush data before changing attributes. We need to do
1892 * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the
1893 * ownership or mode then we may also need to do this. Here, we take
1894 * the safe way out and just do the flush on all setattr requests. If
1895 * the flush returns error, store it to report later and continue.
1897 * BB: This should be smarter. Why bother flushing pages that
1898 * will be truncated anyway? Also, should we error out here if
1899 * the flush returns error?
1901 rc = filemap_write_and_wait(inode->i_mapping);
1902 if (rc != 0) {
1903 cifsInode->write_behind_rc = rc;
1904 rc = 0;
1907 if (attrs->ia_valid & ATTR_SIZE) {
1908 rc = cifs_set_file_size(inode, attrs, xid, full_path);
1909 if (rc != 0)
1910 goto cifs_setattr_exit;
1914 * Without unix extensions we can't send ownership changes to the
1915 * server, so silently ignore them. This is consistent with how
1916 * local DOS/Windows filesystems behave (VFAT, NTFS, etc). With
1917 * CIFSACL support + proper Windows to Unix idmapping, we may be
1918 * able to support this in the future.
1920 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID))
1921 attrs->ia_valid &= ~(ATTR_UID | ATTR_GID);
1923 /* skip mode change if it's just for clearing setuid/setgid */
1924 if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
1925 attrs->ia_valid &= ~ATTR_MODE;
1927 if (attrs->ia_valid & ATTR_MODE) {
1928 cFYI(1, ("Mode changed to 0%o", attrs->ia_mode));
1929 mode = attrs->ia_mode;
1932 if (attrs->ia_valid & ATTR_MODE) {
1933 rc = 0;
1934 #ifdef CONFIG_CIFS_EXPERIMENTAL
1935 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1936 rc = mode_to_acl(inode, full_path, mode);
1937 else
1938 #endif
1939 if (((mode & S_IWUGO) == 0) &&
1940 (cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1942 dosattr = cifsInode->cifsAttrs | ATTR_READONLY;
1944 /* fix up mode if we're not using dynperm */
1945 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
1946 attrs->ia_mode = inode->i_mode & ~S_IWUGO;
1947 } else if ((mode & S_IWUGO) &&
1948 (cifsInode->cifsAttrs & ATTR_READONLY)) {
1950 dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY;
1951 /* Attributes of 0 are ignored */
1952 if (dosattr == 0)
1953 dosattr |= ATTR_NORMAL;
1955 /* reset local inode permissions to normal */
1956 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1957 attrs->ia_mode &= ~(S_IALLUGO);
1958 if (S_ISDIR(inode->i_mode))
1959 attrs->ia_mode |=
1960 cifs_sb->mnt_dir_mode;
1961 else
1962 attrs->ia_mode |=
1963 cifs_sb->mnt_file_mode;
1965 } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
1966 /* ignore mode change - ATTR_READONLY hasn't changed */
1967 attrs->ia_valid &= ~ATTR_MODE;
1971 if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) ||
1972 ((attrs->ia_valid & ATTR_MODE) && dosattr)) {
1973 rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr);
1974 /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */
1976 /* Even if error on time set, no sense failing the call if
1977 the server would set the time to a reasonable value anyway,
1978 and this check ensures that we are not being called from
1979 sys_utimes in which case we ought to fail the call back to
1980 the user when the server rejects the call */
1981 if ((rc) && (attrs->ia_valid &
1982 (ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE)))
1983 rc = 0;
1986 /* do not need local check to inode_check_ok since the server does
1987 that */
1988 if (!rc)
1989 rc = inode_setattr(inode, attrs);
1990 cifs_setattr_exit:
1991 kfree(full_path);
1992 FreeXid(xid);
1993 return rc;
1997 cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1999 struct inode *inode = direntry->d_inode;
2000 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
2001 struct cifsTconInfo *pTcon = cifs_sb->tcon;
2003 if (pTcon->unix_ext)
2004 return cifs_setattr_unix(direntry, attrs);
2006 return cifs_setattr_nounix(direntry, attrs);
2008 /* BB: add cifs_setattr_legacy for really old servers */
2011 #if 0
2012 void cifs_delete_inode(struct inode *inode)
2014 cFYI(1, ("In cifs_delete_inode, inode = 0x%p", inode));
2015 /* may have to add back in if and when safe distributed caching of
2016 directories added e.g. via FindNotify */
2018 #endif