diff options
author | Jeff Layton <jlayton@redhat.com> | 2010-02-12 07:44:18 -0500 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2010-03-09 15:22:53 -0500 |
commit | abab095d1fd25986b910d3c46289d8fa3582cdc5 (patch) | |
tree | 2b70291e5159f9a8332cbeb17b21999962eadad0 /fs/cifs/inode.c | |
parent | c8634fd3115497ac311f57be9c12f993437745cf (diff) |
cifs: add cifs_revalidate_file
...to allow updating inode attributes on an existing inode by
filehandle. Change mmap and llseek codepaths to use that
instead of cifs_revalidate_dentry since they have a filehandle
readily available.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index f050dba920cb..0d034a84bb8d 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -268,6 +268,31 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) | |||
268 | fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; | 268 | fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; |
269 | } | 269 | } |
270 | 270 | ||
271 | int cifs_get_file_info_unix(struct file *filp) | ||
272 | { | ||
273 | int rc; | ||
274 | int xid; | ||
275 | FILE_UNIX_BASIC_INFO find_data; | ||
276 | struct cifs_fattr fattr; | ||
277 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
278 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
279 | struct cifsTconInfo *tcon = cifs_sb->tcon; | ||
280 | struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; | ||
281 | |||
282 | xid = GetXid(); | ||
283 | rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data); | ||
284 | if (!rc) { | ||
285 | cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb); | ||
286 | } else if (rc == -EREMOTE) { | ||
287 | cifs_create_dfs_fattr(&fattr, inode->i_sb); | ||
288 | rc = 0; | ||
289 | } | ||
290 | |||
291 | cifs_fattr_to_inode(inode, &fattr); | ||
292 | FreeXid(xid); | ||
293 | return rc; | ||
294 | } | ||
295 | |||
271 | int cifs_get_inode_info_unix(struct inode **pinode, | 296 | int cifs_get_inode_info_unix(struct inode **pinode, |
272 | const unsigned char *full_path, | 297 | const unsigned char *full_path, |
273 | struct super_block *sb, int xid) | 298 | struct super_block *sb, int xid) |
@@ -469,6 +494,47 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, | |||
469 | fattr->cf_gid = cifs_sb->mnt_gid; | 494 | fattr->cf_gid = cifs_sb->mnt_gid; |
470 | } | 495 | } |
471 | 496 | ||
497 | int cifs_get_file_info(struct file *filp) | ||
498 | { | ||
499 | int rc; | ||
500 | int xid; | ||
501 | FILE_ALL_INFO find_data; | ||
502 | struct cifs_fattr fattr; | ||
503 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
504 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
505 | struct cifsTconInfo *tcon = cifs_sb->tcon; | ||
506 | struct cifsFileInfo *cfile = (struct cifsFileInfo *) filp->private_data; | ||
507 | |||
508 | xid = GetXid(); | ||
509 | rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data); | ||
510 | if (rc == -EOPNOTSUPP || rc == -EINVAL) { | ||
511 | /* | ||
512 | * FIXME: legacy server -- fall back to path-based call? | ||
513 | * for now, just skip revalidating and mark inode for | ||
514 | * immediate reval. | ||
515 | */ | ||
516 | rc = 0; | ||
517 | CIFS_I(inode)->time = 0; | ||
518 | goto cgfi_exit; | ||
519 | } else if (rc == -EREMOTE) { | ||
520 | cifs_create_dfs_fattr(&fattr, inode->i_sb); | ||
521 | rc = 0; | ||
522 | } else if (rc) | ||
523 | goto cgfi_exit; | ||
524 | |||
525 | /* | ||
526 | * don't bother with SFU junk here -- just mark inode as needing | ||
527 | * revalidation. | ||
528 | */ | ||
529 | cifs_all_info_to_fattr(&fattr, &find_data, cifs_sb, false); | ||
530 | fattr.cf_uniqueid = CIFS_I(inode)->uniqueid; | ||
531 | fattr.cf_flags |= CIFS_FATTR_NEED_REVAL; | ||
532 | cifs_fattr_to_inode(inode, &fattr); | ||
533 | cgfi_exit: | ||
534 | FreeXid(xid); | ||
535 | return rc; | ||
536 | } | ||
537 | |||
472 | int cifs_get_inode_info(struct inode **pinode, | 538 | int cifs_get_inode_info(struct inode **pinode, |
473 | const unsigned char *full_path, FILE_ALL_INFO *pfindData, | 539 | const unsigned char *full_path, FILE_ALL_INFO *pfindData, |
474 | struct super_block *sb, int xid, const __u16 *pfid) | 540 | struct super_block *sb, int xid, const __u16 *pfid) |
@@ -1465,6 +1531,26 @@ cifs_invalidate_mapping(struct inode *inode) | |||
1465 | invalidate_remote_inode(inode); | 1531 | invalidate_remote_inode(inode); |
1466 | } | 1532 | } |
1467 | 1533 | ||
1534 | int cifs_revalidate_file(struct file *filp) | ||
1535 | { | ||
1536 | int rc = 0; | ||
1537 | struct inode *inode = filp->f_path.dentry->d_inode; | ||
1538 | |||
1539 | if (!cifs_inode_needs_reval(inode)) | ||
1540 | goto check_inval; | ||
1541 | |||
1542 | if (CIFS_SB(inode->i_sb)->tcon->unix_ext) | ||
1543 | rc = cifs_get_file_info_unix(filp); | ||
1544 | else | ||
1545 | rc = cifs_get_file_info(filp); | ||
1546 | |||
1547 | check_inval: | ||
1548 | if (CIFS_I(inode)->invalid_mapping) | ||
1549 | cifs_invalidate_mapping(inode); | ||
1550 | |||
1551 | return rc; | ||
1552 | } | ||
1553 | |||
1468 | /* revalidate a dentry's inode attributes */ | 1554 | /* revalidate a dentry's inode attributes */ |
1469 | int cifs_revalidate_dentry(struct dentry *dentry) | 1555 | int cifs_revalidate_dentry(struct dentry *dentry) |
1470 | { | 1556 | { |