/* * Fill in inode information from the fattr. */ static void nfs_fill_inode(struct inode *inode, struct nfs_fattr *fattr) { /* * Check whether the mode has been set, as we only want to * do this once. (We don't allow inodes to change types.) */ if (inode->i_mode == 0) { inode->i_mode = fattr->mode; if (S_ISREG(inode->i_mode)) inode->i_op = &nfs_file_inode_operations; else if (S_ISDIR(inode->i_mode)) inode->i_op = &nfs_dir_inode_operations; else if (S_ISLNK(inode->i_mode)) inode->i_op = &nfs_symlink_inode_operations; else if (S_ISCHR(inode->i_mode)) { inode->i_op = &chrdev_inode_operations; inode->i_rdev = to_kdev_t(fattr->rdev); } else if (S_ISBLK(inode->i_mode)) { inode->i_op = &blkdev_inode_operations; inode->i_rdev = to_kdev_t(fattr->rdev); } else if (S_ISFIFO(inode->i_mode)) init_fifo(inode); else inode->i_op = NULL; /* * Preset the size and mtime, as there's no need * to invalidate the caches. */ inode->i_size = fattr->size; inode->i_mtime = fattr->mtime.seconds; NFS_OLDMTIME(inode) = fattr->mtime.seconds; } nfs_refresh_inode(inode, fattr); }
void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) { int was_empty; if (!inode || !fattr) { printk("nfs_refresh_inode: inode or fattr is NULL\n"); return; } if (inode->i_ino != fattr->fileid) { printk("nfs_refresh_inode: inode number mismatch\n"); return; } was_empty = (inode->i_mode == 0); /* * Some (broken?) NFS servers return 0 as the file type. * We'll assume that 0 means the file type has not changed. */ if(!(fattr->mode & S_IFMT)){ inode->i_mode = (inode->i_mode & S_IFMT) | (fattr->mode & ~S_IFMT); }else{ inode->i_mode = fattr->mode; } inode->i_nlink = fattr->nlink; inode->i_uid = fattr->uid; inode->i_gid = fattr->gid; /* Size changed from outside: invalidate caches on next read */ if (inode->i_size != fattr->size) NFS_CACHEINV(inode); if (NFS_OLDMTIME(inode) != fattr->mtime.seconds) NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); inode->i_size = fattr->size; if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) inode->i_rdev = to_kdev_t(fattr->rdev); else inode->i_rdev = 0; inode->i_blocks = fattr->blocks; inode->i_atime = fattr->atime.seconds; inode->i_mtime = fattr->mtime.seconds; inode->i_ctime = fattr->ctime.seconds; if (S_ISREG(inode->i_mode)) inode->i_op = &nfs_file_inode_operations; else if (S_ISDIR(inode->i_mode)) inode->i_op = &nfs_dir_inode_operations; else if (S_ISLNK(inode->i_mode)) inode->i_op = &nfs_symlink_inode_operations; else if (S_ISCHR(inode->i_mode)) inode->i_op = &chrdev_inode_operations; else if (S_ISBLK(inode->i_mode)) inode->i_op = &blkdev_inode_operations; else if (S_ISFIFO(inode->i_mode)) { if (was_empty) init_fifo(inode); } else inode->i_op = NULL; nfs_lookup_cache_refresh(inode, fattr); }
static inline void revalidate_dir(struct nfs_server * server, struct inode * dir) { struct nfs_fattr fattr; if (jiffies - NFS_READTIME(dir) < NFS_ATTRTIMEO(dir)) return; NFS_READTIME(dir) = jiffies; if (nfs_proc_getattr(server, NFS_FH(dir), &fattr) == 0) { nfs_refresh_inode(dir, &fattr); if (fattr.mtime.seconds == NFS_OLDMTIME(dir)) { if ((NFS_ATTRTIMEO(dir) <<= 1) > server->acdirmax) NFS_ATTRTIMEO(dir) = server->acdirmax; return; } NFS_OLDMTIME(dir) = fattr.mtime.seconds; } /* invalidate directory cache here when we _really_ start caching */ }