statx: Add a system call to make enhanced file info available
[platform/kernel/linux-starfive.git] / fs / stat.c
1 /*
2  *  linux/fs/stat.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  */
6
7 #include <linux/export.h>
8 #include <linux/mm.h>
9 #include <linux/errno.h>
10 #include <linux/file.h>
11 #include <linux/highuid.h>
12 #include <linux/fs.h>
13 #include <linux/namei.h>
14 #include <linux/security.h>
15 #include <linux/syscalls.h>
16 #include <linux/pagemap.h>
17
18 #include <linux/uaccess.h>
19 #include <asm/unistd.h>
20
21 /**
22  * generic_fillattr - Fill in the basic attributes from the inode struct
23  * @inode: Inode to use as the source
24  * @stat: Where to fill in the attributes
25  *
26  * Fill in the basic attributes in the kstat structure from data that's to be
27  * found on the VFS inode structure.  This is the default if no getattr inode
28  * operation is supplied.
29  */
30 void generic_fillattr(struct inode *inode, struct kstat *stat)
31 {
32         stat->dev = inode->i_sb->s_dev;
33         stat->ino = inode->i_ino;
34         stat->mode = inode->i_mode;
35         stat->nlink = inode->i_nlink;
36         stat->uid = inode->i_uid;
37         stat->gid = inode->i_gid;
38         stat->rdev = inode->i_rdev;
39         stat->size = i_size_read(inode);
40         stat->atime = inode->i_atime;
41         stat->mtime = inode->i_mtime;
42         stat->ctime = inode->i_ctime;
43         stat->blksize = i_blocksize(inode);
44         stat->blocks = inode->i_blocks;
45
46         if (IS_NOATIME(inode))
47                 stat->result_mask &= ~STATX_ATIME;
48         if (IS_AUTOMOUNT(inode))
49                 stat->attributes |= STATX_ATTR_AUTOMOUNT;
50 }
51 EXPORT_SYMBOL(generic_fillattr);
52
53 /**
54  * vfs_getattr_nosec - getattr without security checks
55  * @path: file to get attributes from
56  * @stat: structure to return attributes in
57  * @request_mask: STATX_xxx flags indicating what the caller wants
58  * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
59  *
60  * Get attributes without calling security_inode_getattr.
61  *
62  * Currently the only caller other than vfs_getattr is internal to the
63  * filehandle lookup code, which uses only the inode number and returns no
64  * attributes to any user.  Any other code probably wants vfs_getattr.
65  */
66 int vfs_getattr_nosec(const struct path *path, struct kstat *stat,
67                       u32 request_mask, unsigned int query_flags)
68 {
69         struct inode *inode = d_backing_inode(path->dentry);
70
71         memset(stat, 0, sizeof(*stat));
72         stat->result_mask |= STATX_BASIC_STATS;
73         request_mask &= STATX_ALL;
74         query_flags &= KSTAT_QUERY_FLAGS;
75         if (inode->i_op->getattr)
76                 return inode->i_op->getattr(path, stat, request_mask,
77                                             query_flags);
78
79         generic_fillattr(inode, stat);
80         return 0;
81 }
82 EXPORT_SYMBOL(vfs_getattr_nosec);
83
84 /*
85  * vfs_getattr - Get the enhanced basic attributes of a file
86  * @path: The file of interest
87  * @stat: Where to return the statistics
88  * @request_mask: STATX_xxx flags indicating what the caller wants
89  * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
90  *
91  * Ask the filesystem for a file's attributes.  The caller must indicate in
92  * request_mask and query_flags to indicate what they want.
93  *
94  * If the file is remote, the filesystem can be forced to update the attributes
95  * from the backing store by passing AT_STATX_FORCE_SYNC in query_flags or can
96  * suppress the update by passing AT_STATX_DONT_SYNC.
97  *
98  * Bits must have been set in request_mask to indicate which attributes the
99  * caller wants retrieving.  Any such attribute not requested may be returned
100  * anyway, but the value may be approximate, and, if remote, may not have been
101  * synchronised with the server.
102  *
103  * 0 will be returned on success, and a -ve error code if unsuccessful.
104  */
105 int vfs_getattr(const struct path *path, struct kstat *stat,
106                 u32 request_mask, unsigned int query_flags)
107 {
108         int retval;
109
110         retval = security_inode_getattr(path);
111         if (retval)
112                 return retval;
113         return vfs_getattr_nosec(path, stat, request_mask, query_flags);
114 }
115 EXPORT_SYMBOL(vfs_getattr);
116
117 /**
118  * vfs_statx_fd - Get the enhanced basic attributes by file descriptor
119  * @fd: The file descriptor referring to the file of interest
120  * @stat: The result structure to fill in.
121  * @request_mask: STATX_xxx flags indicating what the caller wants
122  * @query_flags: Query mode (KSTAT_QUERY_FLAGS)
123  *
124  * This function is a wrapper around vfs_getattr().  The main difference is
125  * that it uses a file descriptor to determine the file location.
126  *
127  * 0 will be returned on success, and a -ve error code if unsuccessful.
128  */
129 int vfs_statx_fd(unsigned int fd, struct kstat *stat,
130                  u32 request_mask, unsigned int query_flags)
131 {
132         struct fd f = fdget_raw(fd);
133         int error = -EBADF;
134
135         if (f.file) {
136                 error = vfs_getattr(&f.file->f_path, stat,
137                                     request_mask, query_flags);
138                 fdput(f);
139         }
140         return error;
141 }
142 EXPORT_SYMBOL(vfs_statx_fd);
143
144 /**
145  * vfs_statx - Get basic and extra attributes by filename
146  * @dfd: A file descriptor representing the base dir for a relative filename
147  * @filename: The name of the file of interest
148  * @flags: Flags to control the query
149  * @stat: The result structure to fill in.
150  * @request_mask: STATX_xxx flags indicating what the caller wants
151  *
152  * This function is a wrapper around vfs_getattr().  The main difference is
153  * that it uses a filename and base directory to determine the file location.
154  * Additionally, the use of AT_SYMLINK_NOFOLLOW in flags will prevent a symlink
155  * at the given name from being referenced.
156  *
157  * The caller must have preset stat->request_mask as for vfs_getattr().  The
158  * flags are also used to load up stat->query_flags.
159  *
160  * 0 will be returned on success, and a -ve error code if unsuccessful.
161  */
162 int vfs_statx(int dfd, const char __user *filename, int flags,
163               struct kstat *stat, u32 request_mask)
164 {
165         struct path path;
166         int error = -EINVAL;
167         unsigned int lookup_flags = LOOKUP_FOLLOW | LOOKUP_AUTOMOUNT;
168
169         if ((flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
170                        AT_EMPTY_PATH | KSTAT_QUERY_FLAGS)) != 0)
171                 return -EINVAL;
172
173         if (flags & AT_SYMLINK_NOFOLLOW)
174                 lookup_flags &= ~LOOKUP_FOLLOW;
175         if (flags & AT_NO_AUTOMOUNT)
176                 lookup_flags &= ~LOOKUP_AUTOMOUNT;
177         if (flags & AT_EMPTY_PATH)
178                 lookup_flags |= LOOKUP_EMPTY;
179
180 retry:
181         error = user_path_at(dfd, filename, lookup_flags, &path);
182         if (error)
183                 goto out;
184
185         error = vfs_getattr(&path, stat, request_mask, flags);
186         path_put(&path);
187         if (retry_estale(error, lookup_flags)) {
188                 lookup_flags |= LOOKUP_REVAL;
189                 goto retry;
190         }
191 out:
192         return error;
193 }
194 EXPORT_SYMBOL(vfs_statx);
195
196
197 #ifdef __ARCH_WANT_OLD_STAT
198
199 /*
200  * For backward compatibility?  Maybe this should be moved
201  * into arch/i386 instead?
202  */
203 static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * statbuf)
204 {
205         static int warncount = 5;
206         struct __old_kernel_stat tmp;
207
208         if (warncount > 0) {
209                 warncount--;
210                 printk(KERN_WARNING "VFS: Warning: %s using old stat() call. Recompile your binary.\n",
211                         current->comm);
212         } else if (warncount < 0) {
213                 /* it's laughable, but... */
214                 warncount = 0;
215         }
216
217         memset(&tmp, 0, sizeof(struct __old_kernel_stat));
218         tmp.st_dev = old_encode_dev(stat->dev);
219         tmp.st_ino = stat->ino;
220         if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
221                 return -EOVERFLOW;
222         tmp.st_mode = stat->mode;
223         tmp.st_nlink = stat->nlink;
224         if (tmp.st_nlink != stat->nlink)
225                 return -EOVERFLOW;
226         SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
227         SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
228         tmp.st_rdev = old_encode_dev(stat->rdev);
229 #if BITS_PER_LONG == 32
230         if (stat->size > MAX_NON_LFS)
231                 return -EOVERFLOW;
232 #endif
233         tmp.st_size = stat->size;
234         tmp.st_atime = stat->atime.tv_sec;
235         tmp.st_mtime = stat->mtime.tv_sec;
236         tmp.st_ctime = stat->ctime.tv_sec;
237         return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
238 }
239
240 SYSCALL_DEFINE2(stat, const char __user *, filename,
241                 struct __old_kernel_stat __user *, statbuf)
242 {
243         struct kstat stat;
244         int error;
245
246         error = vfs_stat(filename, &stat);
247         if (error)
248                 return error;
249
250         return cp_old_stat(&stat, statbuf);
251 }
252
253 SYSCALL_DEFINE2(lstat, const char __user *, filename,
254                 struct __old_kernel_stat __user *, statbuf)
255 {
256         struct kstat stat;
257         int error;
258
259         error = vfs_lstat(filename, &stat);
260         if (error)
261                 return error;
262
263         return cp_old_stat(&stat, statbuf);
264 }
265
266 SYSCALL_DEFINE2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)
267 {
268         struct kstat stat;
269         int error = vfs_fstat(fd, &stat);
270
271         if (!error)
272                 error = cp_old_stat(&stat, statbuf);
273
274         return error;
275 }
276
277 #endif /* __ARCH_WANT_OLD_STAT */
278
279 #if BITS_PER_LONG == 32
280 #  define choose_32_64(a,b) a
281 #else
282 #  define choose_32_64(a,b) b
283 #endif
284
285 #define valid_dev(x)  choose_32_64(old_valid_dev(x),true)
286 #define encode_dev(x) choose_32_64(old_encode_dev,new_encode_dev)(x)
287
288 #ifndef INIT_STRUCT_STAT_PADDING
289 #  define INIT_STRUCT_STAT_PADDING(st) memset(&st, 0, sizeof(st))
290 #endif
291
292 static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf)
293 {
294         struct stat tmp;
295
296         if (!valid_dev(stat->dev) || !valid_dev(stat->rdev))
297                 return -EOVERFLOW;
298 #if BITS_PER_LONG == 32
299         if (stat->size > MAX_NON_LFS)
300                 return -EOVERFLOW;
301 #endif
302
303         INIT_STRUCT_STAT_PADDING(tmp);
304         tmp.st_dev = encode_dev(stat->dev);
305         tmp.st_ino = stat->ino;
306         if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
307                 return -EOVERFLOW;
308         tmp.st_mode = stat->mode;
309         tmp.st_nlink = stat->nlink;
310         if (tmp.st_nlink != stat->nlink)
311                 return -EOVERFLOW;
312         SET_UID(tmp.st_uid, from_kuid_munged(current_user_ns(), stat->uid));
313         SET_GID(tmp.st_gid, from_kgid_munged(current_user_ns(), stat->gid));
314         tmp.st_rdev = encode_dev(stat->rdev);
315         tmp.st_size = stat->size;
316         tmp.st_atime = stat->atime.tv_sec;
317         tmp.st_mtime = stat->mtime.tv_sec;
318         tmp.st_ctime = stat->ctime.tv_sec;
319 #ifdef STAT_HAVE_NSEC
320         tmp.st_atime_nsec = stat->atime.tv_nsec;
321         tmp.st_mtime_nsec = stat->mtime.tv_nsec;
322         tmp.st_ctime_nsec = stat->ctime.tv_nsec;
323 #endif
324         tmp.st_blocks = stat->blocks;
325         tmp.st_blksize = stat->blksize;
326         return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
327 }
328
329 SYSCALL_DEFINE2(newstat, const char __user *, filename,
330                 struct stat __user *, statbuf)
331 {
332         struct kstat stat;
333         int error = vfs_stat(filename, &stat);
334
335         if (error)
336                 return error;
337         return cp_new_stat(&stat, statbuf);
338 }
339
340 SYSCALL_DEFINE2(newlstat, const char __user *, filename,
341                 struct stat __user *, statbuf)
342 {
343         struct kstat stat;
344         int error;
345
346         error = vfs_lstat(filename, &stat);
347         if (error)
348                 return error;
349
350         return cp_new_stat(&stat, statbuf);
351 }
352
353 #if !defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_SYS_NEWFSTATAT)
354 SYSCALL_DEFINE4(newfstatat, int, dfd, const char __user *, filename,
355                 struct stat __user *, statbuf, int, flag)
356 {
357         struct kstat stat;
358         int error;
359
360         error = vfs_fstatat(dfd, filename, &stat, flag);
361         if (error)
362                 return error;
363         return cp_new_stat(&stat, statbuf);
364 }
365 #endif
366
367 SYSCALL_DEFINE2(newfstat, unsigned int, fd, struct stat __user *, statbuf)
368 {
369         struct kstat stat;
370         int error = vfs_fstat(fd, &stat);
371
372         if (!error)
373                 error = cp_new_stat(&stat, statbuf);
374
375         return error;
376 }
377
378 SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname,
379                 char __user *, buf, int, bufsiz)
380 {
381         struct path path;
382         int error;
383         int empty = 0;
384         unsigned int lookup_flags = LOOKUP_EMPTY;
385
386         if (bufsiz <= 0)
387                 return -EINVAL;
388
389 retry:
390         error = user_path_at_empty(dfd, pathname, lookup_flags, &path, &empty);
391         if (!error) {
392                 struct inode *inode = d_backing_inode(path.dentry);
393
394                 error = empty ? -ENOENT : -EINVAL;
395                 /*
396                  * AFS mountpoints allow readlink(2) but are not symlinks
397                  */
398                 if (d_is_symlink(path.dentry) || inode->i_op->readlink) {
399                         error = security_inode_readlink(path.dentry);
400                         if (!error) {
401                                 touch_atime(&path);
402                                 error = vfs_readlink(path.dentry, buf, bufsiz);
403                         }
404                 }
405                 path_put(&path);
406                 if (retry_estale(error, lookup_flags)) {
407                         lookup_flags |= LOOKUP_REVAL;
408                         goto retry;
409                 }
410         }
411         return error;
412 }
413
414 SYSCALL_DEFINE3(readlink, const char __user *, path, char __user *, buf,
415                 int, bufsiz)
416 {
417         return sys_readlinkat(AT_FDCWD, path, buf, bufsiz);
418 }
419
420
421 /* ---------- LFS-64 ----------- */
422 #if defined(__ARCH_WANT_STAT64) || defined(__ARCH_WANT_COMPAT_STAT64)
423
424 #ifndef INIT_STRUCT_STAT64_PADDING
425 #  define INIT_STRUCT_STAT64_PADDING(st) memset(&st, 0, sizeof(st))
426 #endif
427
428 static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf)
429 {
430         struct stat64 tmp;
431
432         INIT_STRUCT_STAT64_PADDING(tmp);
433 #ifdef CONFIG_MIPS
434         /* mips has weird padding, so we don't get 64 bits there */
435         tmp.st_dev = new_encode_dev(stat->dev);
436         tmp.st_rdev = new_encode_dev(stat->rdev);
437 #else
438         tmp.st_dev = huge_encode_dev(stat->dev);
439         tmp.st_rdev = huge_encode_dev(stat->rdev);
440 #endif
441         tmp.st_ino = stat->ino;
442         if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
443                 return -EOVERFLOW;
444 #ifdef STAT64_HAS_BROKEN_ST_INO
445         tmp.__st_ino = stat->ino;
446 #endif
447         tmp.st_mode = stat->mode;
448         tmp.st_nlink = stat->nlink;
449         tmp.st_uid = from_kuid_munged(current_user_ns(), stat->uid);
450         tmp.st_gid = from_kgid_munged(current_user_ns(), stat->gid);
451         tmp.st_atime = stat->atime.tv_sec;
452         tmp.st_atime_nsec = stat->atime.tv_nsec;
453         tmp.st_mtime = stat->mtime.tv_sec;
454         tmp.st_mtime_nsec = stat->mtime.tv_nsec;
455         tmp.st_ctime = stat->ctime.tv_sec;
456         tmp.st_ctime_nsec = stat->ctime.tv_nsec;
457         tmp.st_size = stat->size;
458         tmp.st_blocks = stat->blocks;
459         tmp.st_blksize = stat->blksize;
460         return copy_to_user(statbuf,&tmp,sizeof(tmp)) ? -EFAULT : 0;
461 }
462
463 SYSCALL_DEFINE2(stat64, const char __user *, filename,
464                 struct stat64 __user *, statbuf)
465 {
466         struct kstat stat;
467         int error = vfs_stat(filename, &stat);
468
469         if (!error)
470                 error = cp_new_stat64(&stat, statbuf);
471
472         return error;
473 }
474
475 SYSCALL_DEFINE2(lstat64, const char __user *, filename,
476                 struct stat64 __user *, statbuf)
477 {
478         struct kstat stat;
479         int error = vfs_lstat(filename, &stat);
480
481         if (!error)
482                 error = cp_new_stat64(&stat, statbuf);
483
484         return error;
485 }
486
487 SYSCALL_DEFINE2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf)
488 {
489         struct kstat stat;
490         int error = vfs_fstat(fd, &stat);
491
492         if (!error)
493                 error = cp_new_stat64(&stat, statbuf);
494
495         return error;
496 }
497
498 SYSCALL_DEFINE4(fstatat64, int, dfd, const char __user *, filename,
499                 struct stat64 __user *, statbuf, int, flag)
500 {
501         struct kstat stat;
502         int error;
503
504         error = vfs_fstatat(dfd, filename, &stat, flag);
505         if (error)
506                 return error;
507         return cp_new_stat64(&stat, statbuf);
508 }
509 #endif /* __ARCH_WANT_STAT64 || __ARCH_WANT_COMPAT_STAT64 */
510
511 static inline int __put_timestamp(struct timespec *kts,
512                                   struct statx_timestamp __user *uts)
513 {
514         return (__put_user(kts->tv_sec,         &uts->tv_sec            ) ||
515                 __put_user(kts->tv_nsec,        &uts->tv_nsec           ) ||
516                 __put_user(0,                   &uts->__reserved        ));
517 }
518
519 /*
520  * Set the statx results.
521  */
522 static long statx_set_result(struct kstat *stat, struct statx __user *buffer)
523 {
524         uid_t uid = from_kuid_munged(current_user_ns(), stat->uid);
525         gid_t gid = from_kgid_munged(current_user_ns(), stat->gid);
526
527         if (__put_user(stat->result_mask,       &buffer->stx_mask       ) ||
528             __put_user(stat->mode,              &buffer->stx_mode       ) ||
529             __clear_user(&buffer->__spare0, sizeof(buffer->__spare0))     ||
530             __put_user(stat->nlink,             &buffer->stx_nlink      ) ||
531             __put_user(uid,                     &buffer->stx_uid        ) ||
532             __put_user(gid,                     &buffer->stx_gid        ) ||
533             __put_user(stat->attributes,        &buffer->stx_attributes ) ||
534             __put_user(stat->blksize,           &buffer->stx_blksize    ) ||
535             __put_user(MAJOR(stat->rdev),       &buffer->stx_rdev_major ) ||
536             __put_user(MINOR(stat->rdev),       &buffer->stx_rdev_minor ) ||
537             __put_user(MAJOR(stat->dev),        &buffer->stx_dev_major  ) ||
538             __put_user(MINOR(stat->dev),        &buffer->stx_dev_minor  ) ||
539             __put_timestamp(&stat->atime,       &buffer->stx_atime      ) ||
540             __put_timestamp(&stat->btime,       &buffer->stx_btime      ) ||
541             __put_timestamp(&stat->ctime,       &buffer->stx_ctime      ) ||
542             __put_timestamp(&stat->mtime,       &buffer->stx_mtime      ) ||
543             __put_user(stat->ino,               &buffer->stx_ino        ) ||
544             __put_user(stat->size,              &buffer->stx_size       ) ||
545             __put_user(stat->blocks,            &buffer->stx_blocks     ) ||
546             __clear_user(&buffer->__spare1, sizeof(buffer->__spare1))     ||
547             __clear_user(&buffer->__spare2, sizeof(buffer->__spare2)))
548                 return -EFAULT;
549
550         return 0;
551 }
552
553 /**
554  * sys_statx - System call to get enhanced stats
555  * @dfd: Base directory to pathwalk from *or* fd to stat.
556  * @filename: File to stat *or* NULL.
557  * @flags: AT_* flags to control pathwalk.
558  * @mask: Parts of statx struct actually required.
559  * @buffer: Result buffer.
560  *
561  * Note that if filename is NULL, then it does the equivalent of fstat() using
562  * dfd to indicate the file of interest.
563  */
564 SYSCALL_DEFINE5(statx,
565                 int, dfd, const char __user *, filename, unsigned, flags,
566                 unsigned int, mask,
567                 struct statx __user *, buffer)
568 {
569         struct kstat stat;
570         int error;
571
572         if ((flags & AT_STATX_SYNC_TYPE) == AT_STATX_SYNC_TYPE)
573                 return -EINVAL;
574         if (!access_ok(VERIFY_WRITE, buffer, sizeof(*buffer)))
575                 return -EFAULT;
576
577         if (filename)
578                 error = vfs_statx(dfd, filename, flags, &stat, mask);
579         else
580                 error = vfs_statx_fd(dfd, &stat, mask, flags);
581         if (error)
582                 return error;
583         return statx_set_result(&stat, buffer);
584 }
585
586 /* Caller is here responsible for sufficient locking (ie. inode->i_lock) */
587 void __inode_add_bytes(struct inode *inode, loff_t bytes)
588 {
589         inode->i_blocks += bytes >> 9;
590         bytes &= 511;
591         inode->i_bytes += bytes;
592         if (inode->i_bytes >= 512) {
593                 inode->i_blocks++;
594                 inode->i_bytes -= 512;
595         }
596 }
597
598 void inode_add_bytes(struct inode *inode, loff_t bytes)
599 {
600         spin_lock(&inode->i_lock);
601         __inode_add_bytes(inode, bytes);
602         spin_unlock(&inode->i_lock);
603 }
604
605 EXPORT_SYMBOL(inode_add_bytes);
606
607 void __inode_sub_bytes(struct inode *inode, loff_t bytes)
608 {
609         inode->i_blocks -= bytes >> 9;
610         bytes &= 511;
611         if (inode->i_bytes < bytes) {
612                 inode->i_blocks--;
613                 inode->i_bytes += 512;
614         }
615         inode->i_bytes -= bytes;
616 }
617
618 EXPORT_SYMBOL(__inode_sub_bytes);
619
620 void inode_sub_bytes(struct inode *inode, loff_t bytes)
621 {
622         spin_lock(&inode->i_lock);
623         __inode_sub_bytes(inode, bytes);
624         spin_unlock(&inode->i_lock);
625 }
626
627 EXPORT_SYMBOL(inode_sub_bytes);
628
629 loff_t inode_get_bytes(struct inode *inode)
630 {
631         loff_t ret;
632
633         spin_lock(&inode->i_lock);
634         ret = (((loff_t)inode->i_blocks) << 9) + inode->i_bytes;
635         spin_unlock(&inode->i_lock);
636         return ret;
637 }
638
639 EXPORT_SYMBOL(inode_get_bytes);
640
641 void inode_set_bytes(struct inode *inode, loff_t bytes)
642 {
643         /* Caller is here responsible for sufficient locking
644          * (ie. inode->i_lock) */
645         inode->i_blocks = bytes >> 9;
646         inode->i_bytes = bytes & 511;
647 }
648
649 EXPORT_SYMBOL(inode_set_bytes);