root/fs/nfs/dir.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nfs_dir_read
  2. nfs_readdir
  3. nfs_lookup_cache_index
  4. nfs_lookup_cache_lookup
  5. nfs_lookup_cache_add
  6. nfs_lookup_cache_remove
  7. nfs_lookup_cache_refresh
  8. nfs_lookup
  9. nfs_create
  10. nfs_mknod
  11. nfs_mkdir
  12. nfs_rmdir
  13. nfs_unlink
  14. nfs_symlink
  15. nfs_link
  16. nfs_rename
  17. nfs_refresh_inode

   1 /*
   2  *  linux/fs/nfs/dir.c
   3  *
   4  *  Copyright (C) 1992  Rick Sladkey
   5  *
   6  *  nfs directory handling functions
   7  */
   8 
   9 #include <linux/sched.h>
  10 #include <linux/errno.h>
  11 #include <linux/stat.h>
  12 #include <linux/nfs_fs.h>
  13 #include <linux/fcntl.h>
  14 #include <linux/string.h>
  15 #include <linux/kernel.h>
  16 #include <linux/malloc.h>
  17 #include <linux/mm.h>
  18 
  19 #include <asm/segment.h>        /* for fs functions */
  20 
  21 #define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de)))
  22 #define ROUND_UP(x) (((x)+3) & ~3)
  23 
  24 static int nfs_dir_read(struct inode *, struct file *filp, char *buf,
  25                         int count);
  26 static int nfs_readdir(struct inode *, struct file *, struct dirent *, int);
  27 static int nfs_lookup(struct inode *dir, const char *name, int len,
  28                       struct inode **result);
  29 static int nfs_create(struct inode *dir, const char *name, int len, int mode,
  30                       struct inode **result);
  31 static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode);
  32 static int nfs_rmdir(struct inode *dir, const char *name, int len);
  33 static int nfs_unlink(struct inode *dir, const char *name, int len);
  34 static int nfs_symlink(struct inode *inode, const char *name, int len,
  35                        const char *symname);
  36 static int nfs_link(struct inode *oldinode, struct inode *dir,
  37                     const char *name, int len);
  38 static int nfs_mknod(struct inode *dir, const char *name, int len, int mode,
  39                      int rdev);
  40 static int nfs_rename(struct inode *old_dir, const char *old_name,
  41                       int old_len, struct inode *new_dir, const char *new_name,
  42                       int new_len);
  43 
  44 static struct file_operations nfs_dir_operations = {
  45         NULL,                   /* lseek - default */
  46         nfs_dir_read,           /* read - bad */
  47         NULL,                   /* write - bad */
  48         nfs_readdir,            /* readdir */
  49         NULL,                   /* select - default */
  50         NULL,                   /* ioctl - default */
  51         NULL,                   /* mmap */
  52         NULL,                   /* no special open code */
  53         NULL,                   /* no special release code */
  54         NULL                    /* fsync */
  55 };
  56 
  57 struct inode_operations nfs_dir_inode_operations = {
  58         &nfs_dir_operations,    /* default directory file-ops */
  59         nfs_create,             /* create */
  60         nfs_lookup,             /* lookup */
  61         nfs_link,               /* link */
  62         nfs_unlink,             /* unlink */
  63         nfs_symlink,            /* symlink */
  64         nfs_mkdir,              /* mkdir */
  65         nfs_rmdir,              /* rmdir */
  66         nfs_mknod,              /* mknod */
  67         nfs_rename,             /* rename */
  68         NULL,                   /* readlink */
  69         NULL,                   /* follow_link */
  70         NULL,                   /* bmap */
  71         NULL,                   /* truncate */
  72         NULL                    /* permission */
  73 };
  74 
  75 static int nfs_dir_read(struct inode *inode, struct file *filp, char *buf,
     /* [previous][next][first][last][top][bottom][index][help] */
  76                         int count)
  77 {
  78         return -EISDIR;
  79 }
  80 
  81 /*
  82  * We need to do caching of directory entries to prevent an
  83  * incredible amount of RPC traffic.  Only the most recent open
  84  * directory is cached.  This seems sufficient for most purposes.
  85  * Technically, we ought to flush the cache on close but this is
  86  * not a problem in practice.
  87  */
  88 
  89 static int nfs_readdir(struct inode *inode, struct file *filp,
     /* [previous][next][first][last][top][bottom][index][help] */
  90                        struct dirent *dirent, int count)
  91 {
  92         static int c_dev = 0;
  93         static int c_ino;
  94         static int c_size;
  95         static struct nfs_entry *c_entry = NULL;
  96 
  97         int result;
  98         int i;
  99         struct nfs_entry *entry;
 100 
 101         if (!inode || !S_ISDIR(inode->i_mode)) {
 102                 printk("nfs_readdir: inode is NULL or not a directory\n");
 103                 return -EBADF;
 104         }
 105 
 106         /* initialize cache memory if it hasn't been used before */
 107 
 108         if (c_entry == NULL) {
 109                 i = sizeof (struct nfs_entry)*NFS_READDIR_CACHE_SIZE;
 110                 c_entry = (struct nfs_entry *) kmalloc(i, GFP_KERNEL);
 111                 for (i = 0; i < NFS_READDIR_CACHE_SIZE; i++) {
 112                         c_entry[i].name = (char *) kmalloc(NFS_MAXNAMLEN + 1,
 113                                 GFP_KERNEL);
 114                 }
 115         }
 116         entry = NULL;
 117 
 118         /* try to find it in the cache */
 119 
 120         if (inode->i_dev == c_dev && inode->i_ino == c_ino) {
 121                 for (i = 0; i < c_size; i++) {
 122                         if (filp->f_pos == c_entry[i].cookie) {
 123                                 if (i == c_size - 1) {
 124                                         if (c_entry[i].eof)
 125                                                 return 0;
 126                                 }
 127                                 else
 128                                         entry = c_entry + i + 1;
 129                                 break;
 130                         }
 131                 }
 132         }
 133 
 134         /* if we didn't find it in the cache, revert to an nfs call */
 135 
 136         if (!entry) {
 137                 result = nfs_proc_readdir(NFS_SERVER(inode), NFS_FH(inode),
 138                         filp->f_pos, NFS_READDIR_CACHE_SIZE, c_entry);
 139                 if (result < 0) {
 140                         c_dev = 0;
 141                         return result;
 142                 }
 143                 if (result > 0) {
 144                         c_dev = inode->i_dev;
 145                         c_ino = inode->i_ino;
 146                         c_size = result;
 147                         entry = c_entry + 0;
 148                 }
 149         }
 150 
 151         /* if we found it in the cache or from an nfs call, return results */
 152 
 153         if (entry) {
 154                 i = strlen(entry->name);
 155                 memcpy_tofs(dirent->d_name, entry->name, i + 1);
 156                 put_fs_long(entry->fileid, &dirent->d_ino);
 157                 put_fs_word(i, &dirent->d_reclen);
 158                 filp->f_pos = entry->cookie;
 159                 return ROUND_UP(NAME_OFFSET(dirent)+i+1);
 160         }
 161         return 0;
 162 }
 163 
 164 /*
 165  * Lookup caching is a big win for performance but this is just
 166  * a trial to see how well it works on a small scale.
 167  * For example, bash does a lookup on ".." 13 times for each path
 168  * element when running pwd.  Yes, hard to believe but true.
 169  * Try pwd in a filesystem mounted with noac.
 170  *
 171  * It trades a little cpu time and memory for a lot of network bandwidth.
 172  * Since the cache is not hashed yet, it is a good idea not to make it too
 173  * large because every lookup looks through the entire cache even
 174  * though most of them will fail.
 175  */
 176 
 177 static struct nfs_lookup_cache_entry {
 178         int dev;
 179         int inode;
 180         char filename[NFS_MAXNAMLEN + 1];
 181         struct nfs_fh fhandle;
 182         struct nfs_fattr fattr;
 183         int expiration_date;
 184 } nfs_lookup_cache[NFS_LOOKUP_CACHE_SIZE];
 185 
 186 static struct nfs_lookup_cache_entry *nfs_lookup_cache_index(struct inode *dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 187                                                              const char *filename)
 188 {
 189         struct nfs_lookup_cache_entry *entry;
 190         int i;
 191 
 192         for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
 193                 entry = nfs_lookup_cache + i;
 194                 if (entry->dev == dir->i_dev && entry->inode == dir->i_ino
 195                     && !strncmp(filename, entry->filename, NFS_MAXNAMLEN))
 196                         return entry;
 197         }
 198         return NULL;
 199 }
 200 
 201 static int nfs_lookup_cache_lookup(struct inode *dir, const char *filename,
     /* [previous][next][first][last][top][bottom][index][help] */
 202                                    struct nfs_fh *fhandle,
 203                                    struct nfs_fattr *fattr)
 204 {
 205         static int nfs_lookup_cache_in_use = 0;
 206 
 207         struct nfs_lookup_cache_entry *entry;
 208 
 209         if (!nfs_lookup_cache_in_use) {
 210                 memset(nfs_lookup_cache, 0, sizeof(nfs_lookup_cache));
 211                 nfs_lookup_cache_in_use = 1;
 212         }
 213         if ((entry = nfs_lookup_cache_index(dir, filename))) {
 214                 if (jiffies > entry->expiration_date) {
 215                         entry->dev = 0;
 216                         return 0;
 217                 }
 218                 *fhandle = entry->fhandle;
 219                 *fattr = entry->fattr;
 220                 return 1;
 221         }
 222         return 0;
 223 }
 224 
 225 static void nfs_lookup_cache_add(struct inode *dir, const char *filename,
     /* [previous][next][first][last][top][bottom][index][help] */
 226                                  struct nfs_fh *fhandle,
 227                                  struct nfs_fattr *fattr)
 228 {
 229         static int nfs_lookup_cache_pos = 0;
 230         struct nfs_lookup_cache_entry *entry;
 231 
 232         /* compensate for bug in SGI NFS server */
 233         if (fattr->size == -1 || fattr->uid == -1 || fattr->gid == -1
 234             || fattr->atime.seconds == -1 || fattr->mtime.seconds == -1)
 235                 return;
 236         if (!(entry = nfs_lookup_cache_index(dir, filename))) {
 237                 entry = nfs_lookup_cache + nfs_lookup_cache_pos++;
 238                 if (nfs_lookup_cache_pos == NFS_LOOKUP_CACHE_SIZE)
 239                         nfs_lookup_cache_pos = 0;
 240         }
 241         entry->dev = dir->i_dev;
 242         entry->inode = dir->i_ino;
 243         strcpy(entry->filename, filename);
 244         entry->fhandle = *fhandle;
 245         entry->fattr = *fattr;
 246         entry->expiration_date = jiffies + (S_ISDIR(fattr->mode)
 247                 ? NFS_SERVER(dir)->acdirmax : NFS_SERVER(dir)->acregmax);
 248 }
 249 
 250 static void nfs_lookup_cache_remove(struct inode *dir, struct inode *inode,
     /* [previous][next][first][last][top][bottom][index][help] */
 251                                     const char *filename)
 252 {
 253         struct nfs_lookup_cache_entry *entry;
 254         int dev;
 255         int fileid;
 256         int i;
 257 
 258         if (inode) {
 259                 dev = inode->i_dev;
 260                 fileid = inode->i_ino;
 261         }
 262         else if ((entry = nfs_lookup_cache_index(dir, filename))) {
 263                 dev = entry->dev;
 264                 fileid = entry->fattr.fileid;
 265         }
 266         else
 267                 return;
 268         for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
 269                 entry = nfs_lookup_cache + i;
 270                 if (entry->dev == dev && entry->fattr.fileid == fileid)
 271                         entry->dev = 0;
 272         }
 273 }
 274 
 275 static void nfs_lookup_cache_refresh(struct inode *file,
     /* [previous][next][first][last][top][bottom][index][help] */
 276                                      struct nfs_fattr *fattr)
 277 {
 278         struct nfs_lookup_cache_entry *entry;
 279         int dev = file->i_dev;
 280         int fileid = file->i_ino;
 281         int i;
 282 
 283         for (i = 0; i < NFS_LOOKUP_CACHE_SIZE; i++) {
 284                 entry = nfs_lookup_cache + i;
 285                 if (entry->dev == dev && entry->fattr.fileid == fileid)
 286                         entry->fattr = *fattr;
 287         }
 288 }
 289 
 290 static int nfs_lookup(struct inode *dir, const char *__name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 291                       struct inode **result)
 292 {
 293         struct nfs_fh fhandle;
 294         struct nfs_fattr fattr;
 295         char name[len > NFS_MAXNAMLEN? 1 : len+1];
 296         int error;
 297 
 298         *result = NULL;
 299         if (!dir || !S_ISDIR(dir->i_mode)) {
 300                 printk("nfs_lookup: inode is NULL or not a directory\n");
 301                 iput(dir);
 302                 return -ENOENT;
 303         }
 304         if (len > NFS_MAXNAMLEN) {
 305                 iput(dir);
 306                 return -ENAMETOOLONG;
 307         }
 308         memcpy(name,__name,len);
 309         name[len] = '\0';
 310         if (len == 1 && name[0] == '.') { /* cheat for "." */
 311                 *result = dir;
 312                 return 0;
 313         }
 314         if ((NFS_SERVER(dir)->flags & NFS_MOUNT_NOAC)
 315             || !nfs_lookup_cache_lookup(dir, name, &fhandle, &fattr)) {
 316                 if ((error = nfs_proc_lookup(NFS_SERVER(dir), NFS_FH(dir),
 317                     name, &fhandle, &fattr))) {
 318                         iput(dir);
 319                         return error;
 320                 }
 321                 nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
 322         }
 323         if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
 324                 iput(dir);
 325                 return -EACCES;
 326         }
 327         iput(dir);
 328         return 0;
 329 }
 330 
 331 static int nfs_create(struct inode *dir, const char *name, int len, int mode,
     /* [previous][next][first][last][top][bottom][index][help] */
 332                       struct inode **result)
 333 {
 334         struct nfs_sattr sattr;
 335         struct nfs_fattr fattr;
 336         struct nfs_fh fhandle;
 337         int error;
 338 
 339         *result = NULL;
 340         if (!dir || !S_ISDIR(dir->i_mode)) {
 341                 printk("nfs_create: inode is NULL or not a directory\n");
 342                 iput(dir);
 343                 return -ENOENT;
 344         }
 345         if (len > NFS_MAXNAMLEN) {
 346                 iput(dir);
 347                 return -ENAMETOOLONG;
 348         }
 349         sattr.mode = mode;
 350         sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
 351         sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
 352         if ((error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
 353                 name, &sattr, &fhandle, &fattr))) {
 354                 iput(dir);
 355                 return error;
 356         }
 357         if (!(*result = nfs_fhget(dir->i_sb, &fhandle, &fattr))) {
 358                 iput(dir);
 359                 return -EACCES;
 360         }
 361         nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
 362         iput(dir);
 363         return 0;
 364 }
 365 
 366 static int nfs_mknod(struct inode *dir, const char *name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 367                      int mode, int rdev)
 368 {
 369         struct nfs_sattr sattr;
 370         struct nfs_fattr fattr;
 371         struct nfs_fh fhandle;
 372         int error;
 373 
 374         if (!dir || !S_ISDIR(dir->i_mode)) {
 375                 printk("nfs_mknod: inode is NULL or not a directory\n");
 376                 iput(dir);
 377                 return -ENOENT;
 378         }
 379         if (len > NFS_MAXNAMLEN) {
 380                 iput(dir);
 381                 return -ENAMETOOLONG;
 382         }
 383         sattr.mode = mode;
 384         sattr.uid = sattr.gid = (unsigned) -1;
 385         if (S_ISCHR(mode) || S_ISBLK(mode))
 386                 sattr.size = rdev; /* get out your barf bag */
 387         else
 388                 sattr.size = (unsigned) -1;
 389         sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
 390         error = nfs_proc_create(NFS_SERVER(dir), NFS_FH(dir),
 391                 name, &sattr, &fhandle, &fattr);
 392         if (!error)
 393                 nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
 394         iput(dir);
 395         return error;
 396 }
 397 
 398 static int nfs_mkdir(struct inode *dir, const char *name, int len, int mode)
     /* [previous][next][first][last][top][bottom][index][help] */
 399 {
 400         struct nfs_sattr sattr;
 401         struct nfs_fattr fattr;
 402         struct nfs_fh fhandle;
 403         int error;
 404 
 405         if (!dir || !S_ISDIR(dir->i_mode)) {
 406                 printk("nfs_mkdir: inode is NULL or not a directory\n");
 407                 iput(dir);
 408                 return -ENOENT;
 409         }
 410         if (len > NFS_MAXNAMLEN) {
 411                 iput(dir);
 412                 return -ENAMETOOLONG;
 413         }
 414         sattr.mode = mode;
 415         sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
 416         sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
 417         error = nfs_proc_mkdir(NFS_SERVER(dir), NFS_FH(dir),
 418                 name, &sattr, &fhandle, &fattr);
 419         if (!error)
 420                 nfs_lookup_cache_add(dir, name, &fhandle, &fattr);
 421         iput(dir);
 422         return error;
 423 }
 424 
 425 static int nfs_rmdir(struct inode *dir, const char *name, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 426 {
 427         int error;
 428 
 429         if (!dir || !S_ISDIR(dir->i_mode)) {
 430                 printk("nfs_rmdir: inode is NULL or not a directory\n");
 431                 iput(dir);
 432                 return -ENOENT;
 433         }
 434         if (len > NFS_MAXNAMLEN) {
 435                 iput(dir);
 436                 return -ENAMETOOLONG;
 437         }
 438         error = nfs_proc_rmdir(NFS_SERVER(dir), NFS_FH(dir), name);
 439         if (!error)
 440                 nfs_lookup_cache_remove(dir, NULL, name);
 441         iput(dir);
 442         return error;
 443 }
 444 
 445 static int nfs_unlink(struct inode *dir, const char *name, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 446 {
 447         int error;
 448 
 449         if (!dir || !S_ISDIR(dir->i_mode)) {
 450                 printk("nfs_unlink: inode is NULL or not a directory\n");
 451                 iput(dir);
 452                 return -ENOENT;
 453         }
 454         if (len > NFS_MAXNAMLEN) {
 455                 iput(dir);
 456                 return -ENAMETOOLONG;
 457         }
 458         error = nfs_proc_remove(NFS_SERVER(dir), NFS_FH(dir), name);
 459         if (!error)
 460                 nfs_lookup_cache_remove(dir, NULL, name);
 461         iput(dir);
 462         return error;
 463 }
 464 
 465 static int nfs_symlink(struct inode *dir, const char *name, int len,
     /* [previous][next][first][last][top][bottom][index][help] */
 466                        const char *symname)
 467 {
 468         struct nfs_sattr sattr;
 469         int error;
 470 
 471         if (!dir || !S_ISDIR(dir->i_mode)) {
 472                 printk("nfs_symlink: inode is NULL or not a directory\n");
 473                 iput(dir);
 474                 return -ENOENT;
 475         }
 476         if (len > NFS_MAXNAMLEN) {
 477                 iput(dir);
 478                 return -ENAMETOOLONG;
 479         }
 480         if (strlen(symname) > NFS_MAXPATHLEN) {
 481                 iput(dir);
 482                 return -ENAMETOOLONG;
 483         }
 484         sattr.mode = S_IFLNK | S_IRWXUGO; /* SunOS 4.1.2 crashes without this! */
 485         sattr.uid = sattr.gid = sattr.size = (unsigned) -1;
 486         sattr.atime.seconds = sattr.mtime.seconds = (unsigned) -1;
 487         error = nfs_proc_symlink(NFS_SERVER(dir), NFS_FH(dir),
 488                 name, symname, &sattr);
 489         iput(dir);
 490         return error;
 491 }
 492 
 493 static int nfs_link(struct inode *oldinode, struct inode *dir,
     /* [previous][next][first][last][top][bottom][index][help] */
 494                     const char *name, int len)
 495 {
 496         int error;
 497 
 498         if (!oldinode) {
 499                 printk("nfs_link: old inode is NULL\n");
 500                 iput(oldinode);
 501                 iput(dir);
 502                 return -ENOENT;
 503         }
 504         if (!dir || !S_ISDIR(dir->i_mode)) {
 505                 printk("nfs_link: dir is NULL or not a directory\n");
 506                 iput(oldinode);
 507                 iput(dir);
 508                 return -ENOENT;
 509         }
 510         if (len > NFS_MAXNAMLEN) {
 511                 iput(oldinode);
 512                 iput(dir);
 513                 return -ENAMETOOLONG;
 514         }
 515         error = nfs_proc_link(NFS_SERVER(oldinode), NFS_FH(oldinode),
 516                 NFS_FH(dir), name);
 517         if (!error)
 518                 nfs_lookup_cache_remove(dir, oldinode, NULL);
 519         iput(oldinode);
 520         iput(dir);
 521         return error;
 522 }
 523 
 524 static int nfs_rename(struct inode *old_dir, const char *old_name, int old_len,
     /* [previous][next][first][last][top][bottom][index][help] */
 525                       struct inode *new_dir, const char *new_name, int new_len)
 526 {
 527         int error;
 528 
 529         if (!old_dir || !S_ISDIR(old_dir->i_mode)) {
 530                 printk("nfs_rename: old inode is NULL or not a directory\n");
 531                 iput(old_dir);
 532                 iput(new_dir);
 533                 return -ENOENT;
 534         }
 535         if (!new_dir || !S_ISDIR(new_dir->i_mode)) {
 536                 printk("nfs_rename: new inode is NULL or not a directory\n");
 537                 iput(old_dir);
 538                 iput(new_dir);
 539                 return -ENOENT;
 540         }
 541         if (old_len > NFS_MAXNAMLEN || new_len > NFS_MAXNAMLEN) {
 542                 iput(old_dir);
 543                 iput(new_dir);
 544                 return -ENAMETOOLONG;
 545         }
 546         error = nfs_proc_rename(NFS_SERVER(old_dir),
 547                 NFS_FH(old_dir), old_name,
 548                 NFS_FH(new_dir), new_name);
 549         if (!error) {
 550                 nfs_lookup_cache_remove(old_dir, NULL, old_name);
 551                 nfs_lookup_cache_remove(new_dir, NULL, new_name);
 552         }
 553         iput(old_dir);
 554         iput(new_dir);
 555         return error;
 556 }
 557 
 558 /*
 559  * Many nfs protocol calls return the new file attributes after
 560  * an operation.  Here we update the inode to reflect the state
 561  * of the server's inode.
 562  */
 563 
 564 void nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
     /* [previous][next][first][last][top][bottom][index][help] */
 565 {
 566         int was_empty;
 567 
 568         if (!inode || !fattr) {
 569                 printk("nfs_refresh_inode: inode or fattr is NULL\n");
 570                 return;
 571         }
 572         if (inode->i_ino != fattr->fileid) {
 573                 printk("nfs_refresh_inode: inode number mismatch\n");
 574                 return;
 575         }
 576         was_empty = inode->i_mode == 0;
 577         inode->i_mode = fattr->mode;
 578         inode->i_nlink = fattr->nlink;
 579         inode->i_uid = fattr->uid;
 580         inode->i_gid = fattr->gid;
 581         inode->i_size = fattr->size;
 582         inode->i_blksize = fattr->blocksize;
 583         if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
 584                 inode->i_rdev = fattr->rdev;
 585         else
 586                 inode->i_rdev = 0;
 587         inode->i_blocks = fattr->blocks;
 588         inode->i_atime = fattr->atime.seconds;
 589         inode->i_mtime = fattr->mtime.seconds;
 590         inode->i_ctime = fattr->ctime.seconds;
 591         if (was_empty) {
 592                 if (S_ISREG(inode->i_mode))
 593                         inode->i_op = &nfs_file_inode_operations;
 594                 else if (S_ISDIR(inode->i_mode))
 595                         inode->i_op = &nfs_dir_inode_operations;
 596                 else if (S_ISLNK(inode->i_mode))
 597                         inode->i_op = &nfs_symlink_inode_operations;
 598                 else if (S_ISCHR(inode->i_mode))
 599                         inode->i_op = &chrdev_inode_operations;
 600                 else if (S_ISBLK(inode->i_mode))
 601                         inode->i_op = &blkdev_inode_operations;
 602                 else if (S_ISFIFO(inode->i_mode))
 603                         init_fifo(inode);
 604                 else
 605                         inode->i_op = NULL;
 606         }
 607         nfs_lookup_cache_refresh(inode, fattr);
 608 }
 609 

/* [previous][next][first][last][top][bottom][index][help] */