Blame view
fs/cifs/inode.c
59.4 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 |
/* * fs/cifs/inode.c * |
f19159dc5 [CIFS] Cleanup va... |
4 |
* Copyright (C) International Business Machines Corp., 2002,2010 |
1da177e4c Linux-2.6.12-rc2 |
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
* Author(s): Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/fs.h> |
1da177e4c Linux-2.6.12-rc2 |
22 |
#include <linux/stat.h> |
5a0e3ad6a include cleanup: ... |
23 |
#include <linux/slab.h> |
1da177e4c Linux-2.6.12-rc2 |
24 25 26 27 28 29 30 31 |
#include <linux/pagemap.h> #include <asm/div64.h> #include "cifsfs.h" #include "cifspdu.h" #include "cifsglob.h" #include "cifsproto.h" #include "cifs_debug.h" #include "cifs_fs_sb.h" |
9451a9a52 cifs: define inod... |
32 |
#include "fscache.h" |
1da177e4c Linux-2.6.12-rc2 |
33 |
|
70eff55d2 [CIFS] factoring ... |
34 |
|
01c64feac CIFS: Use d_autom... |
35 |
static void cifs_set_ops(struct inode *inode) |
70eff55d2 [CIFS] factoring ... |
36 37 38 39 40 41 42 43 44 45 46 |
{ struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); switch (inode->i_mode & S_IFMT) { case S_IFREG: inode->i_op = &cifs_file_inode_ops; if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) inode->i_fop = &cifs_file_direct_nobrl_ops; else inode->i_fop = &cifs_file_direct_ops; |
8be7e6ba1 CIFS: Implement c... |
47 48 49 50 51 |
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) inode->i_fop = &cifs_file_strict_nobrl_ops; else inode->i_fop = &cifs_file_strict_ops; |
70eff55d2 [CIFS] factoring ... |
52 53 54 55 56 |
} else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL) inode->i_fop = &cifs_file_nobrl_ops; else { /* not direct, send byte range locks */ inode->i_fop = &cifs_file_ops; } |
70eff55d2 [CIFS] factoring ... |
57 |
/* check if server can support readpages */ |
0d424ad0a cifs: add cifs_sb... |
58 |
if (cifs_sb_master_tcon(cifs_sb)->ses->server->maxBuf < |
70eff55d2 [CIFS] factoring ... |
59 60 61 62 63 64 |
PAGE_CACHE_SIZE + MAX_CIFS_HDR_SIZE) inode->i_data.a_ops = &cifs_addr_ops_smallbuf; else inode->i_data.a_ops = &cifs_addr_ops; break; case S_IFDIR: |
bc5b6e24a [CIFS] Fix build ... |
65 |
#ifdef CONFIG_CIFS_DFS_UPCALL |
01c64feac CIFS: Use d_autom... |
66 |
if (IS_AUTOMOUNT(inode)) { |
7962670e6 [CIFS] DFS patch... |
67 68 |
inode->i_op = &cifs_dfs_referral_inode_operations; } else { |
bc5b6e24a [CIFS] Fix build ... |
69 70 71 |
#else /* NO DFS support, treat as a directory */ { #endif |
7962670e6 [CIFS] DFS patch... |
72 73 74 |
inode->i_op = &cifs_dir_inode_ops; inode->i_fop = &cifs_dir_ops; } |
70eff55d2 [CIFS] factoring ... |
75 76 77 78 79 80 81 82 83 |
break; case S_IFLNK: inode->i_op = &cifs_symlink_inode_ops; break; default: init_special_inode(inode, inode->i_mode, inode->i_rdev); break; } } |
df2cf170c cifs: overhaul ci... |
84 85 86 87 88 89 90 |
/* check inode attributes against fattr. If they don't match, tag the * inode for cache invalidation */ static void cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) { struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
f19159dc5 [CIFS] Cleanup va... |
91 |
cFYI(1, "%s: revalidating inode %llu", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
92 93 |
if (inode->i_state & I_NEW) { |
f19159dc5 [CIFS] Cleanup va... |
94 |
cFYI(1, "%s: inode %llu is new", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
95 96 97 98 99 |
return; } /* don't bother with revalidation if we have an oplock */ if (cifs_i->clientCanCacheRead) { |
f19159dc5 [CIFS] Cleanup va... |
100 101 |
cFYI(1, "%s: inode %llu is oplocked", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
102 103 104 105 106 107 |
return; } /* revalidate if mtime or size have changed */ if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) && cifs_i->server_eof == fattr->cf_eof) { |
f19159dc5 [CIFS] Cleanup va... |
108 109 |
cFYI(1, "%s: inode %llu is unchanged", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
110 111 |
return; } |
f19159dc5 [CIFS] Cleanup va... |
112 113 |
cFYI(1, "%s: invalidating inode %llu mapping", __func__, cifs_i->uniqueid); |
df2cf170c cifs: overhaul ci... |
114 115 |
cifs_i->invalid_mapping = true; } |
cc0bad755 cifs: add new cif... |
116 117 118 |
/* populate an inode with info from a cifs_fattr struct */ void cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) |
75f12983d [CIFS] consolidat... |
119 |
{ |
cc0bad755 cifs: add new cif... |
120 |
struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
0b8f18e35 cifs: convert cif... |
121 122 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); unsigned long oldtime = cifs_i->time; |
cc0bad755 cifs: add new cif... |
123 |
|
df2cf170c cifs: overhaul ci... |
124 |
cifs_revalidate_cache(inode, fattr); |
cc0bad755 cifs: add new cif... |
125 126 127 |
inode->i_atime = fattr->cf_atime; inode->i_mtime = fattr->cf_mtime; inode->i_ctime = fattr->cf_ctime; |
cc0bad755 cifs: add new cif... |
128 |
inode->i_rdev = fattr->cf_rdev; |
bfe868486 filesystems: add ... |
129 |
set_nlink(inode, fattr->cf_nlink); |
cc0bad755 cifs: add new cif... |
130 131 |
inode->i_uid = fattr->cf_uid; inode->i_gid = fattr->cf_gid; |
0b8f18e35 cifs: convert cif... |
132 133 134 135 |
/* if dynperm is set, don't clobber existing mode */ if (inode->i_state & I_NEW || !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) inode->i_mode = fattr->cf_mode; |
cc0bad755 cifs: add new cif... |
136 |
cifs_i->cifsAttrs = fattr->cf_cifsattrs; |
75f12983d [CIFS] consolidat... |
137 |
|
0b8f18e35 cifs: convert cif... |
138 139 140 141 |
if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL) cifs_i->time = 0; else cifs_i->time = jiffies; |
b6b38f704 [CIFS] Neaten cER... |
142 143 |
cFYI(1, "inode 0x%p old_time=%ld new_time=%ld", inode, oldtime, cifs_i->time); |
0b8f18e35 cifs: convert cif... |
144 145 |
cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING; |
cc0bad755 cifs: add new cif... |
146 |
|
835a36ca4 cifs: set server_... |
147 |
cifs_i->server_eof = fattr->cf_eof; |
cc0bad755 cifs: add new cif... |
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
/* * Can't safely change the file size here if the client is writing to * it due to potential races. */ spin_lock(&inode->i_lock); if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) { i_size_write(inode, fattr->cf_eof); /* * i_blocks is not related to (i_size / i_blksize), * but instead 512 byte (2**9) size is required for * calculating num blocks. */ inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9; } spin_unlock(&inode->i_lock); |
01c64feac CIFS: Use d_autom... |
164 165 166 |
if (fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL) inode->i_flags |= S_AUTOMOUNT; cifs_set_ops(inode); |
cc0bad755 cifs: add new cif... |
167 |
} |
4065c802d cifs: fix noserve... |
168 169 170 171 172 173 174 175 176 177 |
void cifs_fill_uniqueid(struct super_block *sb, struct cifs_fattr *fattr) { struct cifs_sb_info *cifs_sb = CIFS_SB(sb); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) return; fattr->cf_uniqueid = iunique(sb, ROOT_I); } |
cc0bad755 cifs: add new cif... |
178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
/* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */ void cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info, struct cifs_sb_info *cifs_sb) { memset(fattr, 0, sizeof(*fattr)); fattr->cf_uniqueid = le64_to_cpu(info->UniqueId); fattr->cf_bytes = le64_to_cpu(info->NumOfBytes); fattr->cf_eof = le64_to_cpu(info->EndOfFile); fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime); fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange); fattr->cf_mode = le64_to_cpu(info->Permissions); |
75f12983d [CIFS] consolidat... |
192 193 194 195 196 |
/* * Since we set the inode type below we need to mask off * to avoid strange results if bits set above. */ |
cc0bad755 cifs: add new cif... |
197 |
fattr->cf_mode &= ~S_IFMT; |
75f12983d [CIFS] consolidat... |
198 199 |
switch (le32_to_cpu(info->Type)) { case UNIX_FILE: |
cc0bad755 cifs: add new cif... |
200 201 |
fattr->cf_mode |= S_IFREG; fattr->cf_dtype = DT_REG; |
75f12983d [CIFS] consolidat... |
202 203 |
break; case UNIX_SYMLINK: |
cc0bad755 cifs: add new cif... |
204 205 |
fattr->cf_mode |= S_IFLNK; fattr->cf_dtype = DT_LNK; |
75f12983d [CIFS] consolidat... |
206 207 |
break; case UNIX_DIR: |
cc0bad755 cifs: add new cif... |
208 209 |
fattr->cf_mode |= S_IFDIR; fattr->cf_dtype = DT_DIR; |
75f12983d [CIFS] consolidat... |
210 211 |
break; case UNIX_CHARDEV: |
cc0bad755 cifs: add new cif... |
212 213 214 215 |
fattr->cf_mode |= S_IFCHR; fattr->cf_dtype = DT_CHR; fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor), le64_to_cpu(info->DevMinor) & MINORMASK); |
75f12983d [CIFS] consolidat... |
216 217 |
break; case UNIX_BLOCKDEV: |
cc0bad755 cifs: add new cif... |
218 219 220 221 |
fattr->cf_mode |= S_IFBLK; fattr->cf_dtype = DT_BLK; fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor), le64_to_cpu(info->DevMinor) & MINORMASK); |
75f12983d [CIFS] consolidat... |
222 223 |
break; case UNIX_FIFO: |
cc0bad755 cifs: add new cif... |
224 225 |
fattr->cf_mode |= S_IFIFO; fattr->cf_dtype = DT_FIFO; |
75f12983d [CIFS] consolidat... |
226 227 |
break; case UNIX_SOCKET: |
cc0bad755 cifs: add new cif... |
228 229 |
fattr->cf_mode |= S_IFSOCK; fattr->cf_dtype = DT_SOCK; |
75f12983d [CIFS] consolidat... |
230 231 232 |
break; default: /* safest to call it a file if we do not know */ |
cc0bad755 cifs: add new cif... |
233 234 |
fattr->cf_mode |= S_IFREG; fattr->cf_dtype = DT_REG; |
b6b38f704 [CIFS] Neaten cER... |
235 |
cFYI(1, "unknown type %d", le32_to_cpu(info->Type)); |
75f12983d [CIFS] consolidat... |
236 237 |
break; } |
cc0bad755 cifs: add new cif... |
238 239 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) fattr->cf_uid = cifs_sb->mnt_uid; |
75f12983d [CIFS] consolidat... |
240 |
else |
cc0bad755 cifs: add new cif... |
241 |
fattr->cf_uid = le64_to_cpu(info->Uid); |
75f12983d [CIFS] consolidat... |
242 |
|
cc0bad755 cifs: add new cif... |
243 244 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) fattr->cf_gid = cifs_sb->mnt_gid; |
75f12983d [CIFS] consolidat... |
245 |
else |
cc0bad755 cifs: add new cif... |
246 |
fattr->cf_gid = le64_to_cpu(info->Gid); |
75f12983d [CIFS] consolidat... |
247 |
|
cc0bad755 cifs: add new cif... |
248 |
fattr->cf_nlink = le64_to_cpu(info->Nlinks); |
75f12983d [CIFS] consolidat... |
249 |
} |
b9a3260f2 [CIFS] Enable DFS... |
250 |
/* |
cc0bad755 cifs: add new cif... |
251 252 253 254 255 |
* Fill a cifs_fattr struct with fake inode info. * * Needed to setup cifs_fattr data for the directory which is the * junction to the new submount (ie to setup the fake directory * which represents a DFS referral). |
b9a3260f2 [CIFS] Enable DFS... |
256 |
*/ |
f1230c979 [CIFS] fix sparse... |
257 |
static void |
cc0bad755 cifs: add new cif... |
258 |
cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) |
0e4bbde94 [CIFS] Enable DFS... |
259 |
{ |
cc0bad755 cifs: add new cif... |
260 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
0e4bbde94 [CIFS] Enable DFS... |
261 |
|
b6b38f704 [CIFS] Neaten cER... |
262 |
cFYI(1, "creating fake fattr for DFS referral"); |
cc0bad755 cifs: add new cif... |
263 264 265 266 267 268 269 270 271 272 |
memset(fattr, 0, sizeof(*fattr)); fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU; fattr->cf_uid = cifs_sb->mnt_uid; fattr->cf_gid = cifs_sb->mnt_gid; fattr->cf_atime = CURRENT_TIME; fattr->cf_ctime = CURRENT_TIME; fattr->cf_mtime = CURRENT_TIME; fattr->cf_nlink = 2; fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; |
0e4bbde94 [CIFS] Enable DFS... |
273 |
} |
abab095d1 cifs: add cifs_re... |
274 275 276 277 278 279 280 281 |
int cifs_get_file_info_unix(struct file *filp) { int rc; int xid; FILE_UNIX_BASIC_INFO find_data; struct cifs_fattr fattr; struct inode *inode = filp->f_path.dentry->d_inode; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
c21dfb699 fs/cifs: Remove u... |
282 |
struct cifsFileInfo *cfile = filp->private_data; |
96daf2b09 [CIFS] Rename thr... |
283 |
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
abab095d1 cifs: add cifs_re... |
284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
xid = GetXid(); rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data); if (!rc) { cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); } else if (rc == -EREMOTE) { cifs_create_dfs_fattr(&fattr, inode->i_sb); rc = 0; } cifs_fattr_to_inode(inode, &fattr); FreeXid(xid); return rc; } |
1da177e4c Linux-2.6.12-rc2 |
298 |
int cifs_get_inode_info_unix(struct inode **pinode, |
cc0bad755 cifs: add new cif... |
299 300 |
const unsigned char *full_path, struct super_block *sb, int xid) |
1da177e4c Linux-2.6.12-rc2 |
301 |
{ |
cc0bad755 cifs: add new cif... |
302 |
int rc; |
0e4bbde94 [CIFS] Enable DFS... |
303 |
FILE_UNIX_BASIC_INFO find_data; |
cc0bad755 cifs: add new cif... |
304 |
struct cifs_fattr fattr; |
96daf2b09 [CIFS] Rename thr... |
305 |
struct cifs_tcon *tcon; |
7ffec3724 cifs: add refcoun... |
306 |
struct tcon_link *tlink; |
1da177e4c Linux-2.6.12-rc2 |
307 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
1da177e4c Linux-2.6.12-rc2 |
308 |
|
b6b38f704 [CIFS] Neaten cER... |
309 |
cFYI(1, "Getting info on %s", full_path); |
7962670e6 [CIFS] DFS patch... |
310 |
|
7ffec3724 cifs: add refcoun... |
311 312 313 314 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
1da177e4c Linux-2.6.12-rc2 |
315 |
/* could have done a find first instead but this returns more info */ |
cc0bad755 cifs: add new cif... |
316 |
rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data, |
737b758c9 [PATCH] cifs: cha... |
317 318 |
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
7ffec3724 cifs: add refcoun... |
319 |
cifs_put_tlink(tlink); |
e911d0cc8 cifs: fix inode l... |
320 |
|
cc0bad755 cifs: add new cif... |
321 322 323 324 325 326 327 328 |
if (!rc) { cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); } else if (rc == -EREMOTE) { cifs_create_dfs_fattr(&fattr, sb); rc = 0; } else { return rc; } |
1da177e4c Linux-2.6.12-rc2 |
329 |
|
1b12b9c15 cifs: use Minshal... |
330 331 332 333 334 335 |
/* check for Minshall+French symlinks */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { int tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid); if (tmprc) cFYI(1, "CIFSCheckMFSymlink: %d", tmprc); } |
0e4bbde94 [CIFS] Enable DFS... |
336 |
if (*pinode == NULL) { |
cc0bad755 cifs: add new cif... |
337 |
/* get new inode */ |
4065c802d cifs: fix noserve... |
338 |
cifs_fill_uniqueid(sb, &fattr); |
cc0bad755 cifs: add new cif... |
339 340 |
*pinode = cifs_iget(sb, &fattr); if (!*pinode) |
0e4bbde94 [CIFS] Enable DFS... |
341 |
rc = -ENOMEM; |
cc0bad755 cifs: add new cif... |
342 343 344 |
} else { /* we already have inode, update it */ cifs_fattr_to_inode(*pinode, &fattr); |
0e4bbde94 [CIFS] Enable DFS... |
345 |
} |
1da177e4c Linux-2.6.12-rc2 |
346 |
|
1da177e4c Linux-2.6.12-rc2 |
347 348 |
return rc; } |
0b8f18e35 cifs: convert cif... |
349 350 351 |
static int cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid) |
d6e2f2a4c [CIFS] Recognize ... |
352 353 |
{ int rc; |
4b18f2a9c [CIFS] convert us... |
354 |
int oplock = 0; |
d6e2f2a4c [CIFS] Recognize ... |
355 |
__u16 netfid; |
7ffec3724 cifs: add refcoun... |
356 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
357 |
struct cifs_tcon *tcon; |
d4ffff1fa CIFS: Add rwpidfo... |
358 |
struct cifs_io_parms io_parms; |
86c96b4bb [CIFS] Fix mknod ... |
359 |
char buf[24]; |
d6e2f2a4c [CIFS] Recognize ... |
360 |
unsigned int bytes_read; |
fb8c4b14d [CIFS] whitespace... |
361 |
char *pbuf; |
d6e2f2a4c [CIFS] Recognize ... |
362 363 |
pbuf = buf; |
0b8f18e35 cifs: convert cif... |
364 365 366 367 368 |
fattr->cf_mode &= ~S_IFMT; if (fattr->cf_eof == 0) { fattr->cf_mode |= S_IFIFO; fattr->cf_dtype = DT_FIFO; |
d6e2f2a4c [CIFS] Recognize ... |
369 |
return 0; |
0b8f18e35 cifs: convert cif... |
370 371 372 |
} else if (fattr->cf_eof < 8) { fattr->cf_mode |= S_IFREG; fattr->cf_dtype = DT_REG; |
d6e2f2a4c [CIFS] Recognize ... |
373 374 |
return -EINVAL; /* EOPNOTSUPP? */ } |
50c2f7538 [CIFS] whitespace... |
375 |
|
7ffec3724 cifs: add refcoun... |
376 377 378 379 380 381 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, GENERIC_READ, |
d6e2f2a4c [CIFS] Recognize ... |
382 383 384 385 |
CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
fb8c4b14d [CIFS] whitespace... |
386 |
if (rc == 0) { |
ec637e3ff [CIFS] Avoid extr... |
387 |
int buf_type = CIFS_NO_BUFFER; |
d6e2f2a4c [CIFS] Recognize ... |
388 |
/* Read header */ |
d4ffff1fa CIFS: Add rwpidfo... |
389 390 391 392 393 394 395 |
io_parms.netfid = netfid; io_parms.pid = current->tgid; io_parms.tcon = tcon; io_parms.offset = 0; io_parms.length = 24; rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf, &buf_type); |
4523cc304 [CIFS] UID/GID ov... |
396 397 |
if ((rc == 0) && (bytes_read >= 8)) { if (memcmp("IntxBLK", pbuf, 8) == 0) { |
b6b38f704 [CIFS] Neaten cER... |
398 |
cFYI(1, "Block device"); |
0b8f18e35 cifs: convert cif... |
399 400 |
fattr->cf_mode |= S_IFBLK; fattr->cf_dtype = DT_BLK; |
4523cc304 [CIFS] UID/GID ov... |
401 |
if (bytes_read == 24) { |
86c96b4bb [CIFS] Fix mknod ... |
402 403 404 405 406 |
/* we have enough to decode dev num */ __u64 mjr; /* major */ __u64 mnr; /* minor */ mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); |
0b8f18e35 cifs: convert cif... |
407 |
fattr->cf_rdev = MKDEV(mjr, mnr); |
86c96b4bb [CIFS] Fix mknod ... |
408 |
} |
4523cc304 [CIFS] UID/GID ov... |
409 |
} else if (memcmp("IntxCHR", pbuf, 8) == 0) { |
b6b38f704 [CIFS] Neaten cER... |
410 |
cFYI(1, "Char device"); |
0b8f18e35 cifs: convert cif... |
411 412 |
fattr->cf_mode |= S_IFCHR; fattr->cf_dtype = DT_CHR; |
4523cc304 [CIFS] UID/GID ov... |
413 |
if (bytes_read == 24) { |
86c96b4bb [CIFS] Fix mknod ... |
414 415 416 417 418 |
/* we have enough to decode dev num */ __u64 mjr; /* major */ __u64 mnr; /* minor */ mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); |
0b8f18e35 cifs: convert cif... |
419 |
fattr->cf_rdev = MKDEV(mjr, mnr); |
fb8c4b14d [CIFS] whitespace... |
420 |
} |
4523cc304 [CIFS] UID/GID ov... |
421 |
} else if (memcmp("IntxLNK", pbuf, 7) == 0) { |
b6b38f704 [CIFS] Neaten cER... |
422 |
cFYI(1, "Symlink"); |
0b8f18e35 cifs: convert cif... |
423 424 |
fattr->cf_mode |= S_IFLNK; fattr->cf_dtype = DT_LNK; |
86c96b4bb [CIFS] Fix mknod ... |
425 |
} else { |
0b8f18e35 cifs: convert cif... |
426 427 |
fattr->cf_mode |= S_IFREG; /* file? */ fattr->cf_dtype = DT_REG; |
fb8c4b14d [CIFS] whitespace... |
428 |
rc = -EOPNOTSUPP; |
86c96b4bb [CIFS] Fix mknod ... |
429 |
} |
3020a1f58 [CIFS] Fix schedu... |
430 |
} else { |
0b8f18e35 cifs: convert cif... |
431 432 |
fattr->cf_mode |= S_IFREG; /* then it is a file */ fattr->cf_dtype = DT_REG; |
fb8c4b14d [CIFS] whitespace... |
433 434 |
rc = -EOPNOTSUPP; /* or some unknown SFU type */ } |
7ffec3724 cifs: add refcoun... |
435 |
CIFSSMBClose(xid, tcon, netfid); |
d6e2f2a4c [CIFS] Recognize ... |
436 |
} |
7ffec3724 cifs: add refcoun... |
437 |
cifs_put_tlink(tlink); |
d6e2f2a4c [CIFS] Recognize ... |
438 |
return rc; |
d6e2f2a4c [CIFS] Recognize ... |
439 |
} |
9e294f1c4 [CIFS] Recognize ... |
440 |
#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ |
0b8f18e35 cifs: convert cif... |
441 442 443 444 445 446 447 |
/* * Fetch mode bits as provided by SFU. * * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ? */ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid) |
9e294f1c4 [CIFS] Recognize ... |
448 |
{ |
3020a1f58 [CIFS] Fix schedu... |
449 |
#ifdef CONFIG_CIFS_XATTR |
9e294f1c4 [CIFS] Recognize ... |
450 451 452 |
ssize_t rc; char ea_value[4]; __u32 mode; |
7ffec3724 cifs: add refcoun... |
453 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
454 |
struct cifs_tcon *tcon; |
7ffec3724 cifs: add refcoun... |
455 456 457 458 459 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
9e294f1c4 [CIFS] Recognize ... |
460 |
|
7ffec3724 cifs: add refcoun... |
461 |
rc = CIFSSMBQAllEAs(xid, tcon, path, "SETFILEBITS", |
0b8f18e35 cifs: convert cif... |
462 463 464 |
ea_value, 4 /* size of buf */, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
7ffec3724 cifs: add refcoun... |
465 |
cifs_put_tlink(tlink); |
4523cc304 [CIFS] UID/GID ov... |
466 |
if (rc < 0) |
9e294f1c4 [CIFS] Recognize ... |
467 468 469 |
return (int)rc; else if (rc > 3) { mode = le32_to_cpu(*((__le32 *)ea_value)); |
0b8f18e35 cifs: convert cif... |
470 |
fattr->cf_mode &= ~SFBITS_MASK; |
b6b38f704 [CIFS] Neaten cER... |
471 472 |
cFYI(1, "special bits 0%o org mode 0%o", mode, fattr->cf_mode); |
0b8f18e35 cifs: convert cif... |
473 |
fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode; |
b6b38f704 [CIFS] Neaten cER... |
474 |
cFYI(1, "special mode bits 0%o", mode); |
9e294f1c4 [CIFS] Recognize ... |
475 |
} |
0b8f18e35 cifs: convert cif... |
476 477 |
return 0; |
3020a1f58 [CIFS] Fix schedu... |
478 479 480 |
#else return -EOPNOTSUPP; #endif |
9e294f1c4 [CIFS] Recognize ... |
481 |
} |
0b8f18e35 cifs: convert cif... |
482 |
/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */ |
f1230c979 [CIFS] fix sparse... |
483 |
static void |
0b8f18e35 cifs: convert cif... |
484 485 |
cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, struct cifs_sb_info *cifs_sb, bool adjust_tz) |
b9a3260f2 [CIFS] Enable DFS... |
486 |
{ |
96daf2b09 [CIFS] Rename thr... |
487 |
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
0d424ad0a cifs: add cifs_sb... |
488 |
|
0b8f18e35 cifs: convert cif... |
489 490 491 492 493 494 495 496 497 498 499 500 501 502 |
memset(fattr, 0, sizeof(*fattr)); fattr->cf_cifsattrs = le32_to_cpu(info->Attributes); if (info->DeletePending) fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING; if (info->LastAccessTime) fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); else fattr->cf_atime = CURRENT_TIME; fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); if (adjust_tz) { |
0d424ad0a cifs: add cifs_sb... |
503 504 |
fattr->cf_ctime.tv_sec += tcon->ses->server->timeAdj; fattr->cf_mtime.tv_sec += tcon->ses->server->timeAdj; |
0b8f18e35 cifs: convert cif... |
505 506 507 508 |
} fattr->cf_eof = le64_to_cpu(info->EndOfFile); fattr->cf_bytes = le64_to_cpu(info->AllocationSize); |
20054bd65 cifs: use Creatio... |
509 |
fattr->cf_createtime = le64_to_cpu(info->CreationTime); |
0b8f18e35 cifs: convert cif... |
510 511 512 513 514 515 516 |
if (fattr->cf_cifsattrs & ATTR_DIRECTORY) { fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode; fattr->cf_dtype = DT_DIR; } else { fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode; fattr->cf_dtype = DT_REG; |
0b8f18e35 cifs: convert cif... |
517 |
|
d0c280d26 cifs: when ATTR_R... |
518 519 520 521 |
/* clear write bits if ATTR_READONLY is set */ if (fattr->cf_cifsattrs & ATTR_READONLY) fattr->cf_mode &= ~(S_IWUGO); } |
0b8f18e35 cifs: convert cif... |
522 523 524 525 526 |
fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks); fattr->cf_uid = cifs_sb->mnt_uid; fattr->cf_gid = cifs_sb->mnt_gid; |
b9a3260f2 [CIFS] Enable DFS... |
527 |
} |
abab095d1 cifs: add cifs_re... |
528 529 530 531 532 533 534 535 |
int cifs_get_file_info(struct file *filp) { int rc; int xid; FILE_ALL_INFO find_data; struct cifs_fattr fattr; struct inode *inode = filp->f_path.dentry->d_inode; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
c21dfb699 fs/cifs: Remove u... |
536 |
struct cifsFileInfo *cfile = filp->private_data; |
96daf2b09 [CIFS] Rename thr... |
537 |
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink); |
abab095d1 cifs: add cifs_re... |
538 539 540 |
xid = GetXid(); rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data); |
42274bb22 CIFS: Fix DFS han... |
541 542 543 544 545 546 547 548 549 550 |
switch (rc) { case 0: cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false); break; case -EREMOTE: cifs_create_dfs_fattr(&fattr, inode->i_sb); rc = 0; break; case -EOPNOTSUPP: case -EINVAL: |
abab095d1 cifs: add cifs_re... |
551 552 |
/* * FIXME: legacy server -- fall back to path-based call? |
ff215713e [CIFS] checkpatch... |
553 554 555 |
* for now, just skip revalidating and mark inode for * immediate reval. */ |
abab095d1 cifs: add cifs_re... |
556 557 |
rc = 0; CIFS_I(inode)->time = 0; |
42274bb22 CIFS: Fix DFS han... |
558 |
default: |
abab095d1 cifs: add cifs_re... |
559 |
goto cgfi_exit; |
42274bb22 CIFS: Fix DFS han... |
560 |
} |
abab095d1 cifs: add cifs_re... |
561 562 563 564 565 |
/* * don't bother with SFU junk here -- just mark inode as needing * revalidation. */ |
abab095d1 cifs: add cifs_re... |
566 567 568 569 570 571 572 |
fattr.cf_uniqueid = CIFS_I(inode)->uniqueid; fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; cifs_fattr_to_inode(inode, &fattr); cgfi_exit: FreeXid(xid); return rc; } |
1da177e4c Linux-2.6.12-rc2 |
573 |
int cifs_get_inode_info(struct inode **pinode, |
646dd5398 [CIFS] Fix paths ... |
574 |
const unsigned char *full_path, FILE_ALL_INFO *pfindData, |
8b1327f6e [CIFS] file creat... |
575 |
struct super_block *sb, int xid, const __u16 *pfid) |
1da177e4c Linux-2.6.12-rc2 |
576 |
{ |
0b8f18e35 cifs: convert cif... |
577 |
int rc = 0, tmprc; |
96daf2b09 [CIFS] Rename thr... |
578 |
struct cifs_tcon *pTcon; |
7ffec3724 cifs: add refcoun... |
579 |
struct tcon_link *tlink; |
1da177e4c Linux-2.6.12-rc2 |
580 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
1da177e4c Linux-2.6.12-rc2 |
581 |
char *buf = NULL; |
5ade9deaa [CIFS] fix typo |
582 |
bool adjustTZ = false; |
0b8f18e35 cifs: convert cif... |
583 |
struct cifs_fattr fattr; |
1da177e4c Linux-2.6.12-rc2 |
584 |
|
7ffec3724 cifs: add refcoun... |
585 586 587 588 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); pTcon = tlink_tcon(tlink); |
b6b38f704 [CIFS] Neaten cER... |
589 |
cFYI(1, "Getting info on %s", full_path); |
1da177e4c Linux-2.6.12-rc2 |
590 |
|
d0d2f2df6 [CIFS] Update cif... |
591 592 |
if ((pfindData == NULL) && (*pinode != NULL)) { if (CIFS_I(*pinode)->clientCanCacheRead) { |
b6b38f704 [CIFS] Neaten cER... |
593 |
cFYI(1, "No need to revalidate cached inode sizes"); |
7ffec3724 cifs: add refcoun... |
594 |
goto cgii_exit; |
1da177e4c Linux-2.6.12-rc2 |
595 596 597 598 |
} } /* if file info not passed in then get it from server */ |
d0d2f2df6 [CIFS] Update cif... |
599 |
if (pfindData == NULL) { |
1da177e4c Linux-2.6.12-rc2 |
600 |
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); |
7ffec3724 cifs: add refcoun... |
601 602 603 604 |
if (buf == NULL) { rc = -ENOMEM; goto cgii_exit; } |
1da177e4c Linux-2.6.12-rc2 |
605 |
pfindData = (FILE_ALL_INFO *)buf; |
7962670e6 [CIFS] DFS patch... |
606 |
|
1da177e4c Linux-2.6.12-rc2 |
607 |
/* could do find first instead but this returns more info */ |
7962670e6 [CIFS] DFS patch... |
608 |
rc = CIFSSMBQPathInfo(xid, pTcon, full_path, pfindData, |
acf1a1b10 [CIFS] Level 1 QP... |
609 |
0 /* not legacy */, |
6b8edfe0f [CIFS] Support fo... |
610 |
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
737b758c9 [PATCH] cifs: cha... |
611 |
CIFS_MOUNT_MAP_SPECIAL_CHR); |
6b8edfe0f [CIFS] Support fo... |
612 613 614 |
/* BB optimize code so we do not make the above call when server claims no NT SMB support and the above call failed at least once - set flag in tcon or mount */ |
4523cc304 [CIFS] UID/GID ov... |
615 |
if ((rc == -EOPNOTSUPP) || (rc == -EINVAL)) { |
7962670e6 [CIFS] DFS patch... |
616 |
rc = SMBQueryInformation(xid, pTcon, full_path, |
fb8c4b14d [CIFS] whitespace... |
617 |
pfindData, cifs_sb->local_nls, |
6b8edfe0f [CIFS] Support fo... |
618 619 |
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
4b18f2a9c [CIFS] convert us... |
620 |
adjustTZ = true; |
6b8edfe0f [CIFS] Support fo... |
621 |
} |
1da177e4c Linux-2.6.12-rc2 |
622 |
} |
0b8f18e35 cifs: convert cif... |
623 624 625 626 627 628 |
if (!rc) { cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData, cifs_sb, adjustTZ); } else if (rc == -EREMOTE) { cifs_create_dfs_fattr(&fattr, sb); |
b9a3260f2 [CIFS] Enable DFS... |
629 |
rc = 0; |
0b8f18e35 cifs: convert cif... |
630 |
} else { |
7962670e6 [CIFS] DFS patch... |
631 |
goto cgii_exit; |
0b8f18e35 cifs: convert cif... |
632 |
} |
1da177e4c Linux-2.6.12-rc2 |
633 |
|
0b8f18e35 cifs: convert cif... |
634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 |
/* * If an inode wasn't passed in, then get the inode number * * Is an i_ino of zero legal? Can we use that to check if the server * supports returning inode numbers? Are there other sanity checks we * can use to ensure that the server is really filling in that field? * * We can not use the IndexNumber field by default from Windows or * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA * CIFS spec claims that this value is unique within the scope of a * share, and the windows docs hint that it's actually unique * per-machine. * * There may be higher info levels that work but are there Windows * server or network appliances for which IndexNumber field is not * guaranteed unique? */ |
b9a3260f2 [CIFS] Enable DFS... |
651 |
if (*pinode == NULL) { |
b9a3260f2 [CIFS] Enable DFS... |
652 653 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { int rc1 = 0; |
b9a3260f2 [CIFS] Enable DFS... |
654 655 |
rc1 = CIFSGetSrvInodeNumber(xid, pTcon, |
0b8f18e35 cifs: convert cif... |
656 |
full_path, &fattr.cf_uniqueid, |
737b758c9 [PATCH] cifs: cha... |
657 658 659 |
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
ec06aedd4 cifs: clean up ha... |
660 |
if (rc1 || !fattr.cf_uniqueid) { |
b6b38f704 [CIFS] Neaten cER... |
661 |
cFYI(1, "GetSrvInodeNum rc %d", rc1); |
0b8f18e35 cifs: convert cif... |
662 |
fattr.cf_uniqueid = iunique(sb, ROOT_I); |
ec06aedd4 cifs: clean up ha... |
663 |
cifs_autodisable_serverino(cifs_sb); |
132ac7b77 cifs: refactor ne... |
664 |
} |
132ac7b77 cifs: refactor ne... |
665 |
} else { |
0b8f18e35 cifs: convert cif... |
666 |
fattr.cf_uniqueid = iunique(sb, ROOT_I); |
132ac7b77 cifs: refactor ne... |
667 |
} |
b9a3260f2 [CIFS] Enable DFS... |
668 |
} else { |
0b8f18e35 cifs: convert cif... |
669 |
fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid; |
b9a3260f2 [CIFS] Enable DFS... |
670 |
} |
0b8f18e35 cifs: convert cif... |
671 672 673 674 675 |
/* query for SFU type info if supported and needed */ if (fattr.cf_cifsattrs & ATTR_SYSTEM && cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid); if (tmprc) |
b6b38f704 [CIFS] Neaten cER... |
676 |
cFYI(1, "cifs_sfu_type failed: %d", tmprc); |
b9a3260f2 [CIFS] Enable DFS... |
677 |
} |
1da177e4c Linux-2.6.12-rc2 |
678 |
|
79df1baee cifs: fix use of ... |
679 |
#ifdef CONFIG_CIFS_ACL |
b9a3260f2 [CIFS] Enable DFS... |
680 681 |
/* fill in 0777 bits from ACL */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
78415d2d3 cifs: Misc. clean... |
682 683 684 685 686 687 688 |
rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid); if (rc) { cFYI(1, "%s: Getting ACL failed with error: %d", __func__, rc); goto cgii_exit; } |
b9a3260f2 [CIFS] Enable DFS... |
689 |
} |
79df1baee cifs: fix use of ... |
690 |
#endif /* CONFIG_CIFS_ACL */ |
b9a3260f2 [CIFS] Enable DFS... |
691 |
|
0b8f18e35 cifs: convert cif... |
692 693 694 |
/* fill in remaining high mode bits e.g. SUID, VTX */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) cifs_sfu_mode(&fattr, full_path, cifs_sb, xid); |
b9a3260f2 [CIFS] Enable DFS... |
695 |
|
1b12b9c15 cifs: use Minshal... |
696 697 698 699 700 701 |
/* check for Minshall+French symlinks */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) { tmprc = CIFSCheckMFSymlink(&fattr, full_path, cifs_sb, xid); if (tmprc) cFYI(1, "CIFSCheckMFSymlink: %d", tmprc); } |
0b8f18e35 cifs: convert cif... |
702 703 704 705 706 707 708 |
if (!*pinode) { *pinode = cifs_iget(sb, &fattr); if (!*pinode) rc = -ENOMEM; } else { cifs_fattr_to_inode(*pinode, &fattr); } |
b9a3260f2 [CIFS] Enable DFS... |
709 |
|
7962670e6 [CIFS] DFS patch... |
710 |
cgii_exit: |
1da177e4c Linux-2.6.12-rc2 |
711 |
kfree(buf); |
7ffec3724 cifs: add refcoun... |
712 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
713 714 |
return rc; } |
7f8ed420f [CIFS] CIFS suppo... |
715 716 717 |
static const struct inode_operations cifs_ipc_inode_ops = { .lookup = cifs_lookup, }; |
f87d39d95 [CIFS] Migrate fr... |
718 |
char *cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, |
96daf2b09 [CIFS] Rename thr... |
719 |
struct cifs_tcon *tcon) |
8be0ed44c [CIFS] Can not mo... |
720 |
{ |
f87d39d95 [CIFS] Migrate fr... |
721 |
int pplen = vol->prepath ? strlen(vol->prepath) : 0; |
8be0ed44c [CIFS] Can not mo... |
722 723 724 725 726 727 728 729 730 731 |
int dfsplen; char *full_path = NULL; /* if no prefix path, simply set path to the root of share to "" */ if (pplen == 0) { full_path = kmalloc(1, GFP_KERNEL); if (full_path) full_path[0] = 0; return full_path; } |
0d424ad0a cifs: add cifs_sb... |
732 733 |
if (tcon->Flags & SMB_SHARE_IS_IN_DFS) dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); |
8be0ed44c [CIFS] Can not mo... |
734 735 736 737 738 739 |
else dfsplen = 0; full_path = kmalloc(dfsplen + pplen + 1, GFP_KERNEL); if (full_path == NULL) return full_path; |
f9e8c4500 cifs: convert pre... |
740 |
if (dfsplen) |
0d424ad0a cifs: add cifs_sb... |
741 |
strncpy(full_path, tcon->treeName, dfsplen); |
f87d39d95 [CIFS] Migrate fr... |
742 |
strncpy(full_path + dfsplen, vol->prepath, pplen); |
f9e8c4500 cifs: convert pre... |
743 |
convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); |
8be0ed44c [CIFS] Can not mo... |
744 745 746 |
full_path[dfsplen + pplen] = 0; /* add trailing null */ return full_path; } |
cc0bad755 cifs: add new cif... |
747 748 749 750 |
static int cifs_find_inode(struct inode *inode, void *opaque) { struct cifs_fattr *fattr = (struct cifs_fattr *) opaque; |
f30b9c118 cifs: don't allow... |
751 |
/* don't match inode with different uniqueid */ |
cc0bad755 cifs: add new cif... |
752 753 |
if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid) return 0; |
20054bd65 cifs: use Creatio... |
754 755 756 |
/* use createtime like an i_generation field */ if (CIFS_I(inode)->createtime != fattr->cf_createtime) return 0; |
f30b9c118 cifs: don't allow... |
757 758 759 |
/* don't match inode of different type */ if ((inode->i_mode & S_IFMT) != (fattr->cf_mode & S_IFMT)) return 0; |
5acfec250 cifs: reduce fals... |
760 761 |
/* if it's not a directory or has no dentries, then flag it */ if (S_ISDIR(inode->i_mode) && !list_empty(&inode->i_dentry)) |
3d6943803 cifs: guard again... |
762 |
fattr->cf_flags |= CIFS_FATTR_INO_COLLISION; |
3d6943803 cifs: guard again... |
763 |
|
cc0bad755 cifs: add new cif... |
764 765 766 767 768 769 770 771 772 |
return 1; } static int cifs_init_inode(struct inode *inode, void *opaque) { struct cifs_fattr *fattr = (struct cifs_fattr *) opaque; CIFS_I(inode)->uniqueid = fattr->cf_uniqueid; |
20054bd65 cifs: use Creatio... |
773 |
CIFS_I(inode)->createtime = fattr->cf_createtime; |
cc0bad755 cifs: add new cif... |
774 775 |
return 0; } |
5acfec250 cifs: reduce fals... |
776 777 778 779 780 781 782 783 784 |
/* * walk dentry list for an inode and report whether it has aliases that * are hashed. We use this to determine if a directory inode can actually * be used. */ static bool inode_has_hashed_dentries(struct inode *inode) { struct dentry *dentry; |
873feea09 fs: dcache per-in... |
785 |
spin_lock(&inode->i_lock); |
5acfec250 cifs: reduce fals... |
786 787 |
list_for_each_entry(dentry, &inode->i_dentry, d_alias) { if (!d_unhashed(dentry) || IS_ROOT(dentry)) { |
873feea09 fs: dcache per-in... |
788 |
spin_unlock(&inode->i_lock); |
5acfec250 cifs: reduce fals... |
789 790 791 |
return true; } } |
873feea09 fs: dcache per-in... |
792 |
spin_unlock(&inode->i_lock); |
5acfec250 cifs: reduce fals... |
793 794 |
return false; } |
cc0bad755 cifs: add new cif... |
795 796 797 798 799 800 |
/* Given fattrs, get a corresponding inode */ struct inode * cifs_iget(struct super_block *sb, struct cifs_fattr *fattr) { unsigned long hash; struct inode *inode; |
3d6943803 cifs: guard again... |
801 |
retry_iget5_locked: |
b6b38f704 [CIFS] Neaten cER... |
802 |
cFYI(1, "looking for uniqueid=%llu", fattr->cf_uniqueid); |
cc0bad755 cifs: add new cif... |
803 804 805 806 807 |
/* hash down to 32-bits on 32-bit arch */ hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid); inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr); |
cc0bad755 cifs: add new cif... |
808 |
if (inode) { |
5acfec250 cifs: reduce fals... |
809 |
/* was there a potentially problematic inode collision? */ |
3d6943803 cifs: guard again... |
810 |
if (fattr->cf_flags & CIFS_FATTR_INO_COLLISION) { |
3d6943803 cifs: guard again... |
811 |
fattr->cf_flags &= ~CIFS_FATTR_INO_COLLISION; |
5acfec250 cifs: reduce fals... |
812 813 814 815 816 817 818 |
if (inode_has_hashed_dentries(inode)) { cifs_autodisable_serverino(CIFS_SB(sb)); iput(inode); fattr->cf_uniqueid = iunique(sb, ROOT_I); goto retry_iget5_locked; } |
3d6943803 cifs: guard again... |
819 |
} |
cc0bad755 cifs: add new cif... |
820 821 822 823 824 |
cifs_fattr_to_inode(inode, fattr); if (sb->s_flags & MS_NOATIME) inode->i_flags |= S_NOATIME | S_NOCMTIME; if (inode->i_state & I_NEW) { inode->i_ino = hash; |
522440ed5 cifs: set backing... |
825 826 |
if (S_ISREG(inode->i_mode)) inode->i_data.backing_dev_info = sb->s_bdi; |
0ccd48025 [CIFS] Missing ifdef |
827 |
#ifdef CONFIG_CIFS_FSCACHE |
9451a9a52 cifs: define inod... |
828 829 |
/* initialize per-inode cache cookie pointer */ CIFS_I(inode)->fscache = NULL; |
0ccd48025 [CIFS] Missing ifdef |
830 |
#endif |
cc0bad755 cifs: add new cif... |
831 832 833 834 835 836 |
unlock_new_inode(inode); } } return inode; } |
1da177e4c Linux-2.6.12-rc2 |
837 |
/* gets root inode */ |
9b6763e0a cifs: Remove unus... |
838 |
struct inode *cifs_root_iget(struct super_block *sb) |
1da177e4c Linux-2.6.12-rc2 |
839 |
{ |
ce634ab28 iget: stop CIFS f... |
840 |
int xid; |
0d424ad0a cifs: add cifs_sb... |
841 |
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
cc0bad755 cifs: add new cif... |
842 |
struct inode *inode = NULL; |
ce634ab28 iget: stop CIFS f... |
843 |
long rc; |
96daf2b09 [CIFS] Rename thr... |
844 |
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
ce634ab28 iget: stop CIFS f... |
845 |
|
8be0ed44c [CIFS] Can not mo... |
846 |
xid = GetXid(); |
0d424ad0a cifs: add cifs_sb... |
847 |
if (tcon->unix_ext) |
f87d39d95 [CIFS] Migrate fr... |
848 |
rc = cifs_get_inode_info_unix(&inode, "", sb, xid); |
0b8f18e35 cifs: convert cif... |
849 |
else |
f87d39d95 [CIFS] Migrate fr... |
850 |
rc = cifs_get_inode_info(&inode, "", NULL, sb, xid, NULL); |
0b8f18e35 cifs: convert cif... |
851 |
|
a7851ce73 cifs: fix another... |
852 853 854 855 |
if (!inode) { inode = ERR_PTR(rc); goto out; } |
cc0bad755 cifs: add new cif... |
856 |
|
0ccd48025 [CIFS] Missing ifdef |
857 |
#ifdef CONFIG_CIFS_FSCACHE |
d03382ce9 cifs: define supe... |
858 |
/* populate tcon->resource_id */ |
0d424ad0a cifs: add cifs_sb... |
859 |
tcon->resource_id = CIFS_I(inode)->uniqueid; |
0ccd48025 [CIFS] Missing ifdef |
860 |
#endif |
d03382ce9 cifs: define supe... |
861 |
|
0d424ad0a cifs: add cifs_sb... |
862 |
if (rc && tcon->ipc) { |
b6b38f704 [CIFS] Neaten cER... |
863 |
cFYI(1, "ipc connection - fake read inode"); |
7f8ed420f [CIFS] CIFS suppo... |
864 |
inode->i_mode |= S_IFDIR; |
bfe868486 filesystems: add ... |
865 |
set_nlink(inode, 2); |
7f8ed420f [CIFS] CIFS suppo... |
866 867 868 869 |
inode->i_op = &cifs_ipc_inode_ops; inode->i_fop = &simple_dir_operations; inode->i_uid = cifs_sb->mnt_uid; inode->i_gid = cifs_sb->mnt_gid; |
ad661334b [CIFS] mount of I... |
870 |
} else if (rc) { |
ce634ab28 iget: stop CIFS f... |
871 |
iget_failed(inode); |
a7851ce73 cifs: fix another... |
872 |
inode = ERR_PTR(rc); |
7f8ed420f [CIFS] CIFS suppo... |
873 |
} |
a7851ce73 cifs: fix another... |
874 |
out: |
ce634ab28 iget: stop CIFS f... |
875 876 877 |
/* can not call macro FreeXid here since in a void func * TODO: This is no longer true */ |
1da177e4c Linux-2.6.12-rc2 |
878 |
_FreeXid(xid); |
ce634ab28 iget: stop CIFS f... |
879 |
return inode; |
1da177e4c Linux-2.6.12-rc2 |
880 |
} |
388e57b27 [CIFS] use common... |
881 882 883 884 885 886 887 888 889 890 891 892 |
static int cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid, char *full_path, __u32 dosattr) { int rc; int oplock = 0; __u16 netfid; __u32 netpid; bool set_time = false; struct cifsFileInfo *open_file; struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
893 |
struct tcon_link *tlink = NULL; |
96daf2b09 [CIFS] Rename thr... |
894 |
struct cifs_tcon *pTcon; |
388e57b27 [CIFS] use common... |
895 |
FILE_BASIC_INFO info_buf; |
1adcb7109 [CIFS] add extra ... |
896 897 |
if (attrs == NULL) return -EINVAL; |
388e57b27 [CIFS] use common... |
898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 |
if (attrs->ia_valid & ATTR_ATIME) { set_time = true; info_buf.LastAccessTime = cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime)); } else info_buf.LastAccessTime = 0; if (attrs->ia_valid & ATTR_MTIME) { set_time = true; info_buf.LastWriteTime = cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime)); } else info_buf.LastWriteTime = 0; /* * Samba throws this field away, but windows may actually use it. * Do not set ctime unless other time stamps are changed explicitly * (i.e. by utimes()) since we would then have a mix of client and * server times. */ if (set_time && (attrs->ia_valid & ATTR_CTIME)) { |
b6b38f704 [CIFS] Neaten cER... |
919 |
cFYI(1, "CIFS - CTIME changed"); |
388e57b27 [CIFS] use common... |
920 921 922 923 924 925 926 927 928 929 930 |
info_buf.ChangeTime = cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); } else info_buf.ChangeTime = 0; info_buf.CreationTime = 0; /* don't change */ info_buf.Attributes = cpu_to_le32(dosattr); /* * If the file is already open for write, just use that fileid */ |
6508d904e cifs: have find_r... |
931 |
open_file = find_writable_file(cifsInode, true); |
388e57b27 [CIFS] use common... |
932 933 934 |
if (open_file) { netfid = open_file->netfid; netpid = open_file->pid; |
13cfb7334 cifs: have cifsFi... |
935 |
pTcon = tlink_tcon(open_file->tlink); |
388e57b27 [CIFS] use common... |
936 937 |
goto set_via_filehandle; } |
7ffec3724 cifs: add refcoun... |
938 939 940 941 942 943 944 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) { rc = PTR_ERR(tlink); tlink = NULL; goto out; } pTcon = tlink_tcon(tlink); |
ba00ba64c cifs: make variou... |
945 |
|
388e57b27 [CIFS] use common... |
946 947 948 949 950 951 952 953 954 |
/* * NT4 apparently returns success on this call, but it doesn't * really work. */ if (!(pTcon->ses->flags & CIFS_SES_NT4)) { rc = CIFSSMBSetPathInfo(xid, pTcon, full_path, &info_buf, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
6b37faa17 [CIFS] fix some s... |
955 956 957 958 |
if (rc == 0) { cifsInode->cifsAttrs = dosattr; goto out; } else if (rc != -EOPNOTSUPP && rc != -EINVAL) |
388e57b27 [CIFS] use common... |
959 960 |
goto out; } |
b6b38f704 [CIFS] Neaten cER... |
961 962 |
cFYI(1, "calling SetFileInfo since SetPathInfo for " "times not supported by this server"); |
388e57b27 [CIFS] use common... |
963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 |
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, SYNCHRONIZE | FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc != 0) { if (rc == -EIO) rc = -EINVAL; goto out; } netpid = current->tgid; set_via_filehandle: rc = CIFSSMBSetFileInfo(xid, pTcon, &info_buf, netfid, netpid); |
d388908ec [CIFS] update DOS... |
980 981 |
if (!rc) cifsInode->cifsAttrs = dosattr; |
388e57b27 [CIFS] use common... |
982 983 984 |
if (open_file == NULL) CIFSSMBClose(xid, pTcon, netfid); else |
6ab409b53 cifs: Replace wrt... |
985 |
cifsFileInfo_put(open_file); |
388e57b27 [CIFS] use common... |
986 |
out: |
7ffec3724 cifs: add refcoun... |
987 988 |
if (tlink != NULL) cifs_put_tlink(tlink); |
388e57b27 [CIFS] use common... |
989 990 |
return rc; } |
a12a1ac7a cifs: move rename... |
991 992 993 994 995 996 |
/* * open the given file (if it isn't already), set the DELETE_ON_CLOSE bit * and rename it to a random name that hopefully won't conflict with * anything else. */ static int |
3270958b7 [CIFS] undo chang... |
997 |
cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid) |
a12a1ac7a cifs: move rename... |
998 999 1000 1001 |
{ int oplock = 0; int rc; __u16 netfid; |
3270958b7 [CIFS] undo chang... |
1002 |
struct inode *inode = dentry->d_inode; |
a12a1ac7a cifs: move rename... |
1003 1004 |
struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
1005 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1006 |
struct cifs_tcon *tcon; |
3270958b7 [CIFS] undo chang... |
1007 1008 |
__u32 dosattr, origattr; FILE_BASIC_INFO *info_buf = NULL; |
a12a1ac7a cifs: move rename... |
1009 |
|
7ffec3724 cifs: add refcoun... |
1010 1011 1012 1013 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
a12a1ac7a cifs: move rename... |
1014 |
rc = CIFSSMBOpen(xid, tcon, full_path, FILE_OPEN, |
dd1db2ded cifs: don't use C... |
1015 |
DELETE|FILE_WRITE_ATTRIBUTES, CREATE_NOT_DIR, |
a12a1ac7a cifs: move rename... |
1016 1017 1018 1019 |
&netfid, &oplock, NULL, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc != 0) goto out; |
3270958b7 [CIFS] undo chang... |
1020 1021 1022 1023 1024 |
origattr = cifsInode->cifsAttrs; if (origattr == 0) origattr |= ATTR_NORMAL; dosattr = origattr & ~ATTR_READONLY; |
a12a1ac7a cifs: move rename... |
1025 1026 1027 |
if (dosattr == 0) dosattr |= ATTR_NORMAL; dosattr |= ATTR_HIDDEN; |
3270958b7 [CIFS] undo chang... |
1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 |
/* set ATTR_HIDDEN and clear ATTR_READONLY, but only if needed */ if (dosattr != origattr) { info_buf = kzalloc(sizeof(*info_buf), GFP_KERNEL); if (info_buf == NULL) { rc = -ENOMEM; goto out_close; } info_buf->Attributes = cpu_to_le32(dosattr); rc = CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid, current->tgid); /* although we would like to mark the file hidden if that fails we will still try to rename it */ |
413460980 [CIFS] fix build ... |
1040 |
if (rc != 0) |
3270958b7 [CIFS] undo chang... |
1041 1042 1043 |
cifsInode->cifsAttrs = dosattr; else dosattr = origattr; /* since not able to change them */ |
a12a1ac7a cifs: move rename... |
1044 |
} |
a12a1ac7a cifs: move rename... |
1045 |
|
dd1db2ded cifs: don't use C... |
1046 1047 |
/* rename the file */ rc = CIFSSMBRenameOpenFile(xid, tcon, netfid, NULL, cifs_sb->local_nls, |
a12a1ac7a cifs: move rename... |
1048 1049 |
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
3270958b7 [CIFS] undo chang... |
1050 1051 1052 1053 |
if (rc != 0) { rc = -ETXTBSY; goto undo_setattr; } |
6d22f0989 cifs: add functio... |
1054 |
|
3270958b7 [CIFS] undo chang... |
1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 |
/* try to set DELETE_ON_CLOSE */ if (!cifsInode->delete_pending) { rc = CIFSSMBSetFileDisposition(xid, tcon, true, netfid, current->tgid); /* * some samba versions return -ENOENT when we try to set the * file disposition here. Likely a samba bug, but work around * it for now. This means that some cifsXXX files may hang * around after they shouldn't. * * BB: remove this hack after more servers have the fix */ if (rc == -ENOENT) rc = 0; else if (rc != 0) { rc = -ETXTBSY; goto undo_rename; } cifsInode->delete_pending = true; } |
7ce86d5a9 cifs: work around... |
1075 |
|
a12a1ac7a cifs: move rename... |
1076 1077 1078 |
out_close: CIFSSMBClose(xid, tcon, netfid); out: |
3270958b7 [CIFS] undo chang... |
1079 |
kfree(info_buf); |
7ffec3724 cifs: add refcoun... |
1080 |
cifs_put_tlink(tlink); |
a12a1ac7a cifs: move rename... |
1081 |
return rc; |
3270958b7 [CIFS] undo chang... |
1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 |
/* * reset everything back to the original state. Don't bother * dealing with errors here since we can't do anything about * them anyway. */ undo_rename: CIFSSMBRenameOpenFile(xid, tcon, netfid, dentry->d_name.name, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); undo_setattr: if (dosattr != origattr) { info_buf->Attributes = cpu_to_le32(origattr); if (!CIFSSMBSetFileInfo(xid, tcon, info_buf, netfid, current->tgid)) cifsInode->cifsAttrs = origattr; } goto out_close; |
a12a1ac7a cifs: move rename... |
1101 |
} |
ff6945279 [CIFS] Make cifs_... |
1102 1103 1104 1105 |
/* * If dentry->d_inode is null (usually meaning the cached dentry * is a negative dentry) then we would attempt a standard SMB delete, but |
af901ca18 tree-wide: fix as... |
1106 1107 |
* if that fails we can not attempt the fall back mechanisms on EACCESS * but will return the EACCESS to the caller. Note that the VFS does not call |
ff6945279 [CIFS] Make cifs_... |
1108 1109 |
* unlink on negative dentries currently. */ |
5f0319a79 cifs: clean up va... |
1110 |
int cifs_unlink(struct inode *dir, struct dentry *dentry) |
1da177e4c Linux-2.6.12-rc2 |
1111 1112 1113 |
{ int rc = 0; int xid; |
1da177e4c Linux-2.6.12-rc2 |
1114 |
char *full_path = NULL; |
5f0319a79 cifs: clean up va... |
1115 |
struct inode *inode = dentry->d_inode; |
ff6945279 [CIFS] Make cifs_... |
1116 |
struct cifsInodeInfo *cifs_inode; |
5f0319a79 cifs: clean up va... |
1117 1118 |
struct super_block *sb = dir->i_sb; struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
7ffec3724 cifs: add refcoun... |
1119 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1120 |
struct cifs_tcon *tcon; |
6050247d8 [CIFS] clean up ... |
1121 1122 |
struct iattr *attrs = NULL; __u32 dosattr = 0, origattr = 0; |
1da177e4c Linux-2.6.12-rc2 |
1123 |
|
b6b38f704 [CIFS] Neaten cER... |
1124 |
cFYI(1, "cifs_unlink, dir=0x%p, dentry=0x%p", dir, dentry); |
1da177e4c Linux-2.6.12-rc2 |
1125 |
|
7ffec3724 cifs: add refcoun... |
1126 1127 1128 1129 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1130 |
xid = GetXid(); |
5f0319a79 cifs: clean up va... |
1131 1132 1133 |
/* Unlink can be called from rename so we can not take the * sb->s_vfs_rename_mutex here */ full_path = build_path_from_dentry(dentry); |
1da177e4c Linux-2.6.12-rc2 |
1134 |
if (full_path == NULL) { |
0f3bc09ee cifs: Fix incorre... |
1135 |
rc = -ENOMEM; |
7ffec3724 cifs: add refcoun... |
1136 |
goto unlink_out; |
1da177e4c Linux-2.6.12-rc2 |
1137 |
} |
2d785a50a [CIFS] Add suppor... |
1138 |
|
5f0319a79 cifs: clean up va... |
1139 |
if ((tcon->ses->capabilities & CAP_UNIX) && |
2d785a50a [CIFS] Add suppor... |
1140 |
(CIFS_UNIX_POSIX_PATH_OPS_CAP & |
5f0319a79 cifs: clean up va... |
1141 1142 |
le64_to_cpu(tcon->fsUnixInfo.Capability))) { rc = CIFSPOSIXDelFile(xid, tcon, full_path, |
2d785a50a [CIFS] Add suppor... |
1143 |
SMB_POSIX_UNLINK_FILE_TARGET, cifs_sb->local_nls, |
737b758c9 [PATCH] cifs: cha... |
1144 |
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
b6b38f704 [CIFS] Neaten cER... |
1145 |
cFYI(1, "posix del rc %d", rc); |
2d785a50a [CIFS] Add suppor... |
1146 1147 1148 |
if ((rc == 0) || (rc == -ENOENT)) goto psx_del_no_retry; } |
1da177e4c Linux-2.6.12-rc2 |
1149 |
|
6050247d8 [CIFS] clean up ... |
1150 |
retry_std_delete: |
5f0319a79 cifs: clean up va... |
1151 |
rc = CIFSSMBDelFile(xid, tcon, full_path, cifs_sb->local_nls, |
2d785a50a [CIFS] Add suppor... |
1152 |
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
6050247d8 [CIFS] clean up ... |
1153 |
|
2d785a50a [CIFS] Add suppor... |
1154 |
psx_del_no_retry: |
1da177e4c Linux-2.6.12-rc2 |
1155 |
if (!rc) { |
5f0319a79 cifs: clean up va... |
1156 1157 |
if (inode) drop_nlink(inode); |
1da177e4c Linux-2.6.12-rc2 |
1158 |
} else if (rc == -ENOENT) { |
5f0319a79 cifs: clean up va... |
1159 |
d_drop(dentry); |
1da177e4c Linux-2.6.12-rc2 |
1160 |
} else if (rc == -ETXTBSY) { |
3270958b7 [CIFS] undo chang... |
1161 |
rc = cifs_rename_pending_delete(full_path, dentry, xid); |
a12a1ac7a cifs: move rename... |
1162 1163 |
if (rc == 0) drop_nlink(inode); |
ff6945279 [CIFS] Make cifs_... |
1164 |
} else if ((rc == -EACCES) && (dosattr == 0) && inode) { |
388e57b27 [CIFS] use common... |
1165 1166 1167 1168 |
attrs = kzalloc(sizeof(*attrs), GFP_KERNEL); if (attrs == NULL) { rc = -ENOMEM; goto out_reval; |
1da177e4c Linux-2.6.12-rc2 |
1169 |
} |
388e57b27 [CIFS] use common... |
1170 1171 |
/* try to reset dos attributes */ |
ff6945279 [CIFS] Make cifs_... |
1172 1173 |
cifs_inode = CIFS_I(inode); origattr = cifs_inode->cifsAttrs; |
6050247d8 [CIFS] clean up ... |
1174 1175 1176 |
if (origattr == 0) origattr |= ATTR_NORMAL; dosattr = origattr & ~ATTR_READONLY; |
388e57b27 [CIFS] use common... |
1177 1178 1179 1180 1181 |
if (dosattr == 0) dosattr |= ATTR_NORMAL; dosattr |= ATTR_HIDDEN; rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr); |
388e57b27 [CIFS] use common... |
1182 1183 |
if (rc != 0) goto out_reval; |
6050247d8 [CIFS] clean up ... |
1184 1185 |
goto retry_std_delete; |
1da177e4c Linux-2.6.12-rc2 |
1186 |
} |
6050247d8 [CIFS] clean up ... |
1187 1188 1189 1190 |
/* undo the setattr if we errored out and it's needed */ if (rc != 0 && dosattr != 0) cifs_set_file_info(inode, attrs, xid, full_path, origattr); |
388e57b27 [CIFS] use common... |
1191 |
out_reval: |
4523cc304 [CIFS] UID/GID ov... |
1192 |
if (inode) { |
ff6945279 [CIFS] Make cifs_... |
1193 1194 |
cifs_inode = CIFS_I(inode); cifs_inode->time = 0; /* will force revalidate to get info |
5f0319a79 cifs: clean up va... |
1195 1196 |
when needed */ inode->i_ctime = current_fs_time(sb); |
06bcfedd0 [CIFS] Fix typo i... |
1197 |
} |
5f0319a79 cifs: clean up va... |
1198 |
dir->i_ctime = dir->i_mtime = current_fs_time(sb); |
ff6945279 [CIFS] Make cifs_... |
1199 |
cifs_inode = CIFS_I(dir); |
6050247d8 [CIFS] clean up ... |
1200 |
CIFS_I(dir)->time = 0; /* force revalidate of dir as well */ |
7ffec3724 cifs: add refcoun... |
1201 |
unlink_out: |
1da177e4c Linux-2.6.12-rc2 |
1202 |
kfree(full_path); |
6050247d8 [CIFS] clean up ... |
1203 |
kfree(attrs); |
1da177e4c Linux-2.6.12-rc2 |
1204 |
FreeXid(xid); |
7ffec3724 cifs: add refcoun... |
1205 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1206 1207 |
return rc; } |
18bb1db3e switch vfs_mkdir(... |
1208 |
int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) |
1da177e4c Linux-2.6.12-rc2 |
1209 |
{ |
6b37faa17 [CIFS] fix some s... |
1210 |
int rc = 0, tmprc; |
1da177e4c Linux-2.6.12-rc2 |
1211 1212 |
int xid; struct cifs_sb_info *cifs_sb; |
7ffec3724 cifs: add refcoun... |
1213 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1214 |
struct cifs_tcon *pTcon; |
1da177e4c Linux-2.6.12-rc2 |
1215 1216 |
char *full_path = NULL; struct inode *newinode = NULL; |
cc0bad755 cifs: add new cif... |
1217 |
struct cifs_fattr fattr; |
1da177e4c Linux-2.6.12-rc2 |
1218 |
|
18bb1db3e switch vfs_mkdir(... |
1219 |
cFYI(1, "In cifs_mkdir, mode = 0x%hx inode = 0x%p", mode, inode); |
1da177e4c Linux-2.6.12-rc2 |
1220 |
|
1da177e4c Linux-2.6.12-rc2 |
1221 |
cifs_sb = CIFS_SB(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
1222 1223 1224 1225 1226 1227 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); pTcon = tlink_tcon(tlink); xid = GetXid(); |
1da177e4c Linux-2.6.12-rc2 |
1228 |
|
7f57356b7 [CIFS] Remove cif... |
1229 |
full_path = build_path_from_dentry(direntry); |
1da177e4c Linux-2.6.12-rc2 |
1230 |
if (full_path == NULL) { |
0f3bc09ee cifs: Fix incorre... |
1231 |
rc = -ENOMEM; |
7ffec3724 cifs: add refcoun... |
1232 |
goto mkdir_out; |
1da177e4c Linux-2.6.12-rc2 |
1233 |
} |
50c2f7538 [CIFS] whitespace... |
1234 |
|
fb8c4b14d [CIFS] whitespace... |
1235 1236 |
if ((pTcon->ses->capabilities & CAP_UNIX) && (CIFS_UNIX_POSIX_PATH_OPS_CAP & |
2dd29d313 [CIFS] New CIFS P... |
1237 1238 |
le64_to_cpu(pTcon->fsUnixInfo.Capability))) { u32 oplock = 0; |
f6d099821 [CIFS] fix checkp... |
1239 |
FILE_UNIX_BASIC_INFO *pInfo = |
2dd29d313 [CIFS] New CIFS P... |
1240 |
kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); |
fb8c4b14d [CIFS] whitespace... |
1241 |
if (pInfo == NULL) { |
2dd29d313 [CIFS] New CIFS P... |
1242 1243 1244 |
rc = -ENOMEM; goto mkdir_out; } |
50c2f7538 [CIFS] whitespace... |
1245 |
|
ce3b0f8d5 New helper - curr... |
1246 |
mode &= ~current_umask(); |
2dd29d313 [CIFS] New CIFS P... |
1247 1248 |
rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT, mode, NULL /* netfid */, pInfo, &oplock, |
fb8c4b14d [CIFS] whitespace... |
1249 1250 |
full_path, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
2dd29d313 [CIFS] New CIFS P... |
1251 |
CIFS_MOUNT_MAP_SPECIAL_CHR); |
c45d707f6 [CIFS] Fallback t... |
1252 1253 1254 1255 |
if (rc == -EOPNOTSUPP) { kfree(pInfo); goto mkdir_retry_old; } else if (rc) { |
b6b38f704 [CIFS] Neaten cER... |
1256 |
cFYI(1, "posix mkdir returned 0x%x", rc); |
2dd29d313 [CIFS] New CIFS P... |
1257 1258 |
d_drop(direntry); } else { |
8f2376adf [CIFS] Fix endian... |
1259 1260 |
if (pInfo->Type == cpu_to_le32(-1)) { /* no return info, go query for it */ |
5a07cdf86 [CIFS] fix small ... |
1261 |
kfree(pInfo); |
fb8c4b14d [CIFS] whitespace... |
1262 |
goto mkdir_get_info; |
5a07cdf86 [CIFS] fix small ... |
1263 |
} |
fb8c4b14d [CIFS] whitespace... |
1264 1265 |
/*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need to set uid/gid */ |
2dd29d313 [CIFS] New CIFS P... |
1266 |
inc_nlink(inode); |
cbac3cba6 [CIFS] New CIFS P... |
1267 |
|
cc0bad755 cifs: add new cif... |
1268 |
cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb); |
4065c802d cifs: fix noserve... |
1269 |
cifs_fill_uniqueid(inode->i_sb, &fattr); |
cc0bad755 cifs: add new cif... |
1270 1271 |
newinode = cifs_iget(inode->i_sb, &fattr); if (!newinode) { |
5a07cdf86 [CIFS] fix small ... |
1272 |
kfree(pInfo); |
cbac3cba6 [CIFS] New CIFS P... |
1273 |
goto mkdir_get_info; |
5a07cdf86 [CIFS] fix small ... |
1274 |
} |
6b37faa17 [CIFS] fix some s... |
1275 |
|
2dd29d313 [CIFS] New CIFS P... |
1276 |
d_instantiate(direntry, newinode); |
cbac3cba6 [CIFS] New CIFS P... |
1277 |
|
cbac3cba6 [CIFS] New CIFS P... |
1278 |
#ifdef CONFIG_CIFS_DEBUG2 |
b6b38f704 [CIFS] Neaten cER... |
1279 1280 |
cFYI(1, "instantiated dentry %p %s to inode %p", direntry, direntry->d_name.name, newinode); |
cbac3cba6 [CIFS] New CIFS P... |
1281 |
|
fb8c4b14d [CIFS] whitespace... |
1282 |
if (newinode->i_nlink != 2) |
b6b38f704 [CIFS] Neaten cER... |
1283 1284 |
cFYI(1, "unexpected number of links %d", newinode->i_nlink); |
cbac3cba6 [CIFS] New CIFS P... |
1285 |
#endif |
2dd29d313 [CIFS] New CIFS P... |
1286 1287 1288 |
} kfree(pInfo); goto mkdir_out; |
fb8c4b14d [CIFS] whitespace... |
1289 |
} |
c45d707f6 [CIFS] Fallback t... |
1290 |
mkdir_retry_old: |
1da177e4c Linux-2.6.12-rc2 |
1291 |
/* BB add setting the equivalent of mode via CreateX w/ACLs */ |
737b758c9 [PATCH] cifs: cha... |
1292 1293 |
rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
1da177e4c Linux-2.6.12-rc2 |
1294 |
if (rc) { |
b6b38f704 [CIFS] Neaten cER... |
1295 |
cFYI(1, "cifs_mkdir returned 0x%x", rc); |
1da177e4c Linux-2.6.12-rc2 |
1296 1297 |
d_drop(direntry); } else { |
fb8c4b14d [CIFS] whitespace... |
1298 |
mkdir_get_info: |
d8c76e6f4 [PATCH] r/o bind ... |
1299 |
inc_nlink(inode); |
c18c842b1 [CIFS] Allow disa... |
1300 |
if (pTcon->unix_ext) |
1da177e4c Linux-2.6.12-rc2 |
1301 |
rc = cifs_get_inode_info_unix(&newinode, full_path, |
fb8c4b14d [CIFS] whitespace... |
1302 |
inode->i_sb, xid); |
1da177e4c Linux-2.6.12-rc2 |
1303 1304 |
else rc = cifs_get_inode_info(&newinode, full_path, NULL, |
8b1327f6e [CIFS] file creat... |
1305 |
inode->i_sb, xid, NULL); |
1da177e4c Linux-2.6.12-rc2 |
1306 |
|
1da177e4c Linux-2.6.12-rc2 |
1307 |
d_instantiate(direntry, newinode); |
2dd29d313 [CIFS] New CIFS P... |
1308 |
/* setting nlink not necessary except in cases where we |
fb8c4b14d [CIFS] whitespace... |
1309 |
* failed to get it from the server or was set bogus */ |
2dd29d313 [CIFS] New CIFS P... |
1310 |
if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) |
bfe868486 filesystems: add ... |
1311 |
set_nlink(direntry->d_inode, 2); |
950899109 [CIFS] cifs_mkdir... |
1312 |
|
ce3b0f8d5 New helper - curr... |
1313 |
mode &= ~current_umask(); |
950899109 [CIFS] cifs_mkdir... |
1314 1315 1316 |
/* must turn on setgid bit if parent dir has it */ if (inode->i_mode & S_ISGID) mode |= S_ISGID; |
c18c842b1 [CIFS] Allow disa... |
1317 |
if (pTcon->unix_ext) { |
4e1e7fb9e bundle up Unix SE... |
1318 1319 1320 1321 1322 1323 1324 |
struct cifs_unix_set_info_args args = { .mode = mode, .ctime = NO_CHANGE_64, .atime = NO_CHANGE_64, .mtime = NO_CHANGE_64, .device = 0, }; |
d0d2f2df6 [CIFS] Update cif... |
1325 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
a001e5b55 CRED: Wrap task c... |
1326 |
args.uid = (__u64)current_fsuid(); |
950899109 [CIFS] cifs_mkdir... |
1327 1328 1329 |
if (inode->i_mode & S_ISGID) args.gid = (__u64)inode->i_gid; else |
a001e5b55 CRED: Wrap task c... |
1330 |
args.gid = (__u64)current_fsgid(); |
1da177e4c Linux-2.6.12-rc2 |
1331 |
} else { |
4e1e7fb9e bundle up Unix SE... |
1332 1333 |
args.uid = NO_CHANGE_64; args.gid = NO_CHANGE_64; |
1da177e4c Linux-2.6.12-rc2 |
1334 |
} |
01ea95e3b cifs: rename CIFS... |
1335 1336 1337 1338 |
CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, &args, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
3ce53fc4c [CIFS] CIFS shoul... |
1339 |
} else { |
67750fb9e [CIFS] when not u... |
1340 1341 1342 |
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && (mode & S_IWUGO) == 0) { FILE_BASIC_INFO pInfo; |
6b37faa17 [CIFS] fix some s... |
1343 1344 |
struct cifsInodeInfo *cifsInode; u32 dosattrs; |
67750fb9e [CIFS] when not u... |
1345 |
memset(&pInfo, 0, sizeof(pInfo)); |
6b37faa17 [CIFS] fix some s... |
1346 1347 1348 1349 1350 1351 |
cifsInode = CIFS_I(newinode); dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; pInfo.Attributes = cpu_to_le32(dosattrs); tmprc = CIFSSMBSetPathInfo(xid, pTcon, full_path, &pInfo, cifs_sb->local_nls, |
67750fb9e [CIFS] when not u... |
1352 1353 |
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
6b37faa17 [CIFS] fix some s... |
1354 1355 |
if (tmprc == 0) cifsInode->cifsAttrs = dosattrs; |
67750fb9e [CIFS] when not u... |
1356 |
} |
fb8c4b14d [CIFS] whitespace... |
1357 |
if (direntry->d_inode) { |
b0fd30d3e when creating new... |
1358 1359 1360 1361 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) direntry->d_inode->i_mode = (mode | S_IFDIR); |
4e94a105e [CIFS] remove tra... |
1362 |
|
fb8c4b14d [CIFS] whitespace... |
1363 |
if (cifs_sb->mnt_cifs_flags & |
6473a559c [CIFS] Fix missin... |
1364 |
CIFS_MOUNT_SET_UID) { |
fb8c4b14d [CIFS] whitespace... |
1365 |
direntry->d_inode->i_uid = |
a001e5b55 CRED: Wrap task c... |
1366 |
current_fsuid(); |
950899109 [CIFS] cifs_mkdir... |
1367 1368 1369 1370 1371 |
if (inode->i_mode & S_ISGID) direntry->d_inode->i_gid = inode->i_gid; else direntry->d_inode->i_gid = |
a001e5b55 CRED: Wrap task c... |
1372 |
current_fsgid(); |
6473a559c [CIFS] Fix missin... |
1373 1374 |
} } |
2a138ebb0 [CIFS] Missing pa... |
1375 |
} |
1da177e4c Linux-2.6.12-rc2 |
1376 |
} |
fb8c4b14d [CIFS] whitespace... |
1377 |
mkdir_out: |
1da177e4c Linux-2.6.12-rc2 |
1378 1379 |
kfree(full_path); FreeXid(xid); |
7ffec3724 cifs: add refcoun... |
1380 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1381 1382 1383 1384 1385 1386 1387 1388 |
return rc; } int cifs_rmdir(struct inode *inode, struct dentry *direntry) { int rc = 0; int xid; struct cifs_sb_info *cifs_sb; |
7ffec3724 cifs: add refcoun... |
1389 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1390 |
struct cifs_tcon *pTcon; |
1da177e4c Linux-2.6.12-rc2 |
1391 1392 |
char *full_path = NULL; struct cifsInodeInfo *cifsInode; |
b6b38f704 [CIFS] Neaten cER... |
1393 |
cFYI(1, "cifs_rmdir, inode = 0x%p", inode); |
1da177e4c Linux-2.6.12-rc2 |
1394 1395 |
xid = GetXid(); |
7f57356b7 [CIFS] Remove cif... |
1396 |
full_path = build_path_from_dentry(direntry); |
1da177e4c Linux-2.6.12-rc2 |
1397 |
if (full_path == NULL) { |
0f3bc09ee cifs: Fix incorre... |
1398 |
rc = -ENOMEM; |
7ffec3724 cifs: add refcoun... |
1399 |
goto rmdir_exit; |
1da177e4c Linux-2.6.12-rc2 |
1400 |
} |
7ffec3724 cifs: add refcoun... |
1401 1402 1403 1404 1405 1406 1407 |
cifs_sb = CIFS_SB(inode->i_sb); tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) { rc = PTR_ERR(tlink); goto rmdir_exit; } pTcon = tlink_tcon(tlink); |
737b758c9 [PATCH] cifs: cha... |
1408 1409 |
rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
7ffec3724 cifs: add refcoun... |
1410 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1411 1412 |
if (!rc) { |
9a53c3a78 [PATCH] r/o bind ... |
1413 |
drop_nlink(inode); |
3677db10a [CIFS] Fix lockin... |
1414 |
spin_lock(&direntry->d_inode->i_lock); |
fb8c4b14d [CIFS] whitespace... |
1415 |
i_size_write(direntry->d_inode, 0); |
ce71ec368 [PATCH] r/o bind ... |
1416 |
clear_nlink(direntry->d_inode); |
3677db10a [CIFS] Fix lockin... |
1417 |
spin_unlock(&direntry->d_inode->i_lock); |
1da177e4c Linux-2.6.12-rc2 |
1418 1419 1420 1421 1422 |
} cifsInode = CIFS_I(direntry->d_inode); cifsInode->time = 0; /* force revalidate to go get info when needed */ |
42c245447 [CIFS] revalidate... |
1423 1424 1425 1426 |
cifsInode = CIFS_I(inode); cifsInode->time = 0; /* force revalidate to get parent dir info since cached search results now invalid */ |
1da177e4c Linux-2.6.12-rc2 |
1427 1428 |
direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
1429 |
rmdir_exit: |
1da177e4c Linux-2.6.12-rc2 |
1430 1431 1432 1433 |
kfree(full_path); FreeXid(xid); return rc; } |
ee2fd967f [CIFS] fix busy-... |
1434 1435 1436 1437 1438 |
static int cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath, struct dentry *to_dentry, const char *toPath) { struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb); |
7ffec3724 cifs: add refcoun... |
1439 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1440 |
struct cifs_tcon *pTcon; |
ee2fd967f [CIFS] fix busy-... |
1441 1442 |
__u16 srcfid; int oplock, rc; |
7ffec3724 cifs: add refcoun... |
1443 1444 1445 1446 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); pTcon = tlink_tcon(tlink); |
ee2fd967f [CIFS] fix busy-... |
1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 |
/* try path-based rename first */ rc = CIFSSMBRename(xid, pTcon, fromPath, toPath, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); /* * don't bother with rename by filehandle unless file is busy and * source Note that cross directory moves do not work with * rename by filehandle to various Windows servers. */ if (rc == 0 || rc != -ETXTBSY) |
7ffec3724 cifs: add refcoun... |
1458 |
goto do_rename_exit; |
ee2fd967f [CIFS] fix busy-... |
1459 |
|
ed0e3ace5 cifs: don't attem... |
1460 1461 |
/* open-file renames don't work across directories */ if (to_dentry->d_parent != from_dentry->d_parent) |
7ffec3724 cifs: add refcoun... |
1462 |
goto do_rename_exit; |
ed0e3ace5 cifs: don't attem... |
1463 |
|
ee2fd967f [CIFS] fix busy-... |
1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 |
/* open the file to be renamed -- we need DELETE perms */ rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, CREATE_NOT_DIR, &srcfid, &oplock, NULL, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc == 0) { rc = CIFSSMBRenameOpenFile(xid, pTcon, srcfid, (const char *) to_dentry->d_name.name, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); CIFSSMBClose(xid, pTcon, srcfid); } |
7ffec3724 cifs: add refcoun... |
1478 1479 |
do_rename_exit: cifs_put_tlink(tlink); |
ee2fd967f [CIFS] fix busy-... |
1480 1481 |
return rc; } |
14121bdcc cifs: make cifs_r... |
1482 1483 |
int cifs_rename(struct inode *source_dir, struct dentry *source_dentry, struct inode *target_dir, struct dentry *target_dentry) |
1da177e4c Linux-2.6.12-rc2 |
1484 |
{ |
ee2fd967f [CIFS] fix busy-... |
1485 1486 |
char *fromName = NULL; char *toName = NULL; |
639e7a913 cifs: eliminate r... |
1487 |
struct cifs_sb_info *cifs_sb; |
7ffec3724 cifs: add refcoun... |
1488 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1489 |
struct cifs_tcon *tcon; |
ee2fd967f [CIFS] fix busy-... |
1490 1491 |
FILE_UNIX_BASIC_INFO *info_buf_source = NULL; FILE_UNIX_BASIC_INFO *info_buf_target; |
8d281efb6 cifs: fix unlinki... |
1492 |
int xid, rc, tmprc; |
1da177e4c Linux-2.6.12-rc2 |
1493 |
|
639e7a913 cifs: eliminate r... |
1494 |
cifs_sb = CIFS_SB(source_dir->i_sb); |
7ffec3724 cifs: add refcoun... |
1495 1496 1497 1498 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); tcon = tlink_tcon(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1499 |
|
ee2fd967f [CIFS] fix busy-... |
1500 1501 1502 |
xid = GetXid(); /* |
ee2fd967f [CIFS] fix busy-... |
1503 1504 1505 |
* we already have the rename sem so we do not need to * grab it again here to protect the path integrity */ |
14121bdcc cifs: make cifs_r... |
1506 |
fromName = build_path_from_dentry(source_dentry); |
ee2fd967f [CIFS] fix busy-... |
1507 1508 1509 1510 |
if (fromName == NULL) { rc = -ENOMEM; goto cifs_rename_exit; } |
14121bdcc cifs: make cifs_r... |
1511 |
toName = build_path_from_dentry(target_dentry); |
ee2fd967f [CIFS] fix busy-... |
1512 |
if (toName == NULL) { |
1da177e4c Linux-2.6.12-rc2 |
1513 1514 1515 |
rc = -ENOMEM; goto cifs_rename_exit; } |
14121bdcc cifs: make cifs_r... |
1516 1517 |
rc = cifs_do_rename(xid, source_dentry, fromName, target_dentry, toName); |
ee2fd967f [CIFS] fix busy-... |
1518 |
|
14121bdcc cifs: make cifs_r... |
1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 |
if (rc == -EEXIST && tcon->unix_ext) { /* * Are src and dst hardlinks of same inode? We can * only tell with unix extensions enabled */ info_buf_source = kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); if (info_buf_source == NULL) { rc = -ENOMEM; goto cifs_rename_exit; } info_buf_target = info_buf_source + 1; |
8d281efb6 cifs: fix unlinki... |
1533 |
tmprc = CIFSSMBUnixQPathInfo(xid, tcon, fromName, |
14121bdcc cifs: make cifs_r... |
1534 |
info_buf_source, |
639e7a913 cifs: eliminate r... |
1535 1536 |
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
14121bdcc cifs: make cifs_r... |
1537 |
CIFS_MOUNT_MAP_SPECIAL_CHR); |
8d281efb6 cifs: fix unlinki... |
1538 |
if (tmprc != 0) |
14121bdcc cifs: make cifs_r... |
1539 |
goto unlink_target; |
ee2fd967f [CIFS] fix busy-... |
1540 |
|
639e7a913 cifs: eliminate r... |
1541 1542 1543 1544 |
tmprc = CIFSSMBUnixQPathInfo(xid, tcon, toName, info_buf_target, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & |
14121bdcc cifs: make cifs_r... |
1545 |
CIFS_MOUNT_MAP_SPECIAL_CHR); |
8d281efb6 cifs: fix unlinki... |
1546 |
if (tmprc == 0 && (info_buf_source->UniqueId == |
ae6884a9d cifs: fix renamin... |
1547 |
info_buf_target->UniqueId)) { |
14121bdcc cifs: make cifs_r... |
1548 |
/* same file, POSIX says that this is a noop */ |
ae6884a9d cifs: fix renamin... |
1549 |
rc = 0; |
14121bdcc cifs: make cifs_r... |
1550 |
goto cifs_rename_exit; |
ae6884a9d cifs: fix renamin... |
1551 |
} |
14121bdcc cifs: make cifs_r... |
1552 |
} /* else ... BB we could add the same check for Windows by |
ee2fd967f [CIFS] fix busy-... |
1553 |
checking the UniqueId via FILE_INTERNAL_INFO */ |
14121bdcc cifs: make cifs_r... |
1554 |
|
ee2fd967f [CIFS] fix busy-... |
1555 |
unlink_target: |
fc6f39433 cifs: when renami... |
1556 1557 |
/* Try unlinking the target dentry if it's not negative */ if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) { |
8d281efb6 cifs: fix unlinki... |
1558 |
tmprc = cifs_unlink(target_dir, target_dentry); |
14121bdcc cifs: make cifs_r... |
1559 1560 |
if (tmprc) goto cifs_rename_exit; |
14121bdcc cifs: make cifs_r... |
1561 1562 |
rc = cifs_do_rename(xid, source_dentry, fromName, target_dentry, toName); |
1da177e4c Linux-2.6.12-rc2 |
1563 1564 1565 |
} cifs_rename_exit: |
ee2fd967f [CIFS] fix busy-... |
1566 |
kfree(info_buf_source); |
1da177e4c Linux-2.6.12-rc2 |
1567 1568 1569 |
kfree(fromName); kfree(toName); FreeXid(xid); |
7ffec3724 cifs: add refcoun... |
1570 |
cifs_put_tlink(tlink); |
1da177e4c Linux-2.6.12-rc2 |
1571 1572 |
return rc; } |
df2cf170c cifs: overhaul ci... |
1573 1574 |
static bool cifs_inode_needs_reval(struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
1575 |
{ |
df2cf170c cifs: overhaul ci... |
1576 |
struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
6d20e8406 cifs: add attribu... |
1577 |
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
1da177e4c Linux-2.6.12-rc2 |
1578 |
|
df2cf170c cifs: overhaul ci... |
1579 1580 |
if (cifs_i->clientCanCacheRead) return false; |
1da177e4c Linux-2.6.12-rc2 |
1581 |
|
df2cf170c cifs: overhaul ci... |
1582 1583 |
if (!lookupCacheEnabled) return true; |
1da177e4c Linux-2.6.12-rc2 |
1584 |
|
df2cf170c cifs: overhaul ci... |
1585 1586 |
if (cifs_i->time == 0) return true; |
1da177e4c Linux-2.6.12-rc2 |
1587 |
|
6d20e8406 cifs: add attribu... |
1588 1589 |
if (!time_in_range(jiffies, cifs_i->time, cifs_i->time + cifs_sb->actimeo)) |
df2cf170c cifs: overhaul ci... |
1590 |
return true; |
db19272ed cifs: always reva... |
1591 |
/* hardlinked files w/ noserverino get "special" treatment */ |
6d20e8406 cifs: add attribu... |
1592 |
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && |
db19272ed cifs: always reva... |
1593 1594 |
S_ISREG(inode->i_mode) && inode->i_nlink != 1) return true; |
df2cf170c cifs: overhaul ci... |
1595 1596 |
return false; } |
523fb8c86 cifs: trivial com... |
1597 1598 1599 |
/* * Zap the cache. Called when invalid_mapping flag is set. */ |
6feb9891d CIFS: Simplify in... |
1600 |
int |
df2cf170c cifs: overhaul ci... |
1601 1602 |
cifs_invalidate_mapping(struct inode *inode) { |
6feb9891d CIFS: Simplify in... |
1603 |
int rc = 0; |
df2cf170c cifs: overhaul ci... |
1604 1605 1606 |
struct cifsInodeInfo *cifs_i = CIFS_I(inode); cifs_i->invalid_mapping = false; |
df2cf170c cifs: overhaul ci... |
1607 |
if (inode->i_mapping && inode->i_mapping->nrpages != 0) { |
257fb1f15 CIFS: Use invalid... |
1608 1609 1610 1611 1612 1613 |
rc = invalidate_inode_pages2(inode->i_mapping); if (rc) { cERROR(1, "%s: could not invalidate inode %p", __func__, inode); cifs_i->invalid_mapping = true; } |
df2cf170c cifs: overhaul ci... |
1614 |
} |
257fb1f15 CIFS: Use invalid... |
1615 |
|
9451a9a52 cifs: define inod... |
1616 |
cifs_fscache_reset_inode_cookie(inode); |
6feb9891d CIFS: Simplify in... |
1617 |
return rc; |
df2cf170c cifs: overhaul ci... |
1618 |
} |
6feb9891d CIFS: Simplify in... |
1619 |
int cifs_revalidate_file_attr(struct file *filp) |
abab095d1 cifs: add cifs_re... |
1620 1621 1622 |
{ int rc = 0; struct inode *inode = filp->f_path.dentry->d_inode; |
ba00ba64c cifs: make variou... |
1623 |
struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; |
abab095d1 cifs: add cifs_re... |
1624 1625 |
if (!cifs_inode_needs_reval(inode)) |
6feb9891d CIFS: Simplify in... |
1626 |
return rc; |
abab095d1 cifs: add cifs_re... |
1627 |
|
13cfb7334 cifs: have cifsFi... |
1628 |
if (tlink_tcon(cfile->tlink)->unix_ext) |
abab095d1 cifs: add cifs_re... |
1629 1630 1631 |
rc = cifs_get_file_info_unix(filp); else rc = cifs_get_file_info(filp); |
abab095d1 cifs: add cifs_re... |
1632 1633 |
return rc; } |
6feb9891d CIFS: Simplify in... |
1634 |
int cifs_revalidate_dentry_attr(struct dentry *dentry) |
df2cf170c cifs: overhaul ci... |
1635 1636 1637 |
{ int xid; int rc = 0; |
df2cf170c cifs: overhaul ci... |
1638 1639 |
struct inode *inode = dentry->d_inode; struct super_block *sb = dentry->d_sb; |
6feb9891d CIFS: Simplify in... |
1640 |
char *full_path = NULL; |
df2cf170c cifs: overhaul ci... |
1641 1642 1643 |
if (inode == NULL) return -ENOENT; |
1da177e4c Linux-2.6.12-rc2 |
1644 |
|
df2cf170c cifs: overhaul ci... |
1645 |
if (!cifs_inode_needs_reval(inode)) |
6feb9891d CIFS: Simplify in... |
1646 1647 1648 |
return rc; xid = GetXid(); |
1da177e4c Linux-2.6.12-rc2 |
1649 1650 1651 |
/* can not safely grab the rename sem here if rename calls revalidate since that would deadlock */ |
df2cf170c cifs: overhaul ci... |
1652 |
full_path = build_path_from_dentry(dentry); |
1da177e4c Linux-2.6.12-rc2 |
1653 |
if (full_path == NULL) { |
0f3bc09ee cifs: Fix incorre... |
1654 |
rc = -ENOMEM; |
6feb9891d CIFS: Simplify in... |
1655 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1656 |
} |
6feb9891d CIFS: Simplify in... |
1657 1658 |
cFYI(1, "Update attributes: %s inode 0x%p count %d dentry: 0x%p d_time " "%ld jiffies %ld", full_path, inode, inode->i_count.counter, |
f19159dc5 [CIFS] Cleanup va... |
1659 |
dentry, dentry->d_time, jiffies); |
1da177e4c Linux-2.6.12-rc2 |
1660 |
|
0d424ad0a cifs: add cifs_sb... |
1661 |
if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) |
df2cf170c cifs: overhaul ci... |
1662 1663 1664 1665 |
rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); else rc = cifs_get_inode_info(&inode, full_path, NULL, sb, xid, NULL); |
1da177e4c Linux-2.6.12-rc2 |
1666 |
|
6feb9891d CIFS: Simplify in... |
1667 |
out: |
1da177e4c Linux-2.6.12-rc2 |
1668 1669 1670 1671 |
kfree(full_path); FreeXid(xid); return rc; } |
6feb9891d CIFS: Simplify in... |
1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 |
int cifs_revalidate_file(struct file *filp) { int rc; struct inode *inode = filp->f_path.dentry->d_inode; rc = cifs_revalidate_file_attr(filp); if (rc) return rc; if (CIFS_I(inode)->invalid_mapping) rc = cifs_invalidate_mapping(inode); return rc; } /* revalidate a dentry's inode attributes */ int cifs_revalidate_dentry(struct dentry *dentry) { int rc; struct inode *inode = dentry->d_inode; rc = cifs_revalidate_dentry_attr(dentry); if (rc) return rc; if (CIFS_I(inode)->invalid_mapping) rc = cifs_invalidate_mapping(inode); return rc; } |
1da177e4c Linux-2.6.12-rc2 |
1700 |
int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
1c456013e cifs: on multiuse... |
1701 |
struct kstat *stat) |
1da177e4c Linux-2.6.12-rc2 |
1702 |
{ |
3aa1c8c29 cifs: on multiuse... |
1703 |
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb); |
96daf2b09 [CIFS] Rename thr... |
1704 |
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
6feb9891d CIFS: Simplify in... |
1705 1706 |
struct inode *inode = dentry->d_inode; int rc; |
3aa1c8c29 cifs: on multiuse... |
1707 |
|
6feb9891d CIFS: Simplify in... |
1708 1709 1710 1711 1712 1713 1714 |
/* * We need to be sure that all dirty pages are written and the server * has actual ctime, mtime and file length. */ if (!CIFS_I(inode)->clientCanCacheRead && inode->i_mapping && inode->i_mapping->nrpages != 0) { rc = filemap_fdatawait(inode->i_mapping); |
156ecb2d8 [CIFS] Fix to pro... |
1715 1716 1717 1718 |
if (rc) { mapping_set_error(inode->i_mapping, rc); return rc; } |
6feb9891d CIFS: Simplify in... |
1719 |
} |
1c456013e cifs: on multiuse... |
1720 |
|
6feb9891d CIFS: Simplify in... |
1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 |
rc = cifs_revalidate_dentry_attr(dentry); if (rc) return rc; generic_fillattr(inode, stat); stat->blksize = CIFS_MAX_MSGSIZE; stat->ino = CIFS_I(inode)->uniqueid; /* * If on a multiuser mount without unix extensions, and the admin hasn't * overridden them, set the ownership to the fsuid/fsgid of the current * process. */ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) && !tcon->unix_ext) { if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) stat->uid = current_fsuid(); if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) stat->gid = current_fsgid(); |
5fe14c851 [CIFS] Explicitly... |
1740 |
} |
6feb9891d CIFS: Simplify in... |
1741 |
return rc; |
1da177e4c Linux-2.6.12-rc2 |
1742 1743 1744 1745 1746 1747 1748 |
} static int cifs_truncate_page(struct address_space *mapping, loff_t from) { pgoff_t index = from >> PAGE_CACHE_SHIFT; unsigned offset = from & (PAGE_CACHE_SIZE - 1); struct page *page; |
1da177e4c Linux-2.6.12-rc2 |
1749 1750 1751 1752 1753 |
int rc = 0; page = grab_cache_page(mapping, index); if (!page) return -ENOMEM; |
eebd2aa35 Pagecache zeroing... |
1754 |
zero_user_segment(page, offset, PAGE_CACHE_SIZE); |
1da177e4c Linux-2.6.12-rc2 |
1755 1756 1757 1758 |
unlock_page(page); page_cache_release(page); return rc; } |
1b9474635 cifs: truncate fa... |
1759 |
static void cifs_setsize(struct inode *inode, loff_t offset) |
3677db10a [CIFS] Fix lockin... |
1760 |
{ |
c08d3b0e3 truncate: use new... |
1761 |
loff_t oldsize; |
3677db10a [CIFS] Fix lockin... |
1762 |
|
ba6a46a03 [CIFS] small piec... |
1763 |
spin_lock(&inode->i_lock); |
c08d3b0e3 truncate: use new... |
1764 |
oldsize = inode->i_size; |
3677db10a [CIFS] Fix lockin... |
1765 |
i_size_write(inode, offset); |
ba6a46a03 [CIFS] small piec... |
1766 |
spin_unlock(&inode->i_lock); |
1b9474635 cifs: truncate fa... |
1767 |
|
c08d3b0e3 truncate: use new... |
1768 |
truncate_pagecache(inode, oldsize, offset); |
3677db10a [CIFS] Fix lockin... |
1769 |
} |
8efdbde64 [CIFS] break ATTR... |
1770 1771 1772 1773 1774 1775 1776 1777 |
static int cifs_set_file_size(struct inode *inode, struct iattr *attrs, int xid, char *full_path) { int rc; struct cifsFileInfo *open_file; struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
1778 |
struct tcon_link *tlink = NULL; |
96daf2b09 [CIFS] Rename thr... |
1779 |
struct cifs_tcon *pTcon = NULL; |
fa2989f44 CIFS: Use pid sav... |
1780 |
struct cifs_io_parms io_parms; |
8efdbde64 [CIFS] break ATTR... |
1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 |
/* * To avoid spurious oplock breaks from server, in the case of * inodes that we already have open, avoid doing path based * setting of file size if we can do it by handle. * This keeps our caching token (oplock) and avoids timeouts * when the local oplock break takes longer to flush * writebehind data than the SMB timeout for the SetPathInfo * request would allow */ |
6508d904e cifs: have find_r... |
1791 |
open_file = find_writable_file(cifsInode, true); |
8efdbde64 [CIFS] break ATTR... |
1792 1793 1794 |
if (open_file) { __u16 nfid = open_file->netfid; __u32 npid = open_file->pid; |
13cfb7334 cifs: have cifsFi... |
1795 |
pTcon = tlink_tcon(open_file->tlink); |
8efdbde64 [CIFS] break ATTR... |
1796 1797 |
rc = CIFSSMBSetFileSize(xid, pTcon, attrs->ia_size, nfid, npid, false); |
6ab409b53 cifs: Replace wrt... |
1798 |
cifsFileInfo_put(open_file); |
b6b38f704 [CIFS] Neaten cER... |
1799 |
cFYI(1, "SetFSize for attrs rc = %d", rc); |
8efdbde64 [CIFS] break ATTR... |
1800 1801 |
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { unsigned int bytes_written; |
fa2989f44 CIFS: Use pid sav... |
1802 1803 1804 1805 1806 1807 1808 1809 |
io_parms.netfid = nfid; io_parms.pid = npid; io_parms.tcon = pTcon; io_parms.offset = 0; io_parms.length = attrs->ia_size; rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, NULL, NULL, 1); |
b6b38f704 [CIFS] Neaten cER... |
1810 |
cFYI(1, "Wrt seteof rc %d", rc); |
8efdbde64 [CIFS] break ATTR... |
1811 1812 1813 1814 1815 |
} } else rc = -EINVAL; if (rc != 0) { |
7ffec3724 cifs: add refcoun... |
1816 1817 1818 1819 1820 1821 |
if (pTcon == NULL) { tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); pTcon = tlink_tcon(tlink); } |
ba00ba64c cifs: make variou... |
1822 |
|
8efdbde64 [CIFS] break ATTR... |
1823 1824 1825 1826 1827 1828 1829 1830 |
/* Set file size by pathname rather than by handle either because no valid, writeable file handle for it was found or because there was an error setting it by handle */ rc = CIFSSMBSetEOF(xid, pTcon, full_path, attrs->ia_size, false, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
b6b38f704 [CIFS] Neaten cER... |
1831 |
cFYI(1, "SetEOF by path (setattrs) rc = %d", rc); |
8efdbde64 [CIFS] break ATTR... |
1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 |
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { __u16 netfid; int oplock = 0; rc = SMBLegacyOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_WRITE, CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc == 0) { unsigned int bytes_written; |
fa2989f44 CIFS: Use pid sav... |
1844 1845 1846 1847 1848 1849 1850 1851 1852 |
io_parms.netfid = netfid; io_parms.pid = current->tgid; io_parms.tcon = pTcon; io_parms.offset = 0; io_parms.length = attrs->ia_size; rc = CIFSSMBWrite(xid, &io_parms, &bytes_written, NULL, NULL, 1); |
b6b38f704 [CIFS] Neaten cER... |
1853 |
cFYI(1, "wrt seteof rc %d", rc); |
8efdbde64 [CIFS] break ATTR... |
1854 1855 1856 |
CIFSSMBClose(xid, pTcon, netfid); } } |
7ffec3724 cifs: add refcoun... |
1857 1858 |
if (tlink) cifs_put_tlink(tlink); |
8efdbde64 [CIFS] break ATTR... |
1859 1860 1861 |
} if (rc == 0) { |
fbec9ab95 cifs: vary timeou... |
1862 |
cifsInode->server_eof = attrs->ia_size; |
1b9474635 cifs: truncate fa... |
1863 |
cifs_setsize(inode, attrs->ia_size); |
8efdbde64 [CIFS] break ATTR... |
1864 1865 1866 1867 1868 |
cifs_truncate_page(inode->i_mapping, inode->i_size); } return rc; } |
3fe5c1dd0 spin off cifs_set... |
1869 1870 1871 1872 1873 1874 1875 1876 1877 |
static int cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) { int rc; int xid; char *full_path = NULL; struct inode *inode = direntry->d_inode; struct cifsInodeInfo *cifsInode = CIFS_I(inode); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
7ffec3724 cifs: add refcoun... |
1878 |
struct tcon_link *tlink; |
96daf2b09 [CIFS] Rename thr... |
1879 |
struct cifs_tcon *pTcon; |
3fe5c1dd0 spin off cifs_set... |
1880 |
struct cifs_unix_set_info_args *args = NULL; |
3bbeeb3c9 cifs: add and use... |
1881 |
struct cifsFileInfo *open_file; |
3fe5c1dd0 spin off cifs_set... |
1882 |
|
b6b38f704 [CIFS] Neaten cER... |
1883 1884 |
cFYI(1, "setattr_unix on file %s attrs->ia_valid=0x%x", direntry->d_name.name, attrs->ia_valid); |
3fe5c1dd0 spin off cifs_set... |
1885 1886 |
xid = GetXid(); |
db78b877f always call inode... |
1887 1888 1889 1890 1891 1892 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) attrs->ia_valid |= ATTR_FORCE; rc = inode_change_ok(inode, attrs); if (rc < 0) goto out; |
3fe5c1dd0 spin off cifs_set... |
1893 1894 1895 1896 1897 1898 |
full_path = build_path_from_dentry(direntry); if (full_path == NULL) { rc = -ENOMEM; goto out; } |
0f4d634c5 cifs: flush data ... |
1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 |
/* * Attempt to flush data before changing attributes. We need to do * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the * ownership or mode then we may also need to do this. Here, we take * the safe way out and just do the flush on all setattr requests. If * the flush returns error, store it to report later and continue. * * BB: This should be smarter. Why bother flushing pages that * will be truncated anyway? Also, should we error out here if * the flush returns error? */ rc = filemap_write_and_wait(inode->i_mapping); |
eb4b756b1 cifs: eliminate c... |
1911 1912 |
mapping_set_error(inode->i_mapping, rc); rc = 0; |
3fe5c1dd0 spin off cifs_set... |
1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 |
if (attrs->ia_valid & ATTR_SIZE) { rc = cifs_set_file_size(inode, attrs, xid, full_path); if (rc != 0) goto out; } /* skip mode change if it's just for clearing setuid/setgid */ if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) attrs->ia_valid &= ~ATTR_MODE; args = kmalloc(sizeof(*args), GFP_KERNEL); if (args == NULL) { rc = -ENOMEM; goto out; } /* set up the struct */ if (attrs->ia_valid & ATTR_MODE) args->mode = attrs->ia_mode; else args->mode = NO_CHANGE_64; if (attrs->ia_valid & ATTR_UID) args->uid = attrs->ia_uid; else args->uid = NO_CHANGE_64; if (attrs->ia_valid & ATTR_GID) args->gid = attrs->ia_gid; else args->gid = NO_CHANGE_64; if (attrs->ia_valid & ATTR_ATIME) args->atime = cifs_UnixTimeToNT(attrs->ia_atime); else args->atime = NO_CHANGE_64; if (attrs->ia_valid & ATTR_MTIME) args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime); else args->mtime = NO_CHANGE_64; if (attrs->ia_valid & ATTR_CTIME) args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime); else args->ctime = NO_CHANGE_64; args->device = 0; |
6508d904e cifs: have find_r... |
1962 |
open_file = find_writable_file(cifsInode, true); |
3bbeeb3c9 cifs: add and use... |
1963 1964 1965 |
if (open_file) { u16 nfid = open_file->netfid; u32 npid = open_file->pid; |
13cfb7334 cifs: have cifsFi... |
1966 |
pTcon = tlink_tcon(open_file->tlink); |
3bbeeb3c9 cifs: add and use... |
1967 |
rc = CIFSSMBUnixSetFileInfo(xid, pTcon, args, nfid, npid); |
6ab409b53 cifs: Replace wrt... |
1968 |
cifsFileInfo_put(open_file); |
3bbeeb3c9 cifs: add and use... |
1969 |
} else { |
7ffec3724 cifs: add refcoun... |
1970 1971 1972 1973 1974 1975 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) { rc = PTR_ERR(tlink); goto out; } pTcon = tlink_tcon(tlink); |
3bbeeb3c9 cifs: add and use... |
1976 |
rc = CIFSSMBUnixSetPathInfo(xid, pTcon, full_path, args, |
01ea95e3b cifs: rename CIFS... |
1977 1978 1979 |
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
7ffec3724 cifs: add refcoun... |
1980 |
cifs_put_tlink(tlink); |
3bbeeb3c9 cifs: add and use... |
1981 |
} |
3fe5c1dd0 spin off cifs_set... |
1982 |
|
1025774ce remove inode_setattr |
1983 1984 |
if (rc) goto out; |
ccd4bb1be [CIFS] Don't cach... |
1985 |
|
1025774ce remove inode_setattr |
1986 |
if ((attrs->ia_valid & ATTR_SIZE) && |
1b9474635 cifs: truncate fa... |
1987 1988 |
attrs->ia_size != i_size_read(inode)) truncate_setsize(inode, attrs->ia_size); |
1025774ce remove inode_setattr |
1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 |
setattr_copy(inode, attrs); mark_inode_dirty(inode); /* force revalidate when any of these times are set since some of the fs types (eg ext3, fat) do not have fine enough time granularity to match protocol, and we do not have a a way (yet) to query the server fs's time granularity (and whether it rounds times down). */ if (attrs->ia_valid & (ATTR_MTIME | ATTR_CTIME)) cifsInode->time = 0; |
3fe5c1dd0 spin off cifs_set... |
2001 2002 2003 2004 2005 2006 |
out: kfree(args); kfree(full_path); FreeXid(xid); return rc; } |
0510eeb73 turn cifs_setattr... |
2007 2008 |
static int cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) |
1da177e4c Linux-2.6.12-rc2 |
2009 2010 |
{ int xid; |
a5ff37696 cifs: Call id to ... |
2011 2012 |
uid_t uid = NO_CHANGE_32; gid_t gid = NO_CHANGE_32; |
3fe5c1dd0 spin off cifs_set... |
2013 2014 |
struct inode *inode = direntry->d_inode; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
3fe5c1dd0 spin off cifs_set... |
2015 |
struct cifsInodeInfo *cifsInode = CIFS_I(inode); |
1da177e4c Linux-2.6.12-rc2 |
2016 2017 |
char *full_path = NULL; int rc = -EACCES; |
feb3e20ce move file time an... |
2018 |
__u32 dosattr = 0; |
4e1e7fb9e bundle up Unix SE... |
2019 |
__u64 mode = NO_CHANGE_64; |
3fe5c1dd0 spin off cifs_set... |
2020 |
|
1da177e4c Linux-2.6.12-rc2 |
2021 |
xid = GetXid(); |
b6b38f704 [CIFS] Neaten cER... |
2022 2023 |
cFYI(1, "setattr on file %s attrs->iavalid 0x%x", direntry->d_name.name, attrs->ia_valid); |
6473a559c [CIFS] Fix missin... |
2024 |
|
db78b877f always call inode... |
2025 2026 2027 2028 2029 2030 2031 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) attrs->ia_valid |= ATTR_FORCE; rc = inode_change_ok(inode, attrs); if (rc < 0) { FreeXid(xid); return rc; |
6473a559c [CIFS] Fix missin... |
2032 |
} |
50c2f7538 [CIFS] whitespace... |
2033 |
|
7f57356b7 [CIFS] Remove cif... |
2034 |
full_path = build_path_from_dentry(direntry); |
1da177e4c Linux-2.6.12-rc2 |
2035 |
if (full_path == NULL) { |
0f3bc09ee cifs: Fix incorre... |
2036 |
rc = -ENOMEM; |
1da177e4c Linux-2.6.12-rc2 |
2037 |
FreeXid(xid); |
0f3bc09ee cifs: Fix incorre... |
2038 |
return rc; |
1da177e4c Linux-2.6.12-rc2 |
2039 |
} |
1da177e4c Linux-2.6.12-rc2 |
2040 |
|
0f4d634c5 cifs: flush data ... |
2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 |
/* * Attempt to flush data before changing attributes. We need to do * this for ATTR_SIZE and ATTR_MTIME for sure, and if we change the * ownership or mode then we may also need to do this. Here, we take * the safe way out and just do the flush on all setattr requests. If * the flush returns error, store it to report later and continue. * * BB: This should be smarter. Why bother flushing pages that * will be truncated anyway? Also, should we error out here if * the flush returns error? */ rc = filemap_write_and_wait(inode->i_mapping); |
eb4b756b1 cifs: eliminate c... |
2053 2054 |
mapping_set_error(inode->i_mapping, rc); rc = 0; |
cea218054 [CIFS] Fix potent... |
2055 |
|
50531444f [CIFS] Fix mtime ... |
2056 |
if (attrs->ia_valid & ATTR_SIZE) { |
8efdbde64 [CIFS] break ATTR... |
2057 2058 |
rc = cifs_set_file_size(inode, attrs, xid, full_path); if (rc != 0) |
e30dcf3a1 [CIFS] Add suppor... |
2059 |
goto cifs_setattr_exit; |
1da177e4c Linux-2.6.12-rc2 |
2060 |
} |
4ca691a89 silently ignore o... |
2061 |
|
a5ff37696 cifs: Call id to ... |
2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 |
if (attrs->ia_valid & ATTR_UID) uid = attrs->ia_uid; if (attrs->ia_valid & ATTR_GID) gid = attrs->ia_gid; #ifdef CONFIG_CIFS_ACL if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { if (uid != NO_CHANGE_32 || gid != NO_CHANGE_32) { rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, uid, gid); if (rc) { cFYI(1, "%s: Setting id failed with error: %d", __func__, rc); goto cifs_setattr_exit; } } } else #endif /* CONFIG_CIFS_ACL */ |
3fe5c1dd0 spin off cifs_set... |
2081 |
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) |
4ca691a89 silently ignore o... |
2082 |
attrs->ia_valid &= ~(ATTR_UID | ATTR_GID); |
1da177e4c Linux-2.6.12-rc2 |
2083 |
|
d32c4f262 CIFS: ignore mode... |
2084 2085 2086 |
/* skip mode change if it's just for clearing setuid/setgid */ if (attrs->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID)) attrs->ia_valid &= ~ATTR_MODE; |
1da177e4c Linux-2.6.12-rc2 |
2087 |
if (attrs->ia_valid & ATTR_MODE) { |
1da177e4c Linux-2.6.12-rc2 |
2088 |
mode = attrs->ia_mode; |
cdbce9c87 [CIFS] Fix setatt... |
2089 |
rc = 0; |
79df1baee cifs: fix use of ... |
2090 |
#ifdef CONFIG_CIFS_ACL |
78415d2d3 cifs: Misc. clean... |
2091 |
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
a5ff37696 cifs: Call id to ... |
2092 2093 |
rc = id_mode_to_cifs_acl(inode, full_path, mode, NO_CHANGE_32, NO_CHANGE_32); |
78415d2d3 cifs: Misc. clean... |
2094 2095 2096 2097 2098 2099 |
if (rc) { cFYI(1, "%s: Setting ACL failed with error: %d", __func__, rc); goto cifs_setattr_exit; } } else |
79df1baee cifs: fix use of ... |
2100 |
#endif /* CONFIG_CIFS_ACL */ |
5132861a7 disable most mode... |
2101 2102 |
if (((mode & S_IWUGO) == 0) && (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { |
feb3e20ce move file time an... |
2103 2104 |
dosattr = cifsInode->cifsAttrs | ATTR_READONLY; |
5132861a7 disable most mode... |
2105 2106 2107 2108 2109 |
/* fix up mode if we're not using dynperm */ if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0) attrs->ia_mode = inode->i_mode & ~S_IWUGO; } else if ((mode & S_IWUGO) && (cifsInode->cifsAttrs & ATTR_READONLY)) { |
feb3e20ce move file time an... |
2110 2111 2112 2113 2114 |
dosattr = cifsInode->cifsAttrs & ~ATTR_READONLY; /* Attributes of 0 are ignored */ if (dosattr == 0) dosattr |= ATTR_NORMAL; |
5132861a7 disable most mode... |
2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 |
/* reset local inode permissions to normal */ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) { attrs->ia_mode &= ~(S_IALLUGO); if (S_ISDIR(inode->i_mode)) attrs->ia_mode |= cifs_sb->mnt_dir_mode; else attrs->ia_mode |= cifs_sb->mnt_file_mode; } } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) { /* ignore mode change - ATTR_READONLY hasn't changed */ attrs->ia_valid &= ~ATTR_MODE; |
1da177e4c Linux-2.6.12-rc2 |
2129 |
} |
1da177e4c Linux-2.6.12-rc2 |
2130 |
} |
feb3e20ce move file time an... |
2131 2132 2133 2134 |
if (attrs->ia_valid & (ATTR_MTIME|ATTR_ATIME|ATTR_CTIME) || ((attrs->ia_valid & ATTR_MODE) && dosattr)) { rc = cifs_set_file_info(inode, attrs, xid, full_path, dosattr); /* BB: check for rc = -EOPNOTSUPP and switch to legacy mode */ |
1da177e4c Linux-2.6.12-rc2 |
2135 |
|
e30dcf3a1 [CIFS] Add suppor... |
2136 2137 2138 2139 2140 |
/* Even if error on time set, no sense failing the call if the server would set the time to a reasonable value anyway, and this check ensures that we are not being called from sys_utimes in which case we ought to fail the call back to the user when the server rejects the call */ |
fb8c4b14d [CIFS] whitespace... |
2141 |
if ((rc) && (attrs->ia_valid & |
feb3e20ce move file time an... |
2142 |
(ATTR_MODE | ATTR_GID | ATTR_UID | ATTR_SIZE))) |
e30dcf3a1 [CIFS] Add suppor... |
2143 |
rc = 0; |
1da177e4c Linux-2.6.12-rc2 |
2144 2145 2146 2147 |
} /* do not need local check to inode_check_ok since the server does that */ |
1025774ce remove inode_setattr |
2148 2149 2150 2151 |
if (rc) goto cifs_setattr_exit; if ((attrs->ia_valid & ATTR_SIZE) && |
1b9474635 cifs: truncate fa... |
2152 2153 |
attrs->ia_size != i_size_read(inode)) truncate_setsize(inode, attrs->ia_size); |
1025774ce remove inode_setattr |
2154 2155 2156 |
setattr_copy(inode, attrs); mark_inode_dirty(inode); |
1025774ce remove inode_setattr |
2157 |
|
e30dcf3a1 [CIFS] Add suppor... |
2158 |
cifs_setattr_exit: |
1da177e4c Linux-2.6.12-rc2 |
2159 2160 2161 2162 |
kfree(full_path); FreeXid(xid); return rc; } |
0510eeb73 turn cifs_setattr... |
2163 2164 2165 2166 2167 |
int cifs_setattr(struct dentry *direntry, struct iattr *attrs) { struct inode *inode = direntry->d_inode; struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
96daf2b09 [CIFS] Rename thr... |
2168 |
struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb); |
0510eeb73 turn cifs_setattr... |
2169 2170 2171 2172 2173 2174 2175 2176 |
if (pTcon->unix_ext) return cifs_setattr_unix(direntry, attrs); return cifs_setattr_nounix(direntry, attrs); /* BB: add cifs_setattr_legacy for really old servers */ } |
99ee4dbd7 [CIFS] Remove som... |
2177 |
#if 0 |
1da177e4c Linux-2.6.12-rc2 |
2178 2179 |
void cifs_delete_inode(struct inode *inode) { |
b6b38f704 [CIFS] Neaten cER... |
2180 |
cFYI(1, "In cifs_delete_inode, inode = 0x%p", inode); |
1da177e4c Linux-2.6.12-rc2 |
2181 2182 2183 |
/* may have to add back in if and when safe distributed caching of directories added e.g. via FindNotify */ } |
99ee4dbd7 [CIFS] Remove som... |
2184 |
#endif |